product-item.vue 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. <template>
  2. <view class="b-radius bg-#fff pd-20 p-rtv" @click.stop="handleClick">
  3. <!-- 顶部类型标签和日期 -->
  4. <view class="d-flex j-sb a-c li-item-head mb-16">
  5. <view :class="['li-left-tag', typeBgClass]">{{ selectDictLabel(pt_product_type, item.instoreBizInfo?.productType) }}</view>
  6. <view class="f-s-22 c-#666">{{ item?.productDate || '' }}</view>
  7. </view>
  8. <!-- 主标题和状态 -->
  9. <view class="d-flex flex1 mb-10">
  10. <view class="flex1">
  11. <span class="f-s-34 c-#333 f-w-500 mr-10">{{ item?.instoreBizInfo?.proName || '' }}</span>
  12. <span v-if="item?.instoreBizInfo?.proLevel" class="f-s-24 c-#666">
  13. {{ item?.instoreBizInfo?.proLevel }}
  14. </span>
  15. </view>
  16. <!-- <view v-if="!props.hideExtraInfo">
  17. <view v-if="item?.isInspected" class="tag-span c-primary bg-#EBF6EE">成品已检</view>
  18. <view v-else class="tag-span c-danger bg-#F9ECEA">成品未检</view>
  19. </view> -->
  20. </view>
  21. <view class="" v-if="+item.instoreBizInfo?.productType == 6">
  22. <span v-if="item?.instoreBizInfo?.finalSpecn" class="f-s-24 c-#666"> {{ item?.instoreBizInfo?.finalSpecn }}{{ item?.instoreBizInfo?.finalUnit }} </span>
  23. </view>
  24. <!-- 详细信息 -->
  25. <view class="pd2-4-0 f-s-28 d-flex a-c">
  26. <span class="c-#666">成品批号:</span>
  27. <span class="c-#333 f-w-500 flex1">{{ item?.batchCode || '-' }}</span>
  28. <up-icon v-if="!props.hideExtraInfo" name="arrow-right" size="24rpx" color="#333"></up-icon>
  29. </view>
  30. <view class="pd2-4-0 f-s-28">
  31. <span class="c-#666">包装批号:</span>
  32. <span class="c-#333 f-w-500">{{ item?.instoreBizInfo?.packSn || '-' }}</span>
  33. </view>
  34. <view class="pd2-4-0 f-s-28">
  35. <span class="c-#666">存放库房:</span>
  36. <span class="c-#333 f-w-500">{{ getStorageRoomNames(item?.warehouses) || '-' }}</span>
  37. </view>
  38. <view class="d-flex">
  39. <view class="pd2-4-0 f-s-28 d-flex w-50%">
  40. <view class="c-#666 w-s-no">入库量:</view>
  41. <view class="d-flex flex-cln">
  42. <span class="c-#333 f-w-500 d-flex a-c">{{ item?.specn }}*{{ item?.capacity }}{{ item?.unit }}</span>
  43. <span class="c-#333 f-w-500 d-flex a-c" v-if="item?.restSpecn">{{ item?.restSpecn }}*1{{ item?.unit }}</span>
  44. </view>
  45. </view>
  46. <view class="pd2-4-0 f-s-28 d-flex w-50%">
  47. <span class="c-primary w-s-no">剩余量:</span>
  48. <view class="d-flex flex-cln">
  49. <span class="c-primary f-w-500">{{ item?.specn }}*{{ +item?.restAmount }}{{ item?.unit }}</span>
  50. <span class="c-primary f-w-500 d-flex a-c" v-if="+item?.restRestAmount">{{ item?.restSpecn }}*{{ item?.restRestAmount }}{{ item?.unit }}</span>
  51. </view>
  52. </view>
  53. </view>
  54. </view>
  55. </template>
  56. <script setup lang="ts">
  57. import { getStorageRoomNames } from '@/utils/common';
  58. const { proxy } = getCurrentInstance() as ComponentInternalInstance;
  59. const { pt_product_type } = toRefs<any>(proxy?.useDict('pt_product_type'));
  60. interface RestAmountItem {
  61. amount?: string | number;
  62. unit?: string;
  63. packInfo?: string;
  64. }
  65. const props = defineProps({
  66. item: {
  67. type: Object as () => Record<string, any>,
  68. default: () => ({}),
  69. },
  70. jumpUrl: {
  71. type: String,
  72. default: '',
  73. },
  74. hideExtraInfo: {
  75. type: Boolean,
  76. default: false,
  77. },
  78. });
  79. const emit = defineEmits<{
  80. click: [value: typeof props.item];
  81. }>();
  82. // 类型名称映射(根据数据结构变化可调整)
  83. const typeNameMap: Record<string, string> = {
  84. '1': '药材',
  85. '2': '鲜货',
  86. '3': '种源',
  87. };
  88. const typeName = computed(() => {
  89. const type = props.item?.instoreType || props.item?.typeName;
  90. return typeNameMap[type] || '药材';
  91. });
  92. const typeBgClass = computed(() => `bg-instore-${props.item.instoreBizInfo?.productType}`);
  93. // 剩余量列表(数据结构待定,暂留空数组)
  94. const restAmountList = computed<RestAmountItem[]>(() => {
  95. // 预留数据结构,等待外部传入
  96. // 期望格式:[{ amount: '50', unit: 'kg', packInfo: '袋*40 袋' }]
  97. return [];
  98. });
  99. const handleClick = () => {
  100. // 如果传入了 jumpUrl,则跳转到指定地址
  101. if (props.jumpUrl) {
  102. uni.navigateTo({
  103. url: `${props.jumpUrl}?id=${encodeURIComponent(props.item?.id || '')}`,
  104. });
  105. }
  106. emit('click', props.item);
  107. };
  108. </script>
  109. <style lang="scss" scoped>
  110. .tag-span {
  111. padding: 4rpx 12rpx;
  112. font-size: 20rpx;
  113. border-radius: 18rpx;
  114. }
  115. .li-item-head {
  116. margin-left: -24rpx;
  117. margin-top: -24rpx;
  118. }
  119. .li-left-tag {
  120. padding: 6rpx 16rpx;
  121. color: #fff;
  122. border-radius: 16rpx 0 16rpx 0;
  123. font-size: 20rpx;
  124. font-weight: 500;
  125. }
  126. /* 类型标签背景色 */
  127. .bg-instore-2 {
  128. background-color: #2289e0;
  129. }
  130. /* 药材 - 绿色 */
  131. .bg-instore-4 {
  132. background-color: #ff9800;
  133. }
  134. /* 鲜货 - 橙色 */
  135. .bg-instore-5 {
  136. background-color: #1ebddc;
  137. }
  138. /* 种源 - 蓝色 */
  139. .bg-instore-6 {
  140. background-color: #3fad5b;
  141. }
  142. </style>