普兆健康管家前端代码仓库
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

250 lines
5.0 KiB

2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
  1. <template>
  2. <view class="flex card">
  3. <view>
  4. <uv-checkbox-group
  5. v-model="checkboxValue"
  6. shape="circle"
  7. @change="onCheckChange"
  8. >
  9. <uv-checkbox
  10. size="36rpx"
  11. icon-size="36rpx"
  12. activeColor="#7451DE"
  13. :name="1"
  14. ></uv-checkbox>
  15. </uv-checkbox-group>
  16. </view>
  17. <view class="flex right" @click="jumpToProductDetail">
  18. <view class="img-box">
  19. <image class="img" :src="coverImg" mode="aspectFit"></image>
  20. </view>
  21. <view class="info">
  22. <view class="title">{{ data.product.name }}</view>
  23. <!-- <view class="desc">{{ data.desc }}</view> -->
  24. <view class="flex price-box">
  25. <view class="flex price">¥<text class="highlight">{{ data.currentPrice }}</text></view>
  26. </view>
  27. <view class="flex tool">
  28. <view class="flex count">
  29. 规格<text class="highlight">{{ data.specName || '' }}</text>
  30. <uv-icon name="arrow-down" color="#7451DE" size="24rpx" :bold="true"></uv-icon>
  31. </view>
  32. <button class="flex btn" @click.stop="openPicker">编辑</button>
  33. </view>
  34. </view>
  35. </view>
  36. <view v-if="data.customized" class="sup customized">
  37. 定制组合
  38. </view>
  39. <view v-else-if="data.free" class="sup free">
  40. 自定组合
  41. </view>
  42. <specOptionsPopup ref="specOptionsPopup" :value="data.specId" :data="data.product" @confirm="onSpecChange"></specOptionsPopup>
  43. </view>
  44. </template>
  45. <script>
  46. import specOptionsPopup from '@/pages_order/product/specOptionsPopup.vue'
  47. export default {
  48. components: {
  49. specOptionsPopup,
  50. },
  51. props: {
  52. data: {
  53. type: Object,
  54. default() {
  55. return {}
  56. }
  57. },
  58. mode: {
  59. type: String,
  60. default: 'read'
  61. },
  62. },
  63. data() {
  64. return {
  65. checkboxValue : [],
  66. }
  67. },
  68. computed: {
  69. checked: {
  70. set(val) {
  71. this.checkboxValue = val ? [1] : []
  72. if (this.data.selected == val) {
  73. return
  74. }
  75. this.$emit('select', val)
  76. },
  77. get() {
  78. return this.checkboxValue[0] == 1 ? true : false
  79. }
  80. },
  81. coverImg() {
  82. const { product } = this.data || {}
  83. const { image } = product || {}
  84. return image?.split(',')?.[0] || ''
  85. },
  86. specOptionsPopupData() {
  87. const { product } = this.data || {}
  88. return {
  89. ...product,
  90. specs: this.specs,
  91. }
  92. },
  93. },
  94. watch: {
  95. data: {
  96. handler(val) {
  97. console.log('card data', this.data)
  98. this.checked = val.selected
  99. },
  100. immediate: true,
  101. deep: true,
  102. }
  103. },
  104. methods: {
  105. onCheckChange(arr) {
  106. this.checked = arr[0] == 1 ? true : false
  107. },
  108. openPicker() {
  109. this.$refs.specOptionsPopup.open()
  110. },
  111. onSpecChange(target) {
  112. this.$emit('change', target)
  113. },
  114. jumpToProductDetail() {
  115. this.$utils.navigateTo(`/pages_order/product/productDetail?id=${this.data.productId}`)
  116. },
  117. },
  118. }
  119. </script>
  120. <style scoped lang="scss">
  121. .card {
  122. position: relative;
  123. height: 240rpx;
  124. padding: 0 32rpx;
  125. background-image: linear-gradient(#FAFAFF, #F3F3F3);
  126. border: 2rpx solid #FFFFFF;
  127. border-radius: 32rpx;
  128. box-sizing: border-box;
  129. column-gap: 24rpx;
  130. overflow: hidden;
  131. /deep/ .uv-checkbox__label-wra {
  132. padding: 0;
  133. }
  134. }
  135. .right {
  136. flex: 1;
  137. column-gap: 24rpx;
  138. }
  139. .img {
  140. &-box {
  141. width: 144rpx;
  142. height: 144rpx;
  143. border-radius: 16rpx;
  144. overflow: hidden;
  145. }
  146. width: 100%;
  147. height: 100%;
  148. }
  149. .info {
  150. flex: 1;
  151. font-family: PingFang SC;
  152. font-weight: 400;
  153. line-height: 1.4;
  154. font-size: 26rpx;
  155. color: #8B8B8B;
  156. .title {
  157. font-weight: 600;
  158. font-size: 28rpx;
  159. color: #000000;
  160. }
  161. .desc {
  162. margin-top: 8rpx;
  163. line-height: 1.5;
  164. }
  165. .price {
  166. &-box {
  167. margin-top: 8rpx;
  168. justify-content: flex-start;
  169. column-gap: 20rpx;
  170. }
  171. font-weight: 600;
  172. font-size: 24rpx;
  173. color: #7451DE;
  174. .highlight {
  175. margin: 0 8rpx;
  176. font-size: 32rpx;
  177. }
  178. &-origin {
  179. font-size: 28rpx;
  180. line-height: 1;
  181. text-decoration: line-through;
  182. }
  183. }
  184. .tool {
  185. margin-top: 8rpx;
  186. justify-content: space-between;
  187. .count {
  188. .highlight {
  189. margin: 0 8rpx;
  190. color: #252545;
  191. }
  192. }
  193. .btn {
  194. padding: 8rpx 40rpx;
  195. font-family: PingFang SC;
  196. font-weight: 600;
  197. font-size: 28rpx;
  198. line-height: 1.5;
  199. color: #FFFFFF;
  200. background: #7451DE;
  201. border-radius: 30rpx;
  202. }
  203. }
  204. }
  205. .sup {
  206. position: absolute;
  207. top: 28rpx;
  208. right: -60rpx;
  209. padding: 5rpx 52rpx;
  210. font-family: PingFang SC;
  211. font-weight: 400;
  212. font-size: 28rpx;
  213. line-height: 1.5;
  214. white-space: nowrap;
  215. transform: rotate(45deg);
  216. &.customized {
  217. color: #FFFFFF;
  218. background: #252545;
  219. }
  220. &.free {
  221. color: #252545;
  222. background: #D7D7FF;
  223. }
  224. }
  225. </style>