inventoryTable.vue 36 KB

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