inventoryTable.vue 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. <template>
  2. <view class="mainBox">
  3. <view v-for="(item, index) in productList" :key="index">
  4. <myCard :item="item" :index="index + 1" :columns="columns">
  5. <!-- 产品名称(标题行) -->
  6. <view slot="productName">
  7. <text style="font-weight: 600;">{{ item.productName || '-' }}</text>
  8. </view>
  9. <!-- 供应商选择 -->
  10. <view slot="supplierIds">
  11. <view v-if="isView" class="supplier-view">
  12. <text class="supplier-text">{{ getSupplierNames(item) || '点击选择供应商' }}</text>
  13. <text class="arrow">›</text>
  14. </view>
  15. <view v-else>
  16. <u-row gutter="10">
  17. <u-col span="8">
  18. <view class="supplier-tags" @click="openPicker(item, index)">
  19. <text v-if="!item.supplierIds || !item.supplierIds.length" class="placeholder">选择供应商</text>
  20. <!-- <u-tag v-for="sId in (item.supplierIds || [])" :key="sId" :text="getSupplierNameById(item, sId)" size="mini" type="success" :closeable="true" @close="removeSupplierId(item, index, sId)"></u-tag> -->
  21. <text v-else>{{ getSupplierNames(item) || '-' }}</text>
  22. </view>
  23. </u-col>
  24. <u-col span="4">
  25. <view class="supplier-tags" @click="openPicker(item, index)">
  26. <u-tag text="选择" size="mini" type="primary" @click="openPicker(item, index)"></u-tag>
  27. </view>
  28. </u-col>
  29. </u-row>
  30. </view>
  31. </view>
  32. <!-- 核价状态 -->
  33. <view slot="isInquiry">
  34. <text>{{ getInquiryStatus(item.isInquiry) || '-' }}</text>
  35. </view>
  36. <!-- 物品级别 -->
  37. <view slot="goodsLevel">
  38. <text>{{ getGoodsLevel(item.goodsLevel) || '-' }}</text>
  39. </view>
  40. <!-- 属性类型 -->
  41. <view slot="produceType">
  42. <text>{{ getProduceType(item.produceType) || '-' }}</text>
  43. </view>
  44. <!-- 产地 -->
  45. <view slot="provenance">
  46. <text>{{ getProvenance(item.provenance) || '-' }}</text>
  47. </view>
  48. <!-- 附件 -->
  49. <view slot="files">
  50. <fileMain :value="item.files || []" type="view" v-if="item.files && item.files.length"></fileMain>
  51. <text v-else>-</text>
  52. </view>
  53. <!-- 备注 -->
  54. <view slot="remark">
  55. <text>{{ item.remark || '-' }}</text>
  56. </view>
  57. </myCard>
  58. </view>
  59. <u-gap height="20" bgColor="#f0f0f0"></u-gap>
  60. <u-empty v-if="!productList.length" text="暂无物品" mode="list"></u-empty>
  61. <!-- 选择物品类型 -->
  62. <ba-tree-picker ref="treePicker" :multiple="true" @select-change="suplierConfirm" title="选择供应商"
  63. :localdata="supplierOptions" valueKey="id" textKey="name" childrenKey="child" />
  64. </view>
  65. </template>
  66. <script>
  67. import myCard from '@/pages/purchasingManage/components/myCard.vue'
  68. import fileMain from "@/pages/doc/index.vue"
  69. import { levelList, lbjtList } from '@/enum/dict.js'
  70. export default {
  71. components: {
  72. myCard,
  73. fileMain
  74. },
  75. props: {
  76. productList: {
  77. type: Array,
  78. default: () => []
  79. },
  80. status: {
  81. type: String,
  82. default: 'edit'
  83. },
  84. acceptUnpack: {
  85. default: ''
  86. }
  87. },
  88. data() {
  89. return {
  90. supplierOptions: [],
  91. currentIndex: -1,
  92. selection: [],
  93. // 核价状态
  94. inquiryStatusList: [
  95. { value: 0, text: '未核价' },
  96. { value: 1, text: '部分核价' },
  97. { value: 2, text: '全部核价完成' }
  98. ],
  99. }
  100. },
  101. computed: {
  102. isView() {
  103. return this.status === 'Detail'
  104. },
  105. btnList() {
  106. if (this.isView) return []
  107. return [
  108. {
  109. name: '生成报价单',
  110. apiName: 'supplierSelect',
  111. btnType: 'primary',
  112. type: '2',
  113. judge: [{ fn: (row) => !this.isView && row.supplierIds && row.supplierIds.length > 0 }]
  114. },
  115. {
  116. name: '删除',
  117. apiName: 'del',
  118. btnType: 'error',
  119. type: '2',
  120. judge: [{ fn: () => !this.isView && !!this.acceptUnpack }]
  121. }
  122. ]
  123. },
  124. columns() {
  125. return [
  126. [{ label: '名称:', prop: 'productName', slot: 'productName', type: 'title', className: 'perce100' }],
  127. [{ label: '编码:', prop: 'productCode' }, { label: '分类:', prop: 'productCategoryName' }],
  128. [{ label: '核价状态:', prop: 'isInquiry', slot: 'isInquiry' }, { label: '物品级别:', prop: 'goodsLevel', slot: 'goodsLevel' }],
  129. [{ label: '供应商:', prop: 'supplierIds', slot: 'supplierIds', className: 'perce100' }],
  130. [{ label: '数量:', prop: 'purchaseCount', formatter: (item) => (item.purchaseCount || item.totalCount || '-') + ' ' + (item.purchaseUnit || item.measuringUnit || '') },
  131. { label: '库存:', prop: 'availableCountBase', formatter: (item) => (item.availableCountBase || '-') + ' ' + (item.measuringUnit || '') }],
  132. [{ label: '型号:', prop: 'modelType' }, { label: '规格:', prop: 'specification' }],
  133. [{ label: '牌号:', prop: 'productBrand' }, { label: '图号/件号:', prop: 'imgCode' }],
  134. [{ label: '包装规格:', prop: 'packingSpecification' }, { label: '重量:', prop: 'totalWeight' }],
  135. [{ label: '属性类型:', prop: 'produceType', slot: 'produceType' }, { label: '产地:', prop: 'provenance', slot: 'provenance' }],
  136. [{ label: '工序:', prop: 'taskName' }, { label: '批次号:', prop: 'batchNo' }],
  137. [{ label: '到货日期:', prop: 'expectReceiveDate' }, { label: '附件:', prop: 'files', slot: 'files' }],
  138. [{ label: '备注:', prop: 'remark', slot: 'remark', className: 'perce100' }]
  139. ]
  140. }
  141. },
  142. methods: {
  143. openPicker(item, index) {
  144. this.supplierOptions = item.supplierList || []
  145. this.currentIndex = index
  146. this.$refs.treePicker._show()
  147. },
  148. suplierConfirm(data, name, allList) {
  149. if (this.currentIndex === -1) return
  150. const item = this.productList[this.currentIndex]
  151. if (!item) return
  152. this.$set(item, 'supplierIds', (allList || []).map(s => s.id))
  153. },
  154. // 获取核价状态文本
  155. getInquiryStatus(val) {
  156. const found = this.inquiryStatusList.find(item => item.value == val)
  157. return found ? found.text : ''
  158. },
  159. getGoodsLevel(val) {
  160. const found = levelList.find(item => item.value == val)
  161. return found ? found.label || found.text : ''
  162. },
  163. getProduceType(val) {
  164. if (val && val.length) {
  165. return val.map(item => lbjtList[item] || item).toString()
  166. }
  167. return ''
  168. },
  169. getProvenance(val) {
  170. if (val && val.length) {
  171. return val.join(',')
  172. }
  173. return ''
  174. },
  175. getSupplierNames(item) {
  176. console.log('item-------', item)
  177. return (item.supplierIds || []).map(id => {
  178. const sup = (item.supplierList || []).find(s => s.id == id)
  179. return sup ? sup.name : ''
  180. }).filter(Boolean).join(', ')
  181. },
  182. getSupplierNameById(item, id) {
  183. const sup = (item.supplierList || []).find(s => s.id == id)
  184. return sup ? sup.name : id
  185. },
  186. removeSupplierId(item, index, id) {
  187. this.$set(this.productList[index], 'supplierIds', (item.supplierIds || []).filter(i => i != id))
  188. },
  189. onSupplierSelect(item, index) {
  190. console.log('onSupplierSelect~~', item)
  191. this.$emit('supplierSelect', item, index)
  192. },
  193. delProduct(index) {
  194. if (!this.acceptUnpack) {
  195. uni.showToast({ title: '本采购计划不能拆单', icon: 'none' })
  196. return
  197. }
  198. const code = this.productList[index]?.productCode
  199. this.productList.splice(index, 1)
  200. this.$emit('delList', code)
  201. },
  202. // 返回列表数据
  203. getTableValue() {
  204. const datasource = this.productList
  205. if (!datasource.length) return []
  206. datasource.forEach(v => {
  207. v.totalPrice = (v.totalCount * v.singlePrice)?.toFixed(2) || 0
  208. v.files = v.files || null
  209. })
  210. return datasource
  211. }
  212. }
  213. }
  214. </script>
  215. <style lang="scss" scoped>
  216. .mainBox {
  217. background: #fff;
  218. }
  219. .supplier-view {
  220. display: flex;
  221. align-items: center;
  222. justify-content: space-between;
  223. min-height: 44rpx;
  224. color: #157A2C;
  225. font-size: 26rpx;
  226. .supplier-text {
  227. flex: 1;
  228. overflow: hidden;
  229. text-overflow: ellipsis;
  230. white-space: nowrap;
  231. }
  232. .arrow {
  233. font-size: 32rpx;
  234. color: #ccc;
  235. margin-left: 8rpx;
  236. }
  237. }
  238. .supplier-tags {
  239. display: flex;
  240. flex-wrap: wrap;
  241. align-items: center;
  242. min-height: 44rpx;
  243. gap: 8rpx;
  244. .placeholder {
  245. color: #ccc;
  246. font-size: 26rpx;
  247. }
  248. }
  249. .text-gray {
  250. color: #999;
  251. font-size: 24rpx;
  252. }
  253. </style>