salesToProduction.vue 34 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046
  1. <template>
  2. <div class="ele-body">
  3. <el-card shadow="never">
  4. <div class="body-title">
  5. <div class="title-left">{{type == 'edit' ? '计划修改' : '销售订单转生产计划'}}</div>
  6. <div class="title-right">
  7. <el-button @click="cancel">取消</el-button>
  8. <el-button type="primary" @click="toSubmit" :loading="loading">
  9. 提交计划
  10. </el-button>
  11. </div>
  12. </div>
  13. <el-form
  14. ref="form"
  15. :model="form"
  16. :rules="rules"
  17. label-width="90px"
  18. class="formbox"
  19. >
  20. <el-row :gutter="24">
  21. <el-col v-bind="styleResponsive ? { lg: 4, md: 8 } : { span: 4 }">
  22. <el-form-item label="计划类型:">
  23. <DictSelection
  24. dictName="订单计划类型"
  25. clearable
  26. v-model="form.planType"
  27. disabled
  28. >
  29. </DictSelection>
  30. </el-form-item>
  31. </el-col>
  32. <el-col v-bind="styleResponsive ? { lg: 5, md: 10 } : { span: 5 }">
  33. <el-form-item label="工艺路线:" prop="produceRoutingName">
  34. <el-input
  35. @click.native="openVersion"
  36. placeholder="请选择工艺路线"
  37. readonly
  38. v-model="form.produceRoutingName"
  39. ></el-input>
  40. </el-form-item>
  41. </el-col>
  42. <!-- <el-col v-bind="styleResponsive ? { lg: 3, md: 6 } : { span: 3 }">
  43. <el-form-item label="使用改型:" prop="modification">
  44. <el-checkbox
  45. v-model="form.modification"
  46. :true-label="1"
  47. :false-label="0"
  48. ></el-checkbox>
  49. </el-form-item>
  50. </el-col> -->
  51. <el-col v-bind="styleResponsive ? { lg: 4, md: 8 } : { span: 4 }">
  52. <el-form-item label="余量系数:" prop="marginCoefficient">
  53. <el-select
  54. v-model="form.marginCoefficient"
  55. filterable
  56. allow-create
  57. @change="itemChange"
  58. >
  59. <el-option
  60. v-for="(item, index) in marginList"
  61. :key="index"
  62. :label="item.name"
  63. :value="item.value"
  64. />
  65. </el-select>
  66. </el-form-item>
  67. </el-col>
  68. <el-col v-bind="styleResponsive ? { lg: 4, md: 8 } : { span: 4 }">
  69. <el-form-item label="批次号:" prop="batchNo">
  70. <el-input
  71. placeholder="请输入批次号"
  72. v-model="form.batchNo"
  73. ></el-input>
  74. </el-form-item>
  75. </el-col>
  76. <el-col v-bind="styleResponsive ? { lg: 4, md: 8 } : { span: 4 }">
  77. <el-form-item label="生产方式:" prop="produced">
  78. <el-select v-model="form.produceType" style="width: 100%">
  79. <el-option
  80. v-for="item of producedList"
  81. :key="item.code"
  82. :label="item.name"
  83. :value="item.code"
  84. ></el-option>
  85. </el-select>
  86. </el-form-item>
  87. </el-col>
  88. </el-row>
  89. <el-row :gutter="24" class="row-intro">
  90. <el-col v-bind="styleResponsive ? { lg: 3, md: 12 } : { span: 3 }">
  91. <el-form-item label="销售单数量:">{{ form.codeNum }}</el-form-item>
  92. </el-col>
  93. <el-col v-bind="styleResponsive ? { lg: 3, md: 12 } : { span: 3 }">
  94. <el-form-item label="订单总数量:">{{
  95. form.contractNum
  96. }}</el-form-item>
  97. </el-col>
  98. <el-col v-bind="styleResponsive ? { lg: 3, md: 12 } : { span: 4 }">
  99. <el-form-item label="订单总重量:">{{
  100. form.sumOrderWeight
  101. }}</el-form-item>
  102. </el-col>
  103. <el-col v-bind="styleResponsive ? { lg: 3, md: 12 } : { span: 3 }">
  104. <el-form-item label="产品编码:">{{
  105. form.productCode
  106. }}</el-form-item>
  107. </el-col>
  108. <el-col v-bind="styleResponsive ? { lg: 3, md: 12 } : { span: 3 }">
  109. <el-form-item label="牌号:">{{ form.brandNo }}</el-form-item>
  110. </el-col>
  111. <el-col v-bind="styleResponsive ? { lg: 4, md: 12 } : { span: 5 }">
  112. <el-form-item label="型号:">{{ form.model }}</el-form-item>
  113. </el-col>
  114. <el-col v-bind="styleResponsive ? { lg: 4, md: 12 } : { span: 3 }">
  115. <el-form-item label="规格:">{{ form.specification }}</el-form-item>
  116. </el-col>
  117. <!--
  118. <el-col v-bind="styleResponsive ? { lg: 3, md: 12 } : { span: 3 }">
  119. <el-form-item label="库存数量:">{{
  120. form.stockCountBase
  121. }}</el-form-item>
  122. </el-col> -->
  123. </el-row>
  124. <el-table :data="form.salesOrders" border>
  125. <el-table-column label="序号" align="center" width="60">
  126. <template slot-scope="scope">
  127. <span>{{ scope.$index + 1 }}</span>
  128. </template>
  129. </el-table-column>
  130. <el-table-column
  131. label="销售订单号"
  132. align="center"
  133. prop="code"
  134. width="120"
  135. sortable
  136. >
  137. </el-table-column>
  138. <el-table-column
  139. label="产品名称"
  140. align="center"
  141. prop="productName"
  142. width="120"
  143. >
  144. </el-table-column>
  145. <el-table-column label="行号" align="center" prop="lineNumber">
  146. </el-table-column>
  147. <el-table-column
  148. :label="'订单数量' + (clientEnvironmentId == '4' ? '(方)' : '')"
  149. align="center"
  150. prop="contractNum"
  151. width="120"
  152. >
  153. <template slot-scope="scope">
  154. {{ scope.row.contractNum }} {{scope.row.measuringUnit }}
  155. </template>
  156. </el-table-column>
  157. <el-table-column
  158. label="订单重量"
  159. align="center"
  160. prop="productSumWeight"
  161. width="120"
  162. >
  163. <template slot-scope="scope">
  164. {{ scope.row.productSumWeight }} {{ form.weightUnit }}
  165. </template>
  166. </el-table-column>
  167. <el-table-column label="规格" align="center" prop="specification">
  168. </el-table-column>
  169. <el-table-column
  170. :label="'欠交数量' + (clientEnvironmentId == '4' ? '(方)' : '')"
  171. align="center"
  172. prop="lackNum"
  173. >
  174. </el-table-column>
  175. <el-table-column
  176. :label="'计划生产数量' + (clientEnvironmentId == '4' ? '(方)' : '')"
  177. align="center"
  178. prop="planProductNum"
  179. width="140"
  180. >
  181. <template slot-scope="scope">
  182. <el-form-item
  183. label-width="0px"
  184. :prop="'salesOrders.' + scope.$index + '.planProductNum'"
  185. :rules="{
  186. required: true,
  187. message: '请输入计划生产数量',
  188. trigger: 'blur'
  189. }"
  190. class="table-item"
  191. >
  192. <el-input
  193. v-model.number="scope.row.planProductNum"
  194. size="small"
  195. oninput="value=value.replace(/[^\d]/g,'')"
  196. style="width: 100%"
  197. @input="
  198. tableHandleKeyUp(scope.row, scope.$index, $event, 'sum')
  199. "
  200. placeholder="输入数量"
  201. ></el-input>
  202. </el-form-item>
  203. </template>
  204. </el-table-column>
  205. <el-table-column
  206. :label="'要求生产数量' + (clientEnvironmentId == '4' ? '(方)' : '')"
  207. align="center"
  208. prop="requiredFormingNum"
  209. width="120"
  210. >
  211. <template slot-scope="scope">
  212. <el-form-item
  213. label-width="0px"
  214. :prop="'salesOrders.' + scope.$index + '.requiredFormingNum'"
  215. :rules="{
  216. required: true,
  217. message: '请输入要求生产数量',
  218. trigger: 'blur'
  219. }"
  220. class="table-item"
  221. >
  222. <el-input
  223. v-model.number="scope.row.requiredFormingNum"
  224. size="small"
  225. disabled
  226. oninput="value=value.replace(/[^\d]/g,'')"
  227. style="width: 100%"
  228. placeholder="输入数量"
  229. ></el-input>
  230. </el-form-item>
  231. </template>
  232. </el-table-column>
  233. <el-table-column
  234. label="模数"
  235. align="center"
  236. width="100"
  237. v-if="clientEnvironmentId == '4'"
  238. >
  239. <template slot-scope="scope">
  240. <div>
  241. <el-input
  242. style="width: 100%"
  243. size="small"
  244. v-model="scope.row.moCount"
  245. oninput="value=value.replace(/[^0-9.]/g,'')"
  246. @input="
  247. tableHandleKeyUp(scope.row, scope.$index, $event, 'moCount')
  248. "
  249. placeholder="请输入"
  250. >
  251. </el-input>
  252. </div>
  253. </template>
  254. </el-table-column>
  255. <el-table-column
  256. align="center"
  257. width="100"
  258. v-if="clientEnvironmentId == '4'"
  259. >
  260. <template slot="header">
  261. <span style="color: red">*</span>
  262. <span>块数</span>
  263. </template>
  264. <template slot-scope="scope">
  265. <div>
  266. <el-input
  267. size="small"
  268. style="width: 100%"
  269. oninput="value=value.replace(/[^0-9.]/g,'')"
  270. @input="
  271. tableHandleKeyUp(
  272. scope.row,
  273. scope.$index,
  274. $event,
  275. 'blockCount'
  276. )
  277. "
  278. v-model="scope.row.blockCount"
  279. placeholder="请输入"
  280. ></el-input>
  281. </div>
  282. </template>
  283. </el-table-column>
  284. <el-table-column
  285. label="权重等级"
  286. align="center"
  287. width="120"
  288. v-if="clientEnvironmentId == '4'"
  289. >
  290. <template slot-scope="scope">
  291. <div>
  292. <el-select v-model="scope.row.weight" style="width: 100%">
  293. <el-option
  294. v-for="item of weightList"
  295. :key="item.code"
  296. :label="item.name"
  297. :value="item.code"
  298. ></el-option>
  299. </el-select>
  300. </div>
  301. </template>
  302. </el-table-column>
  303. <el-table-column
  304. align="center"
  305. width="120"
  306. label="是否开槽"
  307. v-if="clientEnvironmentId == '4'"
  308. >
  309. <template slot-scope="scope">
  310. <div>
  311. <el-select
  312. style="width: 100%"
  313. v-model="scope.row.isSlotting"
  314. placeholder="请选择"
  315. >
  316. <el-option
  317. v-for="item of isSlotting"
  318. :key="item.code"
  319. :label="item.name"
  320. :value="item.code"
  321. />
  322. </el-select>
  323. </div>
  324. </template>
  325. </el-table-column>
  326. <el-table-column
  327. align="center"
  328. width="120"
  329. label="开槽类型"
  330. v-if="clientEnvironmentId == '4'"
  331. >
  332. <template slot-scope="scope">
  333. <DictSelection
  334. dictName="开槽类型"
  335. v-model="scope.row.slottingType"
  336. v-if="scope.row.isSlotting == 1"
  337. >
  338. </DictSelection>
  339. </template>
  340. </el-table-column>
  341. <el-table-column
  342. label="按单按库"
  343. align="center"
  344. prop="orderLibraryType"
  345. >
  346. <template slot-scope="{ row }">
  347. {{ getDictValue('按单按库', row.orderLibraryType) }}
  348. </template>
  349. </el-table-column>
  350. <el-table-column label="订单类型" align="center" prop="orderType">
  351. <template slot-scope="{ row }">
  352. {{ getDictValue('订单类型', row.orderType) }}
  353. </template>
  354. </el-table-column>
  355. <el-table-column
  356. label="交付日期"
  357. align="center"
  358. prop="deliveryTime"
  359. width="160"
  360. >
  361. </el-table-column>
  362. <el-table-column
  363. label="要求生产日期"
  364. align="center"
  365. prop="reqMoldTime"
  366. width="180"
  367. >
  368. <template slot-scope="scope">
  369. <el-form-item
  370. label-width="0px"
  371. :prop="'salesOrders.' + scope.$index + '.reqMoldTime'"
  372. :rules="{
  373. required: true,
  374. message: '请选择要求生产日期',
  375. trigger: 'blur'
  376. }"
  377. class="table-item"
  378. >
  379. <el-date-picker
  380. style="width: 100%"
  381. v-model="scope.row.reqMoldTime"
  382. :pickerOptions="{
  383. disabledDate: (time) =>
  384. time.getTime() <
  385. new Date(new Date().setHours(0, 0, 0, 0)).getTime()
  386. }"
  387. type="date"
  388. placeholder="选择日期"
  389. value-format="yyyy-MM-dd"
  390. >
  391. </el-date-picker>
  392. </el-form-item>
  393. </template>
  394. </el-table-column>
  395. <el-table-column label="客户名称" align="center" prop="customerName">
  396. </el-table-column>
  397. <el-table-column label="业务员" align="center" prop="salesman">
  398. </el-table-column>
  399. <el-table-column
  400. label="交付要求"
  401. align="center"
  402. prop="deliveryRequirements"
  403. >
  404. <template slot-scope="{ row }">
  405. {{ getDictValue('交付要求', row.deliveryRequirements) }}
  406. </template>
  407. </el-table-column>
  408. <el-table-column
  409. prop="priority"
  410. label="优先级"
  411. width="100"
  412. align="center"
  413. >
  414. <template slot-scope="{ row, $index }">
  415. <div style="display: flex">
  416. <el-input
  417. v-if="$index == 0"
  418. v-model="row.priority"
  419. type="number"
  420. size="mini"
  421. :min="0"
  422. :max="10"
  423. @change="priorityChange(row)"
  424. style="width: 80px"
  425. ></el-input>
  426. <el-popover
  427. v-if="$index == 0"
  428. placement="right"
  429. width="200"
  430. trigger="hover"
  431. content="数值越大优先级越高(0-3普通, 4-6优先, 7-10紧急)"
  432. >
  433. <div class="sort-wrap" slot="reference">
  434. <i class="el-icon-caret-top" @click="sortTop(row)"></i>
  435. <i class="el-icon-caret-bottom" @click="sortBottom(row)"></i>
  436. </div>
  437. </el-popover>
  438. </div>
  439. </template>
  440. </el-table-column>
  441. <el-table-column label="操作" align="center" width="70" fixed="right">
  442. <template slot-scope="scope">
  443. <el-button type="text" @click="handleDeleteItem(scope.$index)" v-if="type != 'edit'"
  444. >删除</el-button
  445. >
  446. </template>
  447. </el-table-column>
  448. </el-table>
  449. <div class="add-product" @click="addEquipment" v-if="type != 'edit'">
  450. <i class="el-icon-circle-plus-outline"></i>
  451. </div>
  452. <el-row :gutter="24">
  453. <el-col v-bind="styleResponsive ? { lg: 24, md: 24 } : { span: 24 }">
  454. <el-form-item label="计划备注:">
  455. <el-input
  456. type="textarea"
  457. :rows="4"
  458. v-model="form.notes"
  459. resize="none"
  460. ></el-input>
  461. </el-form-item>
  462. </el-col>
  463. </el-row>
  464. </el-form>
  465. <AdditionalOrder
  466. ref="additionalRefs"
  467. :productCode="form.productCode"
  468. :selectList="form.salesOrders"
  469. @choose="confirmChoose"
  470. ></AdditionalOrder>
  471. <ProductionVersion
  472. ref="versionRefs"
  473. @changeProduct="changeProduct"
  474. ></ProductionVersion>
  475. <PlanSubmit
  476. ref="submitRefs"
  477. :type="$route.query.type"
  478. :info="form"
  479. @publish="publishData"
  480. ></PlanSubmit>
  481. </el-card>
  482. </div>
  483. </template>
  484. <script>
  485. import AdditionalOrder from './components/AdditionalOrder.vue';
  486. import PlanSubmit from './components/plan-submit.vue';
  487. import ProductionVersion from '@/components/CreatePlan/ProductionVersion2.vue';
  488. import {
  489. productionToPlan,
  490. saveSaleToPlan,
  491. updateSaleToPlan,
  492. releaseSave,
  493. getInventory,
  494. getUpdateInfoById,
  495. getProductVersion
  496. } from '@/api/saleOrder';
  497. import { getByCode } from '@/api/system/dictionary-data';
  498. import dictMixins from '@/mixins/dictMixins';
  499. import { deepClone } from '@/utils/index';
  500. import { getRouteTabKey, removePageTab } from '@/utils/page-tab-util';
  501. import { getCode } from '@/api/codeManagement';
  502. import dayjs from 'dayjs';
  503. import { debounce } from 'lodash';
  504. export default {
  505. mixins: [dictMixins],
  506. components: {
  507. AdditionalOrder,
  508. ProductionVersion,
  509. PlanSubmit
  510. },
  511. data() {
  512. return {
  513. type: this.$route.query.type,
  514. weightList: [
  515. { code: 1, name: 'A' },
  516. { code: 2, name: 'B' },
  517. { code: 3, name: 'C' }
  518. ],
  519. isSlotting: [
  520. { code: 1, name: '是' },
  521. { code: 2, name: '否' }
  522. ], //是否开槽
  523. producedList: [
  524. { code: 2, name: '加工' },
  525. { code: 3, name: '装配' }
  526. ],
  527. form: {
  528. planType: 1,
  529. produceRoutingId: '',
  530. stockCountBase: '',
  531. salesOrders: [],
  532. produceRoutingName: '',
  533. marginCoefficient: '1.0',
  534. batchNo: null,
  535. produceType: 2
  536. },
  537. marginList: [],
  538. // 表单验证规则
  539. rules: {
  540. produceRoutingName: [
  541. { required: true, message: '请选择生产版本', trigger: 'change' }
  542. ],
  543. produceType: [
  544. { required: true, message: '请选择生产类型', trigger: 'change' }
  545. ]
  546. },
  547. // selection: [],
  548. loading: false
  549. };
  550. },
  551. computed: {
  552. clientEnvironmentId() {
  553. return this.$store.state.user.info.clientEnvironmentId;
  554. },
  555. // 是否开启响应式布局
  556. styleResponsive() {
  557. return this.$store.state.theme.styleResponsive;
  558. }
  559. },
  560. created() {
  561. this.requestDict('按单按库');
  562. this.requestDict('订单类型');
  563. this.requestDict('交付要求');
  564. this.getByCodeFn();
  565. if (this.type == 'edit') {
  566. this.getPlanInfo(this.$route.query.id);
  567. } else {
  568. this.getSaleInfo();
  569. }
  570. },
  571. methods: {
  572. async getPlanInfo(id) {
  573. const data = await getUpdateInfoById(id);
  574. this.form = data;
  575. },
  576. async _getInventory() {
  577. const res = await getInventory(this.form.productCode, this.form.planType);
  578. this.form.stockCountBase = res;
  579. },
  580. getByCodeFn() {
  581. getByCode('margin_code').then((res) => {
  582. let _arr = [];
  583. res.data.map((item) => {
  584. const key = Object.keys(item)[0];
  585. const value = item[key];
  586. _arr.push({ name: key, value: value });
  587. });
  588. this.marginList = _arr;
  589. });
  590. },
  591. getSaleInfo() {
  592. let params = JSON.parse(this.$route.query.selection);
  593. productionToPlan(params).then((res) => {
  594. this.form = deepClone(res);
  595. this.form.produceRoutingName =
  596. res.produceRoutingName || this.$route.query.produceRoutingName;
  597. this.form.produceRoutingId =
  598. res.produceRoutingId || this.$route.query.produceRoutingId;
  599. this.form.salesOrders.map((item, index) => {
  600. if (this.clientEnvironmentId == '4') {
  601. if (item.productName.includes('板材')) {
  602. this.tableHandleKeyUp(item, '', item.lackNum, 'blockCount');
  603. } else {
  604. this.tableHandleKeyUp(item, '', item.lackNum, 'moCount');
  605. }
  606. } else {
  607. item.planProductNum = item.lackNum;
  608. item.requiredFormingNum = item.lackNum;
  609. }
  610. item.slottingType = item.slottingType && item.slottingType + '';
  611. item.priority = index + 1;
  612. item.reqMoldTime = dayjs(
  613. new Date(item.deliveryTime).getTime() - 3600 * 1000 * 24 * 10
  614. ).format('YYYY-MM-DD');
  615. });
  616. if (this.form.salesOrders.every((itm) => itm.orderType == 2)) {
  617. this.form.planType = 2;
  618. } else if (this.form.salesOrders.every((itm) => itm.orderType == 1)) {
  619. this.form.planType = 1;
  620. } else {
  621. this.form.planType = 3;
  622. }
  623. this._getInventory();
  624. });
  625. this.$forceUpdate();
  626. },
  627. itemChange() {
  628. this.form.salesOrders.map((item, index) => {
  629. this.$set(
  630. item,
  631. 'requiredFormingNum',
  632. item.planProductNum * (this.form.marginCoefficient || 1)
  633. );
  634. });
  635. },
  636. toInt(planProductNum) {
  637. return planProductNum * (this.form.marginCoefficient || 1);
  638. },
  639. cancel() {
  640. const key = getRouteTabKey();
  641. this.$router.go(-1);
  642. removePageTab({ key });
  643. },
  644. toSubmit() {
  645. this.$refs.form.validate((valid) => {
  646. if (valid) {
  647. this.mapList();
  648. this.$refs.submitRefs.open();
  649. }
  650. });
  651. },
  652. // 对比日期,计算要求生产重量
  653. mapList() {
  654. var _sumOrderWeight = 0;
  655. var requiredFormingNum = 0;
  656. var productNum = 0;
  657. this.form.salesOrders.map((item, index) => {
  658. requiredFormingNum =
  659. Number(requiredFormingNum) + Number(item.requiredFormingNum);
  660. if (
  661. this.form.weightUnit == 'G' ||
  662. this.form.weightUnit == 'g' ||
  663. this.form.weightUnit == '克'
  664. ) {
  665. this.form.newWeightUnit = 'kg';
  666. _sumOrderWeight =
  667. (this.form.sumOrderWeight *
  668. Number(this.form.marginCoefficient || 1)) /
  669. 1000;
  670. } else {
  671. this.form.newWeightUnit = this.form.weightUnit;
  672. _sumOrderWeight =
  673. this.form.sumOrderWeight * Number(this.form.marginCoefficient || 1);
  674. }
  675. productNum += Number(item.planProductNum);
  676. });
  677. this.form.productNum = productNum;
  678. this.form.productUnitWeight = this.form.salesOrders[0]?.productUnitWeight;
  679. this.form.newSumOrderWeight = _sumOrderWeight.toFixed(2);
  680. this.form.requiredFormingNum = requiredFormingNum;
  681. const collection = deepClone(this.form.salesOrders);
  682. const sortedCollection = collection.sort(
  683. (a, b) => new Date(b.reqMoldTime) - new Date(a.reqMoldTime)
  684. );
  685. let latestData = {};
  686. for (let i = 0; i < sortedCollection.length; i++) {
  687. const data = sortedCollection[i];
  688. if (
  689. !latestData.reqMoldTime ||
  690. new Date(data.reqMoldTime) >= new Date(latestData.reqMoldTime)
  691. ) {
  692. latestData = data;
  693. }
  694. }
  695. this.form.reqMoldTime = latestData.reqMoldTime;
  696. },
  697. sortTop(row) {
  698. row.priority = Number(row.priority) + 1;
  699. this.priorityChange(row);
  700. },
  701. sortBottom(row) {
  702. if (row.priority <= 1) {
  703. return;
  704. }
  705. row.priority = Number(row.priority) - 1;
  706. this.priorityChange(row);
  707. },
  708. priorityChange(row) {
  709. if (row.priority > 10) {
  710. row.priority = 10; // 如果大于 10,则设置为 10
  711. } else if (row.priority < 0) {
  712. row.priority = 0; // 如果小于 0,则设置为 0
  713. }
  714. this.priorityFn(row);
  715. },
  716. priorityFn: debounce(function (row) {}, 800),
  717. // 删除产品
  718. handleDeleteItem(index) {
  719. this.form.salesOrders.splice(index, 1);
  720. },
  721. addEquipment() {
  722. this.$refs.additionalRefs.open(this.form.planType);
  723. },
  724. openVersion() {
  725. this.$refs.versionRefs.open();
  726. },
  727. changeProduct(data) {
  728. this.$set(this.form, 'produceRoutingName', data.name);
  729. this.$set(this.form, 'produceRoutingId', data.id);
  730. this.$set(this.form, 'produceVersionName', data.produceVersionName);
  731. },
  732. // 表格:模数、数量(方)、块数输入框 输入事件
  733. tableHandleKeyUp(row, index, e, name) {
  734. if (row.specification && this.clientEnvironmentId == '4') {
  735. let modelArr = row.specification.split('*');
  736. let modelLong = modelArr[0]; // model规格长度
  737. let modeWide = modelArr[1]; // model规格宽度
  738. let modeHight = modelArr[2].substr(0, modelArr[2].indexOf('cm')); // model规格高度
  739. modeHight = Number(modeHight);
  740. if (name === 'moCount') {
  741. // 模数
  742. row.moCount = e;
  743. // 计算块数的公式:
  744. // (一模6米长度 / model规格长度) * (一模1.2米宽度 / model规格宽度) = 每一模的块数
  745. // 每一模的块数*模数moCount = 总块数
  746. if (row.productName.includes('板材')) {
  747. row.blockCount =
  748. Math.floor(600 / modelLong) *
  749. Math.floor(120 / modeHight) *
  750. Math.floor(60 / modeWide) *
  751. row.moCount;
  752. } else if (row.productName.includes('砌块')) {
  753. let modelLongFixed = (600 / modelLong).toFixed(2);
  754. modelLongFixed = modelLongFixed.substring(
  755. 0,
  756. modelLongFixed.length - 1
  757. );
  758. let modeWideFixed = (120 / modeWide).toFixed(2);
  759. modeWideFixed = modeWideFixed.substring(
  760. 0,
  761. modeWideFixed.length - 1
  762. );
  763. let modeHightFixed = (60 / modeHight).toFixed(2);
  764. modeHightFixed = modeHightFixed.substring(
  765. 0,
  766. modeHightFixed.length - 1
  767. );
  768. row.blockCount =
  769. Math.floor(modelLongFixed * modeWideFixed * modeHightFixed) *
  770. row.moCount;
  771. }
  772. row.planProductNum =
  773. Nu((modelLong * modeWide * modeHight) / 1000000).toFixed(5) *
  774. row.blockCount;
  775. } else if (name === 'sum') {
  776. //方数
  777. row.planProductNum = e;
  778. row.blockCount = Math.floor(
  779. e / ((modelLong * modeWide * modeHight) / 1000000)
  780. );
  781. if (row.productName.includes('板材')) {
  782. row.moCount = Math.ceil(
  783. row.blockCount /
  784. (Math.floor(600 / modelLong) *
  785. Math.floor(120 / modeHight) *
  786. Math.floor(60 / modeWide))
  787. );
  788. } else if (row.productName.includes('砌块')) {
  789. row.moCount = Math.ceil(
  790. row.blockCount /
  791. Math.floor(
  792. (600 / modelLong) * (120 / modeHight) * (60 / modeWide)
  793. )
  794. );
  795. }
  796. } else if (name === 'blockCount') {
  797. //块数
  798. row.blockCount = e;
  799. if (row.productName.includes('板材')) {
  800. row.moCount = Math.ceil(
  801. row.blockCount /
  802. (Math.floor(600 / modelLong) *
  803. Math.floor(120 / modeHight) *
  804. Math.floor(60 / modeWide))
  805. );
  806. } else if (row.productName.includes('砌块')) {
  807. row.moCount = Math.ceil(
  808. row.blockCount /
  809. Math.floor(
  810. (600 / modelLong) * (120 / modeHight) * (60 / modeWide)
  811. )
  812. );
  813. }
  814. row.planProductNum =
  815. (Number(e) * modelLong * modeWide * modeHight) / 1000000;
  816. }
  817. }
  818. row.planProductNum = Number(row.planProductNum);
  819. row.requiredFormingNum =Number(row.planProductNum * (this.form.marginCoefficient || 1)).toFixed(5);
  820. },
  821. confirmChoose(list) {
  822. // 取出在弹窗中选中并且不在表格中的数据
  823. const result = list.filter(
  824. (i) => this.form.salesOrders.findIndex((p) => p.id === i.id) === -1
  825. );
  826. // 取出在表格中并且不在弹窗中选中的数据 即取消选中的数据
  827. const del = this.form.salesOrders.filter(
  828. (i) => list.findIndex((p) => p.id === i.id) === -1
  829. );
  830. for (let i = this.form.salesOrders.length - 1; i >= 0; i--) {
  831. for (let j in del) {
  832. if (this.form.salesOrders[i].id === del[j].id) {
  833. this.form.salesOrders.splice(i, 1);
  834. }
  835. }
  836. }
  837. let priority =
  838. this.form.salesOrders[this.form.salesOrders.length - 1]?.priority || 0;
  839. this.form.salesOrders = this.form.salesOrders.concat(
  840. result.map((item, index) => {
  841. item.priority = ++priority;
  842. item.planProductNum = item.lackNum;
  843. item.requiredFormingNum = item.lackNum;
  844. item.reqMoldTime = dayjs(
  845. new Date(item.deliveryTime).getTime() - 3600 * 1000 * 24 * 10
  846. ).format('YYYY-MM-DD');
  847. return item;
  848. })
  849. );
  850. this.changeData();
  851. },
  852. changeData() {
  853. var planProductNum = 0;
  854. var productWeight = 0;
  855. this.form.salesOrders.map((item, index) => {
  856. item.priority = index + 1;
  857. planProductNum = planProductNum + item.requiredFormingNum;
  858. productWeight = productWeight + Number(item.productSumWeight);
  859. });
  860. this.$set(this.form, 'codeNum', this.form.salesOrders.length);
  861. this.$set(this.form, 'contractNum', planProductNum);
  862. this.$set(this.form, 'sumOrderWeight', productWeight.toFixed(2));
  863. },
  864. async publishData(type) {
  865. const key = getRouteTabKey();
  866. let params = deepClone(this.form);
  867. params.categoryId = params.salesOrders[0]?.categoryId;
  868. if (this.$route.query.type != 'edit') {
  869. delete params.id;
  870. }
  871. if (type === 2) {
  872. this.$confirm('发布工单后不可撤回,确定发布吗?', '发布确认').then(
  873. async () => {
  874. const loading = this.$loading({
  875. lock: true,
  876. fullscreen: true,
  877. text: '工单发布中...'
  878. });
  879. try {
  880. const code = await getCode('product_order_code');
  881. const data = {
  882. productionPlan: params,
  883. workOrder: {
  884. productionPlanCode: params.code,
  885. code: code,
  886. // formingNum: params.contractNum,
  887. formingNum: this.form.requiredFormingNum,
  888. formingWeight: params.sumOrderWeight,
  889. produceRoutingId: params.produceRoutingId,
  890. status: 4,
  891. model: params.model,
  892. brandNo: params.brandNo,
  893. categoryId: params.categoryId,
  894. productCode: params.productCode,
  895. productName: params.productName,
  896. newWeightUnit: this.form.newWeightUnit,
  897. newSumOrderWeight: this.form.newSumOrderWeight
  898. }
  899. };
  900. if (this.$route.query.type == 'edit') {
  901. data.workOrder.productionPlanId = params.id;
  902. }
  903. await releaseSave(data)
  904. .then((res) => {
  905. if (res === 1) {
  906. this.$message.success('工单已发布!');
  907. this.$router.push({
  908. path: '/productionPlan'
  909. });
  910. } else {
  911. this.$confirm(
  912. '生产计划创建成功,但工单发布失败。请前往【生产计划】列表【重新发布】工单',
  913. '提示',
  914. {
  915. confirmButtonText: '返回',
  916. cancelButtonText: '立即前往',
  917. type: 'warning'
  918. }
  919. )
  920. .then(() => {
  921. this.$router.push({
  922. path: '/productionPlan'
  923. });
  924. })
  925. .catch(() => {
  926. this.$router.go(-1);
  927. });
  928. }
  929. removePageTab({ key });
  930. })
  931. .catch(() => {
  932. this.$message.error('发布失败,请重新发布!');
  933. });
  934. } catch (error) {}
  935. loading.close();
  936. }
  937. );
  938. } else {
  939. let request =
  940. this.$route.query.type == 'edit' ? updateSaleToPlan : saveSaleToPlan;
  941. request(params)
  942. .then(async (res) => {
  943. // 提交
  944. this.$router.push({
  945. path: '/productionPlan'
  946. });
  947. removePageTab({ key });
  948. })
  949. .catch(() => {
  950. this.$message.error('提交失败,请重新提交!');
  951. });
  952. }
  953. }
  954. }
  955. };
  956. </script>
  957. <style lang="scss" scoped>
  958. .ele-body {
  959. background: #fff;
  960. }
  961. .body-title {
  962. width: 100%;
  963. display: flex;
  964. align-items: center;
  965. justify-content: space-between;
  966. }
  967. .title-left {
  968. font-size: 20px;
  969. color: #333;
  970. }
  971. .formbox {
  972. margin: 20px auto;
  973. }
  974. .row-intro {
  975. border-bottom: 1px dashed #ccc;
  976. margin-bottom: 20px;
  977. }
  978. .add-product {
  979. width: 100%;
  980. display: flex;
  981. align-items: center;
  982. justify-content: flex-end;
  983. font-size: 30px;
  984. color: #1890ff;
  985. margin: 10px 0;
  986. cursor: pointer;
  987. }
  988. .table-item {
  989. margin-bottom: 0;
  990. }
  991. </style>