addDialog.vue 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748
  1. <template>
  2. <ele-modal
  3. custom-class="ele-dialog-form long-dialog-form"
  4. :centered="true"
  5. v-if="visible"
  6. :visible.sync="visible"
  7. :title="title"
  8. :append-to-body="true"
  9. :close-on-click-modal="false"
  10. width="60%"
  11. @close="cancel"
  12. :maxable="true"
  13. :resizable="true"
  14. >
  15. <el-form ref="form" :model="form" :rules="rules" label-width="120px">
  16. <headerTitle title="基本信息"></headerTitle>
  17. <el-row>
  18. <el-col :span="12">
  19. <el-form-item
  20. label="需求类型"
  21. prop="sourceType"
  22. style="margin-bottom: 22px"
  23. >
  24. <el-select
  25. v-model="form.sourceType"
  26. placeholder="请选择"
  27. style="width: 100%"
  28. clearable
  29. :disabled="!!form.requirementCode"
  30. >
  31. <el-option
  32. v-for="item in requirementSourceType"
  33. :key="item.value"
  34. :label="item.label"
  35. :value="item.value"
  36. >
  37. </el-option>
  38. </el-select>
  39. </el-form-item>
  40. </el-col>
  41. <el-col :span="12">
  42. <el-form-item
  43. label="需求单名称"
  44. prop="requirementName"
  45. style="margin-bottom: 22px"
  46. >
  47. <el-input
  48. @click.native="handParent"
  49. v-model="form.requirementName"
  50. placeholder="请选择"
  51. ></el-input>
  52. </el-form-item>
  53. </el-col>
  54. <el-col :span="12">
  55. <el-form-item
  56. label="计划单名称"
  57. prop="planName"
  58. style="margin-bottom: 22px"
  59. >
  60. <el-input v-model="form.planName" placeholder="请选择"></el-input>
  61. </el-form-item>
  62. </el-col>
  63. <el-col :span="12">
  64. <el-form-item
  65. label="责任人"
  66. prop="responsibleName"
  67. style="margin-bottom: 22px"
  68. >
  69. <el-input
  70. @click.native="openStaffSelection"
  71. v-model="form.responsibleName"
  72. placeholder="请选择"
  73. ></el-input>
  74. </el-form-item>
  75. </el-col>
  76. <el-col :span="12">
  77. <el-form-item
  78. label="需求部门"
  79. prop="requireDeptId"
  80. style="margin-bottom: 22px"
  81. >
  82. <ele-tree-select
  83. :disabled="!!form.requirementCode"
  84. clearable
  85. :data="groupTreeData"
  86. v-model="form.requireDeptId"
  87. valueKey="id"
  88. labelKey="name"
  89. placeholder="请选择"
  90. @change="change_principalDep"
  91. default-expand-all
  92. />
  93. </el-form-item>
  94. </el-col>
  95. <el-col :span="12">
  96. <el-form-item
  97. label="需求人"
  98. prop="requireUserId"
  99. style="margin-bottom: 22px"
  100. >
  101. <personSelect
  102. :disabled="!!form.requirementCode"
  103. ref="directorRef"
  104. v-model="form.requireUserId"
  105. @selfChange="salesmanChange"
  106. :init="false"
  107. />
  108. </el-form-item>
  109. </el-col>
  110. <el-col :span="12">
  111. <el-form-item prop="remark" label="是否接受拆单" label-width="120px">
  112. <el-radio-group
  113. v-model="form.acceptUnpack"
  114. :disabled="!!form.requirementCode"
  115. >
  116. <el-radio v-for="item in acceptUnpackList" :label="item.value">{{
  117. item.label
  118. }}</el-radio>
  119. </el-radio-group>
  120. </el-form-item>
  121. </el-col>
  122. <el-col :span="12">
  123. <el-form-item prop="remark" label="是否需要核价" label-width="120px">
  124. <el-radio-group v-model="form.needInquiry">
  125. <el-radio v-for="item in needInquiryList" :label="item.value">{{
  126. item.label
  127. }}</el-radio>
  128. </el-radio-group>
  129. </el-form-item>
  130. </el-col>
  131. <el-col :span="12">
  132. <el-form-item prop="files" label="附件">
  133. <fileMain v-model="form.files"></fileMain>
  134. </el-form-item>
  135. </el-col>
  136. <el-col :span="12">
  137. <el-form-item prop="remark" label="备注">
  138. <el-input
  139. type="textarea"
  140. resize="none"
  141. v-model="form.remark"
  142. :rows="2"
  143. placeholder="请输入"
  144. size="small"
  145. maxlength="200"
  146. ></el-input>
  147. </el-form-item>
  148. </el-col>
  149. </el-row>
  150. </el-form>
  151. <div slot="footer" class="footer">
  152. <el-button type="primary" @click="save" v-click-once>保存</el-button>
  153. <el-button type="primary" @click="save('sub')" v-click-once
  154. >提交</el-button
  155. >
  156. <el-button @click="cancel">返回</el-button>
  157. </div>
  158. <headerTitle title="计划清单" style="margin-top: 15px"></headerTitle>
  159. <el-tabs v-model="activeName" style="margin-top: 15px" type="border-card">
  160. <el-tab-pane label="物品清单" name="1">
  161. <inventoryTable
  162. :needInquiry="form.needInquiry"
  163. ref="inventoryTable"
  164. ></inventoryTable>
  165. </el-tab-pane>
  166. <el-tab-pane
  167. label="带料清单"
  168. name="2"
  169. v-if="orderSourceType.includes(form.sourceType)"
  170. >
  171. <inventoryTable
  172. :needInquiry="form.needInquiry"
  173. ref="rawDetailListRef"
  174. :detailType="1"
  175. ></inventoryTable>
  176. </el-tab-pane>
  177. <el-tab-pane
  178. label="产出清单"
  179. name="3"
  180. v-if="orderSourceType.includes(form.sourceType)"
  181. >
  182. <inventoryTable
  183. :needInquiry="form.needInquiry"
  184. ref="outputDetailListRef"
  185. :detailType="2"
  186. ></inventoryTable>
  187. </el-tab-pane>
  188. </el-tabs>
  189. <purchaseNeedList
  190. generatedType="plan"
  191. ref="purchaseNeedList"
  192. @changeParent="changeParent"
  193. ></purchaseNeedList>
  194. <staffSelection
  195. ref="staffSelection"
  196. @confirm="confirmStaffSelection"
  197. ></staffSelection>
  198. <process-submit-dialog
  199. api-fun-name="purchaseplanStatusAPI"
  200. :processSubmitDialogFlag.sync="processSubmitDialogFlag"
  201. v-if="processSubmitDialogFlag"
  202. ref="processSubmitDialogRef"
  203. @reload="reload"
  204. ></process-submit-dialog>
  205. </ele-modal>
  206. </template>
  207. <script>
  208. import inventoryTable from './inventoryTable.vue';
  209. import purchaseNeedList from './purchaseNeed-list.vue';
  210. import staffSelection from './staffSelection.vue';
  211. import fileUpload from '@/components/upload/fileUpload';
  212. import dictMixins from '@/mixins/dictMixins';
  213. import personSelect from '@/components/CommomSelect/person-select.vue';
  214. import {
  215. getDetail,
  216. isHasGeneratedPlanAPI
  217. } from '@/api/purchasingManage/purchaseNeedManage';
  218. import {
  219. getplanDetail,
  220. UpdateInformation,
  221. addPurchaseplanManage,
  222. saveAndSubmitPurchasePlanAPI
  223. } from '@/api/purchasingManage/purchasePlanManage';
  224. import { getCode } from '@/api/login/index.js';
  225. import headList from '@/BIZComponents/user-select/user-select.vue';
  226. import { copyObj } from '@/utils/util';
  227. import { listOrganizations } from '@/api/system/organization';
  228. import { getFile } from '@/api/system/file';
  229. // import fileMain from '@/components/addDoc/index.vue';
  230. import processSubmitDialog from '@/BIZComponents/processSubmitDialog/processSubmitDialog.vue';
  231. import { orderSourceType,requirementSourceType } from '@/enum/dict';
  232. export default {
  233. props: {
  234. categoryTreeList: Array,
  235. saleOrderData: {
  236. type: Object,
  237. default: () => {
  238. return {};
  239. }
  240. }
  241. },
  242. mixins: [dictMixins],
  243. components: {
  244. processSubmitDialog,
  245. // fileMain,
  246. fileUpload,
  247. headList,
  248. inventoryTable,
  249. purchaseNeedList,
  250. personSelect,
  251. staffSelection,
  252. },
  253. data() {
  254. let formDef = {
  255. id: '',
  256. expectReceiveDate: null,
  257. remark: null,
  258. requireDeptId: '',
  259. requireUserId: '',
  260. sourceCode: '',
  261. sourceId: '',
  262. sourceType: '',
  263. files: [],
  264. planName: '',
  265. responsibleName: '',
  266. responsibleId: '',
  267. requirementId: '',
  268. requirementName: '',
  269. sourceTypeName: '',
  270. acceptUnpack: 1,
  271. needInquiry: 1,
  272. isFirstProcess: 0
  273. };
  274. return {
  275. orderSourceType,
  276. requirementSourceType,
  277. activeName: '1',
  278. fullscreen: false,
  279. visible: false,
  280. processSubmitDialogFlag: false,
  281. title: '',
  282. detailList: [],
  283. delDetailIds: [],
  284. formDef,
  285. form: copyObj(formDef),
  286. selectList: [],
  287. acceptUnpackList: [
  288. {
  289. label: '接受',
  290. value: 1
  291. },
  292. {
  293. label: '不接受',
  294. value: 0
  295. }
  296. ],
  297. needInquiryList: [
  298. {
  299. label: '是',
  300. value: 1
  301. },
  302. {
  303. label: '否',
  304. value: 0
  305. }
  306. ],
  307. processList: [
  308. {
  309. label: '是',
  310. value: 1
  311. },
  312. {
  313. label: '否',
  314. value: 0
  315. }
  316. ],
  317. columns: [
  318. {
  319. width: 45,
  320. type: 'index',
  321. columnKey: 'index',
  322. align: 'center',
  323. fixed: 'left'
  324. },
  325. {
  326. width: 150,
  327. prop: 'productCategoryName',
  328. label: '分类',
  329. slot: 'productCategoryName'
  330. },
  331. {
  332. width: 140,
  333. prop: 'productCode',
  334. label: '编码',
  335. slot: 'productCode'
  336. },
  337. {
  338. width: 240,
  339. prop: 'productName',
  340. label: '名称',
  341. slot: 'productName'
  342. },
  343. {
  344. width: 150,
  345. prop: 'productBrand',
  346. label: '牌号',
  347. slot: 'productBrand'
  348. },
  349. {
  350. width: 80,
  351. prop: 'totalCount',
  352. label: '数量',
  353. slot: 'totalCount'
  354. },
  355. {
  356. width: 100,
  357. prop: 'measuringUnit',
  358. label: '单位',
  359. slot: 'measuringUnit'
  360. },
  361. {
  362. width: 130,
  363. prop: 'modelType',
  364. label: '型号',
  365. slot: 'modelType'
  366. },
  367. {
  368. width: 120,
  369. prop: 'specification',
  370. label: '规格',
  371. slot: 'specification'
  372. },
  373. {
  374. width: 130,
  375. prop: 'brand',
  376. label: '品牌',
  377. slot: 'brand'
  378. },
  379. {
  380. width: 130,
  381. prop: 'supplierName',
  382. label: '供应商',
  383. slot: 'supplierName',
  384. headerSlot: 'headerSupplierName'
  385. },
  386. {
  387. width: 170,
  388. prop: 'expectReceiveDate',
  389. label: '到货日期',
  390. slot: 'expectReceiveDate'
  391. },
  392. {
  393. width: 140,
  394. prop: 'files',
  395. label: '附件',
  396. slot: 'files'
  397. },
  398. {
  399. width: 220,
  400. prop: 'remark',
  401. label: '备注',
  402. slot: 'remark'
  403. }
  404. ],
  405. rules: {
  406. responsibleName: [
  407. { required: true, message: '请选择责任人', trigger: 'change' }
  408. ],
  409. requireDeptId: [
  410. { required: true, message: '请选择需求部门', trigger: 'change' }
  411. ],
  412. requireUserId: [
  413. { required: true, message: '请选择需求人', trigger: 'change' }
  414. ],
  415. expectReceiveDate: [
  416. { required: true, message: '请选择到货日期', trigger: 'change' }
  417. ],
  418. sourceId: [
  419. { required: true, message: '请选择来源类型', trigger: 'change' }
  420. ],
  421. sourceType: [
  422. { required: true, message: '请选择订单类型', trigger: 'change' }
  423. ],
  424. planName: [
  425. { required: true, message: '请输入计划单名称', trigger: 'blur' }
  426. ]
  427. },
  428. // 提交状态
  429. loading: false,
  430. // 是否是修改
  431. isUpdate: false,
  432. // 组织机构树形结构数据
  433. groupTreeData: [],
  434. // 组织机构平铺数据
  435. groupData: []
  436. };
  437. },
  438. created() {},
  439. methods: {
  440. listFormatte(data) {
  441. return data;
  442. // return data.filter((item) => item.dictCode != 1);
  443. },
  444. // 获取公司数据
  445. getGroupAll() {
  446. listOrganizations().then((list) => {
  447. this.groupData = list;
  448. this.groupTreeData = this.$util.toTreeData({
  449. data: list,
  450. idField: 'id',
  451. parentIdField: 'parentId'
  452. });
  453. });
  454. },
  455. // 选择负责人部门
  456. change_principalDep(id) {
  457. const info = this.groupData.find((e) => e.id == id);
  458. this.form.requireDeptName = info.name;
  459. this.form.requireUserId = '';
  460. this.form.requireUserName = '';
  461. // 根据部门获取人员
  462. this.$nextTick(() => {});
  463. this.getrequireUser(id);
  464. },
  465. getrequireUser(groupId) {
  466. if (groupId) {
  467. this.$refs.directorRef.getList({ groupId });
  468. }
  469. },
  470. salesmanChange(val, info) {
  471. this.form.requireUserName = info.name;
  472. },
  473. openStaffSelection() {
  474. this.$refs.staffSelection.open(
  475. this.form.responsibleName
  476. ? [{ name: this.form.responsibleName, id: this.form.responsibleId }]
  477. : []
  478. );
  479. },
  480. confirmStaffSelection(data) {
  481. this.form.responsibleName = (data && data[0].name) || '';
  482. this.form.responsibleId = (data && data[0].id) || '';
  483. },
  484. //获取计划详情
  485. async getplanData(id) {
  486. this.loading = true;
  487. let data = await getplanDetail(id);
  488. this.loading = false;
  489. if (data) {
  490. this.form = data;
  491. this.$nextTick(() => {
  492. this.$refs.inventoryTable &&
  493. this.$refs.inventoryTable.putTableValue(data.detailList);
  494. this.$refs.rawDetailListRef &&
  495. this.$refs.rawDetailListRef.putTableValue(data.rawDetailList); //原料
  496. this.$refs.outputDetailListRef &&
  497. this.$refs.outputDetailListRef.putTableValue(
  498. data.outputDetailList
  499. ); //产成品
  500. // 根据部门获取人员
  501. this.getrequireUser(this.form.requireDeptId);
  502. });
  503. }
  504. },
  505. //获取需求详情
  506. async getDetailData(id, type = '') {
  507. this.loading = true;
  508. let data = await getDetail(id);
  509. this.loading = false;
  510. if (data) {
  511. this.$nextTick(() => {
  512. for (let key in data) {
  513. if (key != 'id') {
  514. this.form[key] = data[key];
  515. } else {
  516. this.form.requirementId = data[key];
  517. }
  518. }
  519. this.$refs.inventoryTable &&
  520. this.$refs.inventoryTable.putTableValue(data.detailList);
  521. // 根据部门获取人员
  522. this.getrequireUser(this.form.requireDeptId);
  523. });
  524. }
  525. },
  526. async open(type, row, contactCategoryId) {
  527. this.activeName = '1';
  528. this.title = type === 'add' ? '新增' : '修改';
  529. this.row = row;
  530. this.visible = true;
  531. if (type == 'add') {
  532. this.isUpdate = false;
  533. if (row.id) {
  534. let res = await isHasGeneratedPlanAPI(row.id);
  535. if (res) this.$message.warning('该需求已经生成过计划,请注意');
  536. await this.getDetailData(row.id);
  537. }
  538. this.$set(this.form,'planName',await getCode('purchase_plan_code_name'))
  539. } else {
  540. this.isUpdate = true;
  541. await this.init(row.id);
  542. }
  543. await this.getGroupAll();
  544. },
  545. getValidate() {
  546. let promiseAll = [
  547. new Promise((resolve, reject) => {
  548. this.$refs.form.validate((valid) => {
  549. if (!valid) {
  550. reject(false);
  551. } else {
  552. resolve(true);
  553. }
  554. });
  555. }),
  556. new Promise((resolve, reject) => {
  557. this.$refs.inventoryTable.validateForm((valid) => {
  558. if (!valid) {
  559. reject(false);
  560. this.activeName = '1';
  561. } else {
  562. resolve(true);
  563. }
  564. });
  565. })
  566. ];
  567. if (
  568. this.$refs.rawDetailListRef &&
  569. this.$refs.rawDetailListRef.validateForm
  570. ) {
  571. promiseAll.push(
  572. new Promise((resolve, reject) => {
  573. this.$refs.rawDetailListRef.validateForm((valid) => {
  574. if (!valid) {
  575. reject(false);
  576. this.activeName = '2';
  577. } else {
  578. resolve(true);
  579. }
  580. });
  581. })
  582. );
  583. }
  584. if (
  585. this.$refs.outputDetailListRef &&
  586. this.$refs.outputDetailListRef.validateForm
  587. ) {
  588. promiseAll.push(
  589. new Promise((resolve, reject) => {
  590. this.$refs.outputDetailListRef.validateForm((valid) => {
  591. if (!valid) {
  592. reject(false);
  593. this.activeName = '3';
  594. } else {
  595. resolve(true);
  596. }
  597. });
  598. })
  599. );
  600. }
  601. return Promise.all(promiseAll);
  602. },
  603. //选择产品
  604. handParent() {
  605. this.$refs.purchaseNeedList.open(this.form.requirementCode);
  606. },
  607. changeParent(data) {
  608. this.getDetailData(data.id);
  609. },
  610. async save(type = '') {
  611. try {
  612. await this.getValidate();
  613. // 表单验证通过,执行保存操作
  614. this.loading = true;
  615. if (this.$refs.inventoryTable.getTableValue().length == 0) {
  616. this.$message.warning('物品清单不能为空');
  617. return;
  618. }
  619. if (!this.isUpdate) {
  620. delete this.form.id;
  621. }
  622. this.form.sourceTypeName = this.requirementSourceType.find(
  623. (val) => val.value == this.form.sourceType
  624. )?.label;
  625. this.form.files = this.form.files || [];
  626. const rawDetailList =
  627. (this.$refs.rawDetailListRef &&
  628. this.$refs.rawDetailListRef.getTableValue()) ||
  629. [];
  630. const outputDetailList =
  631. (this.$refs.outputDetailListRef &&
  632. this.$refs.outputDetailListRef.getTableValue()) ||
  633. [];
  634. const detailList = [
  635. ...this.$refs.inventoryTable.getTableValue(),
  636. ...rawDetailList,
  637. ...outputDetailList
  638. ];
  639. this.form.detailList = detailList;
  640. // let API = type == 'sub' ? saveAndSubmitPurchasePlanAPI : this.isUpdate ? UpdateInformation : addPurchaseplanManage;
  641. let API = this.isUpdate ? UpdateInformation : addPurchaseplanManage;
  642. API(this.form)
  643. .then((res) => {
  644. this.loading = false;
  645. this.$message.success('修改成功');
  646. if (type == 'sub') {
  647. this.submit(res);
  648. return;
  649. }
  650. this.cancel();
  651. this.$emit('done');
  652. })
  653. .catch((e) => {
  654. //this.loading = false;
  655. });
  656. } catch (error) {
  657. console.log(error);
  658. // 表单验证未通过,不执行保存操作
  659. }
  660. },
  661. async submit(res) {
  662. console.log(res);
  663. let data = await getplanDetail(this.form.id || res);
  664. this.processSubmitDialogFlag = true;
  665. this.$nextTick(() => {
  666. let params = {
  667. businessId: data.id,
  668. businessKey: 'purchase_plan_approve',
  669. formCreateUserId: data.createUserId,
  670. variables: {
  671. businessCode: data.planCode,
  672. businessName: data.planName,
  673. businessType: data.sourceTypeName
  674. }
  675. // callBackMethodType : '1',
  676. // callBackMethod : 'proTargetPlanApproveApiImpl.updatePlanApprovalStatus',
  677. // pcHandle : '/bpm/handleTask/components/project-manage/plan-manage/submit.vue',
  678. // pcView : '/bpm/handleTask/components/project-manage/plan-manage/detailDialog.vue',
  679. // miniHandle : '',
  680. // miniView : '',
  681. };
  682. this.$refs.processSubmitDialogRef.init(params);
  683. });
  684. },
  685. reload() {
  686. this.cancel();
  687. this.$emit('done');
  688. },
  689. downloadFile(file) {
  690. getFile({ objectName: file.storePath }, file.name);
  691. },
  692. cancel() {
  693. this.$nextTick(() => {
  694. // 关闭后,销毁所有的表单数据
  695. this.$refs['otherForm'] && this.$refs['otherForm'].resetFields();
  696. this.$refs['formRef'] && this.$refs['formRef'].resetFields();
  697. this.form = copyObj(this.formDef);
  698. this.visible = false;
  699. });
  700. },
  701. async init(id) {
  702. if (id) await this.getplanData(id);
  703. }
  704. }
  705. };
  706. </script>
  707. <style scoped lang="scss">
  708. .TotalAmount {
  709. font-size: 16px;
  710. padding-right: 30px;
  711. }
  712. </style>