index.vue 59 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881
  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" v-if="isSaleOrder">
  73. <el-form-item label="销售订单号:" prop="saleOrder">
  74. <div class="sale-order-select">
  75. <el-input
  76. v-model="form.saleOrder"
  77. size="mini"
  78. type="text"
  79. style="width: calc(100% - 54px)"
  80. placeholder="请选择销售订单号"
  81. readonly
  82. ></el-input>
  83. <el-button
  84. size="mini"
  85. type="primary"
  86. @click="openSaleOrderDialog"
  87. >
  88. 选择
  89. </el-button>
  90. </div>
  91. </el-form-item>
  92. </el-col>
  93. <el-col :span="6">
  94. <el-form-item
  95. label="生产编号:"
  96. label-width="110px"
  97. prop="productionCodes"
  98. >
  99. <el-input
  100. v-model="form.productionCodes"
  101. size="mini"
  102. type="text"
  103. style="width: 100%"
  104. placeholder=" "
  105. ></el-input>
  106. </el-form-item>
  107. </el-col>
  108. <el-col :span="6">
  109. <el-form-item
  110. label="计划开始日期:"
  111. label-width="110px"
  112. prop="startTime"
  113. >
  114. <el-date-picker
  115. style="width: 100%"
  116. size="mini"
  117. v-model="form.startTime"
  118. @change="handleStartTimeChange(form)"
  119. type="datetime"
  120. placeholder="选择日期"
  121. value-format="yyyy-MM-dd HH:mm:ss"
  122. >
  123. </el-date-picker>
  124. </el-form-item>
  125. </el-col>
  126. <el-col :span="6">
  127. <el-form-item
  128. label="计划结束日期:"
  129. label-width="110px"
  130. prop="endTime"
  131. >
  132. <el-date-picker
  133. style="width: 100%"
  134. size="mini"
  135. v-model="form.endTime"
  136. @change="handleEndTimeChange(form)"
  137. type="datetime"
  138. placeholder="选择日期"
  139. value-format="yyyy-MM-dd HH:mm:ss"
  140. >
  141. </el-date-picker>
  142. </el-form-item>
  143. </el-col>
  144. <el-col :span="6">
  145. <el-form-item
  146. label="要求完成日期:"
  147. label-width="110px"
  148. prop="reqMoldTime"
  149. >
  150. <el-date-picker
  151. style="width: 100%"
  152. size="mini"
  153. v-model="form.reqMoldTime"
  154. type="datetime"
  155. placeholder="选择日期"
  156. value-format="yyyy-MM-dd HH:mm:ss"
  157. >
  158. </el-date-picker>
  159. </el-form-item>
  160. </el-col>
  161. </el-row>
  162. <!-- <el-row :gutter="24">
  163. <el-col :span="6">
  164. <el-form-item
  165. label="要求完成日期:"
  166. label-width="110px"
  167. prop="reqMoldTime"
  168. >
  169. <el-date-picker
  170. style="width: 100%"
  171. size="mini"
  172. v-model="form.reqMoldTime"
  173. type="datetime"
  174. placeholder="选择日期"
  175. value-format="yyyy-MM-dd HH:mm:ss"
  176. >
  177. </el-date-picker>
  178. </el-form-item>
  179. </el-col>
  180. </el-row> -->
  181. <headerTitle title="产品信息"> </headerTitle>
  182. <el-row :gutter="24">
  183. <ele-pro-table
  184. ref="tableRef"
  185. :columns="columns"
  186. row-key="code"
  187. :cache-key="`ProductionPlanTable`"
  188. :datasource="form.productInfoList"
  189. border
  190. height="40vh"
  191. key="id"
  192. >
  193. <template v-slot:modelKey="{ row, $index }">
  194. <el-select
  195. clearable
  196. v-model="row.modelKey"
  197. multiple
  198. filterable
  199. allow-create
  200. default-first-option
  201. >
  202. <el-option
  203. v-for="item in modelList"
  204. :key="item.label"
  205. :value="item.label"
  206. :label="item.label"
  207. >
  208. </el-option>
  209. </el-select>
  210. </template>
  211. <template v-slot:colorKey="{ row, $index }">
  212. <el-select
  213. clearable
  214. v-model="row.colorKey"
  215. multiple
  216. filterable
  217. allow-create
  218. default-first-option
  219. >
  220. <el-option
  221. v-for="item in colorList"
  222. :key="item.label"
  223. :value="item.label"
  224. :label="item.label"
  225. >
  226. </el-option>
  227. </el-select>
  228. </template>
  229. <template v-slot:requiredFormingNum="{ row, $index }">
  230. <el-input
  231. v-model="row.requiredFormingNum"
  232. size="small"
  233. type="text"
  234. style="width: 100%"
  235. placeholder="输入要求生产数量"
  236. @input="(e) => handleQuantityInput(e, row)"
  237. ></el-input>
  238. <!-- placeholder="输入要求生产数量" @input="tableHandleKeyUp(row, 'sum')"></el-input> -->
  239. </template>
  240. <!-- <template v-slot:productionCodes="{ row, $index }">
  241. <el-input
  242. v-model="row.productionCodes"
  243. size="small"
  244. type="text"
  245. style="width: 100%"
  246. placeholder=" "
  247. ></el-input>
  248. </template> -->
  249. <template v-slot:productType="{ row, $index }">
  250. <el-select
  251. v-model="row.productType"
  252. @change="changeProductType(row, $index)"
  253. :key="$index"
  254. >
  255. <el-option
  256. v-for="item of row.producedList"
  257. :key="$index + item.code"
  258. :label="item.name"
  259. :value="item.code"
  260. ></el-option>
  261. </el-select>
  262. </template>
  263. <template v-slot:bomCategoryId="{ row, $index }">
  264. <el-select v-model="row.bomCategoryId">
  265. <el-option
  266. v-for="item of row.bomVersionList"
  267. :key="item.id"
  268. :label="item.name + '(V' + item.versions + '.0)'"
  269. :value="item.id"
  270. @click.native="changeBomId(row, $index, item)"
  271. ></el-option>
  272. </el-select>
  273. </template>
  274. <!-- //权重等级 -->
  275. <template
  276. v-slot:weight="{ row, $index }"
  277. v-if="clientEnvironmentId == 4"
  278. >
  279. <el-select
  280. v-model="row.weight"
  281. style="width: 100%"
  282. @change="changeProduceType"
  283. size="mini"
  284. >
  285. <el-option
  286. v-for="item of weightList"
  287. :key="item.code"
  288. :label="item.name"
  289. :value="item.code"
  290. ></el-option>
  291. </el-select>
  292. </template>
  293. <!-- 是否开槽 -->
  294. <template
  295. v-slot:isSlotting="{ row, $index }"
  296. v-if="clientEnvironmentId == 4"
  297. >
  298. <el-select
  299. v-model="row.isSlotting"
  300. style="width: 100%"
  301. @change="changeProduceType"
  302. size="mini"
  303. >
  304. <el-option
  305. v-for="item of isSlotting"
  306. :key="item.code"
  307. :label="item.name"
  308. :value="item.code"
  309. ></el-option>
  310. </el-select>
  311. </template>
  312. <!-- 开槽类型 -->
  313. <template
  314. v-slot:slottingType="{ row, $index }"
  315. v-if="clientEnvironmentId == 4"
  316. >
  317. <DictSelection
  318. dictName="开槽类型"
  319. v-model="row.slottingType"
  320. size="mini"
  321. >
  322. </DictSelection>
  323. </template>
  324. <!-- 工艺路线 -->
  325. <template
  326. v-slot:produceRoutingId="{ row, $index }"
  327. v-if="clientEnvironmentId != 4"
  328. >
  329. <!-- <el-form-item required> -->
  330. <div style="display: flex">
  331. <el-select
  332. v-model="row.produceRoutingId"
  333. v-show="isRouteSelect(row)"
  334. >
  335. <el-option
  336. v-for="item of row.routingList"
  337. :key="item.id"
  338. :label="item.name"
  339. :value="item.id"
  340. ></el-option>
  341. </el-select>
  342. <div style="display: flex">
  343. <el-input
  344. v-show="!isRouteSelect(row)"
  345. disabled
  346. v-model="row.produceRoutingName"
  347. ></el-input>
  348. <el-button
  349. v-show="isSelectShow"
  350. type="primary"
  351. size="mini"
  352. @click="openDialog($index)"
  353. >选择</el-button
  354. >
  355. </div>
  356. </div>
  357. <!-- </el-form-item> -->
  358. </template>
  359. <template v-slot:produceRoutingId="{ row, $index }" v-else>
  360. <el-input
  361. v-model="row.produceRoutingName"
  362. style="width: 100%"
  363. readonly
  364. ></el-input>
  365. </template>
  366. <template v-slot:factoriesId="{ row, $index }">
  367. <el-select
  368. v-model="row.factoriesId"
  369. :key="row.factoriesId"
  370. @change="(e) => selectFactory(e, row)"
  371. :disabled="!!factoriesId"
  372. >
  373. <el-option
  374. v-for="item of factoryList"
  375. :key="item.id"
  376. :label="item.name"
  377. :value="item.id"
  378. ></el-option>
  379. </el-select>
  380. </template>
  381. <!-- <el-table-column label="所属工厂" width="140" align="center" prop="factoriesId">
  382. <template slot-scope="scope">
  383. <el-form-item label-width="0px">
  384. <el-select v-model="scope.row.factoriesId" :key="scope.row.factoriesId">
  385. <el-option v-for="item of factoryList" :key="item.id" :label="item.name"
  386. :value="item.id"></el-option>
  387. </el-select>
  388. </el-form-item>
  389. </template>
  390. </el-table-column> -->
  391. <!-- 模具数量 -->
  392. <template
  393. v-slot:moCount="{ row, $index }"
  394. v-if="clientEnvironmentId == '4'"
  395. >
  396. <div>
  397. <el-input
  398. style="width: 100%"
  399. size="small"
  400. v-model="row.moCount"
  401. oninput="value=value.replace(/[^0-9.]/g,'')"
  402. @input="tableHandleKeyUp(row, 'moCount')"
  403. placeholder="请输入"
  404. >
  405. </el-input>
  406. </div>
  407. </template>
  408. <!-- 块数 -->
  409. <template
  410. v-slot:blockCount="{ row, $index }"
  411. v-if="clientEnvironmentId == '4'"
  412. >
  413. <div>
  414. <el-input
  415. size="small"
  416. style="width: 100%"
  417. @input="tableHandleKeyUp(row, 'blockCount')"
  418. v-model="row.blockCount"
  419. placeholder="请输入"
  420. ></el-input>
  421. </div>
  422. </template>
  423. <!-- <template v-slot:productWeight="{ row, $index }">
  424. <span>{{ row.productWeight ? row.productWeight : '-' }}</span>
  425. </template> -->
  426. <template v-slot:set="{ row, $index }">
  427. <el-button type="text" @click="handleDeleteItem($index)"
  428. >删除</el-button
  429. >
  430. </template>
  431. <template v-slot:headerProduceRoutingId="{ column }">
  432. <div class="header_required"
  433. ><span class="is-required">{{ column.label }}</span></div
  434. >
  435. </template>
  436. <template v-slot:headeRequiredFormingNum="{ column }">
  437. <div class="header_required"
  438. ><span class="is-required">{{ column.label }}</span></div
  439. >
  440. </template>
  441. <template v-slot:headerProcessingBOM="{ column }">
  442. <div :class="isRequired ? 'header_required' : ''"
  443. ><span class="is-required">{{ column.label }}</span></div
  444. >
  445. </template>
  446. </ele-pro-table>
  447. <div class="add-product" @click="addEquipment" v-if="!form.id">
  448. <i class="el-icon-circle-plus-outline"></i>
  449. </div>
  450. </el-row>
  451. </el-form>
  452. <!-- 选择产品 -->
  453. <EquipmentDialog
  454. @choose="confirmChoose"
  455. :treeType="['9']"
  456. :selectList="[]"
  457. ref="equipmentRefs"
  458. >
  459. </EquipmentDialog>
  460. <saleOrderPop
  461. ref="saleOrderRef"
  462. :isMultiple="false"
  463. @chooseOrder="chooseSaleOrder"
  464. />
  465. </div>
  466. <template v-slot:footer>
  467. <el-button @click="cancel">取消</el-button>
  468. <el-button type="primary" @click="save" :loading="loading">
  469. 确定
  470. </el-button>
  471. <el-button
  472. type="primary"
  473. @click="save('sub')"
  474. :loading="loading"
  475. v-if="!isReview"
  476. >
  477. 发布
  478. </el-button>
  479. </template>
  480. <ProcessRoute ref="processRouteRef" @changeParent="changeParent" />
  481. </ele-modal>
  482. </template>
  483. <script>
  484. import { findBomCategoryByCategoryId } from '@/api/productionPlan/index';
  485. import EquipmentDialog from '@/views/saleOrder/components/EquipmentDialog';
  486. import saleOrderPop from './components/saleOrderPop.vue';
  487. import { getCode } from '@/api/codeManagement';
  488. import ProcessRoute from '@/components/selectionDialog/processRoute.vue';
  489. import { parameterGetByCode } from '@/api/mainData/index';
  490. import { getByCode } from '@/api/system/dictionary-data';
  491. import {
  492. bomRoutingList,
  493. bomListByPlan,
  494. getFactoryList,
  495. saveAndRelease,
  496. temporaryPlanSave,
  497. getUpdateInfoByCode
  498. } from '@/api/saleOrder';
  499. import { planIsReview } from '@/api/productionPlan/index';
  500. import contactDialog from '@/components/contactDialog/openContactDialog.vue';
  501. import { deepClone } from '@/utils';
  502. export default {
  503. components: {
  504. EquipmentDialog,
  505. saleOrderPop,
  506. ProcessRoute,
  507. contactDialog
  508. },
  509. props: {
  510. factoryType: {
  511. type: Number,
  512. default: 3
  513. },
  514. factoryObj: {
  515. type: Object,
  516. default: () => {}
  517. },
  518. isAdd: {
  519. type: Boolean,
  520. default: true
  521. }
  522. },
  523. watch: {
  524. // factoryObj: {
  525. // immediate: true,
  526. // deep: true,
  527. // handler(val) {
  528. // // 修改
  529. // // this.$nextTick(() => {
  530. // // if (val.id) {
  531. // // this.bomListVersion();
  532. // // if (val.bomCategoryId) {
  533. // // this.getPlanRouting();
  534. // // }
  535. // // }
  536. // // });
  537. // }
  538. // }
  539. },
  540. computed: {
  541. // 是否必填 字段 ( 首先看计划类型 如果是返工返修)
  542. // 就不是必填 否则就看配置参数
  543. // 必填的时候 不显示选择按钮 跟 展示输入框 只能有下拉选择框 ( 选择了生产类型 带出 BOM 版本 带出 工艺路线 工艺路线不能选择)
  544. // 不必填的时候 显示 选择按钮跟 展示输入框 并且可以存在选择框 一开始默认展示选择框
  545. // 选择按钮选择数据后 隐藏选择框 显示展示框(input) 情况 生产类型 跟 BOM版本
  546. // 选择了生产类型 清空 选择框选择的工艺路线
  547. // 是否必填字段
  548. isRequired() {
  549. if (this.form.planType == 5) {
  550. return false;
  551. }
  552. return this.processingRequired == 1;
  553. },
  554. // 工艺路线 输入框展示跟选择框判断
  555. isRouteSelect() {
  556. return (row) => {
  557. if (this.isRequired) {
  558. return true;
  559. }
  560. if (!row.selectionRowShow) {
  561. return true;
  562. }
  563. return false;
  564. };
  565. },
  566. // 选择按钮的显示
  567. isSelectShow() {
  568. if (this.form.planType == 5) {
  569. return true;
  570. }
  571. return this.processingRequired == 0;
  572. },
  573. // clientEnvironmentId() {
  574. // return this.$store.state.user.info.clientEnvironmentId;
  575. // },
  576. columns() {
  577. return [
  578. {
  579. columnKey: 'index',
  580. label: '序号',
  581. type: 'index',
  582. width: 55,
  583. align: 'center',
  584. showOverflowTooltip: true
  585. },
  586. {
  587. slot: 'lineNumber',
  588. prop: 'lineNumber',
  589. label: '行号',
  590. align: 'center',
  591. minWidth: 140
  592. },
  593. {
  594. slot: 'productName',
  595. prop: 'productName',
  596. label: '名称',
  597. align: 'center',
  598. minWidth: 140
  599. },
  600. {
  601. slot: 'productCode',
  602. prop: 'productCode',
  603. label: '编码',
  604. align: 'center',
  605. minWidth: 140
  606. },
  607. {
  608. slot: 'brandNo',
  609. prop: 'brandNo',
  610. label: '牌号',
  611. align: 'center',
  612. minWidth: 140
  613. },
  614. {
  615. slot: 'model',
  616. prop: 'model',
  617. label: '型号',
  618. align: 'center',
  619. minWidth: 140
  620. },
  621. {
  622. slot: 'specification',
  623. prop: 'specification',
  624. label: '规格',
  625. align: 'center',
  626. minWidth: 140
  627. },
  628. {
  629. slot: 'productUnitWeight',
  630. prop: 'productUnitWeight',
  631. label: '单重',
  632. align: 'center',
  633. minWidth: 140
  634. },
  635. {
  636. slot: 'weightUnit',
  637. prop: 'weightUnit',
  638. label: '重量单位',
  639. align: 'center',
  640. minWidth: 140
  641. },
  642. {
  643. slot: 'modelKey',
  644. prop: 'modelKey',
  645. label: '机型',
  646. align: 'center',
  647. minWidth: 240
  648. },
  649. {
  650. slot: 'colorKey',
  651. prop: 'colorKey',
  652. label: '颜色',
  653. align: 'center',
  654. minWidth: 240
  655. },
  656. {
  657. slot: 'requiredFormingNum',
  658. prop: 'requiredFormingNum',
  659. headerSlot: 'headeRequiredFormingNum',
  660. label: '要求生产数量',
  661. align: 'center',
  662. minWidth: 140
  663. },
  664. {
  665. slot: 'measuringUnit',
  666. prop: 'measuringUnit',
  667. label: '计量单位',
  668. align: 'center',
  669. minWidth: 140
  670. },
  671. // {
  672. // slot: 'productionCodes',
  673. // prop: 'productionCodes',
  674. // label: '生产编号',
  675. // align: 'center',
  676. // minWidth: 140
  677. // },
  678. {
  679. slot: 'moCount',
  680. prop: 'moCount',
  681. label: '模数',
  682. headerSlot: 'headeRequiredFormingNum',
  683. align: 'center',
  684. minWidth: 140,
  685. show: this.clientEnvironmentId == 4
  686. },
  687. {
  688. slot: 'blockCount',
  689. prop: 'blockCount',
  690. label: '块数',
  691. headerSlot: 'headeRequiredFormingNum',
  692. align: 'center',
  693. minWidth: 140,
  694. show: this.clientEnvironmentId == 4
  695. },
  696. {
  697. slot: 'productType',
  698. prop: 'productType',
  699. label: '生产类型',
  700. headerSlot: 'headerProcessingBOM',
  701. align: 'center',
  702. minWidth: 180
  703. },
  704. {
  705. slot: 'bomCategoryId',
  706. prop: 'bomCategoryId',
  707. label: 'BOM版本',
  708. headerSlot: 'headerProcessingBOM',
  709. align: 'center',
  710. minWidth: 180,
  711. show: this.clientEnvironmentId !== 4
  712. },
  713. {
  714. slot: 'produceRoutingId',
  715. prop: 'produceRoutingId',
  716. headerSlot: 'headerProduceRoutingId',
  717. label: '工艺路线',
  718. align: 'center',
  719. minWidth: 240
  720. },
  721. {
  722. slot: 'factoriesId',
  723. prop: 'factoriesId',
  724. headerSlot: 'headerProduceRoutingId',
  725. label: '所属工厂',
  726. align: 'center',
  727. minWidth: 140
  728. },
  729. {
  730. slot: 'weight',
  731. prop: 'weight',
  732. label: '权重等级',
  733. align: 'center',
  734. minWidth: 140,
  735. show: this.clientEnvironmentId == 4
  736. },
  737. {
  738. slot: 'isSlotting',
  739. prop: 'isSlotting',
  740. label: '是否开槽',
  741. align: 'center',
  742. minWidth: 140,
  743. show: this.clientEnvironmentId == 4
  744. },
  745. {
  746. slot: 'slottingType',
  747. prop: 'slottingType',
  748. label: '开槽类型',
  749. align: 'center',
  750. minWidth: 140,
  751. show: this.clientEnvironmentId == 4
  752. },
  753. {
  754. slot: 'newSumOrderWeight',
  755. prop: 'newSumOrderWeight',
  756. label: '计划重量',
  757. align: 'center',
  758. minWidth: 140
  759. },
  760. {
  761. slot: 'set',
  762. prop: 'set',
  763. label: '操作',
  764. align: 'center',
  765. minWidth: 140,
  766. fixed: 'right'
  767. }
  768. ];
  769. }
  770. },
  771. data() {
  772. return {
  773. visible: false,
  774. factoriesId: '',
  775. clientEnvironmentId: '',
  776. title: '新增临时生产计划',
  777. type: 3,
  778. weightList: [
  779. { code: 1, name: 'A' },
  780. { code: 2, name: 'B' },
  781. { code: 3, name: 'C' }
  782. ],
  783. factoryList: [],
  784. isSlotting: [
  785. { code: 1, name: '是' },
  786. { code: 2, name: '否' }
  787. ], //是否开槽
  788. planTypeList: [
  789. { label: '内销计划', value: 1 },
  790. { label: '外销计划', value: 2 },
  791. { label: '预制计划', value: 3 },
  792. { label: '改型计划', value: 4 },
  793. { label: '返工返修计划', value: 5 }
  794. ],
  795. loading: false,
  796. form: {
  797. timeDimensionPlanType: 3,
  798. categoryId: '',
  799. productName: '',
  800. planType: '',
  801. saleOrder: '',
  802. moCount: '', // 模具数量
  803. blockCount: 0, // 块数
  804. noWordCount: '', // 无字数量
  805. weight: '',
  806. startTime: '',
  807. endTime: '',
  808. isSlotting: '', //是否开槽
  809. slottingType: '', //开槽类型
  810. id: '',
  811. produceType: 2,
  812. bomCategoryId: '',
  813. produceRoutingId: '',
  814. requiredFormingNum: '',
  815. productInfoList: []
  816. },
  817. disabledList: [],
  818. bomVersionList: [],
  819. routingList: [],
  820. rules: {
  821. productName: [
  822. { required: true, message: '请选择名称', trigger: 'change' }
  823. ],
  824. bomCategoryId: [
  825. { required: true, message: '请选择BOM版本', trigger: 'blur' }
  826. ],
  827. planType: [
  828. { required: true, message: '请选择计划类型', trigger: 'blur' }
  829. ],
  830. produceType: [
  831. { required: true, message: '请选择工艺路线', trigger: 'blur' }
  832. ],
  833. produceRoutingId: [
  834. { required: true, message: '请选择工艺路线', trigger: 'blur' }
  835. ],
  836. startTime: [
  837. { required: true, message: '请选择计划开始日期', trigger: 'blur' }
  838. ],
  839. endTime: [
  840. { required: true, message: '请选择计划结束日期', trigger: 'blur' }
  841. ],
  842. // reqMoldTime: [
  843. // { required: true, message: '请选择要求完成日期', trigger: 'blur' }
  844. // ],
  845. requiredFormingNum: [
  846. { required: true, message: '请输入生产数量', trigger: 'blur' }
  847. ]
  848. },
  849. producedList: [
  850. { code: 2, name: '加工(MBOM)' },
  851. { code: 3, name: '装配(ABOM)' }
  852. ],
  853. selectIndex: 0, // 选择工艺路线的当前数据下标
  854. processingRequired: 0, // 生产类型跟BOM 版本是否必填 1:是 0:否
  855. isReview: false,
  856. isSaleOrder: false
  857. // selectionRowShow: false // 工艺路线输入框展示 状态
  858. };
  859. },
  860. // computed: {
  861. // clientEnvironmentId() {
  862. // return this.$store.state.user.info.clientEnvironmentId;
  863. // }
  864. // },
  865. mounted() {},
  866. methods: {
  867. // 获取
  868. async getCodeData() {
  869. let arr1 = await this.getLevelCode('product_model_key');
  870. let arr2 = await this.getLevelCode('product_color_key');
  871. this.modelList = arr1;
  872. this.colorList = arr2;
  873. },
  874. async getLevelCode(code) {
  875. try {
  876. const res = await getByCode(code);
  877. if (res.code == 0) {
  878. let list = Object.values(res.data).map((el) => {
  879. let k = Object.keys(el)[0];
  880. let v = Object.values(el)[0];
  881. return {
  882. label: v,
  883. value: k
  884. };
  885. });
  886. return list;
  887. }
  888. } catch (err) {
  889. this.$message.error(err.message);
  890. }
  891. },
  892. selectFactory(e, row) {
  893. let data = this.factoryList.find((item) => item.id === e);
  894. this.$set(row, 'factoriesName', data.name);
  895. },
  896. async getPlannedReleaseRequire(code) {
  897. parameterGetByCode({ code }).then((res) => {
  898. if (res) {
  899. this.isReview = res.value == '1' ? true : false;
  900. }
  901. });
  902. },
  903. // 打开工艺路线
  904. openDialog(index) {
  905. this.selectIndex = index;
  906. this.$refs.processRouteRef.open();
  907. },
  908. // 选择工艺路线
  909. changeParent(item) {
  910. let data = this.form.productInfoList[this.selectIndex];
  911. this.$set(data, 'bomVersionList', []);
  912. this.$set(data, 'bomCategoryId', '');
  913. this.$set(data, 'model', '');
  914. this.$set(data, 'routingList', []);
  915. this.$set(data, 'productType', '');
  916. this.$set(data, 'produceRoutingName', item.name);
  917. this.$set(data, 'produceRoutingId', item.id);
  918. this.$set(data, 'selectionRowShow', true);
  919. // this.selectionRowShow = true;
  920. },
  921. async getFactoryList() {
  922. this.factoryList = await getFactoryList();
  923. },
  924. async open(val) {
  925. const [processingRes, saleOrderRes] = await Promise.all([
  926. parameterGetByCode({ code: 'production_plan_code' }),
  927. parameterGetByCode({ code: 'create_plan_binding_sale_order' }),
  928. this.getCodeData(),
  929. this.getFactoryList(),
  930. this.getPlannedReleaseRequire('planned_release_require')
  931. ]);
  932. if (processingRes) {
  933. this.processingRequired = processingRes.value;
  934. }
  935. this.isSaleOrder = saleOrderRes?.value === '1';
  936. this.clientEnvironmentId =
  937. this.$store.state.user.info.clientEnvironmentId;
  938. this.factoriesId = this.$store.state.user.info.factoryId;
  939. if (!val) {
  940. this.title = '新增临时生产计划';
  941. this.visible = true;
  942. return;
  943. }
  944. if (val.planType == null || val.planType === 'null') {
  945. val.planType = '';
  946. }
  947. this.title = val.id ? '编辑临时生产计划' : '新增临时生产计划';
  948. val.planType = String(val.planType);
  949. this.form = await getUpdateInfoByCode(val.code);
  950. if (this.isSaleOrder) {
  951. const salesCode = this.form.salesCode;
  952. this.$set(
  953. this.form,
  954. 'saleOrder',
  955. Array.isArray(salesCode) ? salesCode.join(',') : salesCode || ''
  956. );
  957. }
  958. if (val.id) {
  959. await this.initEditProductList(val);
  960. }
  961. this.$forceUpdate();
  962. this.visible = true;
  963. },
  964. async initEditProductList(val) {
  965. const productList = this.form.productInfoList;
  966. if (Array.isArray(val.productInfoList) && val.productInfoList.length) {
  967. await Promise.all(
  968. productList.map(async (v, index) => {
  969. v.selectionRowShow = !v.bomCategoryId;
  970. if (!v.bomCategoryId) {
  971. v.productType = '';
  972. }
  973. if (v.productType) {
  974. this.$set(productList[index], 'bomVersionList',
  975. await this.bomListVersionFn(v.productType, v.categoryId)
  976. );
  977. }
  978. if (v.bomCategoryId) {
  979. this.$set(productList[index], 'routingList',
  980. await this.changeBomIdFn(v.bomCategoryId, productList[index])
  981. );
  982. }
  983. })
  984. );
  985. }
  986. const resAll = await Promise.all(
  987. productList.map((item) => findBomCategoryByCategoryId(item.categoryId))
  988. );
  989. productList.forEach((item, index) => {
  990. if (typeof item.colorKey === 'string' && item.colorKey) {
  991. this.$set(productList[index], 'colorKey', item.colorKey.split(','));
  992. }
  993. if (typeof item.modelKey === 'string' && item.modelKey) {
  994. this.$set(productList[index], 'modelKey', item.modelKey.split(','));
  995. }
  996. if (!resAll[index]) return;
  997. const listMap = {};
  998. resAll[index].forEach((el) => {
  999. if (el.bomType === '2' || el.bomType === '3') {
  1000. if (!listMap[el.bomType]) listMap[el.bomType] = [];
  1001. listMap[el.bomType].push(el);
  1002. }
  1003. });
  1004. const list = [];
  1005. if (listMap[2]) list.push({ code: 2, name: 'MBOM' });
  1006. if (listMap[3]) list.push({ code: 3, name: 'ABOM' });
  1007. if (!item.factoriesId) {
  1008. this.$set(productList[index], 'factoriesId', this.factoriesId);
  1009. this.$set(productList[index], 'factoriesName',
  1010. this.factoryList?.find((f) => f.id === this.factoriesId)?.name
  1011. );
  1012. }
  1013. this.$set(productList[index], 'producedList', list);
  1014. });
  1015. },
  1016. addEquipment() {
  1017. this.$refs.equipmentRefs.open();
  1018. },
  1019. async confirmChoose(data) {
  1020. let list = deepClone(data);
  1021. list.map((el) => (el.selectionRowShow = false));
  1022. if (this.clientEnvironmentId == 4) {
  1023. list.map((v) => {
  1024. if (v.name.includes('板材')) {
  1025. v.produceRoutingId = '1856970794952372226';
  1026. v.produceRoutingName = '板材';
  1027. v.produceVersionName = '板材';
  1028. } else {
  1029. (v.produceRoutingId = '1857313733642596353'),
  1030. (v.produceRoutingName = '砌块'),
  1031. (v.produceVersionName = '砌块');
  1032. }
  1033. });
  1034. }
  1035. let ids = this.form.productInfoList.map((item) => item.categoryId);
  1036. let result = list
  1037. .filter((i) => !ids.includes(i.id))
  1038. .map((item, index) => {
  1039. return {
  1040. categoryId: item.id,
  1041. productCode: item.code,
  1042. productName: item.name,
  1043. productUnitWeight: item.netWeight,
  1044. weightUnit: item.weightUnit,
  1045. model: item.modelType,
  1046. specification: item.specification,
  1047. brandNo: item.brandNum,
  1048. measuringUnit: item.measuringUnit,
  1049. produceRoutingId: item.produceRoutingId,
  1050. produceRoutingName: item.produceRoutingName,
  1051. produceVersionName: item.produceVersionName,
  1052. factoriesId: this.factoriesId,
  1053. colorKey: item.colorKey ? item.colorKey.split(',') : [],
  1054. modelKey: item.modelKey ? item.modelKey.split(',') : [],
  1055. factoriesName: this.factoryList?.find(
  1056. (factoryData) => factoryData.id === this.factoriesId
  1057. )?.name
  1058. };
  1059. });
  1060. // this.form.productInfoList = [];
  1061. // 取出在弹窗中选中并且不在表格中的数据
  1062. // const result = list.filter(
  1063. // (i) =>
  1064. // this.form.productInfoList.findIndex(
  1065. // (p) => p.productCode === i.productCode
  1066. // ) === -1
  1067. // );
  1068. // // 取出在表格中并且不在弹窗中选中的数据 即取消选中的数据
  1069. // const del = this.form.productInfoList.filter(
  1070. // (i) => list.findIndex((p) => p.productCode === i.productCode) === -1
  1071. // );
  1072. // for (let i = this.form.productInfoList.length - 1; i >= 0; i--) {
  1073. // for (let j in del) {
  1074. // if (
  1075. // this.form.productInfoList[i].productCode === del[j].productCode
  1076. // ) {
  1077. // this.form.productInfoList.splice(i, 1);
  1078. // break;
  1079. // }
  1080. // }
  1081. // }
  1082. let promiseAll = [];
  1083. result.forEach(async (item) => {
  1084. let categoryId = item.categoryId;
  1085. promiseAll.push(findBomCategoryByCategoryId(categoryId));
  1086. });
  1087. const resAll = await Promise.all(promiseAll);
  1088. try {
  1089. await result.forEach(async (item, index) => {
  1090. if (resAll[index]) {
  1091. let listMap = {};
  1092. let list = [];
  1093. let arr = [];
  1094. resAll[index].map((el) => {
  1095. if (el.bomType == '2' || el.bomType == '3') {
  1096. console.log(listMap, 'listMap');
  1097. if (listMap[el.bomType]) {
  1098. listMap[el.bomType].push(el);
  1099. } else {
  1100. listMap[el.bomType] = [el];
  1101. }
  1102. }
  1103. });
  1104. if (listMap[2]) {
  1105. list.push({ code: 2, name: 'MBOM' });
  1106. arr = listMap[2];
  1107. item.productType = 2;
  1108. }
  1109. if (listMap[3]) {
  1110. list.push({ code: 3, name: 'ABOM' });
  1111. if (!listMap[2]) {
  1112. arr = listMap[3];
  1113. item.productType = 3;
  1114. }
  1115. }
  1116. if (arr.length > 0) {
  1117. arr.map((el) => (el.bomCategoryId = el.id));
  1118. item.bomCategoryId = arr[0].id;
  1119. await this.changeBomId(arr[0], 0);
  1120. this.$set(item, 'produceRoutingId', arr[0].produceRoutingId);
  1121. this.$set(
  1122. item,
  1123. 'produceVersionName',
  1124. arr[0].produceVersionName
  1125. );
  1126. this.$set(
  1127. item,
  1128. 'produceRoutingName',
  1129. arr[0].produceRoutingName
  1130. );
  1131. console.log(arr[0], 'arr[0]');
  1132. this.$set(item, 'routingList', arr[0].routingList);
  1133. this.$set(item, 'bomCategoryName', arr[0].name);
  1134. this.$set(item, 'bomCategoryVersions', arr[0].versions);
  1135. }
  1136. item.producedList = list;
  1137. item.bomVersionList = arr;
  1138. return item;
  1139. }
  1140. });
  1141. } catch (err) {}
  1142. console.log(result, 'result');
  1143. // return
  1144. this.form.productInfoList.push(...result);
  1145. this.changeLineNumber();
  1146. console.log(this.form.productInfoList, 'this.form.productInfoList');
  1147. this.$refs.tableRef.setData(this.form.productInfoList);
  1148. // console.log(this.form.productInfoList, 'this.form.productInfoList');
  1149. //重置
  1150. this.$set(this.form, 'produceType', '');
  1151. this.$set(this.form, 'bomCategoryId', '');
  1152. this.$set(this.form, 'produceRoutingId', '');
  1153. },
  1154. changeLineNumber() {
  1155. this.form.productInfoList.forEach((item, index) => {
  1156. let data = this.form.productInfoList[index - 1];
  1157. this.$set(
  1158. this.form.productInfoList[index],
  1159. 'lineNumber',
  1160. data ? data.lineNumber + 10 : 10
  1161. );
  1162. });
  1163. },
  1164. handleDeleteItem(index) {
  1165. this.$confirm('确定删除当前数据?', '提示')
  1166. .then(() => {
  1167. const newArray = this.form.productInfoList.filter(
  1168. (item, i) => i !== index
  1169. );
  1170. this.form.productInfoList = newArray;
  1171. this.$refs.tableRef.setData(newArray);
  1172. })
  1173. .catch(() => {});
  1174. },
  1175. async getPlanCode() {
  1176. this.loading = true;
  1177. try {
  1178. const code = await getCode('product_code');
  1179. this.$set(this.form, 'code', code);
  1180. } catch (err) {}
  1181. },
  1182. initForm() {
  1183. this.form = {
  1184. timeDimensionPlanType: 3,
  1185. categoryId: '',
  1186. productName: '',
  1187. planType: '',
  1188. saleOrder: '',
  1189. moCount: '', // 模具数量
  1190. blockCount: 0, // 块数
  1191. noWordCount: '', // 无字数量
  1192. weight: '',
  1193. isSlotting: '', //是否开槽
  1194. slottingType: '', //开槽类型
  1195. id: '',
  1196. produceType: 2,
  1197. status: 2,
  1198. bomCategoryId: '',
  1199. produceRoutingId: '',
  1200. productInfoList: [],
  1201. requiredFormingNum: ''
  1202. };
  1203. // console.log(this.$refs);
  1204. // this.$refs.tableRef.setData([]);
  1205. },
  1206. changeBomIdFn(bomCategoryId, row) {
  1207. return new Promise((resolve, reject) => {
  1208. bomRoutingList(bomCategoryId).then((res) => {
  1209. let arr = res || [];
  1210. if (arr.length == 0) {
  1211. row.produceRoutingId = '';
  1212. }
  1213. resolve(arr);
  1214. });
  1215. });
  1216. },
  1217. // 选择BOM
  1218. async changeBomId(row, index, bomData, typeChange) {
  1219. if (bomData) {
  1220. row.bomCategoryName = bomData.name;
  1221. row.bomCategoryVersions = bomData.versions;
  1222. }
  1223. // row.routingList = []
  1224. return await bomRoutingList(row.bomCategoryId).then((res) => {
  1225. let arr = res || [];
  1226. if (arr.length > 0) {
  1227. // this.$nextTick(() => {
  1228. row.produceRoutingName = arr[0].name;
  1229. row.produceVersionName = arr[0].version;
  1230. row.produceRoutingId = arr[0].id;
  1231. row.routingList = arr;
  1232. if (typeChange) {
  1233. this.$set(this.form.productInfoList[index], 'routingList', arr);
  1234. this.$set(
  1235. this.form.productInfoList[index],
  1236. 'produceRoutingId',
  1237. arr[0].id
  1238. );
  1239. } else {
  1240. this.$set(row, 'produceRoutingId', arr[0].id);
  1241. this.$set(row, 'routingList', arr);
  1242. }
  1243. row.selectionRowShow = false;
  1244. console.log(row.routingList, 'this.form.productInfoList');
  1245. // });
  1246. }
  1247. this.$forceUpdate();
  1248. });
  1249. },
  1250. contactDialogSuccess(data) {
  1251. console.log(data, 'data 11');
  1252. // serialNo
  1253. this.form.serialNo = data.serialNo;
  1254. this.$set(this.form, 'customerName', data.name);
  1255. },
  1256. openSaleOrderDialog() {
  1257. this.$refs.saleOrderRef.open([]);
  1258. },
  1259. chooseSaleOrder(list) {
  1260. const currentRow = list[0] || {};
  1261. this.$set(this.form, 'saleOrder', currentRow.orderNo || '');
  1262. },
  1263. // 清空BOM 跟工艺路线
  1264. wipeData(index) {
  1265. this.$set(this.form.productInfoList[index], 'bomCategoryId', '');
  1266. this.$set(this.form.productInfoList[index], 'routingList', []);
  1267. this.$set(this.form.productInfoList[index], 'bomVersionList', []);
  1268. this.$set(this.form.productInfoList[index], 'produceRoutingId', '');
  1269. this.$set(this.form.productInfoList[index], 'produceRoutingName', '');
  1270. this.$set(this.form.productInfoList[index], 'produceVersionName', '');
  1271. this.$set(this.form.productInfoList[index], 'selectionRowShow', false);
  1272. // this.selectionRowShow = false;
  1273. },
  1274. // 选择生产类型
  1275. changeProductType(row, index) {
  1276. let param = {
  1277. bomType: row.productType,
  1278. categoryId: row.categoryId
  1279. };
  1280. this.wipeData(index);
  1281. // row.bomCategoryId = '';
  1282. // this.form.productInfoList[index].bomVersionList = [];
  1283. bomListByPlan(param).then((res) => {
  1284. let arr = res || [];
  1285. this.$nextTick(() => {
  1286. if (arr.length) {
  1287. row.bomVersionList = arr;
  1288. this.form.productInfoList[index].bomVersionList = arr;
  1289. row.bomCategoryId = arr[0].id;
  1290. this.changeBomId(row, index, arr[0], 'typeChange');
  1291. let arrAll = JSON.parse(JSON.stringify(this.form));
  1292. this.$set(this, 'form', arrAll);
  1293. }
  1294. });
  1295. // this.$set(this.form.productInfoList[index], 'bomVersionList', arr);
  1296. });
  1297. },
  1298. // 参数校验
  1299. parameterVerification() {
  1300. let flag = true;
  1301. this.form.productInfoList.forEach((v) => {
  1302. if (this.isRequired) {
  1303. if (!v.productType) {
  1304. flag = false;
  1305. this.$message.warning('请选择生产类型');
  1306. return;
  1307. }
  1308. if (!v.bomCategoryId) {
  1309. flag = false;
  1310. this.$message.warning('请选择BOM版本');
  1311. return;
  1312. }
  1313. }
  1314. if (!v.produceRoutingId) {
  1315. flag = false;
  1316. this.$message.warning('请选择工艺路线');
  1317. return;
  1318. }
  1319. if (!v.factoriesId) {
  1320. flag = false;
  1321. this.$message.warning('请选择所属工厂');
  1322. return;
  1323. }
  1324. if (v.requiredFormingNum == 0) {
  1325. flag = false;
  1326. this.$message.warning('要求生产数量不能为0');
  1327. return;
  1328. }
  1329. if (!v.requiredFormingNum) {
  1330. flag = false;
  1331. this.$message.warning('请输入要求生产数量');
  1332. return;
  1333. }
  1334. if (!v.moCount && this.clientEnvironmentId == 4) {
  1335. flag = false;
  1336. this.$message.warning('请输入模数');
  1337. return;
  1338. }
  1339. if (!v.blockCount && this.clientEnvironmentId == 4) {
  1340. flag = false;
  1341. this.$message.warning('请输入块数');
  1342. return;
  1343. }
  1344. });
  1345. return flag;
  1346. },
  1347. save(type) {
  1348. this.$refs.form.validate(async (valid) => {
  1349. if (!valid) return;
  1350. if (!this.parameterVerification()) return;
  1351. const isAdd = !this.form.id;
  1352. this.form.productInfoList.forEach((item) => {
  1353. item.colorKey = item.colorKey.toString();
  1354. item.modelKey = item.modelKey.toString();
  1355. if (isAdd) delete item.selectionRowShow;
  1356. });
  1357. if (isAdd) {
  1358. this.form.timeDimensionPlanType = this.type;
  1359. }
  1360. if (this.isSaleOrder) {
  1361. this.form.salesCode = this.form.saleOrder.split(',');
  1362. }
  1363. this.loading = true;
  1364. const api = type === 'sub' ? saveAndRelease : temporaryPlanSave;
  1365. api(this.form)
  1366. .then(() => {
  1367. this.$message.success(isAdd ? '新增成功!' : '修改成功!');
  1368. this.visible = false;
  1369. this.initForm();
  1370. this.$emit('close', true);
  1371. })
  1372. .finally(() => {
  1373. this.loading = false;
  1374. });
  1375. });
  1376. },
  1377. // save(type) {
  1378. // this.$refs.form.validate(async (valid) => {
  1379. // if (!valid) {
  1380. // return false;
  1381. // }
  1382. // let flag = this.parameterVerification();
  1383. // // 必填参数校验
  1384. // if (!flag) return;
  1385. // this.form.productInfoList.forEach((item, index) => {
  1386. // this.$set(
  1387. // this.form.productInfoList[index],
  1388. // 'colorKey',
  1389. // item.colorKey.toString()
  1390. // );
  1391. // this.$set(
  1392. // this.form.productInfoList[index],
  1393. // 'modelKey',
  1394. // item.modelKey.toString()
  1395. // );
  1396. // });
  1397. // // this.
  1398. // if (!this.form.id) {
  1399. // if (this.form.productInfoList.length) {
  1400. // this.form.productInfoList.map((item, index) => {
  1401. // delete item.selectionRowShow;
  1402. // // if (item.bomVersionList && item.bomVersionList.length) {
  1403. // // item.bomCategoryName = item.bomVersionList[0].name;
  1404. // // item.bomCategoryVersions = item.bomVersionList[0].versions;
  1405. // // item.produceRoutingName = item.routingList[0].name;
  1406. // // }
  1407. // });
  1408. // }
  1409. // this.form.timeDimensionPlanType = this.type;
  1410. // if (this.isSaleOrder) {
  1411. // this.form.saleOrder = this.form.saleOrder.split(',');
  1412. // }
  1413. // this.loading = true;
  1414. // let api = type == 'sub' ? saveAndRelease : temporaryPlanSave;
  1415. // api(this.form)
  1416. // .then((res) => {
  1417. // this.$message.success('新增成功!');
  1418. // this.visible = false;
  1419. // this.initForm();
  1420. // this.$emit('close', true);
  1421. // })
  1422. // .finally(() => {
  1423. // this.loading = false;
  1424. // });
  1425. // } else {
  1426. // this.loading = true;
  1427. // let api = type == 'sub' ? saveAndRelease : temporaryPlanSave;
  1428. // if (this.isSaleOrder) {
  1429. // this.form.saleOrder = this.form.saleOrder.split(',');
  1430. // }
  1431. // api(this.form)
  1432. // .then((res) => {
  1433. // this.$message.success('修改成功!');
  1434. // this.visible = false;
  1435. // this.initForm();
  1436. // this.$emit('close', true);
  1437. // })
  1438. // .finally(() => {
  1439. // this.loading = false;
  1440. // });
  1441. // }
  1442. // });
  1443. // },
  1444. bomListVersionFn(produceType, categoryId) {
  1445. return new Promise((resolve, reject) => {
  1446. let param = {
  1447. bomType: produceType,
  1448. categoryId: categoryId
  1449. };
  1450. bomListByPlan(param).then((res) => {
  1451. this.bomVersionList = res || [];
  1452. resolve(res || []);
  1453. });
  1454. });
  1455. },
  1456. bomListVersion() {
  1457. let param = {
  1458. bomType: this.form.produceType,
  1459. categoryId: this.form.categoryId
  1460. };
  1461. bomListByPlan(param).then((res) => {
  1462. this.$nextTick(() => {
  1463. this.bomVersionList = res || [];
  1464. console.log(res, 'res 000');
  1465. });
  1466. });
  1467. },
  1468. // 工艺路线
  1469. getPlanRouting() {
  1470. bomRoutingList(this.form.bomCategoryId).then((res) => {
  1471. this.routingList = res || [];
  1472. });
  1473. },
  1474. // 宝悦 工艺路线
  1475. getPlanRoutingNew() {
  1476. // bomRoutingList(this.form.bomCategoryId).then((res) => {
  1477. // this.routingList = res || []
  1478. // })
  1479. },
  1480. tableHandleKeyUp(row, name) {
  1481. // return
  1482. // , index, e, name
  1483. if (name == 'procut') {
  1484. return;
  1485. }
  1486. if (row.specification && this.clientEnvironmentId == 4) {
  1487. let modelArr = row.specification.split('*');
  1488. let modelLong = modelArr[0]; // model规格长度
  1489. let modeWide = modelArr[1]; // model规格宽度
  1490. let modeHight = modelArr[2].substr(0, modelArr[2].indexOf('cm')); // model规格高度
  1491. modeHight = Number(modeHight);
  1492. if (name === 'moCount') {
  1493. // 模数
  1494. this.$set(row, 'moCount', row.moCount);
  1495. // 计算块数的公式:
  1496. // (一模6米长度 / model规格长度) * (一模1.2米宽度 / model规格宽度) = 每一模的块数
  1497. // 每一模的块数*模数moCount = 总块数
  1498. if (row.productName.includes('板材')) {
  1499. // 块数
  1500. let blockCount =
  1501. Math.floor(600 / modelLong) *
  1502. Math.floor(120 / modeHight) *
  1503. Math.floor(60 / modeWide) *
  1504. row.moCount;
  1505. row['blockCount'] = blockCount;
  1506. // this.$set(row, 'blockCount', blockCount);
  1507. } else if (row.productName.includes('砌块')) {
  1508. let modelLongFixed = (600 / modelLong).toFixed(2);
  1509. modelLongFixed = modelLongFixed.substring(
  1510. 0,
  1511. modelLongFixed.length - 1
  1512. );
  1513. let modeWideFixed = (120 / modeWide).toFixed(2);
  1514. modeWideFixed = modeWideFixed.substring(
  1515. 0,
  1516. modeWideFixed.length - 1
  1517. );
  1518. let modeHightFixed = (60 / modeHight).toFixed(2);
  1519. modeHightFixed = modeHightFixed.substring(
  1520. 0,
  1521. modeHightFixed.length - 1
  1522. );
  1523. let num =
  1524. Math.floor(modelLongFixed * modeWideFixed * modeHightFixed) *
  1525. row.moCount;
  1526. row['blockCount'] = num;
  1527. }
  1528. let numNew = (
  1529. Number((modelLong * modeWide * modeHight) / 1000000).toFixed(5) *
  1530. row.blockCount
  1531. ).toFixed(5);
  1532. row['requiredFormingNum'] = numNew;
  1533. } else if (name === 'sum') {
  1534. let e = row.requiredFormingNum;
  1535. row.blockCount = Math.floor(
  1536. e / ((modelLong * modeWide * modeHight) / 1000000)
  1537. );
  1538. if (row.productName.includes('板材')) {
  1539. let num = Math.ceil(
  1540. row.blockCount /
  1541. (Math.floor(600 / modelLong) *
  1542. Math.floor(120 / modeHight) *
  1543. Math.floor(60 / modeWide))
  1544. );
  1545. // 48 480 4807 480
  1546. row.moCount = num;
  1547. } else if (row.productName.includes('砌块')) {
  1548. row.moCount = Math.ceil(
  1549. row.blockCount /
  1550. Math.floor(
  1551. (600 / modelLong) * (120 / modeHight) * (60 / modeWide)
  1552. )
  1553. );
  1554. }
  1555. } else if (name === 'blockCount') {
  1556. //块数
  1557. // row.blockCount = row.moCount;
  1558. row.blockCount = row.blockCount;
  1559. if (row.productName.includes('板材')) {
  1560. let moCount = Math.ceil(
  1561. row.blockCount /
  1562. (Math.floor(600 / modelLong) *
  1563. Math.floor(120 / modeHight) *
  1564. Math.floor(60 / modeWide))
  1565. );
  1566. row.moCount = moCount;
  1567. } else if (row.productName.includes('砌块')) {
  1568. let moCount = Math.ceil(
  1569. row.blockCount /
  1570. Math.floor(
  1571. (600 / modelLong) * (120 / modeHight) * (60 / modeWide)
  1572. )
  1573. );
  1574. this.$set(this.form, 'moCount', moCount);
  1575. row.moCount = moCount;
  1576. }
  1577. let a = (
  1578. (Number(row.blockCount) * modelLong * modeWide * modeHight) /
  1579. 1000000
  1580. ).toFixed(5);
  1581. row.requiredFormingNum = a;
  1582. }
  1583. }
  1584. },
  1585. // 数量正则 quantity
  1586. handleQuantityInput(e, row) {
  1587. // 过滤非数字字符(包括负号)
  1588. let value = e.replace(/[^\d.]/g, '');
  1589. // value = value.replace(/-/g, '');
  1590. // 限制不能以 0 开头(除非是 0 本身)
  1591. // if (value.startsWith('0') && value.length > 1) {
  1592. // value = value.slice(1);
  1593. // }
  1594. // 更新绑定值
  1595. row.requiredFormingNum = value;
  1596. // if (
  1597. // item.weightUnit == 'G' ||
  1598. // item.weightUnit == 'g' ||
  1599. // item.weightUnit == '克'
  1600. // ) {
  1601. // let total =
  1602. // ((item.requiredFormingNum - 0) * item.productUnitWeight) /
  1603. // 1000;
  1604. // item.newSumOrderWeight = total.toFixed(2);
  1605. // item.newWeightUnit = 'KG';
  1606. // } else {
  1607. // item.newWeightUnit = item.weightUnit;
  1608. // item.newSumOrderWeight = item.requiredFormingNum;
  1609. // }
  1610. row.newWeightUnit = row.weightUnit;
  1611. if (row.weightUnit == row.measuringUnit) {
  1612. row.newSumOrderWeight = row.requiredFormingNum;
  1613. } else if (row.requiredFormingNum && row.productUnitWeight) {
  1614. row.newSumOrderWeight =
  1615. row.requiredFormingNum * row.productUnitWeight;
  1616. } else {
  1617. row.newSumOrderWeight = 0;
  1618. }
  1619. row.productWeight = row.newSumOrderWeight;
  1620. this.tableHandleKeyUp(row, 'sum');
  1621. },
  1622. changeProduceType(e) {
  1623. if (this.clientEnvironmentId !== 4) {
  1624. this.form.bomCategoryId = '';
  1625. this.form['bomCategoryName'] = '';
  1626. this.form['bomCategoryVersions'] = '';
  1627. this.bomVersionList = [];
  1628. this.routingList = [];
  1629. this.form.produceRoutingId = '';
  1630. this.form.produceRoutingName = '';
  1631. this.form.produceVersionName = '';
  1632. this.bomListVersion();
  1633. }
  1634. },
  1635. // changeBomId() {
  1636. // this.routingList = [];
  1637. // this.form.produceRoutingId = '';
  1638. // this.form.produceRoutingName = '';
  1639. // this.form.produceVersionName = '';
  1640. // this.bomVersionList.forEach((f) => {
  1641. // if (f.id == this.form.bomCategoryId) {
  1642. // this.$set(this.form, 'bomCategoryName', f.name);
  1643. // this.$set(this.form, 'bomCategoryVersions', f.versions);
  1644. // }
  1645. // });
  1646. // this.getPlanRouting();
  1647. // },
  1648. changeRoute() {
  1649. this.$forceUpdate();
  1650. this.routingList.forEach((f) => {
  1651. if (f.id == this.form.produceRoutingId) {
  1652. this.$set(this.form, 'produceRoutingId', f.id);
  1653. this.$set(this.form, 'produceRoutingName', f.name);
  1654. this.$set(this.form, 'produceVersionName', f.version);
  1655. }
  1656. });
  1657. },
  1658. cancel() {
  1659. this.visible = false;
  1660. this.initForm();
  1661. this.$emit('close');
  1662. },
  1663. // 【开始时间变化时】触发
  1664. handleStartTimeChange(row) {
  1665. // 校验 是否 大于结束时间 wda
  1666. this.checkEndTimeValid(row);
  1667. },
  1668. // 【结束时间变化时】触发
  1669. handleEndTimeChange(row) {
  1670. // 校验 是否 大于结束时间 wda
  1671. this.checkEndTimeValid(row);
  1672. },
  1673. handleCompleteChange(row) {
  1674. const { reqMoldTime } = row;
  1675. if (!row.startTime) {
  1676. row.reqMoldTime = '';
  1677. return this.$message.warning('请选择计划开始时间');
  1678. }
  1679. this.handleComplete(reqMoldTime, row);
  1680. },
  1681. handleComplete(reqMoldTime, row) {
  1682. const startTime = new Date(row.startTime).getTime();
  1683. const completeTime = new Date(reqMoldTime).getTime();
  1684. if (completeTime < startTime) {
  1685. row.reqMoldTime = ''; // 修正为开始时间
  1686. return this.$message.warning(
  1687. '要求完成时间不能早于计划开始时间, 请重新选择要求完成时间'
  1688. );
  1689. }
  1690. },
  1691. // 时间校验
  1692. checkEndTimeValid(row) {
  1693. const { startTime: start, endTime: end } = row;
  1694. this.handleChange(start, end, row);
  1695. // // if (!start || !end) return; // 开始/结束时间未填,跳过
  1696. // const startTime = new Date(start); // 开始时间
  1697. // const endTime = new Date(end); // 结束时间
  1698. // if (endTime < startTime) {
  1699. // row.endTime = new Date(startTime); // 修正为开始时间
  1700. // this.$message.info('结束时间不能早于开始时间,已自动设为开始时间');
  1701. // }
  1702. },
  1703. handleChange(start, end, row) {
  1704. const startTime = new Date(start).getTime();
  1705. const endTime = new Date(end).getTime();
  1706. if (endTime < startTime) {
  1707. row.endTime = ''; // 修正为开始时间
  1708. return this.$message.warning(
  1709. '计划结束时间不能早于计划开始时间,请重新选择计划结束时间'
  1710. );
  1711. }
  1712. }
  1713. }
  1714. };
  1715. </script>
  1716. <style lang="scss" scoped>
  1717. .el-form-item {
  1718. margin-bottom: 14px !important;
  1719. }
  1720. .sale-order-select {
  1721. display: flex;
  1722. align-items: center;
  1723. gap: 4px;
  1724. }
  1725. .add-product {
  1726. width: 100%;
  1727. display: flex;
  1728. align-items: center;
  1729. justify-content: flex-end;
  1730. font-size: 30px;
  1731. color: #1890ff;
  1732. margin: 10px 0;
  1733. cursor: pointer;
  1734. }
  1735. .header_required {
  1736. .is-required:before {
  1737. content: '*';
  1738. color: #f56c6c;
  1739. margin-right: 4px;
  1740. }
  1741. }
  1742. </style>