bd-xbc.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341
  1. <template>
  2. <view class="bd-xbc">
  3. <template v-if="type === 'goods' && goodsStock > 0 && coAttr === 1">
  4. <view class="dir-left-nowrap cross-center bd-attr bd-server" @click="open('attr')">
  5. <text class="box-grow-0 bd-name">选择</text>
  6. <view class="box-grow-1 attr u-content u-line-1">
  7. {{attrStr}}
  8. </view>
  9. <image class="bd-icon" src="../../../static/image/icon/arrow-right.png"></image>
  10. </view>
  11. <view v-if="newAttrGroups.length > 0 && attrCount > 1" class="bd-x dir-left-nowrap cross-center">
  12. <div class="dir-left-wrap cross-center">
  13. <template v-if="pictureList.length > 0">
  14. <image class="bd-attr-img" v-for="(picture, index) in pictureList" :key="index" :src="picture"></image>
  15. </template>
  16. <template v-else>
  17. <view v-for="attrItem in newAttrGroups" :key="attrItem.attr_name"
  18. class="bd-attr-text bd-attr-count u-line-1">
  19. {{attrItem.attr_name}}
  20. </view>
  21. </template>
  22. </div>
  23. <view v-if="attrCount > 0" class="bd-attr-count t-omit">
  24. 共{{attrCount}}个{{attrName}}可选
  25. </view>
  26. </view>
  27. </template>
  28. <view v-if="services.length" class="dir-left-nowrap cross-center bd-server" @click.stop="open('service')">
  29. <text class="box-grow-0 bd-name">保障</text>
  30. <view class="box-grow-1 u-content u-line-1">
  31. {{serviceStr}}
  32. </view>
  33. <image class="bd-icon" src="../../../static/image/icon/arrow-right.png"></image>
  34. </view>
  35. <view v-if="param_content.length" class="dir-left-nowrap cross-center bd-server" @click.stop="open('param')">
  36. <text class="box-grow-0 bd-name">参数</text>
  37. <view class="box-grow-1 u-content u-line-1">
  38. {{paramStr}}
  39. </view>
  40. <image class="bd-icon" src="../../../static/image/icon/arrow-right.png"></image>
  41. </view>
  42. <u-popup v-model="show" mode="bottom" border-radius="14" @close="show = false">
  43. <view class="model">
  44. <view class="f-top dir-left-nowrap main-between cross-center">
  45. <view class="f-title dir-left-nowrap cross-center u-line-1">
  46. <template v-if="isShow === 'service'">
  47. <image class="u-top-icon" :src="guaranteePic"></image>
  48. <view>
  49. {{guaranteeTitle}}
  50. </view>
  51. </template>
  52. <template v-else-if="isShow === 'param'">
  53. <view class="p-title">{{ param_name }}</view>
  54. </template>
  55. </view>
  56. <view class="f-image" @click="show = false">
  57. <image class="f-img" src="/static/image/icon/icon-close.png"></image>
  58. </view>
  59. </view>
  60. <scroll-view scroll-y class="f-scroll">
  61. <view class="f-scroll-content">
  62. <template v-if="isShow === 'service'">
  63. <view class="f-item dir-top-nowrap" v-for="(item, index) in services" :key="index">
  64. <view class="dir-left-nowrap cross-center">
  65. <image class="u-icon" :src="item.pic"></image>
  66. <view class="u-name">{{item.name}}</view>
  67. </view>
  68. <text class="u-remark">{{item.remark}}</text>
  69. </view>
  70. </template>
  71. <template v-else-if="isShow === 'param'">
  72. <view v-for="(con, index) of param_content" :key="index" class="p-box dir-left-nowrap cross-center">
  73. <view class="p-label">{{ con.key }}</view>
  74. <view class="p-value">{{ con.value }}</view>
  75. </view>
  76. </template>
  77. </view>
  78. </scroll-view>
  79. </view>
  80. </u-popup>
  81. </view>
  82. </template>
  83. <script>
  84. import uPopup from '../../basic-component/u-popup/u-popup.vue';
  85. export default {
  86. name: "bd-xbc",
  87. props: {
  88. attrGroups: Array,
  89. services: Array,
  90. attrList: Array,
  91. guaranteeTitle: String,
  92. guaranteePic: String,
  93. param_content: Array,
  94. param_name: String,
  95. type: String,
  96. goodsStock: Number,
  97. coAttr: {
  98. type: Number,
  99. default: 1
  100. }
  101. },
  102. data() {
  103. return {
  104. attrStr: `请选择规格`,
  105. serviceStr: ``,
  106. paramStr: ``,
  107. newAttrGroups: [],
  108. attrCount: [],
  109. attrName: '',
  110. pictureList: [],
  111. show: false,
  112. isShow: '',
  113. }
  114. },
  115. watch: {
  116. attrList: {
  117. deep: true,
  118. immediate: true,
  119. handler: function(newVal) {
  120. let str = ``;
  121. if (!this.$validation.isEmpty(newVal)) {
  122. newVal.forEach(item => {
  123. str += `${item.attr_group_name}:${item.attr_name} `;
  124. });
  125. } else {
  126. str = '请选择规格';
  127. }
  128. this.attrStr = str;
  129. }
  130. },
  131. services: {
  132. immediate: true,
  133. handler: function() {
  134. let str = ``;
  135. if (!this.$validation.isEmpty(this.services)) {
  136. this.services.forEach(item => {
  137. str += `${item.name} · `;
  138. });
  139. }
  140. str = str.substring(0, str.lastIndexOf(' · ') + 1);
  141. this.serviceStr = str;
  142. }
  143. },
  144. attrGroups: {
  145. immediate: true,
  146. handler(newVal) {
  147. this.newAttrGroups = [];
  148. this.pictureList = [];
  149. this.attrCount = 0;
  150. this.attrName = '';
  151. newVal.forEach((item, index) => {
  152. if (!this.attrName) {
  153. this.attrName = item.attr_group_name;
  154. item.attr_list.forEach( () => {
  155. this.attrCount += 1;
  156. });
  157. }
  158. if (index === 0) {
  159. item.attr_list.forEach(item2 => {
  160. if (this.newAttrGroups.length < 3) this.newAttrGroups.push(item2);
  161. if (item2.pic_url && this.pictureList.length < 5) this.pictureList.push(item2.pic_url);
  162. });
  163. }
  164. });
  165. }
  166. },
  167. param_content: {
  168. immediate: true,
  169. handler: function(newVal) {
  170. let str = ``;
  171. if (!this.$validation.isEmpty(newVal)) {
  172. newVal.forEach(item => {
  173. str += `${item.key} `;
  174. });
  175. }
  176. str = str.substring(0, str.lastIndexOf(' ') + 1);
  177. this.paramStr = str;
  178. }
  179. }
  180. },
  181. components: {
  182. uPopup
  183. },
  184. methods: {
  185. open(data) {
  186. if (data === 'attr') {
  187. this.$emit('openAttr');
  188. } else {
  189. this.show = true;
  190. this.isShow = data;
  191. }
  192. }
  193. }
  194. }
  195. </script>
  196. <style scoped>
  197. .bd-xbc {
  198. width: 100%;
  199. background-color: #ffffff;
  200. padding: 20upx;
  201. margin-top: 16upx;
  202. }
  203. .bd-icon {
  204. width: 12upx;
  205. height: 22upx;
  206. position: absolute;
  207. right: 0;
  208. }
  209. .bd-attr {
  210. position: relative;
  211. line-height: 36upx;
  212. }
  213. .bd-name {
  214. margin-right: 26upx;
  215. color: #999999;
  216. font-size: 26upx;
  217. }
  218. .bd-server {
  219. position: relative;
  220. margin-top: 20upx;
  221. line-height: 36upx;
  222. }
  223. .bd-server:first-child {
  224. margin-top: 0;
  225. }
  226. .u-content {
  227. color: #353535;
  228. font-size: 26upx;
  229. padding-right: 20upx;
  230. }
  231. .bd-attr-count {
  232. max-width: 200upx;
  233. background: #f7f7f7;
  234. color: #999999;
  235. height: 51upx;
  236. line-height: 51upx;
  237. border-radius: 8upx;
  238. font-size: 24upx;
  239. padding: 0 20upx;
  240. }
  241. .bd-x {
  242. margin: 30upx 0 0 100upx;
  243. }
  244. .bd-attr-text {
  245. width: 100upx;
  246. text-align: center;
  247. margin-right: 7upx;
  248. }
  249. .bd-attr-img {
  250. width: 54upx;
  251. height: 54upx;
  252. margin-right: 7upx;
  253. }
  254. .model {
  255. height: 80vh;
  256. width: 750upx;
  257. }
  258. .f-top {
  259. height: 105upx;
  260. background-color: #ffffff;
  261. position: relative;
  262. border-radius: 15rpx;
  263. }
  264. .f-image {
  265. width: 78upx;
  266. height: 78upx;
  267. padding: 24upx;
  268. position: absolute;
  269. right: 0;
  270. }
  271. .f-img {
  272. width: 30upx;
  273. height: 30upx;
  274. }
  275. .f-title {
  276. position: absolute;
  277. left: 50%;
  278. transform: translateX(-50%);
  279. max-width: 594upx;
  280. }
  281. .f-scroll {
  282. height: calc(80vh - 105upx);
  283. width: 100%;
  284. }
  285. .f-scroll-content {
  286. padding: 0 24upx;
  287. }
  288. .u-icon {
  289. width: 24upx;
  290. height: 24upx;
  291. }
  292. .u-name {
  293. color: #353535;
  294. font-size: 24upx;
  295. margin-left: 20upx;
  296. }
  297. .u-remark {
  298. font-size: 24upx;
  299. color: #999999;
  300. margin-top: 26upx;
  301. margin-left: 44upx;
  302. }
  303. .f-item {
  304. margin-bottom: 30upx;
  305. }
  306. .u-top-icon {
  307. width: 28upx;
  308. height: 28upx;
  309. margin-right: 10upx;
  310. }
  311. .p-title {
  312. font-size: 28upx;
  313. line-height: 106upx;
  314. color: #000000;
  315. text-align: center;
  316. overflow: hidden;
  317. white-space: nowrap;
  318. }
  319. .p-box {
  320. padding: 32upx 0;
  321. font-size: 26upx;
  322. border-bottom: 1upx solid #e2e2e2;
  323. }
  324. .p-box:last-child{
  325. border-width: 0;
  326. }
  327. .p-label {
  328. width: 120upx;
  329. min-width: 120upx;
  330. color: #999999;
  331. margin-right: calc(36upx);
  332. word-break: break-word;
  333. }
  334. .p-value {
  335. color: #353535;
  336. word-break: break-word;
  337. }
  338. </style>