inventoryTable.vue 40 KB

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