salesToProductionNewTwo.vue 58 KB

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