index.vue 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567
  1. <template>
  2. <div class="ele-body">
  3. <el-card shadow="never" v-loading="loading">
  4. <div class="ele-border-lighter form-content" v-loading="loading">
  5. <search-quotation @search="reload"></search-quotation>
  6. <!-- 数据表格 -->
  7. <ele-pro-table
  8. ref="table"
  9. :columns="columns"
  10. :datasource="datasource"
  11. height="calc(100vh - 375px)"
  12. full-height="calc(100vh - 116px)"
  13. tool-class="ele-toolbar-form"
  14. :selection.sync="selection"
  15. :page-size="20"
  16. @columns-change="handleColumnChange"
  17. :cache-key="cacheKeyUrl"
  18. >
  19. <!-- 表头工具栏 -->
  20. <template v-slot:toolbar>
  21. <el-button
  22. size="small"
  23. type="primary"
  24. icon="el-icon-plus"
  25. class="ele-btn-icon"
  26. @click="openEdit('add', {})"
  27. v-if="contactData?.contactStatus==1"
  28. >
  29. 新建
  30. </el-button>
  31. <el-button
  32. size="small"
  33. type="danger"
  34. el-icon-delete
  35. class="ele-btn-icon"
  36. @click="allDelBtn"
  37. :disabled="selection?.length === 0"
  38. >
  39. 批量删除
  40. </el-button>
  41. </template>
  42. <!-- 查看详情列 -->
  43. <template v-slot:contactName="{ row }">
  44. <el-link type="primary" :underline="false" @click="openDetail(row)">
  45. {{ row.contactName }}
  46. </el-link>
  47. </template>
  48. <!-- 附件 -->
  49. <template v-slot:askFile="{ row }">
  50. <fileMain
  51. type="view"
  52. v-model="row.askFile"
  53. v-if="row.askFile?.length"
  54. ></fileMain>
  55. </template>
  56. <!-- 操作列 -->
  57. <template v-slot:action="{ row }">
  58. <el-link
  59. type="primary"
  60. :underline="false"
  61. icon="el-icon-edit"
  62. v-if="
  63. (isNeed_process_is_close && [0, 3].includes(row.status)) ||
  64. !isNeed_process_is_close
  65. "
  66. @click="openEdit('edit', row)"
  67. >
  68. 修改
  69. </el-link>
  70. <el-link
  71. type="primary"
  72. :underline="false"
  73. icon="el-icon-plus"
  74. v-if="isNeed_process_is_close && [0, 3].includes(row.status)"
  75. @click="quotationSubmit(row)"
  76. >
  77. 提交
  78. </el-link>
  79. <el-link
  80. type="primary"
  81. :underline="false"
  82. icon="el-icon-plus"
  83. v-if="[2].includes(row.status) && [1].includes(row.dataStatus)"
  84. @click="addGenerateContract(row)"
  85. >
  86. 生成合同
  87. </el-link>
  88. <el-link
  89. type="danger"
  90. :underline="false"
  91. v-if="[2].includes(row.status) && [1].includes(row.dataStatus)"
  92. @click="setQuoteStatus(row)"
  93. >
  94. 终止
  95. </el-link>
  96. <el-popconfirm
  97. class="ele-action"
  98. title="确定要删除此信息吗?"
  99. @confirm="remove([row.id])"
  100. >
  101. <template v-slot:reference>
  102. <el-link
  103. type="danger"
  104. :underline="false"
  105. icon="el-icon-delete"
  106. v-if="
  107. (isNeed_process_is_close && [0, 3].includes(row.status)) ||
  108. !isNeed_process_is_close
  109. "
  110. >
  111. 删除
  112. </el-link>
  113. </template>
  114. </el-popconfirm>
  115. </template>
  116. </ele-pro-table>
  117. </div>
  118. </el-card>
  119. <add-dialog
  120. ref="addDialogRef"
  121. @done="reload"
  122. :contactData="contactData"
  123. :businessOpportunityData="businessOpportunityData"
  124. ></add-dialog>
  125. <detail-dialog ref="contactDetailDialogRef"></detail-dialog>
  126. <!-- 多选删除弹窗 -->
  127. <pop-modal
  128. :visible.sync="delVisible"
  129. content="是否确定删除?"
  130. @done="commitBtn"
  131. />
  132. <addContractBookDialog
  133. ref="addContractBookDialogRef"
  134. :categoryTreeList="treeList"
  135. :contactData="contactData"
  136. :businessOpportunityData="businessOpportunityData"
  137. ></addContractBookDialog>
  138. <process-submit-dialog
  139. api-fun-name="quoteUpdateStatusAPI"
  140. :processSubmitDialogFlag.sync="processSubmitDialogFlag"
  141. v-if="processSubmitDialogFlag"
  142. ref="processSubmitDialogRef"
  143. @reload="reload"
  144. ></process-submit-dialog>
  145. </div>
  146. </template>
  147. <script>
  148. import searchQuotation from './components/searchQuotation.vue';
  149. import addDialog from './components/addDialog.vue';
  150. import detailDialog from './components/detailDialog.vue';
  151. import popModal from '@/components/pop-modal';
  152. import { reviewStatus } from '@/enum/dict';
  153. import addContractBookDialog from '@/views/contractManage/contractBook/components/addDialog.vue';
  154. import { contactTypeTree, contactDetail } from '@/api/saleManage/contact';
  155. import fileMain from '@/components/addDoc/index.vue';
  156. import {
  157. getTableList,
  158. getDetail,
  159. deleteInformation,
  160. submit,
  161. quoteUpdateStatus
  162. } from '@/api/saleManage/quotation';
  163. import dictMixins from '@/mixins/dictMixins';
  164. import processSubmitDialog from '@/BIZComponents/processSubmitDialog/processSubmitDialog.vue';
  165. import tabMixins from '@/mixins/tableColumnsMixin';
  166. export default {
  167. mixins: [dictMixins, tabMixins],
  168. components: {
  169. processSubmitDialog,
  170. searchQuotation,
  171. popModal,
  172. addDialog,
  173. detailDialog,
  174. addContractBookDialog,
  175. fileMain
  176. },
  177. props: {
  178. contactData: {
  179. default: () => {
  180. return {};
  181. }
  182. },
  183. businessOpportunityData: {
  184. //商机
  185. default: () => {
  186. return {};
  187. }
  188. }
  189. },
  190. data() {
  191. return {
  192. selection: [], //单选中集合
  193. delVisible: false, //批量删除弹框状态
  194. loading: false, // 加载状态
  195. processSubmitDialogFlag: false,
  196. treeList: [],
  197. columns: [
  198. {
  199. width: 45,
  200. type: 'selection',
  201. columnKey: 'selection',
  202. align: 'center'
  203. },
  204. {
  205. columnKey: 'index',
  206. label: '序号',
  207. type: 'index',
  208. width: 55,
  209. align: 'center',
  210. showOverflowTooltip: true,
  211. fixed: 'left'
  212. },
  213. {
  214. prop: 'code',
  215. label: '编码',
  216. align: 'center',
  217. showOverflowTooltip: true,
  218. minWidth: 200
  219. },
  220. {
  221. prop: 'contactName',
  222. label: '询价方名称',
  223. align: 'center',
  224. slot: 'contactName',
  225. showOverflowTooltip: true,
  226. minWidth: 200
  227. },
  228. {
  229. prop: 'contactLinkName',
  230. label: '询价方联系人',
  231. align: 'center',
  232. showOverflowTooltip: true,
  233. minWidth: 140
  234. },
  235. {
  236. prop: 'contactTel',
  237. label: '询价方联系电话',
  238. align: 'center',
  239. showOverflowTooltip: true,
  240. minWidth: 140
  241. },
  242. {
  243. prop: 'productNames',
  244. label: '产品名称',
  245. align: 'center',
  246. showOverflowTooltip: true,
  247. minWidth: 140
  248. },
  249. {
  250. prop: 'quoteName',
  251. label: '报价方名称',
  252. align: 'center',
  253. showOverflowTooltip: true,
  254. minWidth: 200
  255. },
  256. {
  257. prop: 'quoteLinkName',
  258. label: '报价方联系人',
  259. align: 'center',
  260. showOverflowTooltip: true,
  261. minWidth: 140
  262. },
  263. {
  264. prop: 'quoteTel',
  265. label: '报价方联系电话',
  266. align: 'center',
  267. showOverflowTooltip: true,
  268. minWidth: 140
  269. },
  270. {
  271. prop: 'deliveryDate',
  272. label: '交货日期',
  273. align: 'center',
  274. showOverflowTooltip: true,
  275. minWidth: 100
  276. },
  277. {
  278. prop: 'settlementModeName',
  279. label: '付款方式',
  280. align: 'center',
  281. showOverflowTooltip: true,
  282. minWidth: 100
  283. },
  284. // {
  285. // prop: 'taxRate',
  286. // label: '税率',
  287. // align: 'center',
  288. // showOverflowTooltip: true,
  289. // minWidth: 140,
  290. // formatter: (_row, _column, cellValue) => {
  291. // return _row.taxRate ? _row.taxRate + '%' : '';
  292. // }
  293. // },
  294. {
  295. prop: 'totalPrice',
  296. label: '总金额',
  297. align: 'center',
  298. showOverflowTooltip: true,
  299. minWidth: 100
  300. },
  301. {
  302. prop: 'askFile',
  303. label: '附件',
  304. align: 'center',
  305. showOverflowTooltip: true,
  306. slot: 'askFile',
  307. minWidth: 130
  308. },
  309. {
  310. prop: 'dataStatus',
  311. label: '启用状态',
  312. align: 'center',
  313. showOverflowTooltip: true,
  314. minWidth: 100,
  315. formatter: (_row, _column, cellValue) => {
  316. return _row.dataStatus === 1 ? '正常' : '终止';
  317. }
  318. },
  319. {
  320. prop: 'status',
  321. label: '审核状态',
  322. align: 'center',
  323. showOverflowTooltip: true,
  324. minWidth: 100,
  325. formatter: (_row, _column, cellValue) => {
  326. return reviewStatus[_row.status];
  327. }
  328. },
  329. {
  330. prop: 'createUserName',
  331. label: '创建人',
  332. align: 'center',
  333. showOverflowTooltip: true,
  334. minWidth: 80
  335. },
  336. {
  337. prop: 'createTime',
  338. label: '创建时间',
  339. align: 'center',
  340. showOverflowTooltip: true,
  341. minWidth: 170,
  342. formatter: (_row, _column, cellValue) => {
  343. return this.$util.toDateString(cellValue);
  344. }
  345. },
  346. {
  347. columnKey: 'action',
  348. label: '操作',
  349. width: 230,
  350. align: 'center',
  351. resizable: false,
  352. slot: 'action',
  353. showOverflowTooltip: true,
  354. fixed: 'right'
  355. }
  356. ],
  357. cacheKeyUrl: 'eos-5569a1b1-saleManage-quotation'
  358. };
  359. },
  360. computed: {},
  361. created() {
  362. this.requestDict('客户状态');
  363. this.getTreeData();
  364. },
  365. methods: {
  366. quoteUpdateStatus,
  367. /* 表格数据源 */
  368. datasource({ page, limit, where, order }) {
  369. if (this.contactData.id) {
  370. where['contactId'] = this.contactData.id;
  371. }
  372. if (this.businessOpportunityData.id) {
  373. where['opportunityId'] = this.businessOpportunityData.id;
  374. }
  375. return getTableList({
  376. pageNum: page,
  377. size: limit,
  378. ...where
  379. });
  380. },
  381. //获取合同分类
  382. async getTreeData() {
  383. try {
  384. this.treeLoading = true;
  385. const res = await contactTypeTree({ id: '20' });
  386. this.treeLoading = false;
  387. if (res?.code === '0') {
  388. this.treeList = res.data;
  389. return this.treeList;
  390. }
  391. } catch (error) {}
  392. this.treeLoading = false;
  393. },
  394. /* 刷新表格 */
  395. reload(where) {
  396. this.$refs.table.reload({ page: 1, where });
  397. },
  398. //新增编辑
  399. openEdit(type, row) {
  400. this.$refs.addDialogRef.open(type, row, row.id);
  401. this.$refs.addDialogRef.$refs.form &&
  402. this.$refs.addDialogRef.$refs.form.clearValidate();
  403. },
  404. //批量删除
  405. allDelBtn() {
  406. if (this.selection.length === 0) return;
  407. let flag = this.selection.some((item) => [1, 2].includes(item.status));
  408. if (flag)
  409. return this.$message.warning(
  410. '抱歉已审核、审核中的数据不能删除,请检查'
  411. );
  412. this.delVisible = true;
  413. },
  414. //删除接口
  415. remove(delData) {
  416. deleteInformation(delData).then((res) => {
  417. this.$message.success('删除成功!');
  418. this.reload();
  419. });
  420. },
  421. //删除弹框确定
  422. commitBtn() {
  423. const dataId = this.selection.map((v) => v.id);
  424. this.remove(dataId);
  425. },
  426. async setQuoteStatus(row) {
  427. await quoteUpdateStatus({ id: row.id, status: 2 });
  428. this.$message.success('操作成功!');
  429. this.reload();
  430. },
  431. //新增合同
  432. async addGenerateContract(row) {
  433. //获取详情
  434. const data = await getDetail(row.id);
  435. const contact = await contactDetail(data.contactId);
  436. let obj = {
  437. contractVO: {
  438. categoryId: '',
  439. categoryName: '',
  440. contractEndDate: '',
  441. contractFile: [],
  442. contractNo: '',
  443. contractNumber: '',
  444. contractStartDate: '',
  445. createDept: '',
  446. createTime: '',
  447. createUsername: '',
  448. discountTotalPrice: '',
  449. enabled: '',
  450. id: '',
  451. opportunityId: '',
  452. partaAddress: data.contactAddress,
  453. partaEmail: data.contactEmail,
  454. partaFax: data.contactFax,
  455. partaId: data.contactId,
  456. partaLinkId: data.contactLinkId,
  457. partaLinkName: data.contactLinkName,
  458. partaName: data.contactName,
  459. partaTel: data.contactTel,
  460. partaUnifiedSocialCreditCode: '',
  461. partbAddress: data.quoteAddress,
  462. partbEmail: data.quoteEmail,
  463. partbFax: data.quoteFax,
  464. partbId: data.quoteCompanyId,
  465. partbLinkId: data.quoteLinkId,
  466. partbLinkName: data.quoteLinkName,
  467. partbName: data.quoteName,
  468. partbTel: data.quoteTel,
  469. partbUnifiedSocialCreditCode: '',
  470. receiptPaymentType: '',
  471. reviewerId: '',
  472. reviewerName: '',
  473. reviewerTime: '',
  474. sourceId: row.id,
  475. sourceType: 1,
  476. sourceName: data.code,
  477. status: '',
  478. totalPrice: data.totalPrice,
  479. type: '1',
  480. typeName: '销售合同',
  481. updateUsername: '',
  482. sourceCode: row.code,
  483. contractName: contact.base.simpleName,
  484. settlementModeName: data.settlementModeName,
  485. settlementMode: data.settlementMode
  486. },
  487. receiptPaymentList: [],
  488. productList: data.quoteProductList
  489. };
  490. // return;
  491. this.$refs.addContractBookDialogRef.open('add', obj, true, 'quotation');
  492. },
  493. //查看详情
  494. openDetail(row) {
  495. this.$refs.contactDetailDialogRef.open(row);
  496. },
  497. quotationSubmit(res) {
  498. this.processSubmitDialogFlag = true;
  499. this.$nextTick(() => {
  500. let params = {
  501. businessId: res.id,
  502. businessKey: 'quote_approve',
  503. formCreateUserId: res.createUserId,
  504. variables: {
  505. businessCode: res.code,
  506. businessName: res.contactName,
  507. businessType: '报价单'
  508. }
  509. // callBackMethodType : '1',
  510. // callBackMethod : 'proTargetPlanApproveApiImpl.updatePlanApprovalStatus',
  511. // pcHandle : '/bpm/handleTask/components/project-manage/plan-manage/submit.vue',
  512. // pcView : '/bpm/handleTask/components/project-manage/plan-manage/detailDialog.vue',
  513. // miniHandle : '',
  514. // miniView : '',
  515. };
  516. this.$refs.processSubmitDialogRef.init(params);
  517. });
  518. // submit({
  519. // businessId: res.id
  520. // }).then((res) => {
  521. // this.$message.success('提交成功!');
  522. // this.reload();
  523. // });
  524. }
  525. }
  526. };
  527. </script>
  528. <style lang="scss" scoped>
  529. :deep(.el-link--inner) {
  530. margin-left: 0px !important;
  531. }
  532. .sys-organization-list {
  533. height: calc(100vh - 264px);
  534. box-sizing: border-box;
  535. border-width: 1px;
  536. border-style: solid;
  537. overflow: auto;
  538. }
  539. .sys-organization-list :deep(.el-tree-node__content) {
  540. height: 40px;
  541. & > .el-tree-node__expand-icon {
  542. margin-left: 10px;
  543. }
  544. }
  545. </style>