index.vue 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768
  1. <template>
  2. <div class="relation pagePadding">
  3. <!--新建 编辑 详情 审核 -->
  4. <add-view
  5. :id="modelId"
  6. :showModel="showModel"
  7. :is-detail="isDetail"
  8. :newTime="newTime"
  9. @refresh="(showModel = false), searchList()"
  10. @cancel="showModel = false"
  11. />
  12. <ex-table
  13. v-loading="loading"
  14. v-if="powers && powers.length > 0 && powers.some((item) => item == '001')"
  15. :table="table"
  16. :data="tableData"
  17. :columns="columns"
  18. :page="pageInfo"
  19. :size="size"
  20. @page-curr-change="handlePageChange"
  21. @page-size-change="handleSizeChange"
  22. @screen-reset="
  23. pageInfo.curr = 1;
  24. parmValue.page = 1;
  25. searchList();
  26. "
  27. @screen-submit="
  28. pageInfo.curr = 1;
  29. parmValue.page = 1;
  30. searchList();
  31. "
  32. >
  33. <template #table-header="{ selection }">
  34. <div style="width: 100%">
  35. <el-row :gutter="10" style="padding: 0 0 10px 80px">
  36. <el-col :span="7" style="width: 180px">
  37. <el-select
  38. style="width: 100%"
  39. :size="searchSize"
  40. v-model="parmValue.type"
  41. clearable
  42. @change="
  43. pageInfo.curr = 1;
  44. parmValue.page = 1;
  45. searchList();
  46. "
  47. placeholder="关联类型"
  48. >
  49. <el-option
  50. v-for="item in RQList"
  51. :key="item.code"
  52. :label="item.name"
  53. :value="item.code"
  54. >
  55. </el-option>
  56. </el-select>
  57. </el-col>
  58. <el-col :span="7" style="width: 170px">
  59. <el-select
  60. style="width: 100%"
  61. :size="searchSize"
  62. v-model="parmValue.status"
  63. clearable
  64. @change="
  65. pageInfo.curr = 1;
  66. parmValue.page = 1;
  67. searchList();
  68. "
  69. placeholder="关联状态"
  70. >
  71. <el-option
  72. v-for="item in relationType"
  73. :key="item.code"
  74. :label="item.name"
  75. :value="item.code"
  76. >
  77. </el-option>
  78. </el-select>
  79. </el-col>
  80. <el-col :span="6" style="width: 320px">
  81. <period-date-picker
  82. :start="parmValue.start"
  83. :end="parmValue.end"
  84. :type="1"
  85. :width="'144px'"
  86. :size="searchSize"
  87. @timeReturned="timeReturned($event)"
  88. />
  89. </el-col>
  90. <el-col :span="4" style="width: 66px" class="fr">
  91. <el-button
  92. v-if="powers.some((item) => item == '002')"
  93. :size="searchSize"
  94. type="primary"
  95. class="fr"
  96. @click="searchList"
  97. >
  98. 刷新
  99. </el-button>
  100. </el-col>
  101. <el-col :span="4" style="width: 66px" class="fr">
  102. <el-button
  103. type="warning"
  104. v-if="powers.some((item) => item == '024')"
  105. :size="searchSize"
  106. @click="restSearch"
  107. >
  108. 重置
  109. </el-button>
  110. </el-col>
  111. <el-col :span="4" style="width: 56px" class="fr">
  112. <el-button
  113. :size="searchSize"
  114. type="primary"
  115. icon="el-icon-search"
  116. @click="searchList"
  117. />
  118. </el-col>
  119. </el-row>
  120. <el-row :gutter="10">
  121. <el-col :span="6" style="width: 430px">
  122. <el-select
  123. v-model="code"
  124. multiple
  125. filterable
  126. :size="searchSize"
  127. remote
  128. style="width: 100%"
  129. :multiple-limit="1"
  130. reserve-keyword
  131. placeholder="请输入公司名称"
  132. :remote-method="remoteMethod"
  133. :loading="selectLoading"
  134. class="setWidth"
  135. >
  136. <el-option
  137. v-for="item in activeOptions"
  138. :key="item.companyNo"
  139. :label="item.companyName"
  140. :value="item.companyNo"
  141. />
  142. </el-select>
  143. </el-col>
  144. <el-col :span="4" style="width: 330px">
  145. <el-input
  146. placeholder="请输入编号"
  147. v-model="parmValue.codeNo"
  148. :size="searchSize"
  149. class="input-with-select"
  150. >
  151. <el-select
  152. style="width: 105px"
  153. :size="searchSize"
  154. v-model="parmValue.codeType"
  155. slot="prepend"
  156. >
  157. <el-option
  158. v-for="(item, index) in selectList"
  159. :key="item.code + index"
  160. :label="item.name"
  161. :value="item.code"
  162. ></el-option>
  163. </el-select>
  164. </el-input>
  165. </el-col>
  166. <el-col :span="4" style="width: 88px; float: right">
  167. <el-button
  168. type="primary"
  169. class="fr"
  170. :size="searchSize"
  171. :disabled="loading"
  172. @click="batchExport(selection)"
  173. >
  174. 页面导出
  175. </el-button>
  176. </el-col>
  177. <el-col :span="4" style="width: 66px" class="fr">
  178. <el-button
  179. v-if="powers.some((item) => item == '003')"
  180. type="success"
  181. class="fr"
  182. style="margin-left: 0px"
  183. :size="searchSize"
  184. @click="openModal('add', '003')"
  185. >
  186. 添加
  187. </el-button>
  188. </el-col>
  189. </el-row>
  190. </div>
  191. </template>
  192. <template #orderNo="{ scope }">
  193. <el-popover
  194. placement="top"
  195. width="180"
  196. v-if="scope.row.orderNo_length > 1"
  197. trigger="hover"
  198. >
  199. <ul class="my-tag-ul-main" style="list-style-type: disc">
  200. <li
  201. style="
  202. font-size: 12px;
  203. line-height: 20px;
  204. list-style-type: disc;
  205. list-style-position: inside;
  206. display: list-item;
  207. "
  208. v-for="(key1, ki1) in scope.row.orderNo_showMain"
  209. :key="ki1 + scope.row.orderNo + key1"
  210. >
  211. {{ key1 }}
  212. </li>
  213. </ul>
  214. <p
  215. slot="reference"
  216. style="display: inline-block; vertical-align: top; cursor: pointer"
  217. >
  218. <span style="display: inline-block; vertical-align: top">{{
  219. scope.row.orderNo
  220. }}</span
  221. ><span style="display: inline-block; vertical-align: top; padding: 0 0 0 2px"
  222. ><i
  223. class="el-icon-more"
  224. style="
  225. font-size: 12px;
  226. height: 23px;
  227. display: inline-block;
  228. line-height: 30px;
  229. "
  230. ></i>
  231. </span>
  232. <!-- {{ scope.row.orderNo }} -->
  233. </p>
  234. </el-popover>
  235. <p v-else>{{ scope.row.orderNo }}</p>
  236. </template>
  237. <template #traNo="{ scope }">
  238. <el-popover
  239. placement="top"
  240. width="200"
  241. v-if="scope.row.traNo_length > 1"
  242. trigger="hover"
  243. >
  244. <ul style="list-style-type: disc; list-style-position: inside">
  245. <li
  246. style="
  247. font-size: 12px;
  248. line-height: 20px;
  249. list-style-type: disc;
  250. list-style-position: inside;
  251. display: list-item;
  252. "
  253. v-for="(key1, ki1) in scope.row.traNo_showMain"
  254. :key="ki1 + scope.row.traNo + key1"
  255. >
  256. {{ key1 }}
  257. </li>
  258. </ul>
  259. <p
  260. slot="reference"
  261. style="display: inline-block; vertical-align: top; cursor: pointer"
  262. >
  263. <span style="display: inline-block; vertical-align: top">{{
  264. scope.row.traNo
  265. }}</span
  266. ><span style="display: inline-block; vertical-align: top; padding: 0 0 0 2px"
  267. ><i
  268. class="el-icon-more"
  269. style="
  270. font-size: 12px;
  271. height: 23px;
  272. display: inline-block;
  273. line-height: 30px;
  274. "
  275. ></i>
  276. </span>
  277. </p>
  278. </el-popover>
  279. <p v-else>{{ scope.row.traNo }}</p>
  280. </template>
  281. <template #invNo="{ scope }">
  282. <el-popover
  283. placement="top"
  284. width="200"
  285. v-if="scope.row.invNo_length > 1"
  286. trigger="hover"
  287. >
  288. <ul style="list-style-type: disc; list-style-position: inside">
  289. <li
  290. style="
  291. font-size: 12px;
  292. line-height: 20px;
  293. list-style-type: disc;
  294. list-style-position: inside;
  295. display: list-item;
  296. "
  297. v-for="(key1, ki1) in scope.row.invNo_showMain"
  298. :key="ki1 + scope.row.invNo + key1"
  299. >
  300. {{ key1 }}
  301. </li>
  302. </ul>
  303. <p
  304. slot="reference"
  305. style="display: inline-block; vertical-align: top; cursor: pointer"
  306. >
  307. <span style="display: inline-block; vertical-align: top">{{
  308. scope.row.invNo
  309. }}</span
  310. ><span style="display: inline-block; vertical-align: top; padding: 0 0 0 2px"
  311. ><i
  312. class="el-icon-more"
  313. style="
  314. font-size: 12px;
  315. height: 23px;
  316. display: inline-block;
  317. line-height: 28px;
  318. "
  319. ></i>
  320. </span>
  321. </p>
  322. </el-popover>
  323. <p v-else>{{ scope.row.invNo }}</p>
  324. </template>
  325. <template #rela_form="{ scope }">
  326. <el-tag
  327. size="mini"
  328. :type="''"
  329. v-text="
  330. (RQList.find((item) => item.code == scope.row.rela_form) || {}).name || '--'
  331. "
  332. ></el-tag>
  333. </template>
  334. <template #status="{ scope }">
  335. <el-tag
  336. size="mini"
  337. :type="
  338. scope.row.status == '3' ? 'success' : scope.row.status == '2' ? 'warning' : ''
  339. "
  340. v-text="
  341. (relationType.find((item) => item.code == scope.row.status) || {}).name ||
  342. '--'
  343. "
  344. ></el-tag>
  345. </template>
  346. <template #operation="{ scope }">
  347. <el-tooltip
  348. v-if="
  349. (powers.some((item) => item == '007') && scope.row.rela_form === '2') ||
  350. (powers.some((item) => item == '007') && scope.row.rela_form === '3')
  351. "
  352. effect="dark"
  353. content="详情"
  354. placement="top"
  355. >
  356. <i class="el-icon-view tb-icon" @click="openModal(scope.row.id, '007')"></i>
  357. </el-tooltip>
  358. <el-tooltip
  359. v-if="
  360. (powers.some((item) => item == '027') &&
  361. scope.row.status !== '3' &&
  362. scope.row.rela_form === '2') ||
  363. (powers.some((item) => item == '027') &&
  364. scope.row.status !== '3' &&
  365. scope.row.rela_form === '3')
  366. "
  367. effect="dark"
  368. content="申请取消"
  369. placement="top"
  370. >
  371. <i class="el-icon-video-pause tb-icon" @click="changeStatus(scope.row.id)"></i>
  372. </el-tooltip>
  373. <el-tooltip
  374. v-if="
  375. (powers.some((item) => item == '029') &&
  376. scope.row.status === '1' &&
  377. scope.row.rela_form === '2') ||
  378. (powers.some((item) => item == '029') &&
  379. scope.row.status === '1' &&
  380. scope.row.rela_form === '3')
  381. "
  382. effect="dark"
  383. content="财务审核"
  384. placement="top"
  385. >
  386. <i class="el-icon-s-check tb-icon" @click="openModal(scope.row.id, '029')"></i>
  387. </el-tooltip>
  388. </template>
  389. </ex-table>
  390. <no-auth v-else></no-auth>
  391. </div>
  392. </template>
  393. <script>
  394. import ExTable from "@/components/ExTableNew.vue";
  395. import addView from "./addView";
  396. import asyncRequest from "@/apis/service/InvoiceSales/relation";
  397. import mixinPage from "@/mixins/elPaginationHandle";
  398. import { mapGetters } from "vuex";
  399. import { relationType, RQList } from "@/assets/js/linkType";
  400. import PeriodDatePicker from "@/components/PeriodDatePicker";
  401. import resToken from "@/mixins/resToken";
  402. import { formatJson } from "@/utils/publicMethods";
  403. export default {
  404. name: "relation",
  405. mixins: [mixinPage, resToken],
  406. components: {
  407. ExTable,
  408. addView,
  409. PeriodDatePicker,
  410. },
  411. computed: {
  412. //组件SIZE设置
  413. ...mapGetters(["tablebtnSize", "searchSize", "size"]),
  414. powers() {
  415. let tran =
  416. this.$store.getters.btnList.find((item) => item.menu_route == "relation") || {};
  417. if (tran && tran.action && tran.action.length > 0) {
  418. return tran.action;
  419. } else {
  420. return [];
  421. }
  422. },
  423. },
  424. data() {
  425. return {
  426. selectList: [
  427. {
  428. code: "1",
  429. name: "确认单号",
  430. },
  431. {
  432. code: "2",
  433. name: "发票单号",
  434. },
  435. {
  436. code: "3",
  437. name: "资金单号",
  438. },
  439. ],
  440. newTime: 0,
  441. code: [],
  442. relationType,
  443. RQList: RQList,
  444. selectLoading: false,
  445. activeOptions: [],
  446. name: "",
  447. contector: "",
  448. loading: true,
  449. showModel: false,
  450. isDetail: false,
  451. modelId: 0,
  452. parmValue: {
  453. companyNo: "",
  454. type: "",
  455. status: "",
  456. start: "",
  457. end: "",
  458. codeType: "1",
  459. codeNo: "",
  460. page: 1, // 页码
  461. size: 15, // 每页显示条数
  462. },
  463. // 表格 - 数据
  464. tableData: [],
  465. // 表格 - 参数
  466. table: {
  467. stripe: true,
  468. border: true,
  469. _defaultHeader_: ["setcol"],
  470. },
  471. // 表格 - 分页
  472. pageInfo: {
  473. size: 15,
  474. curr: 1,
  475. total: 0,
  476. },
  477. // 表格 - 列参数
  478. columns: [
  479. { type: "selection", fixed: "left", _noset_: true },
  480. {
  481. prop: "id",
  482. label: "ID",
  483. fixed: "left",
  484. width: "70px",
  485. },
  486. {
  487. prop: "companyNo",
  488. label: "公司编码",
  489. width: "130px",
  490. },
  491. {
  492. prop: "companyName",
  493. label: "公司名称",
  494. "min-width": "230px",
  495. },
  496. {
  497. prop: "cancel_total",
  498. label: "核销额度",
  499. width: "120px",
  500. },
  501. {
  502. prop: "rela_form",
  503. label: "关联类型",
  504. _slot_: "rela_form",
  505. width: "120px",
  506. },
  507. {
  508. prop: "orderNo",
  509. label: "订单编号",
  510. width: "180px",
  511. _slot_: "orderNo",
  512. },
  513. {
  514. prop: "traNo",
  515. label: "资金编号",
  516. width: "250px",
  517. _slot_: "traNo",
  518. },
  519. {
  520. prop: "invNo",
  521. label: "发票编号",
  522. width: "200px",
  523. _slot_: "invNo",
  524. },
  525. {
  526. prop: "status",
  527. label: "状态",
  528. _slot_: "status",
  529. width: "110px",
  530. },
  531. {
  532. prop: "addtime",
  533. label: "创建时间",
  534. sortable: true,
  535. width: "145px",
  536. },
  537. {
  538. prop: "",
  539. label: "操作",
  540. width: "120px",
  541. fixed: "right",
  542. _noset_: true,
  543. _slot_: "operation",
  544. },
  545. ],
  546. };
  547. },
  548. mounted() {
  549. this.showModel = false;
  550. this.searchList();
  551. },
  552. methods: {
  553. restSearch() {
  554. // 表格 - 分页
  555. this.pageInfo = {
  556. size: 15,
  557. curr: 1,
  558. total: 0,
  559. };
  560. this.parmValue = {
  561. companyNo: "",
  562. type: "",
  563. status: "",
  564. start: "",
  565. end: "",
  566. codeType: "1",
  567. codeNo: "",
  568. page: 1, // 页码
  569. size: 15, // 每页显示条数
  570. };
  571. this.searchList();
  572. },
  573. // 新建/编辑/详情
  574. openModal(id, isDetail) {
  575. this.showModel = true;
  576. this.changea();
  577. this.modelId = id;
  578. this.isDetail = isDetail;
  579. },
  580. /**
  581. * 启用/禁用
  582. * @param {String} id id
  583. */
  584. async changeStatus(id) {
  585. await this.$confirm(`确定要取消申请?`, {
  586. confirmButtonText: "确定",
  587. cancelButtonText: "取消",
  588. type: "warning",
  589. })
  590. .then(async () => {
  591. const res = await asyncRequest.delete({ id: id });
  592. if (res && res.code === 0) {
  593. this.$notify.success({
  594. title: "取消申请成功",
  595. message: "",
  596. });
  597. this.searchList();
  598. } else if (res && res.code >= 100 && res.code <= 104) {
  599. await this.logout();
  600. } else {
  601. this.$message.warning(res.message);
  602. }
  603. })
  604. .catch(() => {
  605. console.log("取消");
  606. });
  607. },
  608. async timeReturned(e) {
  609. if (e.startTime !== "") {
  610. this.parmValue.start = e.startTime;
  611. } else {
  612. this.parmValue.start = "";
  613. }
  614. if (e.endTime !== "") {
  615. this.parmValue.end = e.endTime;
  616. } else {
  617. this.parmValue.end = "";
  618. }
  619. if (this.parmValue.start !== "" && this.parmValue.end !== "") {
  620. this.parmValue.page = 1;
  621. await this.searchList();
  622. }
  623. },
  624. // 刷新表格
  625. async searchList() {
  626. this.loading = true;
  627. this.parmValue.companyNo = this.code.join(",");
  628. let obj = JSON.parse(JSON.stringify(this.parmValue));
  629. const res = await asyncRequest.list(obj);
  630. if (res && res.code === 0 && res.data) {
  631. this.tableData = res.data.list;
  632. this.tableData.map((v1) => {
  633. let arr1 = v1.orderNo.split(",");
  634. v1.orderNo = arr1[0];
  635. v1.orderNo_length = arr1.length;
  636. // v1.orderNo_show = false;
  637. v1.orderNo_showMain = arr1;
  638. let arr2 = v1.traNo.split(",");
  639. v1.traNo = arr2[0];
  640. v1.traNo_length = arr2.length;
  641. // v1.traNo_show = false;
  642. v1.traNo_showMain = arr2;
  643. let arr3 = v1.invNo.split(",");
  644. v1.invNo = arr3[0];
  645. v1.invNo_length = arr3.length;
  646. // v1.invNo_show = false;
  647. v1.invNo_showMain = arr3;
  648. return v1;
  649. });
  650. console.log(this.tableData);
  651. this.pageInfo.total = Number(res.data.count);
  652. } else if (res && res.code >= 100 && res.code <= 104) {
  653. await this.logout();
  654. } else {
  655. this.tableData = [];
  656. this.pageInfo.total = 0;
  657. }
  658. this.loading = false;
  659. },
  660. /**
  661. * 批量导出
  662. * @param {Array} selection 当前选择项
  663. */
  664. batchExport(selection) {
  665. if (!this.loading) {
  666. if (selection.length == 0) {
  667. this.$message.warning("请至少选择一条数据!");
  668. return;
  669. }
  670. this.loading = true;
  671. let data = [].concat(...selection);
  672. let list = [];
  673. data.forEach((item) => {
  674. let model = Object.assign({}, item);
  675. model.orderNo = model.orderNo_showMain.toString();
  676. model.traNo = model.traNo_showMain.toString();
  677. model.invNo = model.invNo_showMain.toString();
  678. model.rela_form =
  679. (this.RQList.find((v) => v.code == item.rela_form) || {}).name || "--";
  680. model.status =
  681. (this.relationType.find((v) => v.code == item.status) || {}).name || "--";
  682. list.push(model);
  683. });
  684. const xlsName = `单款票确认数据批量导出`;
  685. import("@/vendor/Export2Excel").then((excel) => {
  686. const tHeader = [
  687. "ID",
  688. "公司编码",
  689. "公司名称",
  690. "核销额度",
  691. "关联类型",
  692. "订单编号",
  693. "资金编号",
  694. "发票编号",
  695. "状态",
  696. "创建时间",
  697. ];
  698. const filterVal = [
  699. "id",
  700. "companyNo",
  701. "companyName",
  702. "cancel_total",
  703. "rela_form",
  704. "orderNo",
  705. "traNo",
  706. "invNo",
  707. "status",
  708. "addtime",
  709. ];
  710. const data = formatJson(filterVal, list);
  711. excel.export_json_to_excel({
  712. header: tHeader,
  713. data,
  714. filename: `${xlsName}`,
  715. });
  716. this.$message.success("单款票确认数据导出成功!");
  717. setTimeout(() => {
  718. this.loading = false;
  719. }, 500);
  720. });
  721. }
  722. },
  723. async remoteMethod(query) {
  724. this.selectLoading = true;
  725. if (query !== "") {
  726. this.activeOptions = [];
  727. const res = await asyncRequest.clist({
  728. page: 1,
  729. size: 100,
  730. company: query,
  731. });
  732. if (res && res.code === 0 && res.data && res.data.list) {
  733. this.activeOptions = res.data.list;
  734. } else if (res && res.code >= 100 && res.code <= 104) {
  735. await this.logout();
  736. } else {
  737. this.$message.warning(res.message);
  738. }
  739. } else {
  740. this.activeOptions = [];
  741. }
  742. this.selectLoading = false;
  743. },
  744. changea() {
  745. this.newTime = new Date().valueOf();
  746. },
  747. },
  748. };
  749. </script>
  750. <style lang="scss" scoped>
  751. .relation {
  752. position: absolute;
  753. width: 100%;
  754. height: calc(100% - 84px);
  755. box-sizing: border-box;
  756. overflow: scroll;
  757. }
  758. </style>