inventoryTable.vue 37 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246
  1. <template>
  2. <el-form ref="form" :model="form" :rules="rules">
  3. <template>
  4. <ele-pro-table
  5. ref="table"
  6. :needPage="false"
  7. :columns="columns"
  8. :toolkit="[]"
  9. max-height="500px"
  10. :datasource="form.datasource"
  11. cache-key="systemRoleTable17"
  12. class="time-form"
  13. >
  14. <!-- 表头工具栏 -->
  15. <template v-slot:toolbar>
  16. <div class="headbox">
  17. <div>
  18. <!-- <el-button-->
  19. <!-- size="small"-->
  20. <!-- type="primary"-->
  21. <!-- icon="el-icon-plus"-->
  22. <!-- class="ele-btn-icon"-->
  23. <!-- @click="handlAdd"-->
  24. <!-- v-if="!isContractId"-->
  25. <!-- >-->
  26. <!-- 新增-->
  27. <!-- </el-button>-->
  28. <el-button
  29. size="small"
  30. type="primary"
  31. icon="el-icon-plus"
  32. class="ele-btn-icon"
  33. @click="handParent('', -1)"
  34. v-if="!isContractId"
  35. >
  36. 新增
  37. </el-button>
  38. </div>
  39. </div>
  40. </template>
  41. <template v-slot:requirementTotalCount="{ row, $index }">
  42. <el-button type="text" @click="handleGetBillDetail(row, 1)">{{
  43. row.requirementTotalCount
  44. }}</el-button>
  45. </template>
  46. <template v-slot:planTotalCount="{ row, $index }">
  47. <el-button type="text" @click="handleGetBillDetail(row, 2)">{{
  48. row.planTotalCount
  49. }}</el-button>
  50. </template>
  51. <template v-slot:inquiryTotalCount="{ row, $index }">
  52. <el-button type="text" @click="handleGetBillDetail(row, 3)">{{
  53. row.inquiryTotalCount
  54. }}</el-button>
  55. </template>
  56. <template v-slot:contractTotalCount="{ row, $index }">
  57. <el-button type="text" @click="handleGetBillDetail(row, 4)">{{
  58. row.contractTotalCount
  59. }}</el-button>
  60. </template>
  61. <template v-slot:doneTotalCount="{ row, $index }">
  62. <el-button type="text" @click="handleGetBillDetail(row, 5)">{{
  63. row.doneTotalCount
  64. }}</el-button>
  65. </template>
  66. <template v-slot:waitTotalCount="{ row, $index }">
  67. <el-button type="text" @click="handleGetBillDetail(row, 6)">{{
  68. row.waitTotalCount
  69. }}</el-button>
  70. </template>
  71. <template v-slot:taskName="scope">
  72. <el-form-item
  73. style="margin-bottom: 20px"
  74. :prop="'datasource.' + scope.$index + '.taskName'"
  75. >
  76. <el-input
  77. v-model="scope.row.taskName"
  78. placeholder="请选择"
  79. style="width: 60%; margin-right: 10px"
  80. disabled
  81. ></el-input>
  82. <el-button
  83. v-if="scope.row.productCode"
  84. size="small"
  85. type="primary"
  86. @click.native="handleTaskinstance(scope.row, scope.$index)"
  87. >选择
  88. </el-button>
  89. </el-form-item>
  90. </template>
  91. <template v-slot:productName="{ row, $index }">
  92. <el-form-item
  93. style="margin-bottom: 20px"
  94. :prop="'datasource.' + $index + '.productName'"
  95. :rules="{
  96. required: true,
  97. message: '请输入',
  98. trigger: 'change'
  99. }"
  100. >
  101. <el-input
  102. v-model="row.productName"
  103. :disabled="isContractId"
  104. placeholder="请输入"
  105. @click.native="handParent(row, $index)"
  106. ></el-input>
  107. </el-form-item>
  108. </template>
  109. <template v-slot:productCode="scope">
  110. <el-form-item
  111. style="margin-bottom: 20px"
  112. :prop="'datasource.' + scope.$index + '.productCode'"
  113. >
  114. <el-input v-model="scope.row.productCode" disabled></el-input>
  115. </el-form-item>
  116. </template>
  117. <template v-slot:productCategoryName="scope">
  118. <el-form-item
  119. style="margin-bottom: 20px"
  120. :prop="'datasource.' + scope.$index + '.productCategoryName'"
  121. >
  122. <el-input
  123. v-model="scope.row.productCategoryName"
  124. disabled
  125. ></el-input>
  126. </el-form-item>
  127. </template>
  128. <template v-slot:taxRate="scope">
  129. <el-form-item
  130. style="margin-bottom: 20px"
  131. :prop="'datasource.' + scope.$index + '.taxRate'"
  132. >
  133. <el-input v-model="scope.row.taxRate"></el-input>
  134. </el-form-item>
  135. </template>
  136. <template v-slot:totalCount="scope">
  137. <el-form-item
  138. style="margin-bottom: 20px"
  139. :prop="'datasource.' + scope.$index + '.totalCount'"
  140. :rules="{
  141. required: true,
  142. message: '请输入',
  143. trigger: 'blur'
  144. }"
  145. >
  146. <!-- :prop="'datasource.' + scope.$index + '.totalCount'"
  147. :rules="{
  148. required: true,
  149. pattern: positiveIntegerReg,
  150. message: '请输入数字',
  151. trigger: 'blur'
  152. }" -->
  153. <el-input
  154. :disabled="isContractId"
  155. v-model="scope.row.totalCount"
  156. placeholder="请输入"
  157. @input="changeCount(scope.row, scope.$index)"
  158. type="number"
  159. ></el-input>
  160. </el-form-item>
  161. </template>
  162. <template v-slot:totalPrice="scope">
  163. <el-form-item
  164. style="margin-bottom: 20px"
  165. :prop="'datasource.' + scope.$index + '.totalPrice'"
  166. >
  167. {{ (Number(scope.row.totalPrice) || 0).toFixed(2) }}元
  168. </el-form-item>
  169. </template>
  170. <template v-slot:productBrand="scope">
  171. <el-form-item
  172. style="margin-bottom: 20px"
  173. :prop="'datasource.' + scope.$index + '.productBrand'"
  174. >
  175. <el-input v-model="scope.row.productBrand" disabled></el-input>
  176. </el-form-item>
  177. </template>
  178. <template v-slot:modelType="scope">
  179. <el-form-item
  180. style="margin-bottom: 20px"
  181. :prop="'datasource.' + scope.$index + '.modelType'"
  182. >
  183. <el-input v-model="scope.row.modelType" disabled></el-input>
  184. </el-form-item>
  185. </template>
  186. <template v-slot:specification="scope">
  187. <el-form-item
  188. style="margin-bottom: 20px"
  189. :prop="'datasource.' + scope.$index + '.specification'"
  190. >
  191. <el-input v-model="scope.row.specification" disabled></el-input>
  192. </el-form-item>
  193. </template>
  194. <template v-slot:deliveryDays="scope">
  195. <el-form-item
  196. style="margin-bottom: 20px"
  197. :prop="'datasource.' + scope.$index + '.deliveryDays'"
  198. :rules="{
  199. pattern: numberReg,
  200. message: '请输入数字',
  201. trigger: 'blur'
  202. }"
  203. >
  204. <el-input
  205. v-model="scope.row.deliveryDays"
  206. @change="setDeliveryDays(scope.row, scope.$index, 'deliveryDays')"
  207. :disabled="isContractId"
  208. placeholder="请输入"
  209. ></el-input>
  210. </el-form-item>
  211. </template>
  212. <template v-slot:guaranteePeriod="scope">
  213. <div class="period">
  214. <div class="borderleftnone">
  215. <el-form-item
  216. style="margin-bottom: 20px"
  217. :prop="'datasource.' + scope.$index + '.guaranteePeriod'"
  218. :rules="{
  219. pattern: numberReg,
  220. message: '请输入数字',
  221. trigger: 'blur'
  222. }"
  223. >
  224. <el-input
  225. v-model="scope.row.guaranteePeriod"
  226. :disabled="isContractId"
  227. @change="
  228. setDeliveryDays(scope.row, scope.$index, 'guaranteePeriod')
  229. "
  230. placeholder="请输入"
  231. ></el-input>
  232. </el-form-item>
  233. </div>
  234. <div class="borderrightnone">
  235. <DictSelection
  236. dictName="质保期单位"
  237. clearable
  238. v-model="scope.row.guaranteePeriodUnitCode"
  239. :disabled="isContractId"
  240. @change="
  241. setDeliveryDays(scope.row, scope.$index, 'guaranteePeriod')
  242. "
  243. >
  244. </DictSelection>
  245. </div>
  246. </div>
  247. </template>
  248. <!-- <template v-slot:guaranteePeriodUnitCode="scope"> </template> -->
  249. <template v-slot:measuringUnit="scope">
  250. <el-form-item
  251. style="margin-bottom: 20px"
  252. :prop="'datasource.' + scope.$index + '.measuringUnit'"
  253. >
  254. <el-input
  255. v-model="scope.row.measuringUnit"
  256. :disabled="isContractId"
  257. placeholder="请输入"
  258. ></el-input>
  259. </el-form-item>
  260. </template>
  261. <template v-slot:remark="scope">
  262. <el-form-item
  263. style="margin-bottom: 20px"
  264. :prop="'datasource.' + scope.$index + '.remark'"
  265. >
  266. <el-input
  267. :disabled="isContractId"
  268. v-model="scope.row.remark"
  269. type="textarea"
  270. placeholder="请输入"
  271. ></el-input>
  272. </el-form-item>
  273. </template>
  274. <template v-slot:singlePrice="scope">
  275. <el-form-item
  276. style="margin-bottom: 20px"
  277. :prop="'datasource.' + scope.$index + '.singlePrice'"
  278. :rules="{
  279. required: true,
  280. pattern: numberReg,
  281. message: '请输入正确的单价',
  282. trigger: 'change'
  283. }"
  284. >
  285. <el-input
  286. :disabled="isContractId"
  287. v-model="scope.row.singlePrice"
  288. placeholder="请输入"
  289. @input="getTotalPrice"
  290. >
  291. <template slot="append">元</template>
  292. </el-input>
  293. </el-form-item>
  294. </template>
  295. <template v-slot:singleWeight="scope">
  296. <el-form-item
  297. style="margin-bottom: 20px"
  298. :rules="{
  299. required: false,
  300. pattern: numberReg,
  301. trigger: 'change'
  302. }"
  303. :prop="'datasource.' + scope.$index + '.singleWeight'"
  304. >
  305. <el-input
  306. :disabled="isContractId"
  307. v-model="scope.row.singleWeight"
  308. @input="singleWeightChange(scope.row, scope.$index)"
  309. placeholder="请输入"
  310. ></el-input>
  311. </el-form-item>
  312. </template>
  313. <template v-slot:technicalAnswerName="{ row, $index }">
  314. <el-form-item
  315. style="margin-bottom: 20px"
  316. :prop="'datasource.' + $index + '.technicalAnswerName'"
  317. >
  318. <el-input
  319. :disabled="isContractId"
  320. v-model="row.technicalAnswerName"
  321. placeholder="请输入"
  322. @click.native="handHead(row, $index)"
  323. ></el-input>
  324. </el-form-item>
  325. </template>
  326. <template v-slot:technicalParams="scope">
  327. <el-form-item
  328. style="margin-bottom: 20px"
  329. :prop="'datasource.' + scope.$index + '.technicalParams'"
  330. >
  331. <el-input
  332. :disabled="isContractId"
  333. type="textarea"
  334. v-model="scope.row.technicalParams"
  335. placeholder="请输入"
  336. ></el-input>
  337. </el-form-item>
  338. </template>
  339. <template v-slot:supplierMark="scope">
  340. <el-form-item
  341. style="margin-bottom: 20px"
  342. :prop="'datasource.' + scope.$index + '.supplierMark'"
  343. >
  344. <el-input
  345. v-model="scope.row.supplierMark"
  346. placeholder="请输入"
  347. ></el-input>
  348. </el-form-item>
  349. </template>
  350. <template v-slot:technicalDrawings="scope">
  351. <el-form-item
  352. style="margin-bottom: 20px"
  353. :prop="'datasource.' + scope.$index + '.technicalDrawings'"
  354. >
  355. <fileMain
  356. v-model="scope.row.technicalDrawings"
  357. :type="isContractId ? 'view' : ''"
  358. ></fileMain>
  359. <!-- <fileUpload-->
  360. <!-- v-if="!isContractId"-->
  361. <!-- v-model="scope.row.technicalDrawings"-->
  362. <!-- module="main"-->
  363. <!-- :showLib="false"-->
  364. <!-- :limit="5"-->
  365. <!-- />-->
  366. <!-- <div v-else v-if="scope.row.technicalDrawings && scope.row.technicalDrawings?.length">-->
  367. <!-- <el-link-->
  368. <!-- v-for="link in scope.row.technicalDrawings"-->
  369. <!-- :key="link.id"-->
  370. <!-- type="primary"-->
  371. <!-- :underline="false"-->
  372. <!-- @click="downloadFile(link)"-->
  373. <!-- >-->
  374. <!-- {{ link.name }}-->
  375. <!-- </el-link-->
  376. <!-- >-->
  377. <!-- </div>-->
  378. </el-form-item>
  379. </template>
  380. <template v-slot:guaranteePeriodDeadline="scope">
  381. <el-form-item
  382. :prop="'datasource.' + scope.$index + '.guaranteePeriodDeadline'"
  383. >
  384. <el-date-picker
  385. style="width: 140px"
  386. v-model="scope.row.guaranteePeriodDeadline"
  387. :disabled="isContractId"
  388. type="date"
  389. placeholder="选择日期"
  390. >
  391. </el-date-picker>
  392. </el-form-item>
  393. </template>
  394. <template v-slot:deliveryDeadline="scope">
  395. <el-form-item
  396. :prop="'datasource.' + scope.$index + '.deliveryDeadline'"
  397. >
  398. <el-date-picker
  399. :disabled="isContractId"
  400. style="width: 140px"
  401. v-model="scope.row.deliveryDeadline"
  402. type="date"
  403. placeholder="选择日期"
  404. >
  405. </el-date-picker>
  406. </el-form-item>
  407. </template>
  408. <template v-slot:headerDeadline="{ column }">
  409. <span class="is-required">{{ column.label }}</span>
  410. </template>
  411. <template v-slot:headerSupplierMark="{ column }">
  412. <span class="is-required">{{ column.label }}</span>
  413. </template>
  414. <template v-slot:headerProductName="{ column }">
  415. <span class="is-required">{{ column.label }}</span>
  416. </template>
  417. <template v-slot:headerTotalCount="{ column }">
  418. <span class="is-required">{{ column.label }}</span>
  419. </template>
  420. <template v-slot:headerSinglePrice="{ column }">
  421. <span class="is-required">{{ column.label }}</span>
  422. </template>
  423. <template v-slot:batchNo="scope">
  424. <el-form-item
  425. style="margin-bottom: 20px"
  426. :prop="'datasource.' + scope.$index + '.batchNo'"
  427. >
  428. <el-input v-model="scope.row.batchNo" placeholder="请输入">
  429. </el-input>
  430. </el-form-item>
  431. </template>
  432. <!-- 操作列 -->
  433. <template v-slot:action="{ row, $index }">
  434. <el-popconfirm
  435. class="ele-action"
  436. title="确定要删除吗?"
  437. @confirm="remove(row, $index)"
  438. >
  439. <template v-slot:reference>
  440. <el-link type="danger" :underline="false" icon="el-icon-delete">
  441. 删除
  442. </el-link>
  443. </template>
  444. </el-popconfirm>
  445. </template>
  446. </ele-pro-table>
  447. </template>
  448. <product-list
  449. ref="productListRef"
  450. classType="1"
  451. :isGetInventoryTotal="true"
  452. @changeParent="changeParent"
  453. ></product-list>
  454. <head-list ref="headRef" @changeParent="changeAnswer"></head-list>
  455. <bill-detail-dialog
  456. :bill-detail-dialog-flag.sync="billDetailDialogFlag"
  457. v-if="billDetailDialogFlag"
  458. ref="billDetailDialogRef"
  459. ></bill-detail-dialog>
  460. <taskinstance-dialog
  461. ref="taskinstanceDialogRef"
  462. v-if="taskinstanceDialogFlag"
  463. @saveTaskInstance="saveTaskInstance"
  464. :visible.sync="taskinstanceDialogFlag"
  465. ></taskinstance-dialog>
  466. </el-form>
  467. </template>
  468. <script>
  469. import { emailReg, phoneReg, numberReg, positiveIntegerReg } from 'ele-admin';
  470. import productList from '@/BIZComponents/product-list.vue';
  471. import dictMixins from '@/mixins/dictMixins';
  472. import store from '@/store';
  473. import fileUpload from '@/components/upload/fileUpload';
  474. import headList from '@/BIZComponents/user-select/user-select.vue';
  475. import { getFile } from '@/api/system/file';
  476. import { getByCode } from '@/api/system/dictionary-data';
  477. import fileMain from '@/components/addDoc/index.vue';
  478. import billDetailDialog from './billDetailDialog.vue';
  479. import taskinstanceDialog from '@/BIZComponents/procedure/taskinstanceDialog.vue';
  480. import { getCode } from '@/components/addDoc/api/index.js';
  481. const dayjs = require('dayjs');
  482. export default {
  483. mixins: [dictMixins],
  484. props: {
  485. isContractId: {
  486. type: Boolean,
  487. default: false
  488. },
  489. pricingWay: {
  490. type: [Number, String],
  491. default: 1
  492. },
  493. supplierMark: {
  494. type: [Number, String],
  495. default: ''
  496. },
  497. detailType: {
  498. default: 0
  499. }
  500. },
  501. components: {
  502. taskinstanceDialog,
  503. fileMain,
  504. productList,
  505. fileUpload,
  506. billDetailDialog,
  507. headList
  508. },
  509. computed: {
  510. canHandl() {
  511. return this.form.datasource.length;
  512. },
  513. contractId() {
  514. return this.$store.state.order.contractId;
  515. }
  516. },
  517. data() {
  518. const defaultForm = {
  519. key: null,
  520. endTime: '',
  521. isFirst: 0,
  522. name: '',
  523. startTime: '',
  524. workHour: '',
  525. technicalDrawings: []
  526. };
  527. return {
  528. discountTotalPrice: 0.0,
  529. allPrice: 0.0,
  530. numberReg,
  531. positiveIntegerReg,
  532. defaultForm,
  533. contractStartDate: new Date(),
  534. form: {
  535. datasource: []
  536. },
  537. rules: {},
  538. dictList: {},
  539. billDetailDialogFlag: false,
  540. taskinstanceDialogFlag: false,
  541. columns: [
  542. {
  543. width: 45,
  544. type: 'index',
  545. columnKey: 'index',
  546. align: 'center',
  547. fixed: 'left'
  548. },
  549. {
  550. width: 200,
  551. prop: 'productName',
  552. label: '名称',
  553. slot: 'productName',
  554. headerSlot: 'headerProductName',
  555. align: 'center',
  556. fixed: 'left'
  557. },
  558. {
  559. width: 120,
  560. prop: 'productCode',
  561. label: '编码',
  562. slot: 'productCode',
  563. align: 'center'
  564. },
  565. {
  566. width: 120,
  567. prop: 'requirementTotalCount',
  568. label: '采购需求数量',
  569. slot: 'requirementTotalCount',
  570. align: 'center'
  571. },
  572. {
  573. width: 120,
  574. prop: 'planTotalCount',
  575. label: '采购计划数量',
  576. slot: 'planTotalCount',
  577. align: 'center'
  578. },
  579. {
  580. width: 120,
  581. prop: 'inquiryTotalCount',
  582. label: '采购核价数量',
  583. slot: 'inquiryTotalCount',
  584. align: 'center'
  585. },
  586. {
  587. width: 120,
  588. prop: 'contractTotalCount',
  589. label: '采购合同数量',
  590. slot: 'contractTotalCount',
  591. align: 'center'
  592. },
  593. {
  594. width: 80,
  595. prop: 'doneTotalCount',
  596. label: '已采数量',
  597. slot: 'doneTotalCount',
  598. align: 'center'
  599. },
  600. {
  601. width: 80,
  602. prop: 'waitTotalCount',
  603. label: '待采数量',
  604. // slot: 'waitTotalCount',
  605. align: 'center'
  606. },
  607. {
  608. width: 150,
  609. prop: 'totalCount',
  610. label: '数量',
  611. slot: 'totalCount',
  612. headerSlot: 'headerTotalCount',
  613. align: 'center'
  614. },
  615. {
  616. width: 120,
  617. prop: 'availableCountBase',
  618. label: '库存数量',
  619. slot: 'availableCountBase',
  620. align: 'center'
  621. },
  622. {
  623. width: 160,
  624. prop: 'singlePrice',
  625. label: '单价(含税)',
  626. slot: 'singlePrice',
  627. headerSlot: 'headerSinglePrice',
  628. align: 'center',
  629. show: !this.detailType
  630. },
  631. {
  632. width: 120,
  633. prop: 'taxRate',
  634. label: '税率',
  635. slot: 'taxRate',
  636. align: 'center',
  637. show: !this.detailType
  638. },
  639. {
  640. width: 120,
  641. prop: 'supplierMark',
  642. label: '供应商代号',
  643. // headerSlot: 'headerSupplierMark',
  644. slot: 'supplierMark',
  645. align: 'center'
  646. },
  647. {
  648. width: 200,
  649. prop: 'productCategoryName',
  650. label: '类型',
  651. slot: 'productCategoryName',
  652. showOverflowTooltip: true,
  653. align: 'center'
  654. },
  655. {
  656. minWidth: 240,
  657. prop: 'taskName',
  658. label: '工序',
  659. slot: 'taskName',
  660. align: 'center'
  661. },
  662. {
  663. width: 160,
  664. prop: 'productBrand',
  665. label: '牌号',
  666. slot: 'productBrand',
  667. showOverflowTooltip: true,
  668. align: 'center'
  669. },
  670. {
  671. width: 120,
  672. prop: 'modelType',
  673. label: '型号',
  674. slot: 'modelType',
  675. align: 'center'
  676. },
  677. {
  678. width: 120,
  679. prop: 'specification',
  680. label: '规格',
  681. slot: 'specification',
  682. align: 'center'
  683. },
  684. {
  685. width: 120,
  686. prop: 'imgCode',
  687. align: 'center',
  688. label: '图号/件号',
  689. showOverflowTooltip: true
  690. },
  691. {
  692. width: 120,
  693. prop: 'produceType',
  694. align: 'center',
  695. label: '生产类型',
  696. showOverflowTooltip: true,
  697. formatter: (row, column) => {
  698. return row.produceType && row.produceType.length
  699. ? row.produceType
  700. .map((item) => this.getDictV('productionType', item + ''))
  701. .join(',')
  702. : '';
  703. }
  704. },
  705. {
  706. width: 120,
  707. prop: 'approvalNumber',
  708. align: 'center',
  709. label: '批准文号',
  710. showOverflowTooltip: true
  711. },
  712. {
  713. width: 120,
  714. prop: 'packingSpecification',
  715. align: 'center',
  716. label: '包装规格',
  717. showOverflowTooltip: true
  718. },
  719. {
  720. width: 80,
  721. prop: 'measuringUnit',
  722. label: '计量单位',
  723. slot: 'measuringUnit',
  724. align: 'center'
  725. },
  726. {
  727. width: 120,
  728. prop: 'singleWeight',
  729. label: '单重',
  730. slot: 'singleWeight',
  731. align: 'center'
  732. },
  733. {
  734. width: 120,
  735. prop: 'totalWeight',
  736. label: '总重',
  737. slot: 'totalWeight',
  738. align: 'center'
  739. },
  740. {
  741. width: 120,
  742. prop: 'weightUnit',
  743. label: '重量单位',
  744. slot: 'weightUnit',
  745. align: 'center'
  746. },
  747. {
  748. width: 160,
  749. prop: 'discountSinglePrice',
  750. label: '折后单价(含税)',
  751. slot: 'discountSinglePrice',
  752. align: 'center',
  753. show: !this.detailType
  754. },
  755. {
  756. width: 120,
  757. prop: 'totalPrice',
  758. label: '合计(含税)',
  759. slot: 'totalPrice',
  760. align: 'center',
  761. show: !this.detailType
  762. },
  763. {
  764. width: 120,
  765. prop: 'discountTotalPrice',
  766. label: '折后合计(含税)',
  767. slot: 'discountTotalPrice',
  768. align: 'center',
  769. show: !this.detailType
  770. },
  771. {
  772. width: 110,
  773. prop: 'batchNo',
  774. label: '批次号',
  775. slot: 'batchNo',
  776. align: 'center'
  777. },
  778. // {
  779. // width: 80,
  780. // prop: 'deliveryDays',
  781. // label: '交期(天)',
  782. // slot: 'deliveryDays'
  783. // },
  784. {
  785. width: 160,
  786. prop: 'deliveryDeadline',
  787. label: '交期截止日期',
  788. slot: 'deliveryDeadline',
  789. align: 'center'
  790. // headerSlot: 'headerDeadline'
  791. },
  792. {
  793. width: 200,
  794. prop: 'guaranteePeriod',
  795. label: '质保期',
  796. slot: 'guaranteePeriod',
  797. align: 'center'
  798. },
  799. {
  800. width: 160,
  801. prop: 'guaranteePeriodDeadline',
  802. label: ' 质保截止日期',
  803. slot: 'guaranteePeriodDeadline',
  804. align: 'center'
  805. },
  806. // {
  807. // width: 120,
  808. // prop: 'guaranteePeriodUnitCode',
  809. // label: '',
  810. // slot: 'guaranteePeriodUnitCode'
  811. // },
  812. {
  813. width: 130,
  814. prop: 'technicalAnswerName',
  815. label: '技术答疑人',
  816. slot: 'technicalAnswerName',
  817. align: 'center'
  818. },
  819. {
  820. width: 220,
  821. prop: 'technicalParams',
  822. label: '技术参数',
  823. slot: 'technicalParams',
  824. align: 'center'
  825. },
  826. {
  827. width: 240,
  828. prop: 'technicalDrawings',
  829. label: '技术图纸',
  830. slot: 'technicalDrawings',
  831. align: 'center'
  832. },
  833. {
  834. width: 220,
  835. prop: 'remark',
  836. label: '备注',
  837. slot: 'remark',
  838. align: 'center'
  839. },
  840. {
  841. columnKey: 'action',
  842. label: '操作',
  843. width: 120,
  844. align: 'center',
  845. resizable: false,
  846. slot: 'action',
  847. fixed: 'right',
  848. showOverflowTooltip: true
  849. }
  850. ]
  851. };
  852. },
  853. created() {
  854. this.getDictList('productionType');
  855. },
  856. methods: {
  857. handleGetBillDetail(row, type) {
  858. this.billDetailDialogFlag = true;
  859. this.$nextTick(() => {
  860. this.$refs.billDetailDialogRef.open(row, type);
  861. });
  862. },
  863. getDictV(code, val) {
  864. if (!this.dictList[code]) return '';
  865. return this.dictList[code].find((item) => item.value == val)?.label;
  866. },
  867. async getDictList(code) {
  868. let { data: res } = await getByCode(code);
  869. this.dictList[code] = res.map((item) => {
  870. let values = Object.keys(item);
  871. return {
  872. value: values[0],
  873. label: item[values[0]]
  874. };
  875. });
  876. },
  877. downloadFile(file) {
  878. getFile({ objectName: file.storePath }, file.name);
  879. },
  880. // 返回列表数据
  881. getTableValue() {
  882. let comitDatasource = this.form.datasource;
  883. if (comitDatasource.length === 0) return [];
  884. comitDatasource.forEach((v, i) => {
  885. v.detailType = this.detailType;
  886. // v.totalPrice = (v.totalCount * v.singlePrice)?.toFixed(2) || 0;
  887. v.guaranteePeriodUnitName = this.getDictValue(
  888. '质保期单位',
  889. v.guaranteePeriodUnitCode
  890. );
  891. v.technicalDrawings = Array.isArray(v.technicalDrawings)
  892. ? v.technicalDrawings
  893. : [];
  894. });
  895. return comitDatasource;
  896. },
  897. getPrice() {
  898. return [this.allPrice];
  899. },
  900. //改变数量
  901. changeCount(row, index) {
  902. if (this.detailType) {
  903. return;
  904. }
  905. this.singleWeightChange(row, index);
  906. this.getTotalPrice();
  907. },
  908. //计算总金额
  909. getTotalPrice() {
  910. if (this.form.datasource.length) {
  911. let sum = 0;
  912. sum = this.getNumTotalPrice();
  913. let allsum = sum.toFixed(2);
  914. this.allPrice = allsum;
  915. this.form.discountTotalPrice = allsum;
  916. this.$store.commit('concact/setDiscountAmount', allsum);
  917. this.$store.commit('order/setAllcountAmount', allsum);
  918. this.$emit('orderDiscountAmount', this.allPrice);
  919. this.$refs.table.reload();
  920. return allsum;
  921. } else {
  922. this.allPrice = 0.0;
  923. this.form.discountTotalPrice = 0.0;
  924. this.$emit('orderDiscountAmount', 0);
  925. return 0.0;
  926. }
  927. },
  928. //计算总金额
  929. getNumTotalPrice(sum = 0) {
  930. this.form.datasource.forEach((r) => {
  931. this.$set(
  932. r,
  933. 'discountSinglePrice',
  934. r.singlePrice ? Number(r.singlePrice) : ''
  935. );
  936. if (r.singlePrice && r.totalCount) {
  937. r.totalPrice = this.getAllPrice(r);
  938. r.discountTotalPrice = this.getDiscountTotalPrice(r);
  939. this.$set(r, 'totalPrice', Number(r.totalPrice));
  940. this.$set(r, 'discountTotalPrice', Number(r.discountTotalPrice));
  941. sum += Number(r.totalPrice);
  942. } else {
  943. this.$set(r, 'totalPrice', '');
  944. this.$set(r, 'discountTotalPrice', '');
  945. }
  946. });
  947. return sum;
  948. },
  949. //计算单重
  950. singleWeightChange(row, index) {
  951. if (row && row.singleWeight && row.totalCount) {
  952. row.totalWeight = (row.singleWeight * row.totalCount).toFixed(2) || 0;
  953. this.$set(this.form.datasource[index], 'totalWeight', row.totalWeight);
  954. }
  955. if (this.pricingWay == 2) {
  956. this.getTotalPrice(row);
  957. }
  958. },
  959. //设置优惠后总金额修改产品单价
  960. discountInputByOrder(val) {
  961. this.form.discountTotalPrice = val;
  962. //获取优惠金额和总计的差价
  963. this.form.datasource.forEach((item) => {
  964. if (val === 0) {
  965. item.discountTotalPrice = 0;
  966. item.discountSinglePrice = 0;
  967. return;
  968. }
  969. if (!val) {
  970. item.discountTotalPrice = item.totalPrice;
  971. item.discountSinglePrice = item.singlePrice;
  972. return;
  973. }
  974. //获取折让单价
  975. item.discountSinglePrice = this.getDiscountSinglePrice(item);
  976. item.discountTotalPrice = this.getDiscountTotalPrice(item);
  977. });
  978. this.$refs.table.reload();
  979. this.$store.commit('concact/setDiscountAmount', val);
  980. },
  981. //获取折让单价
  982. getDiscountSinglePrice(row) {
  983. let num =
  984. (Number(this.form.discountTotalPrice) / Number(this.allPrice)) *
  985. Number(row.singlePrice);
  986. return isNaN(num) ? '' : num;
  987. },
  988. handleTaskinstance(row, index) {
  989. this.taskinstanceDialogFlag = true;
  990. this.$nextTick(() => {
  991. this.$refs.taskinstanceDialogRef.open(row, index);
  992. });
  993. },
  994. saveTaskInstance(row = {}) {
  995. this.$set(this.form.datasource[row.index], 'taskId', row.id);
  996. this.$set(this.form.datasource[row.index], 'taskName', row.name);
  997. this.$set(
  998. this.form.datasource[row.index],
  999. 'routingId',
  1000. row.produceRoutingId
  1001. );
  1002. },
  1003. //获取合计
  1004. getAllPrice(row) {
  1005. let num = 0;
  1006. switch (this.pricingWay) {
  1007. case 1: //按数量计价计算总金额
  1008. num = Number(row.singlePrice) * Number(row.totalCount);
  1009. break;
  1010. case 2: //按重量计价计算总金额
  1011. num =
  1012. Number(row.singlePrice) *
  1013. Number(row.totalCount) *
  1014. Number(row.singleWeight);
  1015. break;
  1016. }
  1017. return isNaN(num) ? '' : num.toFixed(2);
  1018. },
  1019. //获取折让合计
  1020. getDiscountTotalPrice(row) {
  1021. let num = 0;
  1022. switch (this.pricingWay) {
  1023. case 1: //按数量计价计算折让合计
  1024. num = Number(row.discountSinglePrice) * Number(row.totalCount);
  1025. break;
  1026. case 2: //按重量计价计算折让合计
  1027. num =
  1028. Number(row.discountSinglePrice) *
  1029. Number(row.totalCount) *
  1030. Number(row.singleWeight);
  1031. break;
  1032. }
  1033. return isNaN(num) ? '' : num.toFixed(2);
  1034. },
  1035. //修改回显
  1036. putTableValue(data, contractStartDate) {
  1037. if (contractStartDate) {
  1038. this.contractStartDate = contractStartDate;
  1039. }
  1040. if (data) {
  1041. data.forEach((item) => {
  1042. item.guaranteePeriodUnitCode = item.guaranteePeriodUnitCode
  1043. ? item.guaranteePeriodUnitCode + ''
  1044. : '';
  1045. item.deliveryDeadline = item.customerExpectDeliveryDeadline;
  1046. // if (item.deliveryDays) {
  1047. // item['deliveryDeadline'] = this.setDay(item.deliveryDays);//customerExpectDeliveryDeadline
  1048. // }
  1049. });
  1050. this.form.datasource = data;
  1051. }
  1052. },
  1053. //选择产品
  1054. handParent(row, index) {
  1055. let item = {
  1056. id: row.productCode
  1057. };
  1058. this.$refs.productListRef.open(item, index);
  1059. },
  1060. //选择技术人回调
  1061. changeAnswer(obj, idx) {
  1062. this.$set(this.form.datasource[idx], 'technicalAnswerId', obj.id);
  1063. this.$set(this.form.datasource[idx], 'technicalAnswerName', obj.name);
  1064. },
  1065. handHead(row, index) {
  1066. let item = {
  1067. id: row.technicalAnswerId
  1068. };
  1069. this.$refs.headRef.open(item, index);
  1070. },
  1071. getGoodsListData(obj = []) {
  1072. obj.forEach((item) => {
  1073. this.$set(item, 'supplierMark', this.supplierMark);
  1074. this.form.datasource.push(item);
  1075. });
  1076. },
  1077. //选择产品回调
  1078. changeParent(obj = [], idx) {
  1079. obj.forEach(async (item, index) => {
  1080. let i = idx == -1 ? index : idx;
  1081. let row = JSON.parse(JSON.stringify(this.defaultForm));
  1082. row.key = this.form.datasource.length + 1;
  1083. let parasm = idx == -1 ? row : this.form.datasource[i];
  1084. this.$set(parasm, 'productId', item.id);
  1085. this.$set(parasm, 'categoryName', item.name);
  1086. this.$set(parasm, 'productCategoryId', item.categoryLevelId);
  1087. this.$set(parasm, 'productBrand', item.brandNum);
  1088. this.$set(parasm, 'productCategoryName', item.categoryLevelPath);
  1089. this.$set(parasm, 'productCode', item.code);
  1090. this.$set(parasm, 'productName', item.name);
  1091. this.$set(parasm, 'modelType', item.modelType);
  1092. this.$set(parasm, 'availableCountBase', item.availableCountBase);
  1093. this.$set(parasm, 'measuringUnit', item.measuringUnit);
  1094. this.$set(parasm, 'specification', item.specification);
  1095. this.$set(parasm, 'weightUnit', item.weightUnit);
  1096. this.$set(parasm, 'imgCode', item.imgCode);
  1097. this.$set(parasm, 'produceType', item.produceType);
  1098. this.$set(parasm, 'approvalNumber', item.extField?.approvalNumber);
  1099. this.$set(parasm, 'singleWeight', item.roughWeight);
  1100. this.$set(
  1101. parasm,
  1102. 'packingSpecification',
  1103. item.extField?.packingSpecification
  1104. );
  1105. this.$set(parasm, 'supplierMark', this.supplierMark);
  1106. this.$set(parasm, 'batchNo', await getCode('1900101420390125570'));
  1107. if (idx == -1) {
  1108. this.form.datasource.push(row);
  1109. }
  1110. });
  1111. },
  1112. remove(row, index) {
  1113. this.form.datasource.splice(index, 1);
  1114. // let index = this.form.datasource.findIndex((n) => n.key == row.key);
  1115. // if (index !== -1) {
  1116. // this.form.datasource.splice(index, 1);
  1117. // this.setSort();
  1118. // }
  1119. },
  1120. // 清空表格
  1121. restTable() {
  1122. this.form.datasource = [];
  1123. },
  1124. // 重新排序
  1125. setSort() {
  1126. this.form.datasource.forEach((n, index) => {
  1127. n.key = index + 1;
  1128. });
  1129. },
  1130. // 添加
  1131. handlAdd() {
  1132. let item = JSON.parse(JSON.stringify(this.defaultForm));
  1133. item.key = this.form.datasource.length + 1;
  1134. this.form.datasource.push(item);
  1135. },
  1136. setDeliveryDays(row, index, type) {
  1137. if (type == 'deliveryDays') {
  1138. this.$set(
  1139. this.form.datasource[index],
  1140. 'deliveryDeadline',
  1141. this.setDay(row.deliveryDays)
  1142. );
  1143. }
  1144. if (type == 'guaranteePeriod') {
  1145. let guaranteePeriodUnitName = this.guaranteePeriodUnit(
  1146. row.guaranteePeriodUnitCode
  1147. );
  1148. this.$set(
  1149. this.form.datasource[index],
  1150. 'guaranteePeriodDeadline',
  1151. guaranteePeriodUnitName != 'second'
  1152. ? this.setDay(row.guaranteePeriod, guaranteePeriodUnitName)
  1153. : ''
  1154. );
  1155. }
  1156. },
  1157. guaranteePeriodUnit(code) {
  1158. return code == 3
  1159. ? 'day'
  1160. : code == 4
  1161. ? 'month'
  1162. : code == 5
  1163. ? 'year'
  1164. : 'second';
  1165. },
  1166. setDay(addDay, dateType = 'day') {
  1167. return dayjs(this.contractStartDate || new Date())
  1168. .add(addDay, dateType)
  1169. .format('YYYY-MM-DD');
  1170. },
  1171. validateForm(callback) {
  1172. //开始表单校验
  1173. this.$refs.form.validate((valid) => {
  1174. callback(valid);
  1175. });
  1176. }
  1177. }
  1178. };
  1179. </script>
  1180. <style lang="scss" scoped>
  1181. .headbox {
  1182. display: flex;
  1183. justify-content: space-between;
  1184. align-items: center;
  1185. .amount {
  1186. font-size: 14px;
  1187. font-weight: bold;
  1188. padding-right: 30px;
  1189. }
  1190. }
  1191. .time-form .el-form-item {
  1192. margin-bottom: 0 !important;
  1193. }
  1194. ::v-deep .period {
  1195. display: flex;
  1196. .borderleftnone {
  1197. .el-input--medium .el-input__inner {
  1198. border-top-right-radius: 0;
  1199. border-bottom-right-radius: 0;
  1200. }
  1201. }
  1202. .borderrightnone {
  1203. .el-input--medium .el-input__inner {
  1204. border-top-left-radius: 0;
  1205. border-bottom-left-radius: 0;
  1206. }
  1207. }
  1208. }
  1209. ::v-deep .time-form tbody > tr:hover > td {
  1210. background-color: transparent !important;
  1211. }
  1212. ::v-deep .time-form .el-table tr {
  1213. background-color: #ffffff;
  1214. }
  1215. .pricebox {
  1216. display: flex;
  1217. justify-content: flex-start;
  1218. align-items: center;
  1219. font-weight: bold;
  1220. }
  1221. </style>