inventoryTable.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472
  1. <template>
  2. <el-form ref="form" :model="form" :rules="rules">
  3. <ele-pro-table
  4. ref="table"
  5. :needPage="false"
  6. :columns="columns"
  7. :toolkit="[]"
  8. max-height="500px"
  9. :datasource="form.datasource"
  10. cache-key="systemRoleTable17"
  11. class="time-form"
  12. :selection.sync="selection"
  13. >
  14. <template v-slot:files="scope">
  15. <el-form-item prop="files">
  16. <fileMain v-model="scope.row.files" type="view"></fileMain>
  17. </el-form-item>
  18. </template>
  19. <template v-slot:supplierIds="scope">
  20. <el-form-item prop="supplierIds">
  21. <el-select v-model="scope.row['supplierIds']" clearable filterable multiple collapse-tags @change="handleSupplierSelect(scope.row)">
  22. <el-option v-for="i in scope.row.supplierList" :key="i.id" :value="i.id" :label="i.name"></el-option>
  23. </el-select>
  24. </el-form-item>
  25. </template>
  26. <!-- 操作列 -->
  27. <template v-slot:[item.slot]="scope" v-for="item in supplierList">
  28. <el-form-item
  29. style="margin-bottom: 20px"
  30. :prop="'datasource.' + scope.$index + '.' + item.prop"
  31. :rules="{
  32. required: true,
  33. message: '请输入',
  34. trigger: 'blur'
  35. }"
  36. >
  37. <el-input
  38. type="input"
  39. v-model="scope.row[item.prop]"
  40. placeholder="请输入"
  41. ></el-input>
  42. </el-form-item>
  43. </template>
  44. <template v-slot:[item.headerSlot]="scope" v-for="item in supplierList">
  45. <el-form-item style="margin-bottom: 20px">
  46. <!-- <div style="display: flex"> -->
  47. <span>{{ item.label }}</span>
  48. <fileUpload
  49. v-model="item.files"
  50. module="main"
  51. :showLib="false"
  52. :limit="1"
  53. />
  54. <!-- </div> -->
  55. </el-form-item>
  56. </template>
  57. <!-- </template> -->
  58. <template v-slot:action="scope">
  59. <el-popconfirm
  60. class="ele-action"
  61. title="确定要删除吗?"
  62. @confirm="remove(scope.$index, scope.row.productCode)"
  63. >
  64. <template v-slot:reference>
  65. <el-link type="danger" :underline="false" icon="el-icon-delete">
  66. 删除
  67. </el-link>
  68. </template>
  69. </el-popconfirm>
  70. </template>
  71. </ele-pro-table>
  72. <!-- <head-list ref="headRef" @changeParent="changeAnswer"></head-list> -->
  73. </el-form>
  74. </template>
  75. <script>
  76. import {numberReg} from 'ele-admin';
  77. import dictMixins from '@/mixins/dictMixins';
  78. import fileUpload from '@/components/upload/fileUpload';
  79. import {getFile} from "@/api/system/file";
  80. import {getInventoryTotalAPI} from "@/api/wms";
  81. import {getByCode} from "@/api/system/dictionary-data";
  82. import fileMain from "@/components/addDoc/index.vue";
  83. // import headList from '@/views/saleManage/businessOpportunity/components/headList.vue';
  84. export default {
  85. mixins: [dictMixins],
  86. components: {
  87. fileMain,
  88. fileUpload
  89. // headList
  90. },
  91. props: {
  92. acceptUnpack: {
  93. default: ''
  94. },
  95. isSupplier: {
  96. default:true
  97. }
  98. },
  99. data() {
  100. const defaultForm = {
  101. key: null,
  102. endTime: '',
  103. isFirst: 0,
  104. name: ''
  105. };
  106. return {
  107. numberReg,
  108. defaultForm,
  109. supplierList: [],
  110. selection: [],
  111. // resultList:'',
  112. form: {
  113. datasource: []
  114. },
  115. dictList: {},
  116. files: [],
  117. rules: {},
  118. };
  119. },
  120. computed: {
  121. canHandl() {
  122. return this.form.datasource.length;
  123. },
  124. columns() {
  125. return [
  126. {
  127. width: 50,
  128. label: '序号',
  129. type: 'index',
  130. columnKey: 'index',
  131. align: 'center',
  132. fixed: 'left'
  133. },
  134. {
  135. width: 45,
  136. type: 'selection',
  137. columnKey: 'selection',
  138. align: 'center',
  139. fixed: 'left',
  140. show:this.isSupplier
  141. },
  142. {
  143. minWidth: 100,
  144. prop: 'productCategoryName',
  145. label: '分类',
  146. slot: 'productCategoryName',
  147. showOverflowTooltip: true,
  148. align: "center"
  149. },
  150. {
  151. minWidth: 100,
  152. prop: 'productCode',
  153. label: '编码',
  154. slot: 'productCode',
  155. showOverflowTooltip: true,
  156. align: "center"
  157. },
  158. {
  159. minWidth: 140,
  160. prop: 'productName',
  161. label: '名称',
  162. slot: 'productName',
  163. headerSlot: 'productNameHeader',
  164. showOverflowTooltip: true,
  165. align: "center"
  166. },
  167. {
  168. minWidth: 200,
  169. prop: 'supplierIds',
  170. label: '供应商选择',
  171. slot: 'supplierIds',
  172. showOverflowTooltip: true,
  173. align: "center"
  174. },
  175. {
  176. minWidth: 100,
  177. prop: 'productBrand',
  178. label: '牌号',
  179. slot: 'productBrand',
  180. showOverflowTooltip: true,
  181. align: "center"
  182. },
  183. {
  184. minWidth: 80,
  185. prop: 'totalCount',
  186. label: '数量',
  187. slot: 'totalCount',
  188. showOverflowTooltip: true,
  189. align: "center"
  190. },
  191. {
  192. minWidth: 80,
  193. prop: 'availableCountBase',
  194. label: '库存数量',
  195. slot: 'availableCountBase',
  196. align: "center"
  197. },
  198. {
  199. width: 120,
  200. prop: 'totalWeight',
  201. label: '重量',
  202. slot: 'totalWeight',
  203. align: 'center'
  204. },
  205. {
  206. minWidth: 150,
  207. prop: 'taskName',
  208. label: '工序',
  209. slot: 'taskName',
  210. align: "center"
  211. },
  212. {
  213. width: 110,
  214. prop: 'batchNo',
  215. label: '批次号',
  216. slot: 'batchNo',
  217. align: "center",
  218. },
  219. {
  220. minWidth: 80,
  221. prop: 'measuringUnit',
  222. label: '单位',
  223. slot: 'measuringUnit',
  224. showOverflowTooltip: true,
  225. align: "center"
  226. },
  227. {
  228. minWidth: 130,
  229. prop: 'modelType',
  230. label: '型号',
  231. slot: 'modelType',
  232. showOverflowTooltip: true,
  233. align: "center"
  234. },
  235. {
  236. minWidth: 120,
  237. prop: 'specification',
  238. label: '规格',
  239. slot: 'specification',
  240. showOverflowTooltip: true,
  241. align: "center"
  242. },
  243. // {
  244. // width: 120,
  245. // prop: 'singleWeight',
  246. // label: '单重',
  247. // slot: 'singleWeight',
  248. // align: 'center'
  249. // },
  250. {
  251. minWidth: 120,
  252. prop: 'imgCode',
  253. align: 'center',
  254. label: '图号/件号',
  255. showOverflowTooltip: true
  256. },
  257. {
  258. minWidth: 120,
  259. prop: 'produceType',
  260. align: 'center',
  261. label: '生产类型',
  262. showOverflowTooltip: true,
  263. formatter: (row, column) => {
  264. return row.produceType && row.produceType.length ? row.produceType.map(item => this.getDictV('productionType', item)).join(',') : ''
  265. }
  266. },
  267. {
  268. minWidth: 120,
  269. prop: 'approvalNumber',
  270. align: 'center',
  271. label: '批准文号',
  272. showOverflowTooltip: true
  273. },
  274. {
  275. minWidth: 120,
  276. prop: 'packingSpecification',
  277. align: 'center',
  278. label: '包装规格',
  279. showOverflowTooltip: true
  280. },
  281. // {
  282. // width: 130,
  283. // prop: 'brand',
  284. // label: '品牌',
  285. // slot: 'brand'
  286. // },
  287. {
  288. minWidth: 170,
  289. prop: 'expectReceiveDate',
  290. label: '到货日期',
  291. slot: 'expectReceiveDate',
  292. showOverflowTooltip: true,
  293. align: "center"
  294. },
  295. {
  296. minWidth: 140,
  297. prop: 'files',
  298. label: '附件',
  299. slot: 'files',
  300. align: "center"
  301. },
  302. {
  303. minWidth: 220,
  304. prop: 'remark',
  305. label: '备注',
  306. slot: 'remark',
  307. showOverflowTooltip: true,
  308. align: "center"
  309. },
  310. // {
  311. // columnKey: 'action',
  312. // label: '操作',
  313. // width: 120,
  314. // align: 'center',
  315. // resizable: false,
  316. // slot: 'action',
  317. // fixed: 'right',
  318. // showOverflowTooltip: true
  319. // }
  320. ]
  321. }
  322. },
  323. created() {
  324. this.getDictList('productionType')
  325. },
  326. methods: {
  327. getDictV(code, val) {
  328. if (!this.dictList[code]) return '';
  329. return this.dictList[code].find(item => item.value == val)?.label
  330. },
  331. async getDictList(code) {
  332. let {data: res} = await getByCode(code)
  333. this.dictList[code] = res.map(item => {
  334. let values = Object.keys(item)
  335. return {
  336. value: values[0],
  337. label: item[values[0]]
  338. }
  339. })
  340. },
  341. downloadFile(file) {
  342. getFile({objectName: file.storePath}, file.name);
  343. },
  344. // 返回列表数据
  345. getTableValue() {
  346. let comitDatasource = this.form.datasource;
  347. if (comitDatasource.length === 0) return [];
  348. comitDatasource.forEach((v) => {
  349. v.totalPrice = (v.totalCount * v.singlePrice)?.toFixed(2) || 0;
  350. v.files = v.files || null;
  351. });
  352. return comitDatasource;
  353. },
  354. //修改回显
  355. async putTableValue(data) {
  356. if (data && data?.length) {
  357. this.form.datasource = data;
  358. let codeList = this.form.datasource.map(item => item.productCode)
  359. //获取仓库库存
  360. let inventoryTotalList = await getInventoryTotalAPI(codeList);
  361. this.form.datasource.forEach((item,index) => {
  362. let find = inventoryTotalList.find((key) => key.code == item.productCode) || {};
  363. // item.availableCountBase = find.availableCountBase;
  364. this.$set(this.form.datasource[index], 'availableCountBase', find.availableCountBase);
  365. });
  366. this.$refs.table.reload()
  367. }
  368. },
  369. handleSupplierSelect(row) {
  370. this.$emit('supplierSelect', row);
  371. },
  372. //选择产品
  373. handParent() {
  374. this.$refs.productListRef.open();
  375. },
  376. //选择产品回调
  377. changeParent(obj, idx) {
  378. obj['productBrand'] = obj.brandNum;
  379. obj['productCode'] = obj.code;
  380. obj['productName'] = obj.name;
  381. obj['productCategoryName'] = obj.categoryLevelPath;
  382. obj['productCategoryId'] = obj.categoryLevelId;
  383. this.form.datasource.push(obj);
  384. },
  385. remove(i, productCode) {
  386. if (!this.acceptUnpack) {
  387. this.$message.warning('本采购计划不能拆单');
  388. return;
  389. }
  390. this.form.datasource.splice(i, 1);
  391. this.$emit('delList', productCode);
  392. },
  393. // 清空表格
  394. restTable() {
  395. this.form.datasource = [];
  396. },
  397. // 添加
  398. handlAdd() {
  399. let item = JSON.parse(JSON.stringify(this.defaultForm));
  400. item.key = this.form.datasource.length + 1;
  401. this.form.datasource.push(item);
  402. },
  403. validateForm(callback) {
  404. //开始表单校验
  405. this.$refs.form.validate((valid) => {
  406. callback(valid);
  407. });
  408. }
  409. }
  410. };
  411. </script>
  412. <style lang="scss" scoped>
  413. .headbox {
  414. display: flex;
  415. justify-content: space-between;
  416. align-items: center;
  417. .amount {
  418. font-size: 14px;
  419. font-weight: bold;
  420. }
  421. }
  422. .time-form .el-form-item {
  423. margin-bottom: 0 !important;
  424. }
  425. ::v-deep .period {
  426. display: flex;
  427. .borderleftnone {
  428. .el-input--medium .el-input__inner {
  429. border-top-right-radius: 0;
  430. border-bottom-right-radius: 0;
  431. }
  432. }
  433. .borderrightnone {
  434. .el-input--medium .el-input__inner {
  435. border-top-left-radius: 0;
  436. border-bottom-left-radius: 0;
  437. }
  438. }
  439. }
  440. ::v-deep .time-form tbody > tr:hover > td {
  441. background-color: transparent !important;
  442. }
  443. ::v-deep .time-form .el-table tr {
  444. background-color: #ffffff;
  445. }
  446. </style>