index.vue 27 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033
  1. <template>
  2. <div class="user">
  3. <div class="content">
  4. <byTable :source="sourceList.data" :pagination="sourceList.pagination" :config="config" :loading="loading" highlight-current-row
  5. :selectConfig="selectConfig" :table-events="{
  6. select: select,
  7. }" :action-list="[]" @moreSearch="moreSearch" @get-list="getList">
  8. <template #amount="{ item }">
  9. <div style="width: 100%">
  10. <span>{{ item.currency }} {{ item.incomeAmount }}</span>
  11. </div>
  12. </template>
  13. <template #file="{ item }">
  14. <div style="width: 100%">
  15. <el-button type="primary" text @click="handleOpenFile(item)">查看</el-button>
  16. </div>
  17. </template>
  18. </byTable>
  19. </div>
  20. <el-dialog title="打款" v-if="dialogVisible" v-model="dialogVisible" width="500" v-loading="loading">
  21. <byForm :formConfig="formConfig" :formOption="formOption" v-model="formData.data" :rules="rules" ref="byform">
  22. <template #fileSlot>
  23. <div style="width: 100%">
  24. <el-upload v-model:fileList="fileList" :action="uploadUrl" :data="uploadData" multiple :before-upload="uploadFile"
  25. :on-preview="onPreviewFile">
  26. <el-button type="primary">文件上传</el-button>
  27. </el-upload>
  28. </div>
  29. </template>
  30. </byForm>
  31. <template #footer>
  32. <el-button @click="dialogVisible = false" size="large">取 消</el-button>
  33. <el-button type="primary" @click="submitForm()" size="large" :loading="submitLoading" v-show="submitType === 'add'">
  34. 确 定
  35. </el-button>
  36. </template>
  37. </el-dialog>
  38. <el-dialog title="高级检索" v-if="openSearch" v-model="openSearch" width="600" :before-close="cancelSearch">
  39. <byForm :formConfig="formSearchConfig" :formOption="formOptionTwo" v-model="sourceList.pagination">
  40. <template #departmentId>
  41. <div>
  42. <el-tree-select v-model="sourceList.pagination.departmentId" :data="deptTreeData" check-strictly :render-after-expand="false"
  43. node-key="deptId" style="width: 100%" :props="defaultProps" clearable />
  44. </div>
  45. </template>
  46. <template #time>
  47. <div style="width: 100%">
  48. <el-row :gutter="10">
  49. <el-col :span="11">
  50. <el-date-picker v-model="sourceList.pagination.beginCreateTime" type="datetime" placeholder="请选择" style="width: 100%"
  51. value-format="YYYY-MM-DD HH:mm:ss" />
  52. </el-col>
  53. <el-col :span="2" style="text-align: center">到</el-col>
  54. <el-col :span="11">
  55. <el-date-picker v-model="sourceList.pagination.endCreateTime" type="datetime" placeholder="请选择" style="width: 100%"
  56. value-format="YYYY-MM-DD HH:mm:ss" />
  57. </el-col>
  58. </el-row>
  59. </div>
  60. </template>
  61. <template #timeTwo>
  62. <div style="width: 100%">
  63. <el-row :gutter="10">
  64. <el-col :span="11">
  65. <el-date-picker v-model="sourceList.pagination.beginTime" type="datetime" placeholder="请选择" style="width: 100%"
  66. value-format="YYYY-MM-DD HH:mm:ss" />
  67. </el-col>
  68. <el-col :span="2" style="text-align: center">到</el-col>
  69. <el-col :span="11">
  70. <el-date-picker v-model="sourceList.pagination.endTime" type="datetime" placeholder="请选择" style="width: 100%"
  71. value-format="YYYY-MM-DD HH:mm:ss" />
  72. </el-col>
  73. </el-row>
  74. </div>
  75. </template>
  76. <template #money>
  77. <div style="width: 100%">
  78. <el-row :gutter="10">
  79. <el-col :span="11">
  80. <el-input-number onmousewheel="return false;" v-model="sourceList.pagination.startAmount" placeholder="请输入" style="width: 100%"
  81. :precision="2" :controls="false" :min="0" />
  82. </el-col>
  83. <el-col :span="2" style="text-align: center">到</el-col>
  84. <el-col :span="11">
  85. <el-input-number onmousewheel="return false;" v-model="sourceList.pagination.endAmount" placeholder="请输入" style="width: 100%"
  86. :precision="2" :controls="false" :min="0" />
  87. </el-col>
  88. </el-row>
  89. </div>
  90. </template>
  91. </byForm>
  92. <template #footer>
  93. <el-button @click="cancelSearch()" size="large">取 消</el-button>
  94. <el-button type="primary" @click="submitSearch()" size="large">确 定</el-button>
  95. </template>
  96. </el-dialog>
  97. <el-dialog title="打印" v-if="openPrint" v-model="openPrint" width="840px">
  98. <FundsPDF v-if="rowData.type != '20'" :rowData="rowData"></FundsPDF>
  99. <PaymentPDF v-else :rowData="rowData"></PaymentPDF>
  100. <template #footer>
  101. <el-button @click="openPrint = false" size="large">取消</el-button>
  102. <el-button type="primary" v-print="printObj" size="large">打印</el-button>
  103. <el-button type="primary" @click="clickDownload()" size="large">下载PDF</el-button>
  104. </template>
  105. </el-dialog>
  106. <el-dialog title="冲销" v-if="openCancelledOut" v-model="openCancelledOut" width="500">
  107. <byForm :formConfig="formCancelledOutConfig" :formOption="formOptionTwo" v-model="formCancelledOutData.data" :rules="rulesCancelledOut"
  108. ref="cancelledOut">
  109. <template #detail>
  110. <div style="width: 100%">
  111. <el-button type="primary" style="margin-left: -15px" @click="clickDetail" text>查看详情</el-button>
  112. </div>
  113. </template>
  114. </byForm>
  115. <template #footer>
  116. <el-button @click="openCancelledOut = false" size="large">取 消</el-button>
  117. <el-button type="danger" @click="submitCancelledOutForm()" size="large" :loading="submitCancelledOutLoading">冲 销</el-button>
  118. </template>
  119. </el-dialog>
  120. <el-dialog title="关联附件" v-if="openFileDialog" v-model="openFileDialog" width="500">
  121. <byForm :formConfig="fileConfig" :formOption="formOption" v-model="fileData.data">
  122. <template #businessFile>
  123. <div style="width: 100%" v-if="fileData.data && fileData.data.fileList.length > 0">
  124. <div v-for="(item, index) in fileData.data.fileList" :key="index">
  125. <div style="cursor: pointer; color: #409eff" @click="openFile(item)">
  126. {{ item.fileName }}
  127. </div>
  128. </div>
  129. </div>
  130. <div v-else>暂无关联</div>
  131. </template>
  132. <template #fundsFile>
  133. <div style="width: 100%" v-if="fileData.data && fileData.data.fileListOne.length > 0">
  134. <div v-for="(item, index) in fileData.data.fileListOne" :key="index">
  135. <div style="cursor: pointer; color: #409eff" @click="openFile(item)">
  136. {{ item.fileName }}
  137. </div>
  138. </div>
  139. </div>
  140. <div v-else>暂无关联</div>
  141. </template>
  142. </byForm>
  143. <template #footer>
  144. <el-button @click="openFileDialog = false" size="large">取 消</el-button>
  145. </template>
  146. </el-dialog>
  147. </div>
  148. </template>
  149. <script setup>
  150. import { ElMessage, ElMessageBox } from "element-plus";
  151. import byTable from "@/components/byTable/index";
  152. import byForm from "@/components/byForm/index";
  153. import { computed, reactive, ref } from "vue";
  154. import moment from "moment";
  155. import useUserStore from "@/store/modules/user";
  156. import FundsPDF from "@/components/PDF/fundsPDF.vue";
  157. import PaymentPDF from "@/components/PDF/paymentPDF.vue";
  158. const loading = ref(false);
  159. const submitLoading = ref(false);
  160. const sourceList = ref({
  161. data: [],
  162. pagination: {
  163. total: 0,
  164. pageNum: 1,
  165. pageSize: 10,
  166. keyword: "",
  167. corporationId: "",
  168. departmentId: "",
  169. createUser: "",
  170. beginCreateTime: "",
  171. endCreateTime: "",
  172. beginTime: "",
  173. endTime: "",
  174. currency: "",
  175. startAmount: undefined,
  176. endAmount: undefined,
  177. paymentStatus: "",
  178. paymentRemark: "",
  179. type: "",
  180. },
  181. });
  182. let dialogVisible = ref(false);
  183. let rules = ref({
  184. amount: [{ required: true, message: "请输入付款金额", trigger: "blur" }],
  185. });
  186. const submitType = ref("add");
  187. const accountCurrency = ref([]);
  188. const accountList = ref([]);
  189. const companyData = ref([]);
  190. const deptTreeData = ref([]);
  191. const userList = ref([]);
  192. const fundsType = ref([]);
  193. const fundsPaymentMethod = ref([]);
  194. const { proxy } = getCurrentInstance();
  195. const selectConfig = computed(() => {
  196. return [
  197. {
  198. label: "打款状态",
  199. prop: "paymentStatus",
  200. data: paymentType.value,
  201. },
  202. {
  203. label: "付款类型",
  204. prop: "type",
  205. data: paymentTypeOne.value,
  206. },
  207. ];
  208. });
  209. const config = computed(() => {
  210. return [
  211. {
  212. attrs: {
  213. label: "归属公司",
  214. prop: "corporationName",
  215. width: 160,
  216. },
  217. },
  218. {
  219. attrs: {
  220. label: "归属部门",
  221. prop: "deptName",
  222. width: 160,
  223. },
  224. },
  225. {
  226. attrs: {
  227. label: "付款类型",
  228. prop: "type",
  229. width: 130,
  230. },
  231. render(type) {
  232. if (type == "40") {
  233. return "售后";
  234. } else if (type != "20") {
  235. return "请款: " + proxy.dictValueLabel(type, fundsType.value);
  236. } else {
  237. return "采购付款 - 申请";
  238. }
  239. },
  240. },
  241. {
  242. attrs: {
  243. label: "申请人",
  244. prop: "userName",
  245. width: 140,
  246. },
  247. },
  248. {
  249. attrs: {
  250. label: "申请时间",
  251. prop: "createTime",
  252. width: 160,
  253. },
  254. },
  255. {
  256. attrs: {
  257. label: "用款时间",
  258. prop: "paymentTime",
  259. width: 160,
  260. },
  261. },
  262. {
  263. attrs: {
  264. label: "金额",
  265. slot: "amount",
  266. width: 120,
  267. align: "right",
  268. },
  269. },
  270. {
  271. attrs: {
  272. label: "款项说明",
  273. prop: "paymentRemark",
  274. "min-width": 200,
  275. },
  276. },
  277. {
  278. attrs: {
  279. label: "关联附件",
  280. slot: "file",
  281. width: 80,
  282. align: "left",
  283. },
  284. },
  285. {
  286. attrs: {
  287. label: "打款状态",
  288. prop: "status",
  289. width: 120,
  290. },
  291. render(status) {
  292. return proxy.dictValueLabel(status, paymentType.value);
  293. },
  294. },
  295. {
  296. attrs: {
  297. label: "操作",
  298. width: "180",
  299. align: "center",
  300. fixed: "right",
  301. },
  302. renderHTML(row) {
  303. return [
  304. row.status != "10"
  305. ? {
  306. attrs: {
  307. label: "打款",
  308. type: "primary",
  309. text: true,
  310. },
  311. el: "button",
  312. click() {
  313. formOption.disabled = false;
  314. submitType.value = "add";
  315. getDtl(row);
  316. },
  317. }
  318. : {
  319. attrs: {
  320. label: "冲销",
  321. type: "danger",
  322. text: true,
  323. },
  324. el: "button",
  325. click(item) {
  326. ElMessageBox.confirm(
  327. "冲销后,已生成的资金流水数据会被删除,且关联的数据状态会由“已打款”退回至“未打款”,并支持重新打款。是否继续?",
  328. "提示",
  329. {
  330. confirmButtonText: "继续",
  331. cancelButtonText: "取消",
  332. type: "warning",
  333. }
  334. )
  335. .then(() => {
  336. rowData.value = item;
  337. formCancelledOutData.data = {
  338. accountPaymentId: item.id,
  339. remark: "",
  340. };
  341. openCancelledOut.value = true;
  342. })
  343. .catch(() => {});
  344. },
  345. },
  346. {
  347. attrs: {
  348. label: "打印",
  349. type: "primary",
  350. text: true,
  351. },
  352. el: "button",
  353. click() {
  354. clickPrint(row);
  355. },
  356. },
  357. {
  358. attrs: {
  359. label: "查看",
  360. type: "primary",
  361. text: true,
  362. },
  363. el: "button",
  364. click() {
  365. formOption.disabled = true;
  366. submitType.value = "edit";
  367. getDtl(row);
  368. },
  369. },
  370. ];
  371. },
  372. },
  373. ];
  374. });
  375. let formData = reactive({
  376. data: {
  377. fileList: [],
  378. },
  379. });
  380. const formOption = reactive({
  381. inline: true,
  382. labelWidth: 100,
  383. itemWidth: 100,
  384. rules: [],
  385. disabled: false,
  386. });
  387. const formOptionTwo = reactive({
  388. inline: true,
  389. labelWidth: 100,
  390. itemWidth: 100,
  391. rules: [],
  392. disabled: false,
  393. });
  394. const byform = ref(null);
  395. const formConfig = computed(() => {
  396. return [
  397. {
  398. type: "title",
  399. label: "请款信息",
  400. },
  401. {
  402. type: "input",
  403. prop: "businessManagementName",
  404. label: "付款账户",
  405. disabled: true,
  406. },
  407. {
  408. type: "input",
  409. prop: "incomeAmount",
  410. label: "请款金额",
  411. disabled: true,
  412. },
  413. {
  414. type: "select",
  415. prop: "paymentMethod",
  416. label: "付款方式",
  417. disabled: true,
  418. data: fundsPaymentMethod.value,
  419. },
  420. {
  421. type: "input",
  422. prop: "name",
  423. label: "户名",
  424. disabled: true,
  425. },
  426. {
  427. type: "input",
  428. prop: "accountOpening",
  429. label: "银行账号",
  430. disabled: true,
  431. },
  432. {
  433. type: "input",
  434. prop: "openingBank",
  435. label: "开户银行",
  436. disabled: true,
  437. },
  438. {
  439. type: "input",
  440. prop: "interbankNumber",
  441. label: "联行号 / SWIFT Code",
  442. disabled: true,
  443. },
  444. {
  445. type: "input",
  446. prop: "paymentRemark",
  447. label: "摘要",
  448. disabled: true,
  449. itemType: "textarea",
  450. },
  451. {
  452. type: "title",
  453. title: "付款信息",
  454. },
  455. {
  456. type: "select",
  457. prop: "accountManagementId",
  458. label: "付款账户",
  459. required: true,
  460. data: accountList.value,
  461. itemWidth: 50.1,
  462. style: {
  463. width: "100%",
  464. },
  465. },
  466. {
  467. type: "select",
  468. label: "付款金额",
  469. prop: "currency",
  470. data: accountCurrency.value,
  471. itemWidth: 50,
  472. disabled: true,
  473. },
  474. {
  475. type: "number",
  476. prop: "amount",
  477. label: " ",
  478. itemWidth: 50,
  479. precision: 2,
  480. min: 0,
  481. controls: false,
  482. style: {
  483. width: "100%",
  484. },
  485. },
  486. {
  487. type: "date",
  488. itemType: "datetime",
  489. prop: "expensesTime",
  490. label: "打款时间",
  491. format: "YYYY-MM-DD HH:mm:ss",
  492. itemWidth: 50,
  493. style: {
  494. width: "100%",
  495. },
  496. },
  497. {
  498. type: "input",
  499. prop: "remark",
  500. label: "摘要",
  501. itemType: "textarea",
  502. },
  503. {
  504. type: "slot",
  505. label: "上传附件",
  506. prop: "fileList",
  507. slotName: "fileSlot",
  508. },
  509. ];
  510. });
  511. const fileList = ref([]);
  512. const uploadData = ref({});
  513. const uploadFile = async (file) => {
  514. const res = await proxy.post("/fileInfo/getSing", { fileName: file.name });
  515. uploadData.value = res.uploadBody;
  516. file.id = res.id;
  517. file.fileName = res.fileName;
  518. file.fileUrl = res.fileUrl;
  519. return true;
  520. };
  521. const onPreviewFile = (file) => {
  522. window.open(file.raw.fileUrl, "_blank");
  523. };
  524. const recursive = (data) => {
  525. data.map((item) => {
  526. item.label = item.deptName;
  527. item.id = item.corporationId;
  528. if (item.children) {
  529. recursive(item.children);
  530. } else {
  531. item.children = [];
  532. }
  533. });
  534. };
  535. const getDict = () => {
  536. proxy
  537. .getDict(["account_currency", "founds_type", "funds_payment_method"])
  538. .then((res) => {
  539. accountCurrency.value = res.account_currency.map((item) => {
  540. return {
  541. label: item.dictValue,
  542. value: item.dictKey,
  543. };
  544. });
  545. fundsType.value = res.founds_type.map((item) => {
  546. return {
  547. label: item.dictValue,
  548. value: item.dictKey,
  549. };
  550. });
  551. fundsPaymentMethod.value = res.funds_payment_method.map((item) => {
  552. return {
  553. label: item.dictValue,
  554. value: item.dictKey,
  555. };
  556. });
  557. });
  558. proxy
  559. .post("/accountManagement/page", { pageNum: 1, pageSize: 9999 })
  560. .then((res) => {
  561. if (res.rows && res.rows.length > 0) {
  562. accountList.value = res.rows.map((item) => {
  563. return {
  564. label: item.alias + " (" + item.name + ")",
  565. value: item.id,
  566. };
  567. });
  568. }
  569. });
  570. proxy
  571. .post("/corporation/page", { pageNum: 1, pageSize: 9999 })
  572. .then((res) => {
  573. if (res.rows && res.rows.length > 0) {
  574. companyData.value = res.rows.map((item) => {
  575. return {
  576. label: item.name,
  577. value: item.id,
  578. };
  579. });
  580. }
  581. });
  582. proxy
  583. .get("/tenantDept/list", {
  584. pageNum: 1,
  585. pageSize: 9999,
  586. tenantId: useUserStore().user.tenantId,
  587. })
  588. .then((message) => {
  589. recursive(message.data);
  590. deptTreeData.value = [];
  591. let data = proxy.handleTree(message.data, "deptId");
  592. if (data && data.length > 0) {
  593. for (let i = 0; i < data.length; i++) {
  594. if (data[i].children && data[i].children.length > 0) {
  595. deptTreeData.value = deptTreeData.value.concat(data[i].children);
  596. }
  597. }
  598. }
  599. });
  600. proxy
  601. .get("/tenantUser/list", {
  602. pageNum: 1,
  603. pageSize: 10000,
  604. tenantId: useUserStore().user.tenantId,
  605. })
  606. .then((res) => {
  607. if (res.rows && res.rows.length > 0) {
  608. userList.value = res.rows.map((item) => {
  609. return {
  610. deptId: item.deptId,
  611. label: item.nickName,
  612. value: item.userId,
  613. };
  614. });
  615. }
  616. });
  617. };
  618. getDict();
  619. const getList = async (req) => {
  620. sourceList.value.pagination = { ...sourceList.value.pagination, ...req };
  621. loading.value = true;
  622. proxy
  623. .post("/accountPayment/page", sourceList.value.pagination)
  624. .then((message) => {
  625. sourceList.value.data = message.rows;
  626. sourceList.value.pagination.total = message.total;
  627. setTimeout(() => {
  628. loading.value = false;
  629. }, 200);
  630. });
  631. };
  632. const paymentType = ref([
  633. {
  634. label: "已打款",
  635. value: 10,
  636. },
  637. {
  638. label: "部分打款",
  639. value: 15,
  640. },
  641. {
  642. label: "未打款",
  643. value: 20,
  644. },
  645. ]);
  646. const foundsType = computed(() => proxy.useUserStore().allDict["founds_type"]);
  647. const paymentTypeOne = computed(() => {
  648. if (foundsType.value && foundsType.value.length > 0) {
  649. return [
  650. ...foundsType.value.map((x) => ({
  651. ...x,
  652. label: "请款: " + x.dictValue,
  653. value: x.dictKey,
  654. })),
  655. {
  656. label: "采购付款",
  657. value: 20,
  658. },
  659. {
  660. label: "售后",
  661. value: 40,
  662. },
  663. ];
  664. } else {
  665. return [
  666. {
  667. label: "采购付款",
  668. value: 20,
  669. },
  670. {
  671. label: "售后",
  672. value: 40,
  673. },
  674. ];
  675. }
  676. });
  677. const selection = ref({
  678. data: [],
  679. });
  680. const select = (_selection, row) => {
  681. selection.value.data = _selection;
  682. };
  683. const submitForm = () => {
  684. byform.value.handleSubmit(() => {
  685. if (fileList.value && fileList.value.length > 0) {
  686. formData.data.fileList = fileList.value.map((item) => {
  687. return {
  688. id: item.raw.id,
  689. fileName: item.raw.fileName,
  690. fileUrl: item.raw.fileUrl,
  691. };
  692. });
  693. } else {
  694. formData.data.fileList = [];
  695. }
  696. submitLoading.value = true;
  697. proxy.post("/accountPayment/add", formData.data).then(
  698. () => {
  699. ElMessage({
  700. message: "打款成功",
  701. type: "success",
  702. });
  703. dialogVisible.value = false;
  704. submitLoading.value = false;
  705. getList();
  706. },
  707. () => {
  708. submitLoading.value = false;
  709. }
  710. );
  711. });
  712. };
  713. const getDtl = (row) => {
  714. proxy.post("/accountPayment/detail", { id: row.id }).then((res) => {
  715. formData.data.fileList = [];
  716. fileList.value = [];
  717. formData.data = res;
  718. if (submitType.value === "add") {
  719. formData.data.expensesTime = moment().format("yyyy-MM-DD HH:mm:ss");
  720. formData.data.currency = row.currency;
  721. formData.data.amount = Number(
  722. parseFloat(res.incomeAmount - res.amount).toFixed(2)
  723. );
  724. } else {
  725. formData.data.expensesTime = formData.data.updateTime;
  726. }
  727. if (submitType.value !== "add") {
  728. let ids = [];
  729. if (
  730. res.accountPaymentRecordsList &&
  731. res.accountPaymentRecordsList.length > 0
  732. ) {
  733. ids = res.accountPaymentRecordsList.map((x) => x.id);
  734. }
  735. proxy
  736. .post("/fileInfo/getList", { businessIdList: [row.id, ...ids] })
  737. .then((fileObj) => {
  738. if (fileObj) {
  739. let arr = [];
  740. for (const key in fileObj) {
  741. if (fileObj[key]) {
  742. arr = [...arr, ...fileObj[key]];
  743. }
  744. }
  745. formData.data.fileList = arr;
  746. if (formData.data.fileList && formData.data.fileList.length > 0) {
  747. fileList.value = formData.data.fileList.map((item) => {
  748. return {
  749. raw: item,
  750. name: item.fileName,
  751. url: item.fileUrl,
  752. };
  753. });
  754. } else {
  755. fileList.value = [];
  756. }
  757. }
  758. });
  759. }
  760. dialogVisible.value = true;
  761. });
  762. };
  763. getList();
  764. const openSearch = ref(false);
  765. const formSearchConfig = computed(() => {
  766. return [
  767. {
  768. type: "select",
  769. prop: "corporationId",
  770. label: "归属公司",
  771. data: companyData.value,
  772. clearable: true,
  773. },
  774. {
  775. type: "slot",
  776. slotName: "departmentId",
  777. label: "归属部门",
  778. },
  779. {
  780. type: "select",
  781. prop: "createUser",
  782. label: "请款人",
  783. data: userList.value,
  784. clearable: true,
  785. },
  786. {
  787. type: "select",
  788. prop: "type",
  789. label: "付款类型",
  790. data: fundsType.value,
  791. clearable: true,
  792. },
  793. {
  794. type: "slot",
  795. slotName: "time",
  796. label: "请款时间",
  797. },
  798. {
  799. type: "slot",
  800. slotName: "timeTwo",
  801. label: "用款时间",
  802. },
  803. {
  804. type: "select",
  805. prop: "currency",
  806. label: "币种",
  807. data: accountCurrency.value,
  808. clearable: true,
  809. itemWidth: 50,
  810. },
  811. {
  812. type: "input",
  813. prop: "oppositeAccountName",
  814. label: "对方账户",
  815. itemWidth: 50,
  816. },
  817. {
  818. type: "slot",
  819. slotName: "money",
  820. label: "交易金额",
  821. },
  822. {
  823. type: "select",
  824. prop: "paymentStatus",
  825. label: "打款状态",
  826. data: paymentType.value,
  827. clearable: true,
  828. },
  829. {
  830. type: "input",
  831. itemType: "textarea",
  832. prop: "paymentRemark",
  833. label: "款项说明",
  834. },
  835. ];
  836. });
  837. let copySearch = ref({});
  838. const moreSearch = () => {
  839. copySearch.value = proxy.deepClone(sourceList.value.pagination);
  840. openSearch.value = true;
  841. };
  842. const cancelSearch = () => {
  843. sourceList.value.pagination = copySearch.value;
  844. openSearch.value = false;
  845. };
  846. const submitSearch = () => {
  847. if (
  848. sourceList.value.pagination.startAmount &&
  849. sourceList.value.pagination.endAmount &&
  850. Number(sourceList.value.pagination.startAmount) >
  851. Number(sourceList.value.pagination.endAmount)
  852. ) {
  853. return ElMessage("交易金额输入错误");
  854. }
  855. if (
  856. sourceList.value.pagination.beginCreateTime &&
  857. sourceList.value.pagination.endCreateTime &&
  858. sourceList.value.pagination.beginCreateTime >
  859. sourceList.value.pagination.endCreateTime
  860. ) {
  861. return ElMessage("开始时间不能大于结束时间");
  862. }
  863. if (
  864. sourceList.value.pagination.beginTime &&
  865. sourceList.value.pagination.endTime &&
  866. sourceList.value.pagination.beginTime > sourceList.value.pagination.endTime
  867. ) {
  868. return ElMessage("开始时间不能大于结束时间");
  869. }
  870. openSearch.value = false;
  871. sourceList.value.pagination.keyword = "";
  872. sourceList.value.pagination.pageNum = 1;
  873. getList();
  874. };
  875. const openPrint = ref(false);
  876. const rowData = ref({});
  877. const clickPrint = (row) => {
  878. rowData.value = {
  879. id: row.businessId,
  880. type: row.type,
  881. };
  882. openPrint.value = true;
  883. };
  884. const clickDownload = () => {
  885. if (rowData.value.type != "20") {
  886. proxy.getPdf("请款PDF文件");
  887. } else {
  888. proxy.getPdf("采购付款PDF文件");
  889. }
  890. };
  891. let formCancelledOutData = reactive({
  892. data: {},
  893. });
  894. const cancelledOut = ref(null);
  895. const formCancelledOutConfig = computed(() => {
  896. return [
  897. {
  898. type: "slot",
  899. label: "打款明细",
  900. slotName: "detail",
  901. },
  902. {
  903. type: "input",
  904. itemType: "textarea",
  905. prop: "remark",
  906. label: "冲销原因",
  907. },
  908. ];
  909. });
  910. let rulesCancelledOut = ref({
  911. remark: [{ required: true, message: "请输入冲销原因", trigger: "blur" }],
  912. });
  913. const openCancelledOut = ref(false);
  914. const submitCancelledOutLoading = ref(false);
  915. const submitCancelledOutForm = () => {
  916. cancelledOut.value.handleSubmit(() => {
  917. submitCancelledOutLoading.value = true;
  918. proxy.post("/writeOffRecords/add", formCancelledOutData.data).then(
  919. () => {
  920. ElMessage({
  921. message: "冲销完成",
  922. type: "success",
  923. });
  924. openCancelledOut.value = false;
  925. submitCancelledOutLoading.value = false;
  926. getList();
  927. },
  928. () => {
  929. submitCancelledOutLoading.value = false;
  930. }
  931. );
  932. });
  933. };
  934. const clickDetail = () => {
  935. formOption.disabled = true;
  936. submitType.value = "edit";
  937. getDtl(rowData.value);
  938. };
  939. const fileData = reactive({
  940. data: {},
  941. });
  942. const fileConfig = computed(() => [
  943. {
  944. type: "title",
  945. title: "业务附件",
  946. },
  947. {
  948. type: "slot",
  949. slotName: "businessFile",
  950. // label: "业务附件",
  951. },
  952. {
  953. type: "title",
  954. title: "打款附件",
  955. },
  956. {
  957. type: "slot",
  958. slotName: "fundsFile",
  959. // label: "打款附件",
  960. },
  961. ]);
  962. const openFileDialog = ref(false);
  963. const handleOpenFile = (row) => {
  964. fileData.data = {
  965. fileList: [],
  966. fileListOne: [],
  967. };
  968. proxy.post("/accountPayment/detail", { id: row.id }).then((res) => {
  969. let ids = [];
  970. if (
  971. res.accountPaymentRecordsList &&
  972. res.accountPaymentRecordsList.length > 0
  973. ) {
  974. ids = res.accountPaymentRecordsList.map((x) => x.id);
  975. }
  976. proxy
  977. .post("/fileInfo/getList", { businessIdList: [row.id, ...ids] })
  978. .then((fileObj) => {
  979. if (fileObj) {
  980. let arr = [];
  981. for (const key in fileObj) {
  982. if (fileObj[key]) {
  983. arr = [...arr, ...fileObj[key]];
  984. }
  985. }
  986. fileData.data.fileListOne = arr;
  987. }
  988. });
  989. });
  990. proxy
  991. .post("/fileInfo/getList", { businessIdList: [row.businessId] })
  992. .then((fileObj) => {
  993. if (fileObj[row.businessId] && fileObj[row.businessId].length > 0) {
  994. fileData.data.fileList = fileObj[row.businessId];
  995. }
  996. });
  997. openFileDialog.value = true;
  998. };
  999. const openFile = (item) => {
  1000. window.open(item.fileUrl, "_blank");
  1001. };
  1002. const printObj = ref({
  1003. id: "pdfDom",
  1004. popTitle: "",
  1005. extraCss:
  1006. "https://cdn.bootcdn.net/ajax/libs/animate.css/4.1.1/animate.compat.css, https://cdn.bootcdn.net/ajax/libs/hover.css/2.3.1/css/hover-min.css",
  1007. extraHead: '<meta http-equiv="Content-Language"content="zh-cn"/>',
  1008. });
  1009. </script>
  1010. <style lang="scss" scoped>
  1011. .user {
  1012. padding: 20px;
  1013. }
  1014. ::v-deep(.el-input-number .el-input__inner) {
  1015. text-align: left;
  1016. }
  1017. </style>