index.vue 44 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459
  1. <template>
  2. <!-- :close-on-click-modal="false" -->
  3. <ele-modal
  4. width="80vw"
  5. :visible.sync="visible"
  6. custom-class="ele-dialog-form"
  7. :before-close="cancel"
  8. :title="title"
  9. :maxable="true"
  10. >
  11. <div class="form-wrapper">
  12. <el-form
  13. ref="form"
  14. :model="form"
  15. :rules="rules"
  16. label-width="110px"
  17. class="formbox"
  18. >
  19. <headerTitle title="基本信息"> </headerTitle>
  20. <el-row :gutter="10">
  21. <el-col :span="6">
  22. <el-form-item label="计划编号:" prop="code">
  23. <el-input
  24. placeholder="计划编号"
  25. size="mini"
  26. disabled
  27. v-model="form.code"
  28. ></el-input>
  29. </el-form-item>
  30. </el-col>
  31. <el-col :span="6">
  32. <el-form-item label="计划类型:" prop="planType">
  33. <el-select
  34. v-model="form.planType"
  35. style="width: 100%"
  36. @change="changeProduceType"
  37. size="mini"
  38. >
  39. <el-option
  40. v-for="item of planTypeList"
  41. :key="item.value"
  42. :label="item.label"
  43. :value="item.value"
  44. ></el-option>
  45. </el-select>
  46. </el-form-item>
  47. </el-col>
  48. <el-col :span="6">
  49. <el-form-item label="批次号:" prop="batchNo">
  50. <el-input
  51. placeholder="输入批次号"
  52. size="mini"
  53. v-model="form.batchNo"
  54. ></el-input>
  55. </el-form-item>
  56. </el-col>
  57. <el-col :span="6">
  58. <el-form-item label="客户名称:">
  59. <el-input
  60. clearable
  61. v-model="form.customerName"
  62. style="width: calc(100% - 80px)"
  63. />
  64. <contactDialog
  65. style="margin-left: 3px"
  66. @changeParent="contactDialogSuccess"
  67. ></contactDialog>
  68. </el-form-item>
  69. </el-col>
  70. </el-row>
  71. <el-row :gutter="24">
  72. <el-col :span="6">
  73. <el-form-item
  74. label="计划开始日期:"
  75. label-width="110px"
  76. prop="startTime"
  77. >
  78. <el-date-picker
  79. style="width: 100%"
  80. size="mini"
  81. v-model="form.startTime"
  82. @change="handleStartTimeChange(form)"
  83. type="datetime"
  84. placeholder="选择日期"
  85. value-format="yyyy-MM-dd HH:mm:ss"
  86. >
  87. </el-date-picker>
  88. </el-form-item>
  89. </el-col>
  90. <el-col :span="6">
  91. <el-form-item
  92. label="计划结束日期:"
  93. label-width="110px"
  94. prop="endTime"
  95. >
  96. <el-date-picker
  97. style="width: 100%"
  98. size="mini"
  99. v-model="form.endTime"
  100. @change="handleEndTimeChange(form)"
  101. type="datetime"
  102. placeholder="选择日期"
  103. value-format="yyyy-MM-dd HH:mm:ss"
  104. >
  105. </el-date-picker>
  106. </el-form-item>
  107. </el-col>
  108. <el-col :span="6">
  109. <el-form-item
  110. label="要求完成日期:"
  111. label-width="110px"
  112. prop="reqMoldTime"
  113. >
  114. <el-date-picker
  115. style="width: 100%"
  116. size="mini"
  117. v-model="form.reqMoldTime"
  118. type="datetime"
  119. placeholder="选择日期"
  120. value-format="yyyy-MM-dd HH:mm:ss"
  121. >
  122. </el-date-picker>
  123. </el-form-item>
  124. </el-col>
  125. </el-row>
  126. <headerTitle title="产品信息"> </headerTitle>
  127. <el-row :gutter="24">
  128. <ele-pro-table
  129. ref="tableRef"
  130. :columns="columns"
  131. row-key="code"
  132. :cache-key="`ProductionPlanTable`"
  133. :datasource="form.productInfoList"
  134. border
  135. height="40vh"
  136. key="id"
  137. >
  138. <template v-slot:requiredFormingNum="{ row, $index }">
  139. <el-input
  140. v-model.number="row.requiredFormingNum"
  141. size="small"
  142. type="text"
  143. style="width: 100%"
  144. placeholder="输入要求生产数量"
  145. @input="(e) => handleQuantityInput(e, row)"
  146. ></el-input>
  147. <!-- placeholder="输入要求生产数量" @input="tableHandleKeyUp(row, 'sum')"></el-input> -->
  148. </template>
  149. <template v-slot:blockCount="{ row, $index }">
  150. <el-input
  151. v-model.number="row.blockCount"
  152. size="small"
  153. type="number"
  154. style="width: 100%"
  155. placeholder="输入数量"
  156. @input="inputNumber(row, $index)"
  157. ></el-input>
  158. </template>
  159. <template v-slot:productType="{ row, $index }">
  160. <el-select
  161. v-model="row.productType"
  162. @change="changeProductType(row, $index)"
  163. :key="$index"
  164. >
  165. <el-option
  166. v-for="item of producedList"
  167. :key="$index + item.code"
  168. :label="item.name"
  169. :value="item.code"
  170. ></el-option>
  171. </el-select>
  172. </template>
  173. <template v-slot:bomCategoryId="{ row, $index }">
  174. <el-select
  175. v-model="row.bomCategoryId"
  176. @change="changeBomId(row, $index)"
  177. >
  178. <el-option
  179. v-for="item of row.bomVersionList"
  180. :key="item.id"
  181. :label="item.name + '(V' + item.versions + '.0)'"
  182. :value="item.id"
  183. ></el-option>
  184. </el-select>
  185. </template>
  186. <!-- //权重等级 -->
  187. <template
  188. v-slot:weight="{ row, $index }"
  189. v-if="clientEnvironmentId == 4"
  190. >
  191. <el-select
  192. v-model="row.weight"
  193. style="width: 100%"
  194. @change="changeProduceType"
  195. size="mini"
  196. >
  197. <el-option
  198. v-for="item of weightList"
  199. :key="item.code"
  200. :label="item.name"
  201. :value="item.code"
  202. ></el-option>
  203. </el-select>
  204. </template>
  205. <!-- 是否开槽 -->
  206. <template
  207. v-slot:isSlotting="{ row, $index }"
  208. v-if="clientEnvironmentId == 4"
  209. >
  210. <el-select
  211. v-model="row.isSlotting"
  212. style="width: 100%"
  213. @change="changeProduceType"
  214. size="mini"
  215. >
  216. <el-option
  217. v-for="item of isSlotting"
  218. :key="item.code"
  219. :label="item.name"
  220. :value="item.code"
  221. ></el-option>
  222. </el-select>
  223. </template>
  224. <!-- 开槽类型 -->
  225. <template
  226. v-slot:slottingType="{ row, $index }"
  227. v-if="clientEnvironmentId == 4"
  228. >
  229. <DictSelection
  230. dictName="开槽类型"
  231. v-model="row.slottingType"
  232. size="mini"
  233. >
  234. </DictSelection>
  235. </template>
  236. <!-- 工艺路线 -->
  237. <template
  238. v-slot:produceRoutingId="{ row, $index }"
  239. v-if="clientEnvironmentId != 4"
  240. >
  241. <!-- <el-form-item required> -->
  242. <div style="display: flex">
  243. <el-select
  244. v-model="row.produceRoutingId"
  245. v-show="isRouteSelect(row)"
  246. >
  247. <el-option
  248. v-for="item of row.routingList"
  249. :key="item.id"
  250. :label="item.name"
  251. :value="item.id"
  252. ></el-option>
  253. </el-select>
  254. <div style="display: flex">
  255. <el-input
  256. v-show="!isRouteSelect(row)"
  257. disabled
  258. v-model="row.produceRoutingName"
  259. ></el-input>
  260. <el-button
  261. v-show="isSelectShow"
  262. type="primary"
  263. size="mini"
  264. @click="openDialog($index)"
  265. >选择</el-button
  266. >
  267. </div>
  268. </div>
  269. <!-- </el-form-item> -->
  270. </template>
  271. <template v-slot:produceRoutingId="{ row, $index }" v-else>
  272. <el-input
  273. v-model="row.produceRoutingName"
  274. style="width: 100%"
  275. readonly
  276. ></el-input>
  277. </template>
  278. <template v-slot:factoriesId="{ row, $index }">
  279. <el-select
  280. v-model="row.factoriesId"
  281. :key="row.factoriesId"
  282. @change="(e) => selectFactory(e, row)"
  283. >
  284. <el-option
  285. v-for="item of factoryList"
  286. :key="item.id"
  287. :label="item.name"
  288. :value="item.id"
  289. ></el-option>
  290. </el-select>
  291. </template>
  292. <!-- <el-table-column label="所属工厂" width="140" align="center" prop="factoriesId">
  293. <template slot-scope="scope">
  294. <el-form-item label-width="0px">
  295. <el-select v-model="scope.row.factoriesId" :key="scope.row.factoriesId">
  296. <el-option v-for="item of factoryList" :key="item.id" :label="item.name"
  297. :value="item.id"></el-option>
  298. </el-select>
  299. </el-form-item>
  300. </template>
  301. </el-table-column> -->
  302. <!-- 模具数量 -->
  303. <template
  304. v-slot:moCount="{ row, $index }"
  305. v-if="clientEnvironmentId == '4'"
  306. >
  307. <div>
  308. <el-input
  309. style="width: 100%"
  310. size="small"
  311. v-model="row.moCount"
  312. oninput="value=value.replace(/[^0-9.]/g,'')"
  313. @input="tableHandleKeyUp(row, 'moCount')"
  314. placeholder="请输入"
  315. >
  316. </el-input>
  317. </div>
  318. </template>
  319. <!-- 块数 -->
  320. <template
  321. v-slot:blockCount="{ row, $index }"
  322. v-if="clientEnvironmentId == '4'"
  323. >
  324. <div>
  325. <el-input
  326. size="small"
  327. style="width: 100%"
  328. @input="tableHandleKeyUp(row, 'blockCount')"
  329. v-model="row.blockCount"
  330. placeholder="请输入"
  331. ></el-input>
  332. </div>
  333. </template>
  334. <template v-slot:productWeight="{ row, $index }">
  335. <span>{{ row.productWeight ? row.productWeight : '-' }}</span>
  336. </template>
  337. <template v-slot:set="{ row, $index }">
  338. <el-button
  339. type="text"
  340. @click="handleDeleteItem($index)"
  341. v-if="!row.id"
  342. >删除</el-button
  343. >
  344. </template>
  345. <template v-slot:headerProduceRoutingId="{ column }">
  346. <div class="header_required"
  347. ><span class="is-required">{{ column.label }}</span></div
  348. >
  349. </template>
  350. <template v-slot:headeRequiredFormingNum="{ column }">
  351. <div class="header_required"
  352. ><span class="is-required">{{ column.label }}</span></div
  353. >
  354. </template>
  355. <template v-slot:headerProcessingBOM="{ column }">
  356. <div :class="isRequired ? 'header_required' : ''"
  357. ><span class="is-required">{{ column.label }}</span></div
  358. >
  359. </template>
  360. </ele-pro-table>
  361. <div class="add-product" @click="addEquipment">
  362. <i class="el-icon-circle-plus-outline"></i>
  363. </div>
  364. </el-row>
  365. </el-form>
  366. <!-- 选择产品 -->
  367. <EquipmentDialog
  368. @choose="confirmChoose"
  369. :selectList="[]"
  370. ref="equipmentRefs"
  371. isMultiple="0"
  372. >
  373. </EquipmentDialog>
  374. </div>
  375. <template v-slot:footer>
  376. <el-button @click="cancel">取消</el-button>
  377. <el-button type="primary" @click="save" :loading="loading">
  378. 确定
  379. </el-button>
  380. </template>
  381. <ProcessRoute ref="processRouteRef" @changeParent="changeParent" />
  382. </ele-modal>
  383. </template>
  384. <script>
  385. import EquipmentDialog from '@/views/saleOrder/components/EquipmentDialog';
  386. import { getCode } from '@/api/codeManagement';
  387. import ProcessRoute from '@/components/selectionDialog/processRoute.vue';
  388. import { parameterGetByCode } from '@/api/mainData/index';
  389. import {
  390. bomRoutingList,
  391. bomListByPlan,
  392. saveSaleToPlan,
  393. getFactoryList,
  394. temporarilyUpdate,
  395. temporaryPlanSave
  396. } from '@/api/saleOrder';
  397. import contactDialog from '@/components/contactDialog/openContactDialog.vue';
  398. export default {
  399. components: {
  400. EquipmentDialog,
  401. ProcessRoute,
  402. contactDialog
  403. },
  404. props: {
  405. factoryType: {
  406. type: Number,
  407. default: 3
  408. },
  409. factoryObj: {
  410. type: Object,
  411. default: () => {}
  412. }
  413. },
  414. watch: {
  415. // factoryObj: {
  416. // immediate: true,
  417. // deep: true,
  418. // handler(val) {
  419. // // 修改
  420. // // this.$nextTick(() => {
  421. // // if (val.id) {
  422. // // this.bomListVersion();
  423. // // if (val.bomCategoryId) {
  424. // // this.getPlanRouting();
  425. // // }
  426. // // }
  427. // // });
  428. // }
  429. // }
  430. },
  431. computed: {
  432. // 是否必填 字段 ( 首先看计划类型 如果是返工返修)
  433. // 就不是必填 否则就看配置参数
  434. // 必填的时候 不显示选择按钮 跟 展示输入框 只能有下拉选择框 ( 选择了生产类型 带出 BOM 版本 带出 工艺路线 工艺路线不能选择)
  435. // 不必填的时候 显示 选择按钮跟 展示输入框 并且可以存在选择框 一开始默认展示选择框
  436. // 选择按钮选择数据后 隐藏选择框 显示展示框(input) 情况 生产类型 跟 BOM版本
  437. // 选择了生产类型 清空 选择框选择的工艺路线
  438. // 是否必填字段
  439. isRequired() {
  440. if (this.form.planType == 5) {
  441. return false;
  442. }
  443. return this.processingRequired == 1;
  444. },
  445. // 工艺路线 输入框展示跟选择框判断
  446. isRouteSelect() {
  447. return (row) => {
  448. if (this.isRequired) {
  449. return true;
  450. }
  451. if (!row.selectionRowShow) {
  452. return true;
  453. }
  454. return false;
  455. };
  456. },
  457. // 选择按钮的显示
  458. isSelectShow() {
  459. if (this.form.planType == 5) {
  460. return true;
  461. }
  462. return this.processingRequired == 0;
  463. },
  464. clientEnvironmentId() {
  465. return this.$store.state.user.info.clientEnvironmentId;
  466. },
  467. columns() {
  468. return [
  469. {
  470. columnKey: 'index',
  471. label: '序号',
  472. type: 'index',
  473. width: 55,
  474. align: 'center',
  475. showOverflowTooltip: true
  476. },
  477. {
  478. slot: 'lineNumber',
  479. prop: 'lineNumber',
  480. label: '行号',
  481. align: 'center',
  482. minWidth: 140
  483. },
  484. {
  485. slot: 'productName',
  486. prop: 'productName',
  487. label: '产品名称',
  488. align: 'center',
  489. minWidth: 140
  490. },
  491. {
  492. slot: 'productCode',
  493. prop: 'productCode',
  494. label: '物料编码',
  495. align: 'center',
  496. minWidth: 140
  497. },
  498. {
  499. slot: 'brandNo',
  500. prop: 'brandNo',
  501. label: '牌号',
  502. align: 'center',
  503. minWidth: 140
  504. },
  505. {
  506. slot: 'model',
  507. prop: 'model',
  508. label: '型号',
  509. align: 'center',
  510. minWidth: 140
  511. },
  512. {
  513. slot: 'specification',
  514. prop: 'specification',
  515. label: '规格',
  516. align: 'center',
  517. minWidth: 140
  518. },
  519. {
  520. slot: 'productUnitWeight',
  521. prop: 'productUnitWeight',
  522. label: '单重',
  523. align: 'center',
  524. minWidth: 140
  525. },
  526. {
  527. slot: 'weightUnit',
  528. prop: 'weightUnit',
  529. label: '重量单位',
  530. align: 'center',
  531. minWidth: 140
  532. },
  533. {
  534. slot: 'requiredFormingNum',
  535. prop: 'requiredFormingNum',
  536. headerSlot: 'headeRequiredFormingNum',
  537. label: '要求生产数量',
  538. align: 'center',
  539. minWidth: 140
  540. },
  541. {
  542. slot: 'productType',
  543. prop: 'productType',
  544. label: '生产类型',
  545. headerSlot: 'headerProcessingBOM',
  546. align: 'center',
  547. minWidth: 180
  548. },
  549. {
  550. slot: 'bomCategoryId',
  551. prop: 'bomCategoryId',
  552. label: 'BOM版本',
  553. headerSlot: 'headerProcessingBOM',
  554. align: 'center',
  555. minWidth: 180,
  556. show: this.clientEnvironmentId !== 4
  557. },
  558. {
  559. slot: 'produceRoutingId',
  560. prop: 'produceRoutingId',
  561. headerSlot: 'headerProduceRoutingId',
  562. label: '工艺路线',
  563. align: 'center',
  564. minWidth: 240
  565. },
  566. {
  567. slot: 'measuringUnit',
  568. prop: 'measuringUnit',
  569. label: '计量单位',
  570. align: 'center',
  571. minWidth: 140
  572. },
  573. {
  574. slot: 'moCount',
  575. prop: 'moCount',
  576. label: '模数',
  577. align: 'center',
  578. minWidth: 140,
  579. show: this.clientEnvironmentId == 4
  580. },
  581. {
  582. slot: 'blockCount',
  583. prop: 'blockCount',
  584. label: '块数',
  585. align: 'center',
  586. minWidth: 140,
  587. show: this.clientEnvironmentId == 4
  588. },
  589. {
  590. slot: 'factoriesId',
  591. prop: 'factoriesId',
  592. headerSlot: 'headerProduceRoutingId',
  593. label: '所属工厂',
  594. align: 'center',
  595. minWidth: 140
  596. },
  597. {
  598. slot: 'weight',
  599. prop: 'weight',
  600. label: '权重等级',
  601. align: 'center',
  602. minWidth: 140,
  603. show: this.clientEnvironmentId == 4
  604. },
  605. {
  606. slot: 'isSlotting',
  607. prop: 'isSlotting',
  608. label: '是否开槽',
  609. align: 'center',
  610. minWidth: 140,
  611. show: this.clientEnvironmentId == 4
  612. },
  613. {
  614. slot: 'slottingType',
  615. prop: 'slottingType',
  616. label: '开槽类型',
  617. align: 'center',
  618. minWidth: 140,
  619. show: this.clientEnvironmentId == 4
  620. },
  621. {
  622. slot: 'productWeight',
  623. prop: 'productWeight',
  624. label: '订单重量',
  625. align: 'center',
  626. minWidth: 140
  627. },
  628. {
  629. slot: 'set',
  630. prop: 'set',
  631. label: '操作',
  632. align: 'center',
  633. minWidth: 140,
  634. fixed: 'right'
  635. }
  636. ];
  637. }
  638. },
  639. data() {
  640. return {
  641. visible: false,
  642. title: '',
  643. type: 3,
  644. weightList: [
  645. { code: 1, name: 'A' },
  646. { code: 2, name: 'B' },
  647. { code: 3, name: 'C' }
  648. ],
  649. factoryList: [],
  650. isSlotting: [
  651. { code: 1, name: '是' },
  652. { code: 2, name: '否' }
  653. ], //是否开槽
  654. planTypeList: [
  655. { label: '内销计划', value: '1' },
  656. { label: '外销计划', value: '2' },
  657. { label: '预制计划', value: '3' },
  658. { label: '改型计划', value: '4' },
  659. { label: '返工返修计划', value: '5' }
  660. ],
  661. loading: false,
  662. form: {
  663. timeDimensionPlanType: 3,
  664. categoryId: '',
  665. productName: '',
  666. planType: '',
  667. moCount: '', // 模具数量
  668. blockCount: 0, // 块数
  669. noWordCount: '', // 无字数量
  670. weight: '',
  671. startTime: '',
  672. endTime: '',
  673. isSlotting: '', //是否开槽
  674. slottingType: '', //开槽类型
  675. id: '',
  676. produceType: 2,
  677. bomCategoryId: '',
  678. produceRoutingId: '',
  679. requiredFormingNum: '',
  680. productInfoList: []
  681. },
  682. disabledList: [],
  683. bomVersionList: [],
  684. routingList: [],
  685. rules: {
  686. productName: [
  687. { required: true, message: '请选择名称', trigger: 'change' }
  688. ],
  689. bomCategoryId: [
  690. { required: true, message: '请选择BOM版本', trigger: 'blur' }
  691. ],
  692. produceType: [
  693. { required: true, message: '请选择工艺路线', trigger: 'blur' }
  694. ],
  695. produceRoutingId: [
  696. { required: true, message: '请选择工艺路线', trigger: 'blur' }
  697. ],
  698. startTime: [
  699. { required: true, message: '请选择计划开始日期', trigger: 'blur' }
  700. ],
  701. endTime: [
  702. { required: true, message: '请选择计划结束日期', trigger: 'blur' }
  703. ],
  704. reqMoldTime: [
  705. { required: true, message: '请选择要求完成日期', trigger: 'blur' }
  706. ],
  707. requiredFormingNum: [
  708. { required: true, message: '请输入生产数量', trigger: 'blur' }
  709. ]
  710. },
  711. producedList: [
  712. { code: 2, name: '加工(MBOM)' },
  713. { code: 3, name: '装配(ABOM)' }
  714. ],
  715. selectIndex: 0, // 选择工艺路线的当前数据下标
  716. processingRequired: 0 // 生产类型跟BOM 版本是否必填 1:是 0:否
  717. // selectionRowShow: false // 工艺路线输入框展示 状态
  718. };
  719. },
  720. // computed: {
  721. // clientEnvironmentId() {
  722. // return this.$store.state.user.info.clientEnvironmentId;
  723. // }
  724. // },
  725. mounted() {
  726. // 生产类型跟BOM版本字段是否必填
  727. parameterGetByCode({
  728. code: 'production_plan_code'
  729. }).then((res) => {
  730. console.log(res,'res 1')
  731. if (res) {
  732. this.processingRequired = res.value;
  733. }
  734. });
  735. },
  736. methods: {
  737. selectFactory(e, row) {
  738. let data = this.factoryList.find((item) => item.id === e);
  739. this.$set(row, 'factoriesName', data.name);
  740. },
  741. // 打开工艺路线
  742. openDialog(index) {
  743. this.selectIndex = index;
  744. this.$refs.processRouteRef.open();
  745. },
  746. // 选择工艺路线
  747. changeParent(item) {
  748. let data = this.form.productInfoList[this.selectIndex];
  749. this.$set(data, 'bomVersionList', []);
  750. this.$set(data, 'bomCategoryId', '');
  751. this.$set(data, 'model', '');
  752. this.$set(data, 'routingList', []);
  753. this.$set(data, 'productType', '');
  754. this.$set(data, 'produceRoutingName', item.name);
  755. this.$set(data, 'produceRoutingId', item.id);
  756. this.$set(data, 'selectionRowShow', true);
  757. // this.selectionRowShow = true;
  758. },
  759. async getFactoryList() {
  760. this.factoryList = await getFactoryList();
  761. },
  762. async open(val) {
  763. await this.getFactoryList();
  764. if (val) {
  765. this.title = !val.id ? '新增临时生产计划' : '编辑临时生产计划';
  766. val.planType = String(val.planType);
  767. this.form = val;
  768. // 修改
  769. if (val.id) {
  770. if (
  771. Array.isArray(val.productInfoList) &&
  772. val.productInfoList.length
  773. ) {
  774. this.form.productInfoList.map(async (v, index) => {
  775. if (!v.bomCategoryId) {
  776. v.productType = '';
  777. v.selectionRowShow = true;
  778. } else {
  779. v.selectionRowShow = false;
  780. }
  781. if (v.productType) {
  782. this.$set(
  783. this.form.productInfoList[index],
  784. 'bomVersionList',
  785. await this.bomListVersionFn(v.productType, v.categoryId)
  786. );
  787. }
  788. if (v.bomCategoryId) {
  789. this.$set(
  790. this.form.productInfoList[index],
  791. 'routingList',
  792. await this.changeBomIdFn(v.bomCategoryId)
  793. );
  794. }
  795. });
  796. }
  797. }
  798. this.$forceUpdate();
  799. }
  800. this.visible = true;
  801. // this.$nextTick(async () => {
  802. // console.log(val.productInfoList);
  803. // this.$set(this.form, 'productInfoList', val.productInfoList);
  804. // this.$set(this.form, 'routingList', val.routingList);
  805. // });
  806. //this.clientEnvironmentId 环境判断 宝悦环境
  807. // if (this.clientEnvironmentId == 4) {
  808. // this.getPlanRoutingNew();
  809. // }
  810. // this.getPlanRoutingNew();
  811. },
  812. addEquipment() {
  813. this.$refs.equipmentRefs.open();
  814. },
  815. confirmChoose(list) {
  816. list.map((el) => (el.selectionRowShow = false));
  817. if (this.clientEnvironmentId == 4) {
  818. list.map((v) => {
  819. if (v.name.includes('板材')) {
  820. v.produceRoutingId = '1856970794952372226';
  821. v.produceRoutingName = '板材';
  822. v.produceVersionName = '板材';
  823. } else {
  824. (v.produceRoutingId = '1857313733642596353'),
  825. (v.produceRoutingName = '砌块'),
  826. (v.produceVersionName = '砌块');
  827. }
  828. });
  829. }
  830. list = list
  831. .filter(
  832. (i) =>
  833. !this.disabledList.find(
  834. (p) => p.productCode == i.code || p.productCode == i.productCode
  835. )
  836. )
  837. .map((item, index) => {
  838. if (item.productCode) {
  839. return item;
  840. } else {
  841. return {
  842. categoryId: item.id,
  843. productCode: item.code,
  844. productName: item.name,
  845. productUnitWeight: item.netWeight,
  846. weightUnit: item.weightUnit,
  847. model: item.modelType,
  848. specification: item.specification,
  849. brandNo: item.brandNum,
  850. measuringUnit: item.measuringUnit,
  851. produceRoutingId: item.produceRoutingId,
  852. produceRoutingName: item.produceRoutingName,
  853. produceVersionName: item.produceVersionName
  854. };
  855. }
  856. })
  857. .concat(this.disabledList);
  858. this.form.productInfoList = [];
  859. // 取出在弹窗中选中并且不在表格中的数据
  860. const result = list.filter(
  861. (i) =>
  862. this.form.productInfoList.findIndex(
  863. (p) => p.productCode === i.productCode
  864. ) === -1
  865. );
  866. // 取出在表格中并且不在弹窗中选中的数据 即取消选中的数据
  867. const del = this.form.productInfoList.filter(
  868. (i) => list.findIndex((p) => p.productCode === i.productCode) === -1
  869. );
  870. for (let i = this.form.productInfoList.length - 1; i >= 0; i--) {
  871. for (let j in del) {
  872. if (
  873. this.form.productInfoList[i].productCode === del[j].productCode
  874. ) {
  875. this.form.productInfoList.splice(i, 1);
  876. break;
  877. }
  878. }
  879. }
  880. // bomVersionList
  881. this.form.productInfoList = this.form.productInfoList.concat(result);
  882. this.$refs.tableRef.setData(this.form.productInfoList);
  883. this.changeLineNumber();
  884. //重置
  885. this.$set(this.form, 'produceType', '');
  886. this.$set(this.form, 'bomCategoryId', '');
  887. this.$set(this.form, 'produceRoutingId', '');
  888. this.bomListVersion();
  889. },
  890. changeLineNumber() {
  891. this.form.productInfoList.map((item, index) => {
  892. item.lineNumber = 10 * (index + 1);
  893. });
  894. },
  895. handleDeleteItem(index) {
  896. this.$confirm('确定删除当前数据?', '提示')
  897. .then(() => {
  898. const newArray = this.form.productInfoList.filter(
  899. (item, i) => i !== index
  900. );
  901. this.form.productInfoList = newArray;
  902. this.$refs.tableRef.setData(newArray);
  903. })
  904. .catch(() => {});
  905. },
  906. async getPlanCode() {
  907. this.loading = true;
  908. try {
  909. const code = await getCode('product_code');
  910. this.$set(this.form, 'code', code);
  911. } catch (err) {}
  912. },
  913. initForm() {
  914. this.form = {
  915. timeDimensionPlanType: 3,
  916. categoryId: '',
  917. productName: '',
  918. planType: '',
  919. moCount: '', // 模具数量
  920. blockCount: 0, // 块数
  921. noWordCount: '', // 无字数量
  922. weight: '',
  923. isSlotting: '', //是否开槽
  924. slottingType: '', //开槽类型
  925. id: '',
  926. produceType: 2,
  927. status: 2,
  928. bomCategoryId: '',
  929. produceRoutingId: '',
  930. productInfoList: [],
  931. requiredFormingNum: ''
  932. };
  933. // console.log(this.$refs);
  934. // this.$refs.tableRef.setData([]);
  935. },
  936. changeBomIdFn(bomCategoryId) {
  937. return new Promise((resolve, reject) => {
  938. bomRoutingList(bomCategoryId).then((res) => {
  939. let arr = res || [];
  940. if (arr.length == 0) {
  941. row.produceRoutingId = '';
  942. }
  943. resolve(arr);
  944. });
  945. });
  946. },
  947. // 选择BOM
  948. changeBomId(row, index) {
  949. // row.routingList = []
  950. bomRoutingList(row.bomCategoryId).then((res) => {
  951. let arr = res || [];
  952. if (arr.length > 0) {
  953. this.$nextTick(() => {
  954. row.produceRoutingName = arr[0].name;
  955. row.produceVersionName = arr[0].version;
  956. row.routingList = arr;
  957. this.$set(
  958. this.form.productInfoList[index],
  959. 'produceRoutingId',
  960. arr[0].id
  961. );
  962. // this.selectionRowShow = false;
  963. row.selectionRowShow = false;
  964. this.$set(this.form.productInfoList[index], 'routingList', arr);
  965. });
  966. }
  967. this.$forceUpdate();
  968. });
  969. },
  970. contactDialogSuccess(data) {
  971. console.log(data, 'data 11');
  972. // serialNo
  973. this.form.serialNo = data.serialNo;
  974. this.$set(this.form, 'customerName', data.name);
  975. },
  976. // 清空BOM 跟工艺路线
  977. wipeData(index) {
  978. let row = this.form.productInfoList[index];
  979. row.bomCategoryId = '';
  980. row.routingList = [];
  981. row.bomVersionList = [];
  982. row.produceRoutingId = '';
  983. row.produceRoutingName = '';
  984. row.produceVersionName = '';
  985. row.selectionRowShow = false;
  986. // this.selectionRowShow = false;
  987. },
  988. // 选择生产类型
  989. changeProductType(row, index) {
  990. let param = {
  991. bomType: row.productType,
  992. categoryId: row.categoryId
  993. };
  994. this.wipeData(index);
  995. // row.bomCategoryId = '';
  996. // this.form.productInfoList[index].bomVersionList = [];
  997. bomListByPlan(param).then((res) => {
  998. let arr = res || [];
  999. this.$nextTick(() => {
  1000. if (arr.length) {
  1001. row.bomVersionList = arr;
  1002. this.form.productInfoList[index].bomVersionList = arr;
  1003. row.bomCategoryId = arr[0].id;
  1004. this.changeBomId(row, index);
  1005. let arrAll = JSON.parse(JSON.stringify(this.form));
  1006. this.$set(this, 'form', arrAll);
  1007. }
  1008. });
  1009. // this.$set(this.form.productInfoList[index], 'bomVersionList', arr);
  1010. });
  1011. },
  1012. // 参数校验
  1013. parameterVerification() {
  1014. let flag = true;
  1015. this.form.productInfoList.forEach((v) => {
  1016. if (this.isRequired) {
  1017. if (!v.productType) {
  1018. flag = false;
  1019. this.$message.warning('请选择生产类型');
  1020. return;
  1021. }
  1022. if (!v.bomCategoryId) {
  1023. flag = false;
  1024. this.$message.warning('请选择BOM版本');
  1025. return;
  1026. }
  1027. }
  1028. if (!v.produceRoutingId) {
  1029. flag = false;
  1030. this.$message.warning('请选择工艺路线');
  1031. return;
  1032. }
  1033. if (!v.factoriesId) {
  1034. flag = false;
  1035. this.$message.warning('请选择所属工厂');
  1036. return;
  1037. }
  1038. if (v.requiredFormingNum == 0) {
  1039. flag = false;
  1040. this.$message.warning('要求生产数量不能为0');
  1041. return;
  1042. }
  1043. if (!v.requiredFormingNum) {
  1044. flag = false;
  1045. this.$message.warning('请输入要求生产数量');
  1046. return;
  1047. }
  1048. });
  1049. return flag;
  1050. },
  1051. save() {
  1052. this.$refs.form.validate(async (valid) => {
  1053. if (!valid) {
  1054. return false;
  1055. }
  1056. console.log(this.form.productInfoList, '1111111111');
  1057. let flag = this.parameterVerification();
  1058. // 必填参数校验
  1059. if (!flag) return;
  1060. if (!this.form.id) {
  1061. if (this.form.productInfoList.length) {
  1062. this.form.productInfoList.map((item, index) => {
  1063. if (
  1064. item.weightUnit == 'G' ||
  1065. item.weightUnit == 'g' ||
  1066. item.weightUnit == '克'
  1067. ) {
  1068. let total =
  1069. ((item.requiredFormingNum - 0) * item.productUnitWeight) /
  1070. 1000;
  1071. item.newSumOrderWeight = total.toFixed(2);
  1072. item.newWeightUnit = 'KG'
  1073. }else{
  1074. item.newWeightUnit = item.weightUnit;
  1075. item.newSumOrderWeight = item.requiredFormingNum;
  1076. }
  1077. delete item.selectionRowShow;
  1078. if (item.bomVersionList && item.bomVersionList.length) {
  1079. item.bomCategoryName = item.bomVersionList[0].name;
  1080. item.bomCategoryVersions = item.bomVersionList[0].versions;
  1081. item.produceRoutingName = item.routingList[0].name;
  1082. }
  1083. });
  1084. }
  1085. this.form.timeDimensionPlanType = this.type;
  1086. await this.getPlanCode();
  1087. this.loading = true;
  1088. // console.log(this.form,'this.form 1+1 ')
  1089. // return
  1090. temporaryPlanSave(this.form)
  1091. .then((res) => {
  1092. this.$message.success('新增成功!');
  1093. this.visible = false;
  1094. this.initForm();
  1095. this.$emit('close', true);
  1096. })
  1097. .finally(() => {
  1098. this.loading = false;
  1099. });
  1100. } else {
  1101. this.loading = true;
  1102. temporaryPlanSave(this.form)
  1103. .then((res) => {
  1104. this.$message.success('修改成功!');
  1105. this.visible = false;
  1106. this.initForm();
  1107. this.$emit('close', true);
  1108. })
  1109. .finally(() => {
  1110. this.loading = false;
  1111. });
  1112. }
  1113. });
  1114. },
  1115. bomListVersionFn(produceType, categoryId) {
  1116. return new Promise((resolve, reject) => {
  1117. let param = {
  1118. bomType: produceType,
  1119. categoryId: categoryId
  1120. };
  1121. bomListByPlan(param).then((res) => {
  1122. this.bomVersionList = res || [];
  1123. resolve(res || []);
  1124. });
  1125. });
  1126. },
  1127. bomListVersion() {
  1128. let param = {
  1129. bomType: this.form.produceType,
  1130. categoryId: this.form.categoryId
  1131. };
  1132. bomListByPlan(param).then((res) => {
  1133. this.$nextTick(() => {
  1134. this.bomVersionList = res || [];
  1135. });
  1136. });
  1137. },
  1138. // 工艺路线
  1139. getPlanRouting() {
  1140. bomRoutingList(this.form.bomCategoryId).then((res) => {
  1141. this.routingList = res || [];
  1142. });
  1143. },
  1144. // 宝悦 工艺路线
  1145. getPlanRoutingNew() {
  1146. // bomRoutingList(this.form.bomCategoryId).then((res) => {
  1147. // this.routingList = res || []
  1148. // })
  1149. },
  1150. tableHandleKeyUp(row, name) {
  1151. // return
  1152. // , index, e, name
  1153. if (name == 'procut') {
  1154. return;
  1155. }
  1156. if (row.specification && this.clientEnvironmentId == 4) {
  1157. let modelArr = row.specification.split('*');
  1158. let modelLong = modelArr[0]; // model规格长度
  1159. let modeWide = modelArr[1]; // model规格宽度
  1160. let modeHight = modelArr[2].substr(0, modelArr[2].indexOf('cm')); // model规格高度
  1161. modeHight = Number(modeHight);
  1162. if (name === 'moCount') {
  1163. // 模数
  1164. this.$set(row, 'moCount', row.moCount);
  1165. // 计算块数的公式:
  1166. // (一模6米长度 / model规格长度) * (一模1.2米宽度 / model规格宽度) = 每一模的块数
  1167. // 每一模的块数*模数moCount = 总块数
  1168. if (row.productName.includes('板材')) {
  1169. // 块数
  1170. let blockCount =
  1171. Math.floor(600 / modelLong) *
  1172. Math.floor(120 / modeHight) *
  1173. Math.floor(60 / modeWide) *
  1174. row.moCount;
  1175. row['blockCount'] = blockCount;
  1176. // this.$set(row, 'blockCount', blockCount);
  1177. } else if (row.productName.includes('砌块')) {
  1178. let modelLongFixed = (600 / modelLong).toFixed(2);
  1179. modelLongFixed = modelLongFixed.substring(
  1180. 0,
  1181. modelLongFixed.length - 1
  1182. );
  1183. let modeWideFixed = (120 / modeWide).toFixed(2);
  1184. modeWideFixed = modeWideFixed.substring(
  1185. 0,
  1186. modeWideFixed.length - 1
  1187. );
  1188. let modeHightFixed = (60 / modeHight).toFixed(2);
  1189. modeHightFixed = modeHightFixed.substring(
  1190. 0,
  1191. modeHightFixed.length - 1
  1192. );
  1193. let num =
  1194. Math.floor(modelLongFixed * modeWideFixed * modeHightFixed) *
  1195. row.moCount;
  1196. row['blockCount'] = num;
  1197. }
  1198. let numNew = (
  1199. Number((modelLong * modeWide * modeHight) / 1000000).toFixed(5) *
  1200. row.blockCount
  1201. ).toFixed(5);
  1202. row['requiredFormingNum'] = numNew;
  1203. } else if (name === 'sum') {
  1204. let e = row.requiredFormingNum;
  1205. //方数
  1206. row.planProductNum = e;
  1207. row.blockCount = Math.floor(
  1208. e / ((modelLong * modeWide * modeHight) / 1000000)
  1209. );
  1210. if (row.productName.includes('板材')) {
  1211. let num = Math.ceil(
  1212. row.blockCount /
  1213. (Math.floor(600 / modelLong) *
  1214. Math.floor(120 / modeHight) *
  1215. Math.floor(60 / modeWide))
  1216. );
  1217. // 48 480 4807 480
  1218. row.moCount = num;
  1219. } else if (row.productName.includes('砌块')) {
  1220. row.moCount = Math.ceil(
  1221. row.blockCount /
  1222. Math.floor(
  1223. (600 / modelLong) * (120 / modeHight) * (60 / modeWide)
  1224. )
  1225. );
  1226. }
  1227. } else if (name === 'blockCount') {
  1228. //块数
  1229. // row.blockCount = row.moCount;
  1230. row.blockCount = row.blockCount;
  1231. if (row.productName.includes('板材')) {
  1232. let moCount = Math.ceil(
  1233. row.blockCount /
  1234. (Math.floor(600 / modelLong) *
  1235. Math.floor(120 / modeHight) *
  1236. Math.floor(60 / modeWide))
  1237. );
  1238. row.moCount = moCount;
  1239. } else if (row.productName.includes('砌块')) {
  1240. let moCount = Math.ceil(
  1241. row.blockCount /
  1242. Math.floor(
  1243. (600 / modelLong) * (120 / modeHight) * (60 / modeWide)
  1244. )
  1245. );
  1246. this.$set(this.form, 'moCount', moCount);
  1247. row.moCount = moCount;
  1248. }
  1249. let a = (
  1250. (Number(row.blockCount) * modelLong * modeWide * modeHight) /
  1251. 1000000
  1252. ).toFixed(5);
  1253. row.requiredFormingNum = a;
  1254. }
  1255. }
  1256. },
  1257. // 数量正则 quantity
  1258. handleQuantityInput(e, row) {
  1259. // 过滤非数字字符(包括负号)
  1260. let value = e.replace(/[^\d]/g, '');
  1261. value = value.replace(/-/g, '');
  1262. // 限制不能以 0 开头(除非是 0 本身)
  1263. if (value.startsWith('0') && value.length > 1) {
  1264. value = value.slice(1);
  1265. }
  1266. // 更新绑定值
  1267. row.requiredFormingNum = value;
  1268. },
  1269. changeProduceType(e) {
  1270. if (this.clientEnvironmentId !== 4) {
  1271. this.form.bomCategoryId = '';
  1272. this.form['bomCategoryName'] = '';
  1273. this.form['bomCategoryVersions'] = '';
  1274. this.bomVersionList = [];
  1275. this.routingList = [];
  1276. this.form.produceRoutingId = '';
  1277. this.form.produceRoutingName = '';
  1278. this.form.produceVersionName = '';
  1279. this.bomListVersion();
  1280. }
  1281. },
  1282. // changeBomId() {
  1283. // this.routingList = [];
  1284. // this.form.produceRoutingId = '';
  1285. // this.form.produceRoutingName = '';
  1286. // this.form.produceVersionName = '';
  1287. // this.bomVersionList.forEach((f) => {
  1288. // if (f.id == this.form.bomCategoryId) {
  1289. // this.$set(this.form, 'bomCategoryName', f.name);
  1290. // this.$set(this.form, 'bomCategoryVersions', f.versions);
  1291. // }
  1292. // });
  1293. // this.getPlanRouting();
  1294. // },
  1295. changeRoute() {
  1296. this.$forceUpdate();
  1297. this.routingList.forEach((f) => {
  1298. if (f.id == this.form.produceRoutingId) {
  1299. this.$set(this.form, 'produceRoutingId', f.id);
  1300. this.$set(this.form, 'produceRoutingName', f.name);
  1301. this.$set(this.form, 'produceVersionName', f.version);
  1302. }
  1303. });
  1304. },
  1305. cancel() {
  1306. this.visible = false;
  1307. this.initForm();
  1308. this.$emit('close');
  1309. },
  1310. // 【开始时间变化时】触发
  1311. handleStartTimeChange(row) {
  1312. // 校验 是否 大于结束时间 wda
  1313. this.checkEndTimeValid(row);
  1314. },
  1315. // 【结束时间变化时】触发
  1316. handleEndTimeChange(row) {
  1317. // 校验 是否 大于结束时间 wda
  1318. this.checkEndTimeValid(row);
  1319. },
  1320. // 时间校验
  1321. checkEndTimeValid(row) {
  1322. const { startTime: start, endTime: end } = row;
  1323. // if (!start || !end) return; // 开始/结束时间未填,跳过
  1324. const startTime = new Date(start); // 开始时间
  1325. const endTime = new Date(end); // 结束时间
  1326. if (endTime < startTime) {
  1327. row.endTime = new Date(startTime); // 修正为开始时间
  1328. this.$message.info('结束时间不能早于开始时间,已自动设为开始时间');
  1329. }
  1330. }
  1331. }
  1332. };
  1333. </script>
  1334. <style lang="scss" scoped>
  1335. .el-form-item {
  1336. margin-bottom: 14px !important;
  1337. }
  1338. .add-product {
  1339. width: 100%;
  1340. display: flex;
  1341. align-items: center;
  1342. justify-content: flex-end;
  1343. font-size: 30px;
  1344. color: #1890ff;
  1345. margin: 10px 0;
  1346. cursor: pointer;
  1347. }
  1348. .header_required {
  1349. .is-required:before {
  1350. content: '*';
  1351. color: #f56c6c;
  1352. margin-right: 4px;
  1353. }
  1354. }
  1355. </style>