index.vue 15 KB

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