goodsDetail.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504
  1. <template>
  2. <ele-modal
  3. :visible.sync="visible"
  4. :title="title"
  5. v-if="visible"
  6. width="65vw"
  7. append-to-body
  8. :maxable="true"
  9. >
  10. <ele-pro-table
  11. ref="entrustCreateTable"
  12. :columns="columns"
  13. :datasource="goodsList"
  14. :selection.sync="selection"
  15. :current.sync="current"
  16. highlight-current-row
  17. row-key="id"
  18. height="40vh"
  19. >
  20. <template v-slot:quantity="{ row }">
  21. <span>{{ row.quantity }}{{ row.measuringUnit }}</span>
  22. </template>
  23. <!-- <template v-slot:receiveQuantity="{ row }">
  24. <el-input
  25. placeholder=""
  26. v-model="row.receiveQuantity"
  27. :disabled="type == 'detail' || type == 'send'"
  28. >
  29. <template slot="append">{{ row.measuringUnit }}</template>
  30. </el-input>
  31. </template> -->
  32. <template v-slot:receiveQuantity="{ row }">
  33. <el-input placeholder="" v-model="row.receiveQuantity" disabled>
  34. <template slot="append">{{ row.measuringUnit }}</template>
  35. </el-input>
  36. </template>
  37. <template v-slot:weight="{ row }">
  38. <span>{{ row.weight }}{{ row.weightUnit }}</span>
  39. </template>
  40. <template v-slot:rootCategoryLevelId="{ row }">
  41. <el-tag>{{ typeName[Number(row.rootCategoryLevelId)] }}</el-tag>
  42. </template>
  43. <template v-slot:status="{ row }">
  44. <span>{{ row.status == 1 ? "已发货" : row.status == 2 ? "已收货" : "驳回"}}</span>
  45. </template>
  46. <template v-slot:isTransferToProductionPlan="{ row }">
  47. <span>{{ row.isTransferToProductionPlan == 1 ? "已转生产计划" : "未转生产计划"}}</span>
  48. </template>
  49. <template v-slot:isMeasuring="{ row }">
  50. <span>{{ row.isMeasuring == 1 ? "是" : "否"}}</span>
  51. </template>
  52. </ele-pro-table>
  53. <template v-slot:footer v-if="type != 'detail' && type != 'send'">
  54. <el-button @click="cancel">取消</el-button>
  55. <el-button type="primary" @click="rejectReason"> 驳回 </el-button>
  56. <el-button type="primary" @click="save"> 确认收货 </el-button>
  57. </template>
  58. <!-- 驳回原因弹窗 -->
  59. <el-dialog
  60. :visible.sync="rejectDialogVisible"
  61. v-if="rejectDialogVisible"
  62. title="请输入驳回原因"
  63. width="30vw"
  64. append-to-body
  65. :close-on-click-modal="false"
  66. :before-close="
  67. () => {
  68. rejectDialogVisible = false;
  69. }
  70. "
  71. >
  72. <el-form
  73. ref="rejectForm"
  74. :model="rejectForm"
  75. :rules="rejectRules"
  76. label-width="80px"
  77. >
  78. <el-form-item label="原因" prop="reason">
  79. <el-input
  80. type="textarea"
  81. v-model="rejectForm.reason"
  82. placeholder="请输入驳回原因"
  83. rows="4"
  84. ></el-input>
  85. </el-form-item>
  86. </el-form>
  87. <span slot="footer" class="dialog-footer">
  88. <el-button @click="rejectDialogVisible = false">取消</el-button>
  89. <el-button type="primary" @click="confirmReject">确定</el-button>
  90. </span>
  91. </el-dialog>
  92. </ele-modal>
  93. </template>
  94. <script>
  95. import { pleaseEntrustGoodsDetail } from '@/api/entrust';
  96. import { confirmReceipt, rejectGoods } from '@/api/beEntrusted';
  97. import { typeName } from '@/views/produce/components/common.js';
  98. export default {
  99. data() {
  100. return {
  101. visible: false,
  102. goodsList: [],
  103. selection: [],
  104. current: null,
  105. typeName,
  106. id: '',
  107. type: '',
  108. title: '',
  109. loading: null,
  110. // 驳回弹窗
  111. rejectDialogVisible: false,
  112. rejectForm: { reason: '' },
  113. rejectRules: {
  114. reason: [
  115. { required: true, message: '请输入驳回原因', trigger: 'blur' }
  116. ]
  117. },
  118. itemData: {}
  119. };
  120. },
  121. computed: {
  122. columns() {
  123. return [
  124. {
  125. width: 45,
  126. type: 'selection',
  127. columnKey: 'selection',
  128. align: 'center',
  129. reserveSelection: true
  130. },
  131. {
  132. columnKey: 'index',
  133. label: '序号',
  134. type: 'index',
  135. width: 55,
  136. align: 'center',
  137. showOverflowTooltip: true,
  138. fixed: 'left'
  139. },
  140. {
  141. prop: 'categoryName',
  142. label: '名称',
  143. align: 'center',
  144. minWidth: 110,
  145. showOverflowTooltip: true
  146. },
  147. {
  148. prop: 'brandNum',
  149. label: '牌号',
  150. align: 'center',
  151. minWidth: 110,
  152. showOverflowTooltip: true
  153. },
  154. {
  155. prop: 'batchNo',
  156. label: '批次号',
  157. align: 'center',
  158. minWidth: 110,
  159. showOverflowTooltip: true
  160. },
  161. // {
  162. // prop: 'quantity',
  163. // slot: 'quantity',
  164. // label: '数量',
  165. // align: 'center',
  166. // minWidth: 110,
  167. // showOverflowTooltip: true
  168. // },
  169. {
  170. prop: 'receiveQuantity',
  171. slot: 'receiveQuantity',
  172. label: '接收数量',
  173. align: 'center',
  174. minWidth: 150,
  175. showOverflowTooltip: true,
  176. show: this.type != 'send' ? true : false
  177. },
  178. {
  179. prop: 'workOrderCode',
  180. label: '生产工单号',
  181. align: 'center',
  182. minWidth: 110,
  183. showOverflowTooltip: true
  184. },
  185. {
  186. prop: 'specification',
  187. label: '规格',
  188. align: 'center',
  189. minWidth: 110,
  190. showOverflowTooltip: true
  191. },
  192. {
  193. prop: 'modelType',
  194. label: '型号',
  195. align: 'center',
  196. minWidth: 110,
  197. showOverflowTooltip: true
  198. },
  199. // {
  200. // prop: 'taskName',
  201. // label: '工序',
  202. // align: 'center',
  203. // minWidth: 150,
  204. // showOverflowTooltip: true
  205. // },
  206. {
  207. prop: 'categoryCode',
  208. label: '编码',
  209. align: 'center',
  210. showOverflowTooltip: true
  211. },
  212. {
  213. prop: 'weight',
  214. slot: 'weight',
  215. label: '重量',
  216. align: 'center',
  217. showOverflowTooltip: true
  218. },
  219. {
  220. prop: 'rootCategoryLevelId',
  221. slot: 'rootCategoryLevelId',
  222. label: '类型',
  223. align: 'center',
  224. showOverflowTooltip: true
  225. },
  226. {
  227. prop: 'status',
  228. slot: 'status',
  229. label: '状态',
  230. align: 'center',
  231. showOverflowTooltip: true
  232. },
  233. // {
  234. // prop: 'isTransferToProductionPlan',
  235. // slot: 'isTransferToProductionPlan',
  236. // label: '是否转生产计划',
  237. // align: 'center',
  238. // showOverflowTooltip: true
  239. // }
  240. {
  241. prop: 'isMeasuring',
  242. slot: 'isMeasuring',
  243. label: '是否收货',
  244. align: 'center',
  245. showOverflowTooltip: true
  246. }
  247. ];
  248. }
  249. },
  250. methods: {
  251. open(item, type) {
  252. this.visible = true;
  253. this.id = item.id;
  254. this.itemData = item;
  255. this.type = type;
  256. this.title = this.type != 'send' ? '收货单' : '发货单';
  257. this.getDetail(item.id);
  258. },
  259. async getDetail(id) {
  260. const detailType = this.type != 'send' ? 1 : 2;
  261. const obj = {
  262. id,
  263. detailType,
  264. }
  265. if(this.type === 'send') {
  266. obj.detailType = 3;
  267. }
  268. if(this.type === 'detail') {
  269. obj.detailType = 2;
  270. }
  271. if(this.type === 'add') {
  272. obj.status = 1;
  273. }
  274. await pleaseEntrustGoodsDetail(obj).then((res) => {
  275. this.goodsList = [];
  276. res.data.forEach((item) => {
  277. if (this.type != 'detail') {
  278. item.receiveQuantity = item.quantity;
  279. }
  280. item.sendStatus = 2;
  281. this.goodsList.push(this.deepCopy(item));
  282. });
  283. });
  284. },
  285. // save() {
  286. // if (this.selection.length == 0) {
  287. // return this.$message.warning('请先选择一条收货数据!');
  288. // }
  289. // const selectionIds = new Set(this.selection.map((it) => it.id));
  290. // for (let item of this.goodsList) {
  291. // if (!selectionIds.has(item.id)) {
  292. // item.receiveQuantity = 0;
  293. // }
  294. // }
  295. // if (
  296. // Number(this.itemData.sendOutQuantity) <
  297. // Number(this.itemData.formingNum)
  298. // ) {
  299. // this.$confirm('收货数量小于请托数量是否继续收货?', '提示', {
  300. // type: 'warning'
  301. // })
  302. // .then(() => {
  303. // this.loading = this.$loading({
  304. // lock: true,
  305. // text: '加载中',
  306. // background: 'rgba(0, 0, 0, 0.7)'
  307. // });
  308. // confirmReceipt(this.goodsList)
  309. // .then((res) => {
  310. // this.loading.close();
  311. // this.$message.success('收货成功');
  312. // this.$emit('done');
  313. // this.visible = false;
  314. // })
  315. // .catch(() => {
  316. // this.loading.close();
  317. // });
  318. // })
  319. // .catch(() => {});
  320. // } else if (
  321. // Number(this.itemData.sendOutQuantity) ==
  322. // Number(this.itemData.formingNum)
  323. // ) {
  324. // this.loading = this.$loading({
  325. // lock: true,
  326. // text: '加载中',
  327. // background: 'rgba(0, 0, 0, 0.7)'
  328. // });
  329. // confirmReceipt(this.goodsList)
  330. // .then((res) => {
  331. // this.loading.close();
  332. // this.$message.success('收货成功');
  333. // this.$emit('done');
  334. // this.visible = false;
  335. // })
  336. // .catch(() => {
  337. // this.loading.close();
  338. // });
  339. // } else if (
  340. // Number(this.itemData.sendOutQuantity) >
  341. // Number(this.itemData.formingNum)
  342. // ) {
  343. // this.$confirm('收货数量大于请托数量是否继续收货?', '提示', {
  344. // type: 'warning'
  345. // })
  346. // .then(() => {
  347. // this.loading = this.$loading({
  348. // lock: true,
  349. // text: '加载中',
  350. // background: 'rgba(0, 0, 0, 0.7)'
  351. // });
  352. // confirmReceipt(this.goodsList)
  353. // .then((res) => {
  354. // this.loading.close();
  355. // this.$message.success('收货成功');
  356. // this.$emit('done');
  357. // this.visible = false;
  358. // })
  359. // .catch(() => {
  360. // this.loading.close();
  361. // });
  362. // })
  363. // .catch(() => {});
  364. // }
  365. // },
  366. save() {
  367. if (this.selection.length === 0) {
  368. return this.$message.warning('请先选择一条收货数据!');
  369. }
  370. // 仅提交勾选的数据
  371. const selectedList = this.selection.map((item) => this.deepCopy(item));
  372. const totalNum = this.selection.reduce(
  373. (total, pro) => total + Number(pro.receiveQuantity || 0),
  374. 0
  375. );
  376. const formingNum = Number(this.itemData.sendOutQuantity);
  377. let confirmMessage = '';
  378. console.log(totalNum, formingNum, '8888');
  379. if (totalNum < formingNum) {
  380. confirmMessage = '收货数量小于请托数量,是否继续收货?';
  381. } else if (totalNum > formingNum) {
  382. confirmMessage = '收货数量大于请托数量,是否继续收货?';
  383. }
  384. const doConfirmReceipt = () => {
  385. this.loading = this.$loading({
  386. lock: true,
  387. text: '加载中',
  388. background: 'rgba(0, 0, 0, 0.7)'
  389. });
  390. confirmReceipt(selectedList)
  391. .then(() => {
  392. this.loading.close();
  393. this.$message.success('收货成功');
  394. this.$emit('done');
  395. this.visible = false;
  396. })
  397. .catch(() => {
  398. this.loading.close();
  399. });
  400. };
  401. // if (confirmMessage) {
  402. // this.$confirm(confirmMessage, '提示', { type: 'warning' })
  403. // .then(() => doConfirmReceipt())
  404. // .catch(() => {});
  405. // } else {
  406. doConfirmReceipt();
  407. // }
  408. },
  409. cancel() {
  410. this.visible = false;
  411. },
  412. rejectReason() {
  413. this.rejectDialogVisible = true;
  414. },
  415. confirmReject() {
  416. if (this.selection.length === 0) {
  417. return this.$message.warning('请先选择一条驳回数据!');
  418. }
  419. this.$refs.rejectForm.validate((valid) => {
  420. if (!valid) return;
  421. this.$confirm('确认要驳回所选数据吗?', '提示', { type: 'warning' })
  422. .then(() => {
  423. // 仅提交勾选的数据
  424. const ids = this.selection.map((it) => it.id);
  425. console.log('7777');
  426. rejectGoods({
  427. ids,
  428. applyId: this.id,
  429. beReason: this.rejectForm.reason
  430. }).then(() => {
  431. this.$message.success('驳回成功');
  432. this.rejectDialogVisible = false;
  433. this.visible = false;
  434. this.$emit('done');
  435. });
  436. })
  437. .catch(() => {});
  438. });
  439. },
  440. chooseData(dataList) {
  441. this.goodsList = [];
  442. dataList.forEach((item) => {
  443. this.goodsList.push(this.deepCopy(item));
  444. });
  445. },
  446. deepCopy(obj, hash = new WeakMap()) {
  447. if (obj === null) return null;
  448. if (obj instanceof Date) return new Date(obj);
  449. if (obj instanceof RegExp) return new RegExp(obj);
  450. if (typeof obj !== 'object' && typeof obj !== 'function') return obj;
  451. if (hash.has(obj)) return hash.get(obj);
  452. const result = Array.isArray(obj) ? [] : {};
  453. hash.set(obj, result);
  454. return Object.keys(obj).reduce((acc, key) => {
  455. acc[key] = this.deepCopy(obj[key], hash);
  456. return acc;
  457. }, result);
  458. }
  459. }
  460. };
  461. </script>
  462. <style></style>