index.vue 17 KB

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