ProductCard.vue 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. <!-- components/ProductCard.vue -->
  2. <template>
  3. <view class="product-card">
  4. <!-- 图片容器增加背景和阴影 -->
  5. <view class="image-container">
  6. <image
  7. class="product-image"
  8. :src="data.image"
  9. :webp="true"
  10. v-if="data.image && !isError"
  11. :style="{ background: '#f5f5f5' }"
  12. @error="handleError"
  13. />
  14. <image
  15. v-else
  16. class="product-image"
  17. src="/static/images/new_ui/kongtu.png"
  18. :webp="true"
  19. />
  20. <view v-if="data.activity" class="activity-badge">
  21. {{ data.activity }}
  22. </view>
  23. </view>
  24. <!-- 信息内容区域 -->
  25. <view class="content">
  26. <!-- 标题与状态开关 -->
  27. <view class="header">
  28. <text class="title">{{ data.store_name }}</text>
  29. <switch
  30. :checked="data.is_show==1?true:false"
  31. @change="$emit('status-change', data)"
  32. class="status-switch"
  33. />
  34. </view>
  35. <!-- 核心数据展示 -->
  36. <view class="data-grid">
  37. <view class="data-item">
  38. <text class="label">售价</text>
  39. <text class="value highlight">¥{{data.price ||"0.00"}}</text>
  40. </view>
  41. <view class="data-item">
  42. <text class="label">利润</text>
  43. <text class="value profit">¥{{data.plate_mer_profit ||"0.00"}}</text>
  44. </view>
  45. </view>
  46. <!-- 辅助信息 -->
  47. <view class="meta-info">
  48. <view class="meta-item">
  49. <uni-icons type="shop-filled" size="30" color="#666" />
  50. <text class="kucun">销量 {{data.sales}}</text>
  51. </view>
  52. <view class="meta-item">
  53. <uni-icons type="shop" size="30" color="#666" />
  54. <text :class="{ warn: data.stock < 100 }" class="kucun"
  55. >库存 {{data.stock}}</text
  56. >
  57. </view>
  58. </view>
  59. <view class="meta-info">
  60. <view class="meta-item">
  61. <view style="padding-right:10rpx;font-size:26rpx">活动:</view>
  62. <text :style="{color:data.seckill == 1?'#FF3C29':'#666666','font-size':'26rpx'}">{{data.seckill == 1?'秒杀':'无'}}</text>
  63. </view>
  64. </view>
  65. <!-- 操作按钮 -->
  66. <view class="action-bar">
  67. <button class="action-btn edit-price" @click="$emit('edit-price',data)">
  68. 改价
  69. </button>
  70. <button class="action-btn set-activity" @click="$emit('edit-activity',data)" v-if="!data.spec_type">
  71. 活动
  72. </button>
  73. </view>
  74. </view>
  75. </view>
  76. </template>
  77. <script>
  78. export default {
  79. props: {
  80. data: {
  81. type: Object,
  82. default: () => {
  83. return {
  84. image: "",
  85. store_name: "",
  86. price: 0,//商品售价
  87. sales: 0,//销量
  88. stock: 0,//库存
  89. status: "",//商品状态
  90. is_show: true,//商品状态
  91. plate_mer_profit: 0,//利润
  92. activity: "",//活动
  93. };
  94. },
  95. },
  96. },
  97. data(){
  98. return {
  99. isError:false
  100. }
  101. },
  102. methods:{
  103. getFormData(image){
  104. // console.log(image,"imageimage")
  105. if(image){
  106. return this.data.image
  107. }else{
  108. return "/static/images/new_ui/kongtu.png"
  109. }
  110. },
  111. handleError(e){
  112. this.isError = e.type=="error"?true:false
  113. // console.log(e,"e")
  114. }
  115. }
  116. };
  117. </script>
  118. <style lang="scss" scoped>
  119. .product-card {
  120. background: #fff;
  121. border-radius: 24rpx;
  122. // margin: 24rpx 32rpx;
  123. width: 100%;
  124. box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.06);
  125. overflow: hidden;
  126. display: flex;
  127. flex-direction: column; // 改为纵向布局
  128. .image-container {
  129. position: relative;
  130. height: 320rpx; // 固定图片容器高度
  131. background: #f8f8f8;
  132. .product-image {
  133. width: 100%;
  134. height: 100%;
  135. object-fit: cover;
  136. }
  137. .activity-badge {
  138. position: absolute;
  139. top: 16rpx;
  140. right: 16rpx;
  141. background: rgba(255, 77, 79, 0.9);
  142. color: white;
  143. padding: 8rpx 16rpx;
  144. border-radius: 8rpx;
  145. font-size: 24rpx;
  146. }
  147. }
  148. .content {
  149. padding: 24rpx;
  150. .header {
  151. display: flex;
  152. justify-content: space-between;
  153. margin-bottom: 24rpx;
  154. .title {
  155. font-size: 32rpx;
  156. color: #333;
  157. font-weight: 500;
  158. flex: 1;
  159. overflow: hidden;
  160. text-overflow: ellipsis;
  161. display: -webkit-box;
  162. -webkit-line-clamp: 3;
  163. -webkit-box-orient: vertical;
  164. line-height: 1.4;
  165. }
  166. .status-switch {
  167. transform: scale(0.9);
  168. margin-left: 16rpx;
  169. }
  170. }
  171. .data-grid {
  172. display: grid;
  173. grid-template-columns: repeat(2, 1fr);
  174. gap: 24rpx;
  175. margin-bottom: 24rpx;
  176. .data-item {
  177. .label {
  178. font-size: 28rpx;
  179. color: #999;
  180. margin-bottom: 8rpx;
  181. padding-right: 10rpx;
  182. }
  183. .value {
  184. font-size: 32rpx;
  185. font-weight: 500;
  186. &.highlight {
  187. color: #ff4d4f;
  188. }
  189. &.profit {
  190. color: #07c160;
  191. }
  192. }
  193. }
  194. }
  195. .meta-info {
  196. display: flex;
  197. gap: 32rpx;
  198. margin-bottom: 24rpx;
  199. .meta-item {
  200. display: flex;
  201. align-items: center;
  202. font-size: 24rpx;
  203. color: #666;
  204. flex: 1;
  205. flex-shrink: 0;
  206. text-align: left;
  207. text {
  208. margin-right: 8rpx;
  209. &.kucun {
  210. font-size: 26rpx;
  211. color: #333;
  212. }
  213. &.warn {
  214. color: #faad14;
  215. }
  216. }
  217. }
  218. }
  219. .action-bar {
  220. display: flex;
  221. gap: 16rpx;
  222. border-top: 1rpx solid #eee;
  223. padding-top: 24rpx;
  224. .action-btn {
  225. flex: 1;
  226. height: 72rpx;
  227. line-height: 72rpx;
  228. border-radius: 12rpx;
  229. font-size: 28rpx;
  230. transition: all 0.2s;
  231. &.edit-price {
  232. background: #fff;
  233. color: #007aff;
  234. border: 1rpx solid #007aff;
  235. }
  236. &.set-activity {
  237. background: #007aff;
  238. color: white;
  239. }
  240. &:active {
  241. opacity: 0.8;
  242. transform: scale(0.98);
  243. }
  244. }
  245. }
  246. }
  247. }
  248. </style>