index.vue 43 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392
  1. <template>
  2. <div class="ele-body">
  3. <el-card shadow="never" v-loading="loading">
  4. <div class="switch" v-if="!contactData?.id">
  5. <div class="switch_left">
  6. <ul>
  7. <li
  8. style="height: 42px; line-height: 38px"
  9. v-for="item in tabOptions"
  10. :key="item.key"
  11. :class="{ active: activeComp == item.key }"
  12. @click="activeComp = item.key"
  13. >
  14. <el-badge
  15. :value="toDoReminder[item.reminder] || 0"
  16. class="item"
  17. v-if="item.reminder"
  18. >
  19. {{ item.name }}
  20. </el-badge>
  21. <span v-else>{{ item.name }}</span>
  22. </li>
  23. </ul>
  24. </div>
  25. </div>
  26. <div class="main" style="padding: 0 10px">
  27. <div v-show="activeComp == 'saleorder'">
  28. <div class="ele-border-lighter form-content" v-loading="loading">
  29. <search-table @search="reload"></search-table>
  30. <el-tabs v-model="activeName" type="card" @tab-click="handleClick">
  31. <el-tab-pane label="全部" name="all"></el-tab-pane>
  32. <el-tab-pane label="待发货" name="700"></el-tab-pane>
  33. <el-tab-pane label="部分发货" name="701"></el-tab-pane>
  34. <el-tab-pane label="全部发货" name="800"></el-tab-pane>
  35. </el-tabs>
  36. <!-- 数据表格 -->
  37. <div v-table-scroll-sync class="table-container">
  38. <ele-pro-table
  39. ref="table"
  40. :columns="columns"
  41. :datasource="datasource"
  42. height="calc(100vh - 400px)"
  43. style="margin-bottom: 10px"
  44. full-height="calc(100vh - 116px)"
  45. tool-class="ele-toolbar-form"
  46. :selection.sync="selection"
  47. :page-size="20"
  48. @columns-change="handleColumnChange"
  49. :cache-key="cacheKeyUrl"
  50. show-summary
  51. :summary-method="getSummaries"
  52. >
  53. <!-- 表头工具栏 -->
  54. <template v-slot:toolbar>
  55. <el-button
  56. size="small"
  57. type="primary"
  58. icon="el-icon-plus"
  59. class="ele-btn-icon"
  60. @click="openEditNew('add', {})"
  61. v-if="$hasPermission('eom:saleorder:save')"
  62. >
  63. 新建
  64. </el-button>
  65. <el-button
  66. size="small"
  67. type="danger"
  68. icon="el-icon-delete"
  69. class="ele-btn-icon"
  70. @click="allDelBtn"
  71. v-if="$hasPermission('eom:saleorder:delete')"
  72. :disabled="selection?.length === 0"
  73. >
  74. 批量删除
  75. </el-button>
  76. <el-button
  77. size="small"
  78. type="primary"
  79. icon="el-icon-plus"
  80. class="ele-btn-icon"
  81. @click="invoiceAll"
  82. v-if="$hasPermission('eom:saleManage:invoiceAll')"
  83. :disabled="selection?.length === 0"
  84. >
  85. 批量发货
  86. </el-button>
  87. <el-button
  88. type="primary"
  89. size="small"
  90. icon="el-icon-upload2"
  91. @click="uploadFile"
  92. v-if="$hasPermission('eom:saleorder:save')"
  93. >导入</el-button
  94. >
  95. <exportButton
  96. btnName="列表导出"
  97. fileName="销售订单"
  98. apiUrl="/eom/saleorder/export"
  99. :params="exportParams"
  100. ></exportButton>
  101. <el-button
  102. v-if="$hasPermission('eom:saleorder:push')"
  103. size="small"
  104. type="primary"
  105. class="ele-btn-icon"
  106. @click="allPushBtn"
  107. :disabled="selection?.length === 0"
  108. >
  109. 批量推送
  110. </el-button>
  111. <el-dropdown
  112. trigger="click"
  113. :disabled="selection?.length === 0"
  114. >
  115. <el-button
  116. type="primary"
  117. class="el-icon-printer"
  118. size="small"
  119. >
  120. 打印<i class="el-icon-arrow-down el-icon--right"></i>
  121. </el-button>
  122. <el-dropdown-menu slot="dropdown">
  123. <el-dropdown-item
  124. v-if="$hasPermission('eom:saleorder:print')"
  125. @click.native="handlePrint"
  126. >打印</el-dropdown-item
  127. >
  128. <el-dropdown-item
  129. v-if="$hasPermission('eom:saleorder:printRt')"
  130. @click.native="handleRtPrint"
  131. >打印(润天)</el-dropdown-item
  132. >
  133. </el-dropdown-menu>
  134. </el-dropdown>
  135. <!-- <el-button
  136. size="small"
  137. type="primary"
  138. class="ele-btn-icon"
  139. @click="handleStockUnlock"
  140. :disabled="selection?.length === 0"
  141. >
  142. 库存解锁
  143. </el-button> -->
  144. </template>
  145. <!-- 查看详情列 -->
  146. <template v-slot:relationCode="{ row }">
  147. <el-link
  148. type="primary"
  149. :underline="false"
  150. @click="openRelationCodeDetail(row)"
  151. >
  152. {{ row.relationCode }}
  153. </el-link>
  154. </template>
  155. <template v-slot:orderNo="{ row }">
  156. <el-link
  157. type="primary"
  158. :underline="false"
  159. @click="openorderDetail(row)"
  160. >
  161. {{ row.orderNo }}
  162. </el-link>
  163. </template>
  164. <!-- 预销售订单编码 -->
  165. <template v-slot:preOrderNo="{ row }">
  166. <el-input
  167. v-model="row.preOrderNo"
  168. @keyup.enter.native="handlePreOrderNoBlur(row)"
  169. style="width: 100%; padding: 0 4px"
  170. placeholder="请输入预销售编码"
  171. ></el-input>
  172. </template>
  173. <!-- 操作列 -->
  174. <template v-slot:action="{ row }">
  175. <el-link
  176. type="primary"
  177. :underline="false"
  178. icon="el-icon-edit"
  179. @click="openEditNew('edit', row)"
  180. v-if="
  181. $hasPermission('eom:saleorder:update') &&
  182. [0, 3].includes(row.orderStatus)
  183. "
  184. >
  185. 修改
  186. </el-link>
  187. <el-link
  188. type="primary"
  189. :underline="false"
  190. icon="el-icon-plus"
  191. @click="saleOrderSubmitOrGenerate(row)"
  192. v-if="
  193. [0, 3].includes(row.orderStatus) &&
  194. $hasPermission('eom:saleorder:update')
  195. "
  196. >
  197. 提交
  198. </el-link>
  199. <!-- <el-link
  200. type="primary"
  201. :underline="false"
  202. icon="el-icon-plus"
  203. @click="handleAutoGenerate(row.id)"
  204. v-if="
  205. [2].includes(row.orderStatus) &&
  206. row.needProduce &&
  207. !!!row.purchasePlanNum
  208. "
  209. >
  210. 生成采购计划
  211. </el-link> -->
  212. <el-popconfirm
  213. class="ele-action"
  214. title="确定要删除此信息吗?"
  215. @confirm="remove([row.id])"
  216. v-if="
  217. [0, 3].includes(row.orderStatus) &&
  218. $hasPermission('eom:saleorder:delete')
  219. "
  220. >
  221. <template v-slot:reference>
  222. <el-link
  223. type="danger"
  224. :underline="false"
  225. icon="el-icon-delete"
  226. >
  227. 删除
  228. </el-link>
  229. </template>
  230. </el-popconfirm>
  231. <el-link
  232. type="primary"
  233. :underline="false"
  234. icon="el-icon-plus"
  235. @click="handleCommand('adjustment', row)"
  236. v-if="row.allowDifference == 1 && $hasPermission('eom:saleorder:adjustment')"
  237. >
  238. 冲差
  239. </el-link>
  240. <el-link
  241. type="primary"
  242. :underline="false"
  243. icon="el-icon-plus"
  244. @click="handleCommand('invoice', row)"
  245. v-if="
  246. [2].includes(row.orderStatus) &&
  247. ((row.saleTypeName.includes('受托') &&
  248. row.isEntrustedReceive == 1) ||
  249. !row.saleTypeName.includes('受托')) &&
  250. $hasPermission('eom:saleordersendrecord:save') &&
  251. ((isTotalCount == '1' &&
  252. row.sendTotalCount < row.productCount) ||
  253. isTotalCount == 0) && row.isLock != 1
  254. "
  255. >
  256. 发货单
  257. </el-link>
  258. <el-link
  259. type="primary"
  260. :underline="false"
  261. icon="el-icon-plus"
  262. @click="handleCommand('entrustedReceive', row)"
  263. v-if="
  264. [2].includes(row.orderStatus) &&
  265. row.saleTypeName.includes('受托') &&
  266. row.isEntrustedReceive != 1
  267. "
  268. >
  269. 受托收货单
  270. </el-link>
  271. <el-link
  272. type="primary"
  273. :underline="false"
  274. icon="el-icon-plus"
  275. @click="handleCommand('saleOrderReminder', row)"
  276. v-if="
  277. [2].includes(row.orderStatus) &&
  278. clientEnvironmentId != 5 &&
  279. row.progress < 800
  280. "
  281. >
  282. 催单
  283. </el-link>
  284. <el-link
  285. type="primary"
  286. :underline="false"
  287. @click="finish('single', row)"
  288. v-if="
  289. [2].includes(row.orderStatus) &&
  290. row.progress != 1000
  291. "
  292. >
  293. 完结
  294. </el-link>
  295. <!-- <el-link
  296. type="primary"
  297. :underline="false"
  298. icon="el-icon-plus"
  299. @click="handleCommand('invoiceManage', row)"
  300. v-if="
  301. [2].includes(row.orderStatus) &&
  302. !row.hasInvoiceApply &&
  303. $hasPermission('eom:fininvoiceapply:save')
  304. "
  305. >
  306. 新增发票
  307. </el-link> -->
  308. </template>
  309. </ele-pro-table>
  310. </div>
  311. </div>
  312. </div>
  313. <keep-alive>
  314. <component
  315. v-if="currentTabComponent"
  316. :is="currentTabComponent"
  317. @getToDoReminder="getToDoReminder"
  318. ></component>
  319. </keep-alive>
  320. </div>
  321. </el-card>
  322. <add-dialog
  323. :isRequired="isRequired"
  324. ref="addDialogRef"
  325. @done="reload"
  326. :contactData="contactData"
  327. ></add-dialog>
  328. <add-dialog-new
  329. :isRequired="isRequired"
  330. ref="addDialogNewRef"
  331. @done="reload"
  332. :contactData="contactData"
  333. ></add-dialog-new>
  334. <add-invoice-dialog
  335. ref="invoiceDialogRef"
  336. @done="reload"
  337. :contactData="contactData"
  338. ></add-invoice-dialog>
  339. <add-return-goods-dialog
  340. ref="addReturnGoodsRef"
  341. :contactData="contactData"
  342. @done="reload"
  343. ></add-return-goods-dialog>
  344. <contractr-detail ref="contractDetailRef"></contractr-detail>
  345. <detail-dialog ref="contactDetailDialogRef"></detail-dialog>
  346. <autogenerate-dialog
  347. ref="autogenerateDialogRef"
  348. @handleSubmit="saleOrderSubmit"
  349. @reload="reload"
  350. ></autogenerate-dialog>
  351. <!-- 多选删除弹窗 -->
  352. <pop-modal
  353. :visible.sync="delVisible"
  354. content="是否确定删除?"
  355. @done="commitBtn"
  356. />
  357. <drawer ref="drawerRef"></drawer>
  358. <process-submit-dialog
  359. :isNotNeedProcess="true"
  360. :processSubmitDialogFlag.sync="processSubmitDialogFlag"
  361. v-if="processSubmitDialogFlag"
  362. :isCloseRefresh="false"
  363. ref="processSubmitDialogRef"
  364. @reload="reload"
  365. :callBack="callBack"
  366. ></process-submit-dialog>
  367. <addInvoiceManage
  368. :add-or-edit-dialog-flag.sync="addOrEditDialogFlag1"
  369. ref="addOrEditDialogRef"
  370. v-if="addOrEditDialogFlag1"
  371. @reload="reload"
  372. ></addInvoiceManage>
  373. <importDialog
  374. ref="importDialogRef"
  375. @success="reload"
  376. :fileUrl="'/eom/saleorder/importTemplate'"
  377. :isWeb="false"
  378. fileName="销售订单导入模板"
  379. apiUrl="/eom/saleorder/importFile"
  380. />
  381. <bomDialog ref="bomDialogRef" :isCloseRefresh="false" @handleSubmit="bomDialogSuccess" @reload="reload"></bomDialog>
  382. <opportunityDetail ref="opportunityDetailRef"></opportunityDetail>
  383. <quotationDetail ref="quotationDetailRef"></quotationDetail>
  384. <addEntrustedReceive
  385. ref="addEntrustedReceiveRef"
  386. @done="reload"
  387. :add-or-edit-dialog-flag.sync="addEntrustedReceiveFlag"
  388. v-if="addEntrustedReceiveFlag"
  389. ></addEntrustedReceive>
  390. <printTemplateSaleOrder
  391. :groupName="groupName"
  392. ref="printTemplateSaleOrderRef"
  393. ></printTemplateSaleOrder>
  394. <printTemplateHt ref="printTemplateHtRef" :groupName="groupName"></printTemplateHt>
  395. <printTemplateRt ref="printTemplateRtRef" :groupName="groupName"></printTemplateRt>
  396. <add-adjust-dialog
  397. v-if="addAdjustDialogFlag"
  398. :addAdjustDialogFlag.sync="addAdjustDialogFlag"
  399. ref="addAdjustDialogRef"
  400. @done="reload"
  401. ></add-adjust-dialog>
  402. </div>
  403. </template>
  404. <script>
  405. import { getSummaries } from '@/utils/util.js';
  406. import searchTable from './components/searchTable.vue';
  407. import addDialog from './components/addDialog.vue';
  408. import addDialogNew from './components/addDialogNew.vue';
  409. import invoice from './invoice/index.vue';
  410. import invoiceConfirm from './invoiceConfirm/index.vue';
  411. import detailDialog from './components/detailDialog.vue';
  412. import exceptionList from './exceptionManagement/exceptionList';
  413. import bomDialog from './components/bomDialog';
  414. import suspend from './suspend/index.vue';
  415. import drawer from './components/drawer.vue';
  416. import contractrDetail from '@/views/contractManage/contractBook/components/detailDialog.vue';
  417. import addInvoiceDialog from '@/views/saleManage/saleOrder/invoice/components/addInvoiceDialog';
  418. import addReturnGoodsDialog from '@/views/saleManage/saleOrder/returnGoods/components/addReturnGoodsDialog';
  419. import popModal from '@/components/pop-modal';
  420. import accountstatement from './accountstatement/index.vue';
  421. import customerReturnOrder from './customerReturnOrder/index.vue';
  422. import returnGoods from './returnGoods/index.vue';
  423. import palletManagement from './palletManagement/index.vue';
  424. import addInvoiceManage from '@/views/financialManage/invoiceManage/components/addOrEditDialog.vue';
  425. import addEntrustedReceive from '@/views/saleManage/saleOrder/entrustedReceive/components/addOrEditDialog';
  426. import adjustmentNote from './adjustmentNote‌/index.vue';
  427. import addAdjustDialog from '@/views/saleManage/saleOrder/adjustmentNote‌/components/addAdjustDialog.vue';
  428. import {
  429. deleteInformation,
  430. getSaleOrderDetail,
  431. getTableList,
  432. saleOrderReminder,
  433. getByRepeatBomAttribute,
  434. saveOrderBomList,
  435. updateOrderInfo,
  436. saleOrderAdd,
  437. batchCompleted
  438. } from '@/api/saleManage/saleorder';
  439. import { getToDoReminder } from '@/api/common/index';
  440. import { exportSaleorder } from '@/api/system/file/index.js';
  441. import dictMixins from '@/mixins/dictMixins';
  442. import { reviewStatus, saleOrderProgressStatusEnum, saleOrderStatusEnum } from '@/enum/dict';
  443. import entrustedReceive from '@/views/saleManage/saleOrder/entrustedReceive/index.vue';
  444. import autogenerateDialog from '@/BIZComponents/autogenerateDialog.vue';
  445. import processSubmitDialog from '@/BIZComponents/processSubmitDialog/processSubmitDialog.vue';
  446. import tabMixins from '@/mixins/tableColumnsMixin';
  447. import importDialog from '@/components/upload/import-dialog.vue';
  448. import exportButton from '@/components/upload/exportButton.vue';
  449. import { parameterGetByCode } from '@/api/main/index.js';
  450. import opportunityDetail from '@/views/saleManage/businessOpportunity/components/opportunityDetailDialog.vue';
  451. import quotationDetail from '@/views/saleManage/quotation/components/detailDialog.vue';
  452. import printTemplateSaleOrder from './components/printTemplateSaleOrder.vue';
  453. import { enterprisePage } from '@/api/contractManage/contractBook';
  454. import { listOrganizations } from '@/api/system/organization';
  455. import printTemplateHt from './components/printTemplateHt.vue';
  456. import printTemplateRt from './components/printTemplateRt.vue';
  457. import stockUnlock from './components/stockUnlock.vue';
  458. export default {
  459. mixins: [dictMixins, tabMixins],
  460. components: {
  461. processSubmitDialog,
  462. autogenerateDialog,
  463. searchTable,
  464. returnGoods,
  465. accountstatement,
  466. popModal,
  467. contractrDetail,
  468. addReturnGoodsDialog,
  469. addInvoiceDialog,
  470. invoice,
  471. addDialog,
  472. detailDialog,
  473. customerReturnOrder,
  474. entrustedReceive,
  475. invoiceConfirm,
  476. drawer,
  477. exceptionList,
  478. addInvoiceManage,
  479. palletManagement,
  480. exportButton,
  481. importDialog,
  482. bomDialog,
  483. opportunityDetail,
  484. quotationDetail,
  485. addEntrustedReceive,
  486. printTemplateSaleOrder,
  487. adjustmentNote,
  488. addAdjustDialog,
  489. suspend,
  490. addDialogNew,
  491. printTemplateHt,
  492. printTemplateRt,
  493. stockUnlock
  494. },
  495. //客户管理数据
  496. props: {
  497. contactData: {
  498. type: Object,
  499. default: () => {
  500. return {};
  501. }
  502. }
  503. },
  504. data() {
  505. return {
  506. activeName: 'all',
  507. activeComp: 'saleorder',
  508. tabOptions: [
  509. { key: 'saleorder', name: '销售订单', reminder: 'salesOrderNum' },
  510. {
  511. key: 'entrustedReceive',
  512. name: '受托收货单',
  513. reminder: 'entrustedReceiptNum'
  514. },
  515. { key: 'invoice', name: '发货单', reminder: 'deliveryNoteNum' },
  516. {
  517. key: 'invoiceConfirm',
  518. name: '发货确认单',
  519. reminder: 'deliveryConfirmationFormNum'
  520. },
  521. { key: 'trayList', name: '托盘清单' },
  522. {
  523. key: 'exceptionList',
  524. name: '异常列表',
  525. reminder: 'exceptionListNum'
  526. },
  527. { key: 'returnorder', name: '退货单', reminder: 'returnOrderNum' },
  528. {
  529. key: 'customerReturnOrder',
  530. name: '退货处理单',
  531. reminder: 'returnProcessingFormNum'
  532. },
  533. {
  534. key: 'accountstatement',
  535. name: '对账单',
  536. reminder: 'statementAccountNum'
  537. },
  538. {
  539. key: 'adjustmentNote',
  540. name: '冲差单',
  541. reminder: 'punchSlipOrderNum'
  542. },
  543. {
  544. key: 'suspend',
  545. name: '挂单',
  546. reminder: 'suspendNum'
  547. },
  548. ],
  549. selection: [], //单选中集合
  550. delVisible: false, //批量删除弹框状态
  551. loading: false, // 加载状态
  552. processSubmitDialogFlag: false, // 加载状态
  553. addOrEditDialogFlag1: false,
  554. addEntrustedReceiveFlag: false,
  555. addAdjustDialogFlag: false, //冲差状态
  556. params: {},
  557. tableList: [],
  558. current: null,
  559. cacheKeyUrl: 'eos-c2e9664a-saleManage-saleOrder',
  560. isRequired: true,
  561. isTotalCount: '0',
  562. columnsVersion: 1,
  563. timeR: null,
  564. toDoReminder: {},
  565. groupName: '',
  566. organizations: []
  567. };
  568. },
  569. created() {
  570. enterprisePage({
  571. pageNum: 1,
  572. size: 200
  573. }).then((res) => {
  574. if (res.list?.length > 0) {
  575. this.groupName = res.list[0].name;
  576. }
  577. });
  578. this.requestDict('客户状态');
  579. parameterGetByCode({
  580. code: 'order_person_info'
  581. }).then((res) => {
  582. if (res.value) {
  583. this.isRequired = res.value === '1';
  584. }
  585. });
  586. //销售发货数量是否限制不能大于采购总数//0否 1是
  587. parameterGetByCode({
  588. code: 'saleOrder_invoice_productList_totalCount'
  589. }).then((res) => {
  590. this.isTotalCount = res.value;
  591. });
  592. this.getToDoReminder();
  593. this.getInfo();
  594. this.timeR = setInterval(() => {
  595. this.getToDoReminder();
  596. }, 60000);
  597. if (this.$route.query.isView) {
  598. this.activeComp = this.$route.query.activeComp;
  599. this.$nextTick(() => {
  600. if (this.activeComp == 'entrustedReceive') {
  601. this.$refs.entrustedReceiveRef.openorderDetail(
  602. {
  603. id: this.$route.query.id
  604. },
  605. 'code'
  606. );
  607. }
  608. const url = new URL(window.location.href);
  609. url.search = ''; // 清空查询参数
  610. window.history.pushState({}, '', url.href);
  611. });
  612. }
  613. // if (!('Notification' in window)) {
  614. // console.log('此浏览器不支持桌面通知');
  615. // } else if (Notification.permission === 'granted') {
  616. // // 如果用户已经授权,直接创建通知
  617. // var notification = new Notification('标题', {
  618. // body: '这是通知的内容。'
  619. // });
  620. // } else if (Notification.permission !== 'denied') {
  621. // // 请求权限
  622. // Notification.requestPermission().then(function (permission) {
  623. // if (permission === 'granted') {
  624. // var notification = new Notification('标题', {
  625. // body: '消息提醒1'
  626. // });
  627. // }
  628. // });
  629. // }
  630. },
  631. beforeDestroy() {
  632. clearInterval(this.timeR);
  633. },
  634. computed: {
  635. // 根据当前页签返回对应的子组件(用于 keep-alive + 单一动态组件,避免多 v-if 兄弟节点导致缓存错乱)
  636. currentTabComponent() {
  637. const map = {
  638. invoice: invoice,
  639. invoiceConfirm: invoiceConfirm,
  640. entrustedReceive: entrustedReceive,
  641. returnorder: returnGoods,
  642. accountstatement: accountstatement,
  643. customerReturnOrder: customerReturnOrder,
  644. exceptionList: exceptionList,
  645. trayList: palletManagement,
  646. adjustmentNote: adjustmentNote,
  647. suspend: suspend
  648. };
  649. return map[this.activeComp] || null;
  650. },
  651. exportParams() {
  652. return {
  653. ...this.params,
  654. orderIds: this.selection.map(item => item.id)
  655. }
  656. },
  657. clientEnvironmentId() {
  658. return this.$store.state.user.info.clientEnvironmentId;
  659. },
  660. columns() {
  661. let columnsVersion = this.columnsVersion;
  662. return [
  663. {
  664. width: 45,
  665. type: 'selection',
  666. columnKey: 'selection',
  667. align: 'center'
  668. },
  669. {
  670. columnKey: 'index',
  671. label: '序号',
  672. type: 'index',
  673. width: 55,
  674. align: 'center',
  675. showOverflowTooltip: true,
  676. fixed: 'left'
  677. },
  678. {
  679. prop: 'orderNo',
  680. label: '订单编码',
  681. align: 'center',
  682. slot: 'orderNo',
  683. showOverflowTooltip: true,
  684. sortable: true,
  685. minWidth: 200,
  686. fixed: 'left'
  687. },
  688. {
  689. prop: 'needProduce',
  690. label: '订单类型',
  691. align: 'center',
  692. showOverflowTooltip: true,
  693. minWidth: 150,
  694. formatter: (_row, _column, cellValue) => {
  695. let businessType =
  696. cellValue == 1
  697. ? '有客户生产性订单'
  698. : cellValue == 2
  699. ? '无客户生产性订单'
  700. : cellValue == 4
  701. ? '不定向订单'
  702. : cellValue == 5
  703. ? '委外订单'
  704. : '库存式订单';
  705. return businessType;
  706. }
  707. },
  708. {
  709. prop: 'preOrderNo',
  710. label: '预销售订单编码',
  711. align: 'center',
  712. slot: 'preOrderNo',
  713. showOverflowTooltip: true,
  714. sortable: true,
  715. minWidth: 200,
  716. fixed: 'left'
  717. },
  718. {
  719. prop: 'createDept',
  720. columnKey: 'createDept',
  721. label: '发起人所属部门',
  722. minWidth: 200,
  723. align: 'center',
  724. showOverflowTooltip: true,
  725. formatter: (_row, _column, cellValue) => {
  726. if (!cellValue) return '';
  727. const matchedDept = this.organizations.find(
  728. (dept) => dept.id === cellValue
  729. );
  730. return matchedDept ? matchedDept.name : '';
  731. }
  732. },
  733. {
  734. prop: 'relationType',
  735. label: '来源类型',
  736. align: 'center',
  737. showOverflowTooltip: true,
  738. minWidth: 150,
  739. formatter: (_row, _column, cellValue) => {
  740. let businessType =
  741. cellValue == 1
  742. ? '商机'
  743. : cellValue == 2
  744. ? '报价'
  745. : cellValue == 3
  746. ? '销售合同'
  747. : cellValue == 4
  748. ? '项目'
  749. : '';
  750. return businessType;
  751. }
  752. },
  753. {
  754. prop: 'relationCode',
  755. label: '来源单据',
  756. align: 'center',
  757. slot: 'relationCode',
  758. showOverflowTooltip: true,
  759. minWidth: 200,
  760. formatter: (_row, _column, cellValue) => {
  761. return _row.relationCode;
  762. }
  763. },
  764. {
  765. prop: 'progress',
  766. label: '订单进度',
  767. align: 'center',
  768. showOverflowTooltip: true,
  769. formatter: (_row, _column, cellValue) => {
  770. return saleOrderProgressStatusEnum.find(
  771. (val) => val.value == _row.progress
  772. )?.label;
  773. },
  774. minWidth: 120
  775. },
  776. // {
  777. // prop: 'deliveryDate',
  778. // label: '交货日期',
  779. // align: 'center',
  780. // showOverflowTooltip: true,
  781. // minWidth: 200
  782. // },
  783. {
  784. prop: 'productNames',
  785. label: '产品名称',
  786. align: 'center',
  787. showOverflowTooltip: true,
  788. minWidth: 140
  789. },
  790. {
  791. prop: 'productCodes',
  792. label: '编码',
  793. align: 'center',
  794. showOverflowTooltip: true,
  795. minWidth: 140
  796. },
  797. {
  798. minWidth: 160,
  799. prop: 'productionCodes',
  800. label: '生产编号',
  801. align: 'center'
  802. },
  803. {
  804. prop: 'batchNos',
  805. label: '批次号',
  806. align: 'center',
  807. showOverflowTooltip: true,
  808. minWidth: 140
  809. },
  810. {
  811. prop: 'productCount',
  812. label: '数量',
  813. align: 'center',
  814. showOverflowTooltip: true,
  815. minWidth: 140
  816. },
  817. {
  818. prop: 'inventoryQuantity',
  819. label: '库存数',
  820. align: 'center',
  821. showOverflowTooltip: true,
  822. minWidth: 140
  823. },
  824. {
  825. prop: 'sendTotalCount',
  826. label: '发货数量',
  827. align: 'center',
  828. showOverflowTooltip: true,
  829. minWidth: 120
  830. },
  831. {
  832. prop: 'outboundTotalCount',
  833. label: '出库数量',
  834. align: 'center',
  835. showOverflowTooltip: true,
  836. minWidth: 140
  837. },
  838. {
  839. prop: 'returnTotalCount',
  840. label: '退货数量',
  841. align: 'center',
  842. showOverflowTooltip: true,
  843. minWidth: 120
  844. },
  845. {
  846. prop: 'inventoryQuantity1',
  847. label: '库存状态',
  848. align: 'center',
  849. showOverflowTooltip: true,
  850. minWidth: 140,
  851. formatter: (_row, _column, cellValue) => {
  852. return _row.inventoryQuantity > 0 ? '有库存' : '无库存';
  853. }
  854. },
  855. {
  856. prop: 'saleTypeName',
  857. label: '销售类型',
  858. align: 'center',
  859. showOverflowTooltip: true,
  860. minWidth: 140
  861. },
  862. {
  863. prop: 'projectName',
  864. label: '项目名称',
  865. align: 'center',
  866. showOverflowTooltip: true,
  867. minWidth: 180
  868. },
  869. {
  870. prop: 'partaName',
  871. label: '客户名称',
  872. align: 'center',
  873. showOverflowTooltip: true,
  874. minWidth: 180
  875. },
  876. {
  877. prop: 'partaLinkName',
  878. label: '客户联系人',
  879. align: 'center',
  880. showOverflowTooltip: true,
  881. minWidth: 130
  882. },
  883. {
  884. prop: 'partaTel',
  885. label: '客户联系电话',
  886. align: 'center',
  887. showOverflowTooltip: true,
  888. minWidth: 130
  889. },
  890. {
  891. prop: 'partbName',
  892. label: '售出方名称',
  893. align: 'center',
  894. showOverflowTooltip: true,
  895. minWidth: 130
  896. },
  897. {
  898. prop: 'partbLinkName',
  899. label: '售出方联系人',
  900. align: 'center',
  901. showOverflowTooltip: true,
  902. minWidth: 130
  903. },
  904. {
  905. prop: 'partbTel',
  906. label: '售出方联系电话',
  907. align: 'center',
  908. showOverflowTooltip: true,
  909. minWidth: 130
  910. },
  911. {
  912. prop: 'payAmount',
  913. label: '金额(元)',
  914. align: 'center',
  915. showOverflowTooltip: true,
  916. minWidth: 170
  917. },
  918. {
  919. prop: 'arrivalWays',
  920. label: '到货方式',
  921. align: 'center',
  922. showOverflowTooltip: true,
  923. minWidth: 170,
  924. formatter: (_row, _column, cellValue) => {
  925. return _row.arrivalWays
  926. ? _row.arrivalWays
  927. .split(',')
  928. .map((val) => {
  929. return val == 1 ? '一次性到货' : val == 2 ? '分批到货' : '';
  930. })
  931. .toString()
  932. : '';
  933. }
  934. },
  935. {
  936. prop: 'externalId',
  937. label: '是否推送',
  938. align: 'center',
  939. showOverflowTooltip: true,
  940. minWidth: 120,
  941. formatter: (_row, _column, cellValue) => {
  942. return _row.preOrderNo? '已推送' : '未推送';
  943. }
  944. },
  945. {
  946. prop: 'orderStatus',
  947. label: '审核状态',
  948. align: 'center',
  949. showOverflowTooltip: true,
  950. minWidth: 100,
  951. formatter: (_row, _column, cellValue) => {
  952. return reviewStatus[_row.orderStatus];
  953. }
  954. },
  955. {
  956. prop: 'salesmanName',
  957. label: '业务员',
  958. align: 'center',
  959. showOverflowTooltip: true,
  960. minWidth: 80
  961. },
  962. {
  963. prop: 'createUserName',
  964. label: '创建人',
  965. align: 'center',
  966. showOverflowTooltip: true,
  967. minWidth: 80
  968. },
  969. {
  970. prop: 'createTime',
  971. label: '创建时间',
  972. align: 'center',
  973. showOverflowTooltip: true,
  974. minWidth: 170
  975. },
  976. {
  977. prop: 'reviewTime',
  978. label: '审核时间',
  979. align: 'center',
  980. showOverflowTooltip: true,
  981. minWidth: 170
  982. },
  983. {
  984. columnKey: 'action',
  985. label: '操作',
  986. width: 280,
  987. align: 'center',
  988. resizable: false,
  989. slot: 'action',
  990. showOverflowTooltip: true,
  991. fixed: 'right'
  992. }
  993. ];
  994. }
  995. },
  996. watch: {
  997. // 切回销售订单主列表时,保持搜索条件与页码不变,仅刷新列表数据
  998. activeComp(val) {
  999. if (val === 'saleorder') {
  1000. this.$nextTick(() => {
  1001. if (this.$refs.table) {
  1002. this.$refs.table.reload();
  1003. if (this.$refs.table.doLayout) this.$refs.table.doLayout();
  1004. }
  1005. });
  1006. }
  1007. }
  1008. },
  1009. methods: {
  1010. handleStockUnlock() {
  1011. console.log('库存解锁', this.selection);
  1012. },
  1013. getSummaries(param) {
  1014. return getSummaries(
  1015. param,
  1016. ['productCount', 'sendTotalCount', 'outboundTotalCount', 'payAmount'],
  1017. ' '
  1018. );
  1019. },
  1020. async getInfo() {
  1021. try {
  1022. const res = await listOrganizations(); // 假设接口直接返回部门数组(如用户提供的示例数据)
  1023. this.organizations = res; // 存储部门列表到状态中
  1024. console.log('部门列表加载完成:', this.organizations);
  1025. } catch (err) {
  1026. console.error('加载部门列表失败:', err);
  1027. this.organizations = []; // 异常时置空,避免匹配错误
  1028. }
  1029. },
  1030. getToDoReminder() {
  1031. getToDoReminder().then((res) => {
  1032. this.toDoReminder = res;
  1033. });
  1034. },
  1035. // 预销售编码输入框失焦回车事件
  1036. handlePreOrderNoBlur(row) {
  1037. updateOrderInfo({
  1038. preOrderNo: row.preOrderNo
  1039. })
  1040. .then((res) => {
  1041. console.log(res);
  1042. this.$message.success('预销售编码更新成功');
  1043. })
  1044. .catch((err) => {});
  1045. },
  1046. finish(type, row) {
  1047. if (type == 'single') {
  1048. batchCompleted([row.id]).then((res) => {
  1049. this.$message.success(res.message);
  1050. this.reload();
  1051. }).catch((err) => {});
  1052. }
  1053. },
  1054. //更多菜单
  1055. handleCommand(command, row) {
  1056. if (command === 'invoice') {
  1057. this.$refs.invoiceDialogRef.open('add', {}, [row.id]);
  1058. }
  1059. if (command === 'entrustedReceive') {
  1060. this.addEntrustedReceiveFlag = true;
  1061. this.$nextTick(() => {
  1062. this.$refs.addEntrustedReceiveRef.open('add', {}, row.id);
  1063. });
  1064. }
  1065. if (command === 'returnOrder') {
  1066. this.$refs.addReturnGoodsRef.open('add', {});
  1067. }
  1068. if (command === 'saleOrderReminder') {
  1069. saleOrderReminder(row.id).then((res) => {
  1070. this.$message.success('催单成功');
  1071. });
  1072. }
  1073. if (command === 'invoiceManage') {
  1074. this.addOrEditDialogFlag1 = true;
  1075. this.$nextTick(() => {
  1076. this.$refs.addOrEditDialogRef.createInvoice1(row, 1, 3);
  1077. });
  1078. }
  1079. // 冲差
  1080. if (command === 'adjustment') {
  1081. console.log(row);
  1082. this.addAdjustDialogFlag = true;
  1083. this.$nextTick(() => {
  1084. this.$refs.addAdjustDialogRef.open('add', row);
  1085. });
  1086. }
  1087. },
  1088. allPushBtn() {
  1089. const dataId = this.selection.map((v) => v.id);
  1090. saleOrderAdd(dataId).then((res) => {
  1091. this.$message.success('推送成功!');
  1092. this.reload();
  1093. });
  1094. },
  1095. invoiceAll() {
  1096. let partaIds = this.selection.map((item) => item.partaId);
  1097. if (new Set(partaIds).size != 1) {
  1098. return this.$message.warning('请选择相同客户的订单!');
  1099. }
  1100. let saleTypeS = this.selection.map((item) => item.saleType);
  1101. if (new Set(saleTypeS).size != 1) {
  1102. return this.$message.warning('请选择相同销售类型的订单!');
  1103. }
  1104. let processObj = this.selection.filter((item) => item.progress == 800);
  1105. if (processObj?.length && this.isTotalCount == '1') {
  1106. return this.$message.warning(
  1107. '订单' +
  1108. processObj.map((item) => item.orderNo).toString() +
  1109. '已全部发货,不能创建发货单'
  1110. );
  1111. }
  1112. if(!this.selection.every((item) => item.isLock == 0 && item.needProduce == 1)){
  1113. return this.$message.warning('生产性订单未入库前不允许发货');
  1114. }
  1115. if (
  1116. this.selection.filter((item) => item.needProduce == 4)?.length &&
  1117. this.selection.filter((item) => item.needProduce == 4)?.length !=
  1118. this.selection.length
  1119. ) {
  1120. return this.$message.warning(
  1121. '不定向订单不能与其它类型的订单一起创建发货单!'
  1122. );
  1123. }
  1124. this.$refs.invoiceDialogRef.open(
  1125. 'add',
  1126. {},
  1127. this.selection.map((item) => item.id)
  1128. );
  1129. },
  1130. //点击左边分类
  1131. handleNodeClick(data, node) {
  1132. // this.curNodeData = data;
  1133. this.reload({ categoryId: data.id });
  1134. },
  1135. /* 表格数据源 */
  1136. datasource({ page, limit, where, order }) {
  1137. console.log('where~~~', where);
  1138. if(where?.needProduces?.length){
  1139. where['needProduces'] = where.needProduces.join(',');
  1140. }
  1141. if (this.contactData.id) {
  1142. where['contactId'] = this.contactData.id;
  1143. }
  1144. // 构建进度列表参数
  1145. const progressList = [];
  1146. // 添加标签页进度筛选(如果不是'all'标签)
  1147. if (this.activeName !== 'all') {
  1148. progressList.push(this.activeName);
  1149. }
  1150. // 添加搜索条件中的进度筛选
  1151. if (where?.progress) {
  1152. progressList.push(where.progress);
  1153. }
  1154. // 构建请求参数
  1155. this.params = {
  1156. pageNum: page,
  1157. size: limit,
  1158. ...where
  1159. };
  1160. delete this.params.progress;
  1161. // 仅当进度列表有值时添加到请求参数
  1162. if (progressList.length > 0) {
  1163. this.params.progressList = progressList.join(',');
  1164. }
  1165. return getTableList(this.params);
  1166. },
  1167. /* 刷新表格 */
  1168. reload(where) {
  1169. this.$refs.table.reload({ page: 1, where });
  1170. this.getToDoReminder();
  1171. },
  1172. handleClick() {
  1173. this.$refs.table.reload({
  1174. page: 1,
  1175. // where: { progress: this.activeName == 'all' ? '' : this.activeName }
  1176. });
  1177. },
  1178. //新增编辑
  1179. openEdit(type, row) {
  1180. this.$refs.addDialogRef.open(type, row, row.id);
  1181. this.$refs.addDialogRef.$refs.form &&
  1182. this.$refs.addDialogRef.$refs.form.clearValidate();
  1183. },
  1184. //新增编辑新
  1185. openEditNew(type, row) {
  1186. this.$refs.addDialogNewRef.open(type, row, row.id);
  1187. this.$refs.addDialogNewRef.$refs.form &&
  1188. this.$refs.addDialogNewRef.$refs.form.clearValidate();
  1189. },
  1190. //批量删除
  1191. allDelBtn() {
  1192. if (this.selection.length === 0) return;
  1193. let flag = this.selection.some((item) =>
  1194. [1, 2].includes(item.orderStatus)
  1195. );
  1196. if (flag)
  1197. return this.$message.warning('抱歉已审核、审核中的数据不能删除,请检查');
  1198. this.delVisible = true;
  1199. },
  1200. //删除接口
  1201. remove(delData) {
  1202. deleteInformation(delData).then((res) => {
  1203. this.$message.success('删除成功!');
  1204. this.reload();
  1205. });
  1206. },
  1207. //删除弹框确定
  1208. commitBtn() {
  1209. const dataId = this.selection.map((v) => v.id);
  1210. this.remove(dataId);
  1211. },
  1212. //查看详情
  1213. openorderDetail(row) {
  1214. this.$refs.drawerRef.open(row);
  1215. },
  1216. async saleOrderSubmit(id) {
  1217. this.$refs.addDialogRef && this.$refs.addDialogRef.cancel();
  1218. // const data = await getSaleOrderDetail(id);
  1219. this.processSubmitDialogFlag = true;
  1220. let businessType =
  1221. this.current.needProduce == 1
  1222. ? '有客户生产性订单'
  1223. : this.current.needProduce == 2
  1224. ? '无客户生产性订单'
  1225. : this.current.needProduce == 4
  1226. ? '不定向订单'
  1227. : '库存式订单';
  1228. this.$nextTick(() => {
  1229. let params = {
  1230. businessId: this.current.id,
  1231. businessKey: 'sales_order_approve',
  1232. formCreateUserId: this.current.createUserId,
  1233. variables: {
  1234. businessCode: this.current.orderNo,
  1235. businessName: this.current.partaName,
  1236. businessType: businessType
  1237. }
  1238. };
  1239. this.$refs.processSubmitDialogRef.init(params);
  1240. });
  1241. },
  1242. async callBack() {
  1243. if (!this.current.generatePurchase && !this.current.generateProduce) {
  1244. return 0;
  1245. }
  1246. const code = saveOrderBomList({
  1247. categoryDTOList: this.tableList || [],
  1248. orderId: this.current.id
  1249. });
  1250. return code;
  1251. },
  1252. async saleOrderSubmitOrGenerate(res) {
  1253. this.tableList = [];
  1254. this.current = await getSaleOrderDetail(res.id);
  1255. if (!this.current.generatePurchase && !this.current.generateProduce) {
  1256. this.saleOrderSubmit(res.id);
  1257. } else {
  1258. const data = await getByRepeatBomAttribute(res.id);
  1259. if (data && data.length) {
  1260. this.$refs.bomDialogRef.open(data);
  1261. return;
  1262. }
  1263. this.saleOrderSubmit(res.id);
  1264. }
  1265. },
  1266. bomDialogSuccess(tableList) {
  1267. this.tableList = tableList;
  1268. // this.callBack()
  1269. this.saleOrderSubmit(this.current.id);
  1270. },
  1271. //生成
  1272. handleAutoGenerate(id, isAuto = false) {
  1273. this.$refs.autogenerateDialogRef.init(id, isAuto);
  1274. },
  1275. //查看来源详情
  1276. openRelationCodeDetail(row) {
  1277. let data = {
  1278. id: row.relationId
  1279. };
  1280. if (row.relationType == 1) {
  1281. this.$refs.opportunityDetailRef.open(data);
  1282. }
  1283. if (row.relationType == 2) {
  1284. this.$refs.quotationDetailRef.open(data);
  1285. }
  1286. if (row.relationType == 3) {
  1287. this.$refs.contractDetailRef.open(data);
  1288. }
  1289. },
  1290. uploadFile() {
  1291. this.$refs.importDialogRef.open();
  1292. },
  1293. exportFn() {
  1294. console.log(this.params);
  1295. exportSaleorder(this.params);
  1296. },
  1297. handlePrint() {
  1298. console.log(this.selection[0]);
  1299. // if (this.selection.length > 1) return this.$message.warning('请选择一条');
  1300. this.$refs.printTemplateHtRef.open(this.selection.map((v) => v.id));
  1301. },
  1302. handleRtPrint() {
  1303. this.$refs.printTemplateRtRef.open(this.selection.map((v) => v.id));
  1304. }
  1305. }
  1306. };
  1307. </script>
  1308. <style lang="scss" scoped>
  1309. :deep .el-card__body {
  1310. padding: 0;
  1311. }
  1312. :deep(.el-link--inner) {
  1313. margin-left: 0px !important;
  1314. }
  1315. .sys-organization-list {
  1316. height: calc(100vh - 264px);
  1317. box-sizing: border-box;
  1318. border-width: 1px;
  1319. border-style: solid;
  1320. overflow: auto;
  1321. }
  1322. .sys-organization-list :deep(.el-tree-node__content) {
  1323. height: 40px;
  1324. & > .el-tree-node__expand-icon {
  1325. margin-left: 10px;
  1326. }
  1327. }
  1328. .el-dropdown-link {
  1329. cursor: pointer;
  1330. color: var(--color-primary-5);
  1331. }
  1332. .el-icon-arrow-down {
  1333. font-size: 12px;
  1334. }
  1335. :deep(.el-badge__content.is-fixed) {
  1336. top: 4px;
  1337. }
  1338. /* 优化输入框在表格中的样式 */
  1339. :deep(.el-table .el-input__inner) {
  1340. border-radius: 4px;
  1341. height: 28px;
  1342. line-height: 28px;
  1343. }
  1344. :deep(.el-table .el-input) {
  1345. margin: 0;
  1346. }
  1347. </style>