detailsPage.vue 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383
  1. <template>
  2. <div class="borderless" v-loading="pageLoading">
  3. <div class="customer-head">
  4. <div class="customer-back">
  5. <!-- <i class="back-icon el-icon-arrow-left"></i><i style="font-style:normal">返回管理列表</i>-->
  6. <el-button
  7. type="danger"
  8. style="border: none;background: none;color: red"
  9. icon="el-icon-arrow-left"
  10. @click="backToList"
  11. >返回列表
  12. </el-button>
  13. </div>
  14. <div class="add-customer-btn" v-if="showBut">
  15. <el-button type="info" @click="saveSell">生成销售单</el-button>
  16. <el-button type="success" disabled>
  17. 复制新单
  18. </el-button>
  19. <el-button
  20. type="primary"
  21. :disabled="disabled"
  22. @click="editCustomer"
  23. :loading="subLoading"
  24. v-if="detailData.status != 1"
  25. >{{ form.id ? "确认修改" : "确认新增" }}
  26. </el-button>
  27. </div>
  28. </div>
  29. <div style="margin-top: 60px;margin-bottom:35px">
  30. <containerTitle title="基础信息"></containerTitle>
  31. <basic-container style="margin-bottom: 10px">
  32. <avue-form ref="form" v-model="form" :option="option">
  33. <template slot="portOfLoad">
  34. <port-info
  35. v-model="form.portOfLoad"
  36. :disabled="detailData.status == 1"
  37. />
  38. </template>
  39. <template slot="portOfDestination">
  40. <port-info
  41. v-model="form.portOfDestination"
  42. :disabled="detailData.status == 1"
  43. />
  44. </template>
  45. <template slot="corpId">
  46. <select-component
  47. v-model="form.corpId"
  48. :configuration="configuration"
  49. :disabled="detailData.status == 1"
  50. ></select-component>
  51. </template>
  52. <template slot="boxNumber">
  53. <el-input
  54. size="mini"
  55. v-model="form.boxNumber"
  56. oninput='this.value=this.value.replace(/[^(\d.)]/g,"").replace(/^(\d+)\.(\d\d).*$/,
  57. "$1.$2")'
  58. placeholder="请输入 起订量"
  59. :disabled="detailData.status == 1"
  60. />
  61. </template>
  62. <template slot="minOrder">
  63. <el-input
  64. size="mini"
  65. v-model="form.minOrder"
  66. oninput='this.value=this.value.replace(/[^(\d.)]/g,"").replace(/^(\d+)\.(\d\d).*$/,
  67. "$1.$2")'
  68. placeholder="请输入 起订量"
  69. :disabled="detailData.status == 1"
  70. />
  71. </template>
  72. <template slot="predictOceanFreight">
  73. <el-input
  74. size="mini"
  75. v-model="form.predictOceanFreight"
  76. oninput='this.value=this.value.replace(/[^(\d.)]/g,"").replace(/^(\d+)\.(\d\d).*$/,
  77. "$1.$2")'
  78. placeholder="请输入 预计海运费"
  79. :disabled="detailData.status == 1"
  80. />
  81. </template>
  82. <template slot="referenceOceanFreight">
  83. <el-input
  84. size="mini"
  85. v-model="form.referenceOceanFreight"
  86. oninput='this.value=this.value.replace(/[^(\d.)]/g,"").replace(/^(\d+)\.(\d\d).*$/,
  87. "$1.$2")'
  88. placeholder="请输入 参考海运费"
  89. :disabled="detailData.status == 1"
  90. />
  91. </template>
  92. <template slot="oceanFreight">
  93. <el-input
  94. size="mini"
  95. v-model="form.oceanFreight"
  96. oninput='this.value=this.value.replace(/[^(\d.)]/g,"").replace(/^(\d+)\.(\d\d).*$/,
  97. "$1.$2")'
  98. placeholder="请输入 实际海运费"
  99. :disabled="detailData.status == 1"
  100. />
  101. </template>
  102. </avue-form>
  103. </basic-container>
  104. <containerTitle title="商品信息"></containerTitle>
  105. <basic-container>
  106. <avue-crud
  107. ref="crud"
  108. :data="data"
  109. :option="tableOption"
  110. @row-del="rowDel"
  111. :summary-method="summaryMethod"
  112. @saveColumn="saveColumn"
  113. >
  114. <template slot="menuLeft">
  115. <el-button
  116. type="primary"
  117. icon="el-icon-plus"
  118. size="small"
  119. @click.stop="newDetails"
  120. :disabled="detailData.status == 1"
  121. >新增明细</el-button
  122. >
  123. <el-button
  124. type="primary"
  125. icon="el-icon-plus"
  126. size="small"
  127. @click.stop="addLibrary"
  128. :disabled="detailData.status == 1"
  129. >出口价格库</el-button
  130. >
  131. <el-button
  132. type="info"
  133. icon="el-icon-printer"
  134. size="small"
  135. @click.stop="openReport()"
  136. >报 表</el-button
  137. >
  138. <el-button
  139. type="info"
  140. size="small"
  141. @click.stop="savePurchase"
  142. :disabled="detailData.status == 1"
  143. >采购询价</el-button
  144. >
  145. <el-button
  146. type="info"
  147. size="small"
  148. @click.stop="saveShipping"
  149. :disabled="detailData.status == 1"
  150. >船务询价</el-button
  151. >
  152. </template>
  153. <template slot="menu" slot-scope="{ row, index }">
  154. <el-button
  155. size="small"
  156. icon="el-icon-edit"
  157. type="text"
  158. @click="rowCell(row, index)"
  159. :disabled="disabled"
  160. >{{ row.$cellEdit ? "保存" : "修改" }}</el-button
  161. >
  162. <el-button
  163. size="small"
  164. icon="el-icon-edit"
  165. type="text"
  166. @click="rowDel(row, index)"
  167. :disabled="detailData.status == 1"
  168. >删 除</el-button
  169. >
  170. </template>
  171. <template slot="itemType" slot-scope="{ row }">
  172. <el-select
  173. v-if="row.$cellEdit"
  174. v-model="row.itemType"
  175. filterable
  176. allow-create
  177. default-first-option
  178. placeholder="请输入"
  179. size="small"
  180. @focus="itemTypeFocus(row)"
  181. >
  182. <el-option
  183. v-for="(item, index) in itemtypeList"
  184. :key="index"
  185. :label="item.value"
  186. :value="item.value"
  187. >
  188. </el-option>
  189. </el-select>
  190. <span v-else>{{ row.itemType }}</span>
  191. </template>
  192. <template slot="cname" slot-scope="{ row, index }">
  193. <!-- <el-button
  194. size="small"
  195. type="text"
  196. @click="rePick(row, index)"
  197. :disabled="disabled"
  198. style="padding:4px 10px;float:left"
  199. >选择</el-button
  200. > -->
  201. <span v-if="row.$cellEdit" style="display:flex">
  202. <el-select
  203. v-model="row.cname"
  204. placeholder="请选择"
  205. size="small"
  206. style="width:60%"
  207. @change="cnameChange(row, index)"
  208. >
  209. <el-option
  210. v-for="item in goodsoptions"
  211. :key="item.id"
  212. :label="item.cname"
  213. :value="item.cname"
  214. >
  215. </el-option>
  216. </el-select>
  217. <el-button
  218. icon="el-icon-search"
  219. size="small"
  220. @click="rePick(row, index)"
  221. ></el-button>
  222. </span>
  223. <span v-else> {{ row.cname }}</span>
  224. </template>
  225. <template slot="partsList" slot-scope="{ row, index }">
  226. <el-button
  227. size="small"
  228. type="text"
  229. @click="partrePick(row, index)"
  230. :disabled="disabled"
  231. >操作</el-button
  232. >
  233. </template>
  234. <template slot="priorityReferrer" slot-scope="{ row }">
  235. <el-checkbox
  236. :disabled="!row.$cellEdit"
  237. v-model="row.priorityReferrer"
  238. :true-label="1"
  239. :false-label="0"
  240. />
  241. </template>
  242. <template slot="corpId" slot-scope="{ row, index }">
  243. <customer-dialog
  244. v-if="row.$cellEdit"
  245. v-model="row.corpName"
  246. :cropIndex="index"
  247. @getcorpId="getcorpId"
  248. ></customer-dialog>
  249. <span v-else>{{ row.corpName }}</span>
  250. </template>
  251. <template slot="purchaseAmount" slot-scope="{ row }">
  252. <el-input
  253. v-if="row.$cellEdit"
  254. v-model="row.purchaseAmount"
  255. size="small"
  256. placeholder="请输入"
  257. @change="priceChange(row)"
  258. oninput='this.value=this.value.replace(/[^(\d.)]/g,"").replace(/^(\d+)\.(\d\d).*$/, "$1.$2")'
  259. ></el-input>
  260. <span v-else>{{ row.purchaseAmount | micrometerFormat }}</span>
  261. </template>
  262. <template slot="price" slot-scope="{ row }">
  263. <el-input
  264. v-if="row.$cellEdit"
  265. v-model="row.price"
  266. size="small"
  267. oninput='this.value=this.value.replace(/[^(\d.)]/g,"").replace(/^(\d+)\.(\d\d).*$/, "$1.$2")'
  268. @change="priceChange(row)"
  269. ></el-input>
  270. <span v-else>{{ row.price | micrometerFormat }}</span>
  271. </template>
  272. <template slot="amount" slot-scope="{ row }">
  273. <span>{{ row.amount | micrometerFormat }}</span>
  274. </template>
  275. <template slot="orderQuantity" slot-scope="{ row }">
  276. <el-input
  277. v-if="row.$cellEdit"
  278. v-model="row.orderQuantity"
  279. size="small"
  280. oninput='this.value=this.value.replace(/[^(\d.)]/g,"").replace(/^(\d+)\.(\d\d).*$/, "$1.$2")'
  281. @change="priceChange(row)"
  282. ></el-input>
  283. <span v-else>{{ row.orderQuantity }}</span>
  284. </template>
  285. <template slot="discount" slot-scope="{ row }">
  286. <el-input
  287. v-if="row.$cellEdit"
  288. v-model="row.discount"
  289. size="small"
  290. oninput='this.value=this.value.replace(/[^(\d.)]/g,"").replace(/^(\d+)\.(\d\d).*$/, "$1.$2")'
  291. @change="discountChange(row)"
  292. ></el-input>
  293. <span v-else>{{ row.discount | isDiscount }}</span>
  294. </template>
  295. <template slot="insurance" slot-scope="{ row }">
  296. <el-input
  297. v-if="row.$cellEdit"
  298. v-model="row.insurance"
  299. size="small"
  300. oninput='this.value=this.value.replace(/[^(\d.)]/g,"").replace(/^(\d+)\.(\d\d).*$/, "$1.$2")'
  301. @change="priceChange(row)"
  302. ></el-input>
  303. <span v-else>{{ row.insurance | micrometerFormat }}</span>
  304. </template>
  305. <template slot="freight" slot-scope="{ row }">
  306. <el-input
  307. v-if="row.$cellEdit"
  308. v-model="row.freight"
  309. size="small"
  310. oninput='this.value=this.value.replace(/[^(\d.)]/g,"").replace(/^(\d+)\.(\d\d).*$/, "$1.$2")'
  311. @change="priceChange(row)"
  312. ></el-input>
  313. <span v-else>{{ row.freight | micrometerFormat }}</span>
  314. </template>
  315. <template slot="taxRate" slot-scope="{ row }">
  316. <el-input
  317. v-if="row.$cellEdit"
  318. v-model="row.taxRate"
  319. size="small"
  320. oninput='this.value=this.value.replace(/[^(\d.)]/g,"").replace(/^(\d+)\.(\d\d).*$/, "$1.$2")'
  321. @change="taxRateChange(row)"
  322. ></el-input>
  323. <span v-else>{{ row.taxRate | isPercentage }}</span>
  324. </template>
  325. </avue-crud>
  326. </basic-container>
  327. <fee-info
  328. ref="feeInfo"
  329. :orderFeesList="orderFeesList"
  330. :disabled="detailData.status == 1"
  331. feeUrl="/blade-purchase-sales/orderfees/update"
  332. />
  333. </div>
  334. <el-dialog
  335. title="导入商品"
  336. append-to-body
  337. class="el-dialogDeep"
  338. :visible.sync="dialogVisible"
  339. width="60%"
  340. :close-on-click-modal="false"
  341. :destroy-on-close="true"
  342. :close-on-press-escape="false"
  343. @close="closeGoods"
  344. top="10vh"
  345. v-dialog-drag
  346. >
  347. <span>
  348. <el-row>
  349. <el-col :span="5">
  350. <div>
  351. <el-scrollbar>
  352. <basic-container style="margin-top:45px">
  353. <avue-tree :option="treeOption" @node-click="nodeClick" />
  354. </basic-container>
  355. </el-scrollbar>
  356. </div>
  357. </el-col>
  358. <el-col :span="19">
  359. <avue-crud
  360. :option="goodsOption"
  361. :table-loading="loading"
  362. :data="goodsList"
  363. ref="goodsCrud"
  364. @refresh-change="refreshChange"
  365. @selection-change="selectionChange"
  366. @row-click="rowClick"
  367. :page.sync="page"
  368. @on-load="onLoad"
  369. @saveColumn="saveGoodsColumn"
  370. ></avue-crud>
  371. </el-col>
  372. </el-row>
  373. </span>
  374. <span slot="footer" class="dialog-footer">
  375. <el-button @click="dialogVisible = false">取 消</el-button>
  376. <el-button
  377. type="primary"
  378. @click="importGoods"
  379. :disabled="selectionList.length == 0"
  380. >导入</el-button
  381. >
  382. </span>
  383. </el-dialog>
  384. <report-dialog
  385. :switchDialog="switchDialog"
  386. :reportId="form.id"
  387. reportName="客户询价"
  388. @onClose="onClose()"
  389. ></report-dialog>
  390. <part-dialog
  391. ref="part"
  392. @partOpen="partOpen()"
  393. :partList="partList"
  394. @importPart="importPart"
  395. @partClosed="partClosed"
  396. @partReData="partReData"
  397. />
  398. <price-library ref="library" @importLibray="importLibray" />
  399. </div>
  400. </template>
  401. <script>
  402. import tableOption from "./config/customerContact.json";
  403. import goodsOption from "./config/commodity.json";
  404. import feeInfo from "@/components/fee-info/main";
  405. import customerDialog from "@/components/customer-dialog/main";
  406. import partDialog from "@/components/part-dialog/main";
  407. import {
  408. detail,
  409. submit,
  410. delItem,
  411. getDeptLazyTree,
  412. getGoods,
  413. savePurchase,
  414. saveShipping,
  415. getPorts,
  416. getSpecification,
  417. saveSell
  418. } from "@/api/basicData/customerInquiry";
  419. import reportDialog from "@/components/report-dialog/main";
  420. import priceLibrary from "./priceLibrary.vue";
  421. import { isDiscount, isPercentage, micrometerFormat } from "@/util/validate";
  422. import { contrastObj, contrastList } from "@/util/contrastData";
  423. import _ from "lodash";
  424. export default {
  425. name: "detailsPageEdit",
  426. data() {
  427. return {
  428. itemtypeList: [],
  429. configuration: {
  430. multipleChoices: false,
  431. multiple: false,
  432. collapseTags: false,
  433. placeholder: "请点击右边按钮选择",
  434. dicData: []
  435. },
  436. switchDialog: false,
  437. form: {
  438. orderStatus: "录入"
  439. },
  440. disabled: false,
  441. dialogVisible: false,
  442. tableOption: {},
  443. option: {
  444. menuBtn: false,
  445. labelWidth: 100,
  446. column: [
  447. {
  448. label: "客户名称",
  449. prop: "corpId",
  450. rules: [
  451. {
  452. required: true,
  453. message: "",
  454. trigger: "blur"
  455. }
  456. ],
  457. span: 16,
  458. slot: true
  459. },
  460. {
  461. label: "系统号",
  462. prop: "sysNo",
  463. span: 8,
  464. disabled: true
  465. },
  466. {
  467. label: "联系人",
  468. prop: "corpAttn",
  469. span: 8
  470. },
  471. {
  472. label: "电话",
  473. prop: "corpTel",
  474. span: 8
  475. },
  476. {
  477. label: "订单状态",
  478. prop: "orderStatus",
  479. span: 8,
  480. type: "select",
  481. dicUrl: "/api/blade-system/dict-biz/dictionary?code=order_status",
  482. props: {
  483. label: "dictValue",
  484. value: "dictValue"
  485. }
  486. },
  487. {
  488. label: "起运港",
  489. prop: "portOfLoad",
  490. span: 8,
  491. type: "select",
  492. filterable: true,
  493. dicData: [],
  494. props: {
  495. label: "name",
  496. value: "name"
  497. }
  498. },
  499. {
  500. label: "目的港",
  501. prop: "portOfDestination",
  502. span: 8,
  503. type: "select",
  504. filterable: true,
  505. dicData: [],
  506. props: {
  507. label: "name",
  508. value: "name"
  509. }
  510. },
  511. {
  512. label: "运输方式",
  513. prop: "transport",
  514. span: 8,
  515. type: "select",
  516. dicUrl: "/api/blade-system/dict-biz/dictionary?code=mode_transport",
  517. props: {
  518. label: "dictValue",
  519. value: "dictValue"
  520. }
  521. },
  522. {
  523. label: "价格条款",
  524. prop: "priceTerms",
  525. span: 8,
  526. type: "select",
  527. dicUrl: "/api/blade-system/dict-biz/dictionary?code=pricing_terms",
  528. props: {
  529. label: "dictValue",
  530. value: "dictValue"
  531. }
  532. },
  533. {
  534. label: "条款说明",
  535. prop: "priceTermsDescription",
  536. span: 16
  537. },
  538. {
  539. label: "收款方式",
  540. prop: "paymentType",
  541. span: 8,
  542. type: "select",
  543. dicUrl: "/api/blade-system/dict-biz/dictionary?code=payment_term",
  544. props: {
  545. label: "dictValue",
  546. value: "dictValue"
  547. }
  548. },
  549. {
  550. label: "收款说明",
  551. prop: "paymentTypeDescription",
  552. span: 16
  553. },
  554. {
  555. label: "订单日期",
  556. prop: "businesDate",
  557. span: 8,
  558. type: "date",
  559. format: "yyyy-MM-dd",
  560. valueFormat: "yyyy-MM-dd 00:00:00",
  561. rules: [
  562. {
  563. required: true,
  564. message: "",
  565. trigger: "blur"
  566. }
  567. ]
  568. },
  569. {
  570. label: "有效日期",
  571. prop: "dateValidity",
  572. span: 8,
  573. type: "date",
  574. format: "yyyy-MM-dd",
  575. valueFormat: "yyyy-MM-dd 00:00:00"
  576. },
  577. {
  578. label: "订单号",
  579. prop: "orderNo",
  580. span: 8
  581. },
  582. {
  583. label: "币别",
  584. prop: "currency",
  585. span: 8,
  586. type: "select",
  587. dicUrl: "/api/blade-system/dict-biz/dictionary?code=currency",
  588. props: {
  589. label: "dictValue",
  590. value: "dictValue"
  591. },
  592. change: ({ value }) => {
  593. if (value == "CNY") {
  594. this.form.exchangeRate = 1;
  595. }
  596. if (value == "USD") {
  597. this.form.exchangeRate = 6.3843;
  598. }
  599. }
  600. },
  601. {
  602. label: "汇率",
  603. prop: "exchangeRate",
  604. span: 8,
  605. slot: true,
  606. row: true,
  607. disabled: true
  608. },
  609. {
  610. label: "箱型",
  611. prop: "boxPile",
  612. span: 8
  613. },
  614. {
  615. label: "箱量",
  616. prop: "boxNumber",
  617. span: 8
  618. },
  619. {
  620. label: "起订量",
  621. prop: "minOrder",
  622. span: 8
  623. },
  624. {
  625. label: "预计海运费",
  626. prop: "predictOceanFreight",
  627. span: 8
  628. },
  629. {
  630. label: "参考海运费",
  631. prop: "referenceOceanFreight",
  632. span: 8
  633. },
  634. {
  635. label: "实际海运费",
  636. prop: "oceanFreight",
  637. span: 8
  638. },
  639. {
  640. label: "毛利额",
  641. prop: "grossProfit",
  642. span: 8,
  643. disabled: true
  644. },
  645. {
  646. label: "毛利率",
  647. prop: "grossProfitRate",
  648. span: 8,
  649. row: true,
  650. append: "%",
  651. disabled: true
  652. },
  653. {
  654. label: "备注",
  655. prop: "orderRemark",
  656. type: "textarea",
  657. minRows: 2,
  658. span: 8
  659. },
  660. {
  661. label: "采购备注",
  662. prop: "purchaseRemark",
  663. type: "textarea",
  664. minRows: 2,
  665. span: 8
  666. },
  667. {
  668. label: "船务备注",
  669. prop: "shippingRemark",
  670. type: "textarea",
  671. minRows: 2,
  672. span: 8
  673. }
  674. ]
  675. },
  676. treeOption: {
  677. nodeKey: "id",
  678. lazy: true,
  679. treeLoad: function(node, resolve) {
  680. const parentId = node.level === 0 ? 0 : node.data.id;
  681. getDeptLazyTree(parentId).then(res => {
  682. resolve(
  683. res.data.data.map(item => {
  684. return {
  685. ...item,
  686. leaf: !item.hasChildren
  687. };
  688. })
  689. );
  690. });
  691. },
  692. addBtn: false,
  693. menu: false,
  694. size: "small",
  695. props: {
  696. label: "title",
  697. value: "value",
  698. children: "children"
  699. }
  700. },
  701. page: {
  702. pageSize: 10,
  703. currentPage: 1,
  704. total: 0
  705. },
  706. goodsOption: {},
  707. data: [],
  708. goodsList: [],
  709. selectionList: [],
  710. treeDeptId: null,
  711. orderFeesList: [],
  712. oldform: {
  713. orderStatus: "录入"
  714. },
  715. olddata: [],
  716. oldorderFeesList: [],
  717. reData: null,
  718. loading: false,
  719. subLoading: false,
  720. pageLoading: false,
  721. showBut: true,
  722. partreData: null,
  723. partType: false,
  724. partList: [],
  725. goodsoptions: []
  726. };
  727. },
  728. props: {
  729. detailData: {
  730. type: Object
  731. }
  732. },
  733. components: {
  734. reportDialog,
  735. feeInfo,
  736. customerDialog,
  737. partDialog,
  738. priceLibrary
  739. },
  740. async created() {
  741. this.tableOption = await this.getColumnData(
  742. this.getColumnName(1),
  743. tableOption
  744. );
  745. this.goodsOption = await this.getColumnData(
  746. this.getColumnName(26),
  747. goodsOption
  748. );
  749. if (this.detailData.id) {
  750. this.getDetail(this.detailData.id);
  751. }
  752. if (this.detailData.status == 1) {
  753. this.option.disabled = true;
  754. }
  755. this.getWorkDicts("product_properties").then(res => {
  756. this.findObject(this.tableOption.column, "itemProp").dicData =
  757. res.data.data;
  758. });
  759. this.getWorkDicts("unit").then(res => {
  760. this.findObject(this.tableOption.column, "unit").dicData = res.data.data;
  761. });
  762. getPorts().then(res => {
  763. this.findObject(this.option.column, "portOfLoad").dicData = res.data;
  764. this.findObject(this.option.column, "portOfDestination").dicData =
  765. res.data;
  766. });
  767. getGoods().then(res => {
  768. this.goodsoptions = res.data.data.records;
  769. });
  770. },
  771. filters: {
  772. isDiscount(val) {
  773. return isDiscount(val);
  774. },
  775. isPercentage(val) {
  776. return isPercentage(val);
  777. },
  778. micrometerFormat(val) {
  779. return micrometerFormat(val);
  780. }
  781. },
  782. methods: {
  783. addLibrary() {
  784. this.$refs.library.init();
  785. },
  786. cnameChange(row) {
  787. this.goodsoptions.forEach(e => {
  788. if (e.cname == row.cname) {
  789. row.itemId = e.id;
  790. row.code = e.code;
  791. row.priceCategory = e.goodsTypeName;
  792. row.itemUrl = e.url;
  793. row.itemDescription = e.cnameDescription;
  794. row.unit = e.unit;
  795. }
  796. });
  797. },
  798. partReData(row) {
  799. this.partreData = row;
  800. this.partOpen();
  801. },
  802. saveSell() {
  803. if (!this.form.id) {
  804. return this.$message.error("此单据没有提交记录,请先提交");
  805. }
  806. this.$confirm("是否生成销售单?", {
  807. confirmButtonText: "确定",
  808. cancelButtonText: "取消",
  809. type: "warning"
  810. }).then(() => {
  811. saveSell(this.form.id).then(res => {
  812. if (res.data.code == 200) {
  813. this.$message.success("生成成功");
  814. this.getDetail(this.detailData.id);
  815. }
  816. });
  817. });
  818. },
  819. partOpen() {
  820. this.partType = true;
  821. this.newDetails();
  822. },
  823. rePick(row, index) {
  824. this.reData = {
  825. ...row,
  826. index: index
  827. };
  828. this.newDetails();
  829. },
  830. partrePick(row, index) {
  831. this.partList = row.partsList;
  832. this.$refs.part.init(row.partsList, index);
  833. },
  834. importPart(rows, sum, index) {
  835. this.data[index].partsList = rows;
  836. this.data[index].partsPrice = sum;
  837. this.priceChange(this.data[index]);
  838. },
  839. partClosed() {
  840. this.partList = [];
  841. this.partreData = null;
  842. },
  843. getcorpId(row) {
  844. this.data[row.index].corpId = row.id;
  845. },
  846. rowCell(row, index) {
  847. if (row.$cellEdit == true) {
  848. this.$set(row, "$cellEdit", false);
  849. } else {
  850. this.$set(row, "$cellEdit", true);
  851. }
  852. },
  853. itemTypeFocus(row) {
  854. this.itemtypeList = [];
  855. getSpecification({ goodId: row.itemId }).then(res => {
  856. const data = res.data.data;
  857. this.itemtypeList = data.map(item => ({ value: item }));
  858. });
  859. },
  860. priceChange(row) {
  861. const sum = _.multiply(
  862. _.add(
  863. _.add(
  864. Number(
  865. _.multiply(
  866. row.price ? row.price : 0,
  867. row.orderQuantity ? row.orderQuantity : 0
  868. )
  869. ),
  870. Number(
  871. _.add(
  872. Number(row.insurance ? row.insurance : 0),
  873. Number(row.freight ? row.freight : 0)
  874. )
  875. )
  876. ),
  877. Number(row.partsPrice ? row.partsPrice : 0)
  878. ),
  879. _.divide(row.discount ? row.discount : 10, 10)
  880. );
  881. row.amount = Number(sum ? sum : 0).toFixed(2);
  882. // let amountSum = 0;
  883. // let purchaseAmountSum = 0;
  884. // let grossProfitRate = 0;
  885. // let grossProfit = 0;
  886. // this.data.forEach(e => {
  887. // amountSum = _.add(amountSum, Number(e.amount));
  888. // purchaseAmountSum = _.add(
  889. // purchaseAmountSum,
  890. // Number(
  891. // _.multiply(
  892. // Number(e.purchaseAmount ? e.purchaseAmount : 0),
  893. // Number(e.orderQuantity)
  894. // )
  895. // )
  896. // );
  897. // grossProfit = _.subtract(amountSum, purchaseAmountSum);
  898. // grossProfitRate =
  899. // amountSum != 0
  900. // ? _.multiply(
  901. // _.divide(_.subtract(amountSum, purchaseAmountSum), amountSum),
  902. // 100
  903. // )
  904. // : 0;
  905. // this.form.grossProfit = Number(grossProfit ? grossProfit : 0).toFixed(
  906. // 2
  907. // );
  908. // this.form.grossProfitRate = Number(
  909. // grossProfitRate ? grossProfitRate : 0
  910. // ).toFixed(2);
  911. // });
  912. },
  913. discountChange(row) {
  914. if (row.discount >= 10) {
  915. row.discount = null;
  916. this.$message.error("请正确输入折扣");
  917. }
  918. this.priceChange(row);
  919. },
  920. taxRateChange(row) {
  921. if (row.taxRate > 100) {
  922. row.taxRate = 0;
  923. this.$message.error("请正确输入税率");
  924. }
  925. },
  926. grossProfitRateChange(row) {
  927. if (row >= 100) {
  928. this.form.grossProfitRate = 0;
  929. this.$message.error("毛利率不能超过100%");
  930. }
  931. },
  932. saveShipping() {
  933. if (!this.form.id) {
  934. return this.$message.error("此单据没有提交记录,请先提交");
  935. }
  936. this.$confirm("是否生成船务询价单?", {
  937. confirmButtonText: "确定",
  938. cancelButtonText: "取消",
  939. type: "warning"
  940. }).then(() => {
  941. saveShipping(this.form.id).then(res => {
  942. if (res.data.code == 200) {
  943. this.$message.success("生成成功");
  944. }
  945. });
  946. });
  947. },
  948. savePurchase() {
  949. if (!this.form.id) {
  950. return this.$message.error("此单据没有提交记录,请先提交");
  951. }
  952. this.$confirm("是否生成采购询价单?", {
  953. confirmButtonText: "确定",
  954. cancelButtonText: "取消",
  955. type: "warning"
  956. }).then(() => {
  957. savePurchase(this.form.id).then(res => {
  958. if (res.data.code == 200) {
  959. this.$message.success("生成成功");
  960. }
  961. });
  962. });
  963. },
  964. rowSave(row) {
  965. this.$set(row, "$cellEdit", false);
  966. },
  967. rowDel(row, index) {
  968. this.$confirm("确定删除数据?", {
  969. confirmButtonText: "确定",
  970. cancelButtonText: "取消",
  971. type: "warning"
  972. }).then(() => {
  973. if (row.id) {
  974. delItem(row.id).then(res => {
  975. this.$message({
  976. type: "success",
  977. message: "删除成功!"
  978. });
  979. this.data.splice(index, 1);
  980. });
  981. } else {
  982. this.$message({
  983. type: "success",
  984. message: "删除成功!"
  985. });
  986. this.data.splice(index, 1);
  987. }
  988. });
  989. },
  990. importGoods() {
  991. if (this.partType) {
  992. if (this.partreData) {
  993. if (this.selectionList.length != 1) {
  994. return this.$message.error("重新选择的时候只能选择一条数据");
  995. } else {
  996. this.selectionList.forEach(e => {
  997. this.partList.forEach((item, index) => {
  998. if (index == this.partreData.index) {
  999. item.goodId = e.id;
  1000. item.goodTypeId = e.goodsTypeId;
  1001. item.goodTypeName = e.goodsTypeName;
  1002. item.goodName = e.cname;
  1003. item.price = this.partreData.goodNumber;
  1004. item.goodNumber = this.partreData.goodNumber;
  1005. item.amout = this.partreData.amout;
  1006. item.$cellEdit = true;
  1007. }
  1008. });
  1009. });
  1010. }
  1011. } else {
  1012. this.selectionList.forEach(e => {
  1013. this.partList.push({
  1014. goodId: e.id,
  1015. goodTypeId: e.goodsTypeId,
  1016. goodTypeName: e.goodsTypeName,
  1017. goodName: e.cname,
  1018. price: e.price,
  1019. goodNumber: 0,
  1020. amout: 0,
  1021. $cellEdit: true
  1022. });
  1023. });
  1024. }
  1025. } else if (this.reData) {
  1026. if (this.selectionList.length != 1) {
  1027. return this.$message.error("重新选择的时候只能选择一条数据");
  1028. } else {
  1029. this.selectionList.forEach(e => {
  1030. this.data.forEach((item, index) => {
  1031. if (index == this.reData.index) {
  1032. item.itemId = e.id;
  1033. item.code = e.code;
  1034. item.cname = e.cname;
  1035. item.priceCategory = e.goodsTypeName;
  1036. item.itemUrl = e.url;
  1037. item.itemProp = this.reData.itemProp;
  1038. item.partsList = this.reData.partsList;
  1039. item.partsPrice = this.reData.ppartsPrice;
  1040. item.itemDescription = e.cnameDescription;
  1041. item.itemType = this.reData.itemType;
  1042. item.tradeTerms = this.reData.tradeTerms;
  1043. item.price = this.reData.price;
  1044. item.orderQuantity = this.reData.orderQuantity;
  1045. item.insurance = this.reData.insurance;
  1046. item.freight = this.reData.freight;
  1047. item.discount = this.reData.discount;
  1048. item.amount = this.reData.amount;
  1049. item.taxRate = this.reData.taxRate;
  1050. item.unit = e.unit;
  1051. item.remarks = this.reData.remarks;
  1052. item.$cellEdit = true;
  1053. }
  1054. });
  1055. });
  1056. }
  1057. } else {
  1058. this.selectionList.forEach(e => {
  1059. this.data.push({
  1060. itemId: e.id,
  1061. code: e.code,
  1062. cname: e.cname,
  1063. priceCategory: e.goodsTypeName,
  1064. itemUrl: e.url,
  1065. itemProp: null,
  1066. itemDescription: e.cnameDescription,
  1067. partsList: [],
  1068. partsPrice: 0,
  1069. itemType: null,
  1070. tradeTerms: null,
  1071. price: 0,
  1072. orderQuantity: 0,
  1073. insurance: 0,
  1074. freight: 0,
  1075. discount: null,
  1076. amount: 0,
  1077. taxRate: 0,
  1078. unit: e.unit,
  1079. remarks: null,
  1080. $cellEdit: true
  1081. });
  1082. });
  1083. }
  1084. this.dialogVisible = false;
  1085. },
  1086. closeGoods() {
  1087. this.selectionList = [];
  1088. this.treeDeptId = "";
  1089. this.reData = null;
  1090. if (this.partType) {
  1091. this.partType = false;
  1092. }
  1093. },
  1094. selectionChange(list) {
  1095. this.selectionList = list;
  1096. },
  1097. rowClick(row) {
  1098. this.$refs.goodsCrud.toggleSelection([this.goodsList[row.$index]]);
  1099. },
  1100. nodeClick(data) {
  1101. this.treeDeptId = data.id;
  1102. this.page.currentPage = 1;
  1103. this.onLoad(this.page);
  1104. },
  1105. //费用查询
  1106. onLoad(page, params = {}) {
  1107. this.loading = true;
  1108. getGoods(page.currentPage, page.pageSize, this.treeDeptId)
  1109. .then(res => {
  1110. const data = res.data.data;
  1111. this.page.total = data.total;
  1112. this.goodsList = data.records;
  1113. if (this.page.total) {
  1114. this.goodsOption.height = window.innerHeight - 550;
  1115. } else {
  1116. this.goodsOption.height = window.innerHeight - 475;
  1117. }
  1118. })
  1119. .finally(() => {
  1120. this.loading = false;
  1121. });
  1122. },
  1123. importLibray(rows) {
  1124. rows.forEach(e => {
  1125. this.data.push({
  1126. itemId: e.id,
  1127. code: e.code,
  1128. cname: e.cname,
  1129. priceCategory: e.goodsTypeName,
  1130. purchaseAmount:e.price,
  1131. itemProp:e.goodNature,
  1132. corpId:e.corpId,
  1133. corpName:e.corpName,
  1134. itemDescription:null,
  1135. partsList: [],
  1136. partsPrice: 0,
  1137. itemType: null,
  1138. tradeTerms: null,
  1139. price: 0,
  1140. orderQuantity: 0,
  1141. insurance: 0,
  1142. freight: 0,
  1143. discount: null,
  1144. amount: 0,
  1145. taxRate: 0,
  1146. unit: e.unit,
  1147. remarks: null,
  1148. $cellEdit: true
  1149. });
  1150. });
  1151. },
  1152. //商品明细导入
  1153. newDetails() {
  1154. this.dialogVisible = !this.dialogVisible;
  1155. },
  1156. getDetail(id) {
  1157. this.loading = true;
  1158. this.showBut = false;
  1159. this.pageLoading = true;
  1160. detail(id)
  1161. .then(res => {
  1162. this.form = res.data.data;
  1163. this.data = res.data.data.orderItemsList;
  1164. this.orderFeesList = res.data.data.orderFeesList;
  1165. this.configuration.dicData = this.form.corpName;
  1166. this.oldform = res.data.data;
  1167. this.olddata = this.deepClone(res.data.data.orderItemsList);
  1168. this.oldorderFeesList = this.deepClone(res.data.data.orderFeesList);
  1169. })
  1170. .finally(() => {
  1171. this.loading = false;
  1172. this.showBut = true;
  1173. this.pageLoading = false;
  1174. });
  1175. },
  1176. //修改提交触发
  1177. editCustomer(status) {
  1178. this.$refs["form"].validate((valid, done) => {
  1179. done();
  1180. if (valid) {
  1181. let orderFeesList = this.$refs.feeInfo.submitData();
  1182. if (this.data.length > 0) {
  1183. for (let i = 0; i < this.data.length; i++) {
  1184. if (this.data[i].corpId == null) {
  1185. return this.$message.error(`请输入第${i + 1}行的供应商`);
  1186. }
  1187. }
  1188. }
  1189. for (let i = 0; i < orderFeesList.length; i++) {
  1190. if (orderFeesList[i].corpId == null) {
  1191. return this.$message.error(`请输入第${i + 1}行的结算中心`);
  1192. }
  1193. if (orderFeesList[i].price == 0) {
  1194. return this.$message.error(`请正确输入第${i + 1}行的销售价`);
  1195. }
  1196. if (orderFeesList[i].orderQuantity == 0) {
  1197. return this.$message.error(`请正确输入第${i + 1}行的数量`);
  1198. }
  1199. }
  1200. this.subLoading = true;
  1201. submit({
  1202. ...this.form,
  1203. orderItemsList: this.data,
  1204. orderFeesList: orderFeesList
  1205. })
  1206. .then(res => {
  1207. if (res.data.code == 200) {
  1208. this.$message.success(this.form.id ? "修改成功" : "提交成功");
  1209. this.form = res.data.data;
  1210. this.data = res.data.data.orderItemsList;
  1211. this.orderFeesList = res.data.data.orderFeesList;
  1212. this.oldform = res.data.data;
  1213. this.olddata = this.deepClone(res.data.data.orderItemsList);
  1214. this.oldorderFeesList = this.deepClone(
  1215. res.data.data.orderFeesList
  1216. );
  1217. if (status == "goBack") {
  1218. this.$emit("goBack");
  1219. }
  1220. }
  1221. })
  1222. .finally(() => {
  1223. this.subLoading = false;
  1224. });
  1225. } else {
  1226. return false;
  1227. }
  1228. });
  1229. },
  1230. //返回列表
  1231. backToList() {
  1232. let orderFeesList = this.$refs.feeInfo.submitData();
  1233. console.log(this.data, this.olddata);
  1234. if (
  1235. contrastObj(this.form, this.oldform) ||
  1236. contrastList(this.data, this.olddata) ||
  1237. contrastList(orderFeesList, this.oldorderFeesList)
  1238. ) {
  1239. this.$confirm("数据发生变化未有提交记录, 是否提交?", "提示", {
  1240. confirmButtonText: "确定",
  1241. cancelButtonText: "取消",
  1242. type: "warning"
  1243. })
  1244. .then(() => {
  1245. this.editCustomer("goBack");
  1246. })
  1247. .catch(() => {
  1248. this.$emit("goBack");
  1249. });
  1250. } else {
  1251. this.$emit("goBack");
  1252. }
  1253. },
  1254. openReport() {
  1255. this.switchDialog = !this.switchDialog;
  1256. },
  1257. onClose(val) {
  1258. this.switchDialog = val;
  1259. },
  1260. summaryMethod({ columns, data }) {
  1261. const sums = [];
  1262. if (columns.length > 0) {
  1263. columns.forEach((item, index) => {
  1264. sums[0] = "合计";
  1265. if (
  1266. item.property == "orderQuantity" ||
  1267. item.property == "amount" ||
  1268. item.property == "insurance" ||
  1269. item.property == "freight"
  1270. ) {
  1271. let qtySum = 0;
  1272. let amountSum = 0;
  1273. let insuranceSum = 0;
  1274. let freightSum = 0;
  1275. data.forEach(e => {
  1276. qtySum = _.add(qtySum, Number(e.orderQuantity));
  1277. amountSum = _.add(amountSum, Number(e.amount));
  1278. insuranceSum = _.add(insuranceSum, Number(e.insurance));
  1279. freightSum = _.add(freightSum, Number(e.freight));
  1280. });
  1281. //数量总计
  1282. if (item.property == "orderQuantity") {
  1283. sums[index] = qtySum ? qtySum.toFixed(2) : "0.00";
  1284. }
  1285. //金额总计
  1286. if (item.property == "amount") {
  1287. sums[index] = micrometerFormat(amountSum);
  1288. }
  1289. //保险总计
  1290. if (item.property == "insurance") {
  1291. sums[index] = micrometerFormat(insuranceSum);
  1292. }
  1293. //运费总计
  1294. if (item.property == "freight") {
  1295. sums[index] = micrometerFormat(freightSum);
  1296. }
  1297. }
  1298. });
  1299. }
  1300. return sums;
  1301. },
  1302. async saveColumn() {
  1303. const inSave = await this.saveColumnData(
  1304. this.getColumnName(1),
  1305. this.tableOption
  1306. );
  1307. if (inSave) {
  1308. this.$message.success("保存成功");
  1309. //关闭窗口
  1310. this.$refs.crud.$refs.dialogColumn.columnBox = false;
  1311. }
  1312. },
  1313. async saveGoodsColumn() {
  1314. const inSave = await this.saveColumnData(
  1315. this.getColumnName(26),
  1316. this.goodsOption
  1317. );
  1318. if (inSave) {
  1319. this.$message.success("保存成功");
  1320. //关闭窗口
  1321. this.$refs.goodsCrud.$refs.dialogColumn.columnBox = false;
  1322. }
  1323. }
  1324. }
  1325. };
  1326. </script>
  1327. <style lang="scss" scoped>
  1328. .customer-head {
  1329. position: fixed;
  1330. top: 105px;
  1331. width: 100%;
  1332. margin-left: -10px;
  1333. height: 62px;
  1334. background: #ffffff;
  1335. box-shadow: 0 4px 12px 0px rgba(232, 232, 235, 1);
  1336. z-index: 999;
  1337. }
  1338. .customer-back {
  1339. cursor: pointer;
  1340. line-height: 62px;
  1341. font-size: 16px;
  1342. color: #323233;
  1343. font-weight: 400;
  1344. }
  1345. .back-icon {
  1346. line-height: 64px;
  1347. font-size: 20px;
  1348. margin-right: 8px;
  1349. }
  1350. .sell-customer-btn {
  1351. position: fixed;
  1352. right: 244px;
  1353. top: 115px;
  1354. }
  1355. .copy-customer-btn {
  1356. position: fixed;
  1357. right: 140px;
  1358. top: 115px;
  1359. }
  1360. .add-customer-btn {
  1361. position: fixed;
  1362. right: 36px;
  1363. top: 115px;
  1364. }
  1365. ::v-deep .el-form-item {
  1366. margin-bottom: 8px;
  1367. }
  1368. ::v-deep .el-form-item__error {
  1369. display: none;
  1370. }
  1371. ::v-deep .select-component {
  1372. display: flex;
  1373. }
  1374. </style>