bd-xbc.vue 12 KB

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