index.vue 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760
  1. <template>
  2. <div class="tenant">
  3. <byTable
  4. :source="sourceList.data"
  5. :pagination="sourceList.pagination"
  6. :config="config"
  7. :loading="loading"
  8. highlight-current-row
  9. :selectConfig="selectConfig"
  10. :action-list="[]"
  11. @get-list="getList"
  12. >
  13. <template #money="{ item }">
  14. {{ item.currency }} {{ moneyFormat(item.amount) }}
  15. </template>
  16. <template #isClaim="{ item }">
  17. <div style="width: 100%">
  18. <span v-if="item.isClaim == 0">未认领</span>
  19. <a
  20. style="color: #409eff; cursor: pointer"
  21. @click="clickRecord(item)"
  22. v-else-if="item.isClaim == 1"
  23. >已认领</a
  24. >
  25. <a
  26. style="color: #409eff; cursor: pointer"
  27. @click="clickRecord(item)"
  28. v-else
  29. >部分认领</a
  30. >
  31. </div>
  32. </template>
  33. </byTable>
  34. <el-dialog
  35. title="认领"
  36. v-if="dialogVisible"
  37. v-model="dialogVisible"
  38. width="50%"
  39. v-loading="loading"
  40. >
  41. <byForm
  42. :formConfig="formConfig"
  43. :formOption="formOption"
  44. v-model="formData.data"
  45. :rules="rules"
  46. ref="byform"
  47. >
  48. <template #detail>
  49. <div style="width: 100%">
  50. <el-button
  51. type="primary"
  52. style="margin-bottom: 10px"
  53. @click="dialogVisibleOne = true"
  54. >选择合同</el-button
  55. >
  56. <el-table :data="formData.data.claimContractList">
  57. <el-table-column
  58. prop="contractCode"
  59. label="合同编码"
  60. width="140"
  61. />
  62. <el-table-column label="合同金额" width="140">
  63. <template #default="{ row, $index }">
  64. {{ row.currency }}{{ moneyFormat(row.contractTotal, 2) }}
  65. </template>
  66. </el-table-column>
  67. <el-table-column
  68. prop="sumContractNotClaimMoney"
  69. label="未结清金额"
  70. width="100"
  71. />
  72. <el-table-column prop="money" label="关联金额" min-width="150">
  73. <template #default="{ row, $index }">
  74. <el-form-item
  75. :prop="'claimContractList.' + $index + '.money'"
  76. :rules="rules.money"
  77. :inline-message="true"
  78. >
  79. <el-input-number
  80. v-model="row.money"
  81. :precision="2"
  82. :controls="false"
  83. :min="0"
  84. onmousewheel="return false;"
  85. />
  86. </el-form-item>
  87. </template>
  88. </el-table-column>
  89. <el-table-column
  90. prop="claimType"
  91. label="到账类型"
  92. min-width="150"
  93. >
  94. <template #default="{ row, $index }">
  95. <el-form-item
  96. :prop="'claimContractList.' + $index + '.claimType'"
  97. :rules="rules.claimType"
  98. :inline-message="true"
  99. >
  100. <el-select v-model="row.claimType" style="width: 100%">
  101. <el-option
  102. v-for="item in claimTypeList"
  103. :key="item.value"
  104. :label="item.label"
  105. :value="item.value"
  106. />
  107. </el-select>
  108. </el-form-item>
  109. </template>
  110. </el-table-column>
  111. <el-table-column
  112. prop="contractMoney"
  113. label="换算金额"
  114. min-width="150"
  115. >
  116. <template #default="{ row, $index }">
  117. <el-form-item
  118. :prop="'claimContractList.' + $index + '.contractMoney'"
  119. :rules="rules.contractMoney"
  120. :inline-message="true"
  121. >
  122. <el-input-number
  123. v-model="row.contractMoney"
  124. :precision="2"
  125. :controls="false"
  126. :min="0"
  127. onmousewheel="return false;"
  128. />
  129. </el-form-item>
  130. </template>
  131. </el-table-column>
  132. <el-table-column
  133. prop="zip"
  134. label="操作"
  135. width="60"
  136. align="center"
  137. >
  138. <template #default="{ $index }">
  139. <el-button type="primary" link @click="handleRemove($index)"
  140. >删除</el-button
  141. >
  142. </template>
  143. </el-table-column>
  144. </el-table>
  145. </div>
  146. </template>
  147. <template #fileSlot>
  148. <div>
  149. <el-upload
  150. v-model:fileList="fileList"
  151. :show-file-list="false"
  152. class="upload-demo"
  153. action="https://winfaster.obs.cn-south-1.myhuaweicloud.com"
  154. :data="uploadData"
  155. :on-preview="handlePreview"
  156. :on-remove="handleRemove"
  157. :on-success="handleSuccess"
  158. :before-upload="handleBeforeUpload"
  159. >
  160. <el-button type="primary">选择</el-button>
  161. </el-upload>
  162. <div>
  163. <div style="margin-top: 15px">
  164. <el-tag
  165. style="margin-right: 10px"
  166. class="ml-2"
  167. type="info"
  168. v-for="(item, index) in fileListCopy"
  169. :key="index"
  170. closable
  171. @close="handleClose(index)"
  172. >
  173. {{ item.fileName }}
  174. </el-tag>
  175. </div>
  176. </div>
  177. </div>
  178. </template>
  179. </byForm>
  180. <template #footer>
  181. <el-button @click="dialogVisible = false" size="large">取 消</el-button>
  182. <el-button
  183. type="primary"
  184. @click="submitForm('byform')"
  185. size="large"
  186. :loading="submitLoading"
  187. >
  188. 确 定
  189. </el-button>
  190. </template>
  191. </el-dialog>
  192. <el-dialog
  193. title="合同选择"
  194. v-if="dialogVisibleOne"
  195. v-model="dialogVisibleOne"
  196. width="80%"
  197. v-loading="loading"
  198. destroy-on-close
  199. >
  200. <ContractSelect
  201. @handleSelectContrct="handleSelectContrct"
  202. ></ContractSelect>
  203. </el-dialog>
  204. <el-dialog
  205. title="认领记录"
  206. v-if="openRecord"
  207. v-model="openRecord"
  208. width="500"
  209. >
  210. <byForm
  211. :formConfig="formRecordConfig"
  212. :formOption="formOption"
  213. v-model="rowData.data"
  214. >
  215. <template #recordList>
  216. <div>
  217. <div
  218. style="width: 100%"
  219. v-if="
  220. rowData.data.recordList && rowData.data.recordList.length > 0
  221. "
  222. >
  223. <div
  224. v-for="(item, index) in rowData.data.recordList"
  225. :key="index"
  226. >
  227. <div style="color: #ccc">{{ item.createTime }}</div>
  228. <div>认领人: {{ item.claimUserName }}</div>
  229. <div>合同编号: {{ item.contractCode }}</div>
  230. <div>认领金额: {{ item.currency }}{{ item.money }}</div>
  231. <br />
  232. </div>
  233. </div>
  234. <div v-else>无</div>
  235. </div>
  236. </template>
  237. </byForm>
  238. <template #footer>
  239. <el-button @click="openRecord = false" size="large">取 消</el-button>
  240. </template>
  241. </el-dialog>
  242. </div>
  243. </template>
  244. <script setup>
  245. import { ElMessage, ElMessageBox } from "element-plus";
  246. import byTable from "@/components/byTable/index";
  247. import byForm from "@/components/byForm/index";
  248. import { computed, ref } from "vue";
  249. import useUserStore from "@/store/modules/user";
  250. import ContractSelect from "@/views/salesMange/saleContract/contractSelect/index";
  251. const { proxy } = getCurrentInstance();
  252. const uploadData = ref({});
  253. let fileList = ref([]);
  254. let fileListCopy = ref([]);
  255. const loading = ref(false);
  256. const submitLoading = ref(false);
  257. const sourceList = ref({
  258. data: [],
  259. pagination: {
  260. total: 3,
  261. pageNum: 1,
  262. pageSize: 10,
  263. type: 1,
  264. dataType: "1",
  265. },
  266. });
  267. let dialogVisible = ref(false);
  268. let dialogVisibleOne = ref(false);
  269. let modalType = ref("add");
  270. let rules = ref({
  271. money: [{ required: true, message: "请输入关联金额", trigger: "blur" }],
  272. claimType: [{ required: true, message: "请选择到账类型", trigger: "change" }],
  273. moneyCny: [{ required: true, message: "请输入换算 CNY", trigger: "blur" }],
  274. contractMoney: [
  275. { required: true, message: "请输入换算金额", trigger: "blur" },
  276. ],
  277. });
  278. const claim = ref([
  279. {
  280. label: "未认领",
  281. value: "0",
  282. },
  283. {
  284. label: "已认领",
  285. value: "1",
  286. },
  287. {
  288. label: "部分认领",
  289. value: "2",
  290. },
  291. ]);
  292. const claimTypeList = ref([]);
  293. const accountList = ref([]);
  294. const selectConfig = computed(() => [
  295. {
  296. label: "认领状态",
  297. prop: "isClaim",
  298. data: claim.value,
  299. },
  300. {
  301. label: "账户名称",
  302. prop: "accountManagementId",
  303. data: accountList.value,
  304. },
  305. ]);
  306. const config = computed(() => {
  307. return [
  308. {
  309. attrs: {
  310. label: "账户名称",
  311. prop: "accountManagementName",
  312. },
  313. },
  314. {
  315. attrs: {
  316. label: "到账金额",
  317. prop: "amount",
  318. slot: "money",
  319. },
  320. },
  321. {
  322. attrs: {
  323. label: "到账时间",
  324. prop: "transactionTime",
  325. },
  326. },
  327. {
  328. attrs: {
  329. label: "对方账户名称",
  330. prop: "name",
  331. },
  332. },
  333. {
  334. attrs: {
  335. label: "对方开户银行",
  336. prop: "openingBank",
  337. },
  338. },
  339. {
  340. attrs: {
  341. label: "对方账号",
  342. prop: "accountOpening",
  343. },
  344. },
  345. {
  346. attrs: {
  347. label: "摘要",
  348. prop: "remarks",
  349. },
  350. },
  351. {
  352. attrs: {
  353. label: "认领状态",
  354. slot: "isClaim",
  355. width: 120,
  356. },
  357. },
  358. {
  359. attrs: {
  360. label: "操作",
  361. width: "140",
  362. align: "right",
  363. },
  364. renderHTML(row) {
  365. return [
  366. row.isClaim != 1
  367. ? {
  368. attrs: {
  369. label: "认领",
  370. type: "primary",
  371. text: true,
  372. bg: true,
  373. disabled: false,
  374. },
  375. el: "button",
  376. click() {
  377. getDtl(row);
  378. },
  379. }
  380. : {},
  381. row.isClaim != 0
  382. ? {
  383. attrs: {
  384. label: "取消认领",
  385. text: true,
  386. bg: true,
  387. type: "primary",
  388. disabled: false,
  389. style: {
  390. color: "#e6a23c",
  391. },
  392. },
  393. el: "button",
  394. click() {
  395. proxy.$router.replace({
  396. path: "/platform_manage/process/processApproval",
  397. query: {
  398. flowKey: "claim_del_flow",
  399. flowName: "取消认领发起",
  400. random: proxy.random(),
  401. businessId: row.id,
  402. },
  403. });
  404. // ElMessageBox.confirm("是否确定取消认领?", "提示", {
  405. // confirmButtonText: "确定",
  406. // cancelButtonText: "取消",
  407. // type: "warning",
  408. // }).then(() => {
  409. // // 删除
  410. // proxy
  411. // .post("/claim/delete", {
  412. // id: row.id,
  413. // })
  414. // .then((res) => {
  415. // ElMessage({
  416. // message: "操作成功",
  417. // type: "success",
  418. // });
  419. // getList();
  420. // });
  421. // });
  422. },
  423. }
  424. : {},
  425. ];
  426. },
  427. },
  428. ];
  429. });
  430. let formData = reactive({
  431. data: {},
  432. });
  433. const formOption = reactive({
  434. inline: true,
  435. labelWidth: 100,
  436. itemWidth: 100,
  437. rules: [],
  438. });
  439. const byform = ref(null);
  440. const formConfig = reactive([
  441. {
  442. type: "title",
  443. title: "账户信息",
  444. },
  445. {
  446. type: "select",
  447. prop: "accountManagementName",
  448. label: "选择账户",
  449. required: true,
  450. disabled: true,
  451. },
  452. {
  453. type: "title",
  454. title: "交易信息",
  455. },
  456. {
  457. type: "date",
  458. itemType: "datetime",
  459. prop: "claimTime",
  460. label: "交易时间",
  461. disabled: true,
  462. },
  463. {
  464. type: "select",
  465. prop: "status",
  466. label: "交易金额",
  467. itemWidth: 30,
  468. disabled: true,
  469. data: [
  470. {
  471. label: "收入",
  472. value: "10",
  473. },
  474. {
  475. label: "支出",
  476. value: "20",
  477. },
  478. ],
  479. },
  480. {
  481. type: "selectInput",
  482. prop: "waitAmount",
  483. selectProp: "currency",
  484. label: " ",
  485. itemWidth: 70,
  486. disabled: true,
  487. },
  488. {
  489. type: "title",
  490. title: "认领信息",
  491. },
  492. {
  493. type: "slot",
  494. slotName: "detail",
  495. label: "",
  496. },
  497. {
  498. type: "slot",
  499. slotName: "fileSlot",
  500. label: "上传附件",
  501. },
  502. ]);
  503. const getList = async (req) => {
  504. sourceList.value.pagination = { ...sourceList.value.pagination, ...req };
  505. loading.value = true;
  506. proxy
  507. .post("/sale/accountRunningWater/page", sourceList.value.pagination)
  508. .then((message) => {
  509. sourceList.value.data = message.rows;
  510. sourceList.value.pagination.total = message.total;
  511. setTimeout(() => {
  512. loading.value = false;
  513. }, 200);
  514. });
  515. };
  516. const submitForm = () => {
  517. byform.value.handleSubmit((valid) => {
  518. const list = formData.data.claimContractList;
  519. if (!(list.length > 0)) {
  520. return ElMessage({
  521. message: `请添加认领信息!`,
  522. type: "info",
  523. });
  524. }
  525. for (let i = 0; i < list.length; i++) {
  526. const e = list[i];
  527. if (!(e.money > 0)) {
  528. return ElMessage({
  529. message: "关联金额不能为0!",
  530. type: "info",
  531. });
  532. }
  533. // if (!(e.moneyCny > 0)) {
  534. // return ElMessage({
  535. // message: "换算CNY不能为0!",
  536. // type: "info",
  537. // });
  538. // }
  539. }
  540. const total = list.reduce((total, x) => (total += Number(x.money)), 0);
  541. if (total > Number(formData.data.waitAmount)) {
  542. return ElMessage({
  543. message: "认领金额总合不能大于交易金额!",
  544. type: "info",
  545. });
  546. }
  547. formData.data.amount = total;
  548. formData.data.fileList =
  549. fileListCopy.value.map((x) => ({
  550. id: x.id,
  551. fileName: x.fileName,
  552. })) || [];
  553. submitLoading.value = true;
  554. proxy.post("/claim/add", formData.data).then(
  555. (res) => {
  556. ElMessage({
  557. message: "操作成功",
  558. type: "success",
  559. });
  560. dialogVisible.value = false;
  561. submitLoading.value = false;
  562. getList();
  563. },
  564. (err) => (submitLoading.value = false)
  565. );
  566. });
  567. };
  568. const rowCurrency = ref("");
  569. const rowRate = ref("");
  570. const getDtl = (row) => {
  571. rowCurrency.value = row.currency;
  572. rowRate.value = row.rate;
  573. proxy.get(`/claim/sumClaimMoney?businessId=${row.id}`).then((res) => {
  574. modalType.value = "edit";
  575. dialogVisible.value = true;
  576. formData.data = {
  577. businessId: row.id,
  578. status: row.status + "",
  579. currency: row.currency,
  580. waitAmount: Number(row.amount) - Number(res.data),
  581. accountManagementId: row.accountManagementId,
  582. accountManagementName: row.accountManagementName,
  583. claimTime: row.transactionTime,
  584. claimContractList: [],
  585. rate: rowRate.value,
  586. };
  587. dialogVisible.value = true;
  588. });
  589. };
  590. const getDict = () => {
  591. proxy
  592. .post("/accountManagement/page", { pageNum: 1, pageSize: 999 })
  593. .then((res) => {
  594. if (res.rows && res.rows.length > 0) {
  595. accountList.value = res.rows.map((item) => {
  596. return {
  597. label: item.alias,
  598. value: item.id,
  599. };
  600. });
  601. }
  602. });
  603. proxy.getDictOne(["claim_type"]).then((res) => {
  604. claimTypeList.value = res["claim_type"].map((x) => ({
  605. label: x.dictValue,
  606. value: x.dictKey,
  607. }));
  608. });
  609. };
  610. const handleBeforeUpload = async (file) => {
  611. const res = await proxy.post("/fileInfo/getSing", { fileName: file.name });
  612. uploadData.value = res.uploadBody;
  613. fileListCopy.value.push({
  614. id: res.id,
  615. fileName: res.fileName,
  616. path: res.fileUrl,
  617. url: res.fileUrl,
  618. uid: file.uid,
  619. });
  620. };
  621. const handleClose = (index) => {
  622. // if (fileListCopy.value.length === 1) {
  623. // return ElMessage({
  624. // message: "最后一个附件啦!",
  625. // type: "info",
  626. // });
  627. // }
  628. fileList.value.splice(index, 1);
  629. fileListCopy.value.splice(index, 1);
  630. };
  631. const handleRemove = (index) => {
  632. formData.data.claimContractList.splice(index, 1);
  633. return ElMessage({
  634. message: "删除成功",
  635. type: "success",
  636. });
  637. };
  638. const handleSelectContrct = (row) => {
  639. const flag = formData.data.claimContractList.some(
  640. (x) => x.contractId === row.id
  641. );
  642. if (flag)
  643. return ElMessage({
  644. message: "该合同已选择",
  645. type: "info",
  646. });
  647. formData.data.claimContractList.push({
  648. dataType: row.dataType,
  649. contractId: row.id,
  650. contractCode: row.code,
  651. money: 0,
  652. currency: row.currency,
  653. rate: rowRate.value,
  654. claimType: "",
  655. moneyCny: null,
  656. contractTotal: row.amount,
  657. sumContractNotClaimMoney: row.sumContractNotClaimMoney,
  658. contractMoney: null,
  659. });
  660. return ElMessage({
  661. message: "选择成功",
  662. type: "success",
  663. });
  664. };
  665. getList();
  666. getDict();
  667. onMounted(() => {});
  668. const openRecord = ref(false);
  669. const rowData = reactive({
  670. data: {},
  671. });
  672. const formRecordConfig = reactive([
  673. {
  674. type: "title",
  675. title: "账户信息",
  676. label: "",
  677. },
  678. {
  679. type: "select",
  680. prop: "accountManagementName",
  681. label: "选择账户",
  682. required: true,
  683. disabled: true,
  684. },
  685. {
  686. type: "title",
  687. title: "交易信息",
  688. label: "",
  689. },
  690. {
  691. type: "date",
  692. itemType: "datetime",
  693. prop: "claimTime",
  694. label: "交易时间",
  695. disabled: true,
  696. },
  697. {
  698. type: "select",
  699. prop: "status",
  700. label: "交易金额",
  701. itemWidth: 30,
  702. disabled: true,
  703. data: [
  704. {
  705. label: "收入",
  706. value: "10",
  707. },
  708. {
  709. label: "支出",
  710. value: "20",
  711. },
  712. ],
  713. },
  714. {
  715. type: "selectInput",
  716. prop: "waitAmount",
  717. selectProp: "currency",
  718. label: " ",
  719. itemWidth: 70,
  720. disabled: true,
  721. },
  722. {
  723. type: "slot",
  724. slotName: "recordList",
  725. label: "认领记录",
  726. },
  727. ]);
  728. const clickRecord = (row) => {
  729. rowData.data = {
  730. businessId: row.id,
  731. status: row.status + "",
  732. currency: row.currency,
  733. waitAmount: Number(row.amount),
  734. accountManagementId: row.accountManagementId,
  735. accountManagementName: row.accountManagementName,
  736. claimTime: row.transactionTime,
  737. recordList: [],
  738. };
  739. openRecord.value = true;
  740. proxy.post("/claim/claimRecord", { businessId: row.id }).then((res) => {
  741. rowData.data.recordList = res;
  742. });
  743. };
  744. </script>
  745. <style lang="scss" scoped>
  746. .tenant {
  747. padding: 20px;
  748. }
  749. </style>