index.vue 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466
  1. <script setup lang="ts">
  2. import AForm from '@/components/AForm/index.vue'
  3. import { FormConfigType } from '@/components/AForm/type'
  4. import { ToolbarConfigType } from '@/components/AToolbar/type'
  5. import { ColumnConfigType } from '@/components/ATable/type'
  6. import { StrAnyObj, StrAnyObjArr } from '@/typings'
  7. import {
  8. getDetailApi,
  9. getRemitPageApi,
  10. remitApi,
  11. remitExcelExportApi
  12. } from '@/api/business/payment/requests'
  13. import { getPageApi as getCorporationPageApi } from '@/api/business/corporation/corporation'
  14. import DeptTreeSelect from '@/views/components/DeptTreeSelect/index.vue'
  15. import { getPageApi as getCapitalAccountPageApi } from '@/api/business/capital/account'
  16. import MoneyPDF from '@/components/PDF/moneyPDF.vue'
  17. import { getPdf } from '@/utils/getPdf.js'
  18. import {getPageApi as getShopApi} from "@/api/business/corporation/shop";
  19. const queryRef = ref<InstanceType<typeof AForm>>()
  20. const formRef = ref<InstanceType<typeof AForm>>()
  21. const showQuery = ref<boolean>(true)
  22. const selectKeys = ref<string[]>([])
  23. const pageTotal = ref<number>(0)
  24. const queryData = ref<StrAnyObj>({ pageNum: 1, pageSize: 10 })
  25. const tableData = ref<StrAnyObjArr>([])
  26. const detailData = ref<StrAnyObj>({ paymentRequestsDetailList: [{}] })
  27. const formData = ref<StrAnyObj>({})
  28. const dialogTitle = ref<string>('')
  29. const dialogVisible = ref<boolean>(false)
  30. const selectDeptIdRef = ref<InstanceType<typeof DeptTreeSelect>>()
  31. const disabled = ref(false)
  32. const dialogPrint = ref<boolean>(false)
  33. const rowData = ref<StrAnyObj>({})
  34. const queryConfig: FormConfigType[] = [
  35. {
  36. type: 'input',
  37. prop: 'keyword',
  38. label: '关键词'
  39. },
  40. {
  41. type: 'select',
  42. prop: 'corporationId',
  43. label: '归属公司',
  44. keyName: 'id',
  45. labelName: 'name',
  46. async option() {
  47. const data = await getCorporationPageApi({ searchAll: true })
  48. return data.records
  49. }
  50. },
  51. {
  52. type: 'select',
  53. prop: 'corporationShopId',
  54. label: '归属店铺',
  55. option: async () => (await getShopApi({ searchAll: true })).records,
  56. keyName: 'id',
  57. labelName: 'name'
  58. },
  59. {
  60. type: 'slot',
  61. prop: 'deptId',
  62. label: '归属部门'
  63. },
  64. {
  65. type: 'select',
  66. prop: 'type',
  67. label: '请款类型',
  68. dict: 'payment_requests_type'
  69. },
  70. {
  71. type: 'select',
  72. prop: 'payType',
  73. label: '付款方式',
  74. dict: 'pay_type'
  75. },
  76. {
  77. type: 'select',
  78. prop: 'paymentStatus',
  79. label: '放款状态',
  80. option: [
  81. {
  82. key: 0,
  83. label: '未打款'
  84. },
  85. {
  86. key: 1,
  87. label: '部分打款'
  88. },
  89. {
  90. key: 2,
  91. label: '已打款'
  92. }
  93. ]
  94. }
  95. ]
  96. const toolbarConfig: ToolbarConfigType[] = [
  97. {
  98. common: 'search',
  99. click() {
  100. queryData.value.pageNum = 1
  101. getPage()
  102. }
  103. },
  104. {
  105. common: 'reset',
  106. click() {
  107. queryRef.value?.resetFields()
  108. getPage()
  109. }
  110. // },
  111. // {
  112. // common: 'add',
  113. // click() {
  114. // dialogVisible.value = true
  115. // dialogTitle.value = '新增'
  116. // }
  117. },
  118. {
  119. text: '导出',
  120. icon: 'Download',
  121. type: 'primary',
  122. click() {
  123. remitExcelExportApi(queryData.value).then(() => {
  124. ElMessage.success('导出成功')
  125. })
  126. }
  127. }
  128. ]
  129. const columnConfig: ColumnConfigType[] = [
  130. {
  131. prop: 'corporationName',
  132. label: '归属公司'
  133. },
  134. {
  135. prop: 'corporationShopName',
  136. label: '归属店铺'
  137. },
  138. {
  139. prop: 'deptName',
  140. label: '归属部门'
  141. },
  142. {
  143. prop: 'type',
  144. label: '请款类型',
  145. dict: 'payment_requests_type'
  146. },
  147. {
  148. prop: 'userName',
  149. label: '请款人'
  150. },
  151. {
  152. prop: 'createTime',
  153. label: '请款时间'
  154. },
  155. {
  156. prop: 'useTime',
  157. label: '用款时间'
  158. },
  159. {
  160. prop: 'useRemark',
  161. label: '用款说明',
  162. showOverflowTooltip: true
  163. },
  164. {
  165. prop: 'totalAmount',
  166. label: '请款金额'
  167. },
  168. {
  169. prop: 'paymentStatus',
  170. label: '放款状态',
  171. formatter(row) {
  172. switch (row.paymentStatus) {
  173. case 0:
  174. return '未打款'
  175. case 1:
  176. return '部分打款'
  177. case 2:
  178. return '已打款'
  179. }
  180. }
  181. },
  182. {
  183. width: 250,
  184. handleConfig: [
  185. {
  186. text: '打款',
  187. if: (row) => row.paymentStatus != 2,
  188. click(row) {
  189. dialogVisible.value = true
  190. dialogTitle.value = '打款'
  191. disabled.value = false
  192. getDetailApi({ id: row.id }).then((resp: StrAnyObj) => {
  193. detailData.value = resp
  194. formData.value.capitalAccountId = resp.capitalAccountId
  195. formData.value.amount = resp.totalAmount - resp.remitAmount
  196. formData.value.remark = resp.useRemark
  197. formData.value.paymentRequestsId = resp.id
  198. })
  199. }
  200. },
  201. {
  202. common: 'detail',
  203. click(row) {
  204. dialogVisible.value = true
  205. dialogTitle.value = '详情'
  206. disabled.value = true
  207. getDetailApi({ id: row.id }).then((resp: StrAnyObj) => {
  208. detailData.value = resp
  209. })
  210. }
  211. },
  212. {
  213. text: '打印',
  214. click(row) {
  215. rowData.value = row
  216. dialogPrint.value = true
  217. }
  218. }
  219. ]
  220. }
  221. ]
  222. const detailConfig: FormConfigType[] = [
  223. {
  224. type: 'input',
  225. prop: 'totalAmount',
  226. label: '请款金额',
  227. placeholder: '',
  228. disabled: true
  229. },
  230. {
  231. type: 'input',
  232. prop: 'remitAmount',
  233. label: '已打款金额',
  234. placeholder: '',
  235. disabled: true
  236. },
  237. {
  238. type: 'select',
  239. prop: 'payType',
  240. label: '付款方式',
  241. dict: 'pay_type',
  242. placeholder: '',
  243. disabled: true
  244. },
  245. {
  246. type: 'select',
  247. prop: 'capitalAccountId',
  248. label: '付款账户',
  249. keyName: 'id',
  250. labelName: 'accountAlias',
  251. placeholder: '',
  252. async option() {
  253. const data = await getCapitalAccountPageApi({ searchAll: true })
  254. return data.records
  255. },
  256. disabled: true
  257. },
  258. {
  259. type: 'input',
  260. prop: 'accountName',
  261. label: '户名',
  262. placeholder: '',
  263. disabled: true
  264. },
  265. {
  266. type: 'input',
  267. prop: 'account',
  268. label: '银行账号',
  269. placeholder: '',
  270. disabled: true
  271. },
  272. {
  273. type: 'input',
  274. prop: 'depositBank',
  275. label: '开户银行',
  276. placeholder: '',
  277. disabled: true
  278. },
  279. {
  280. type: 'input',
  281. prop: 'correspondentNumber',
  282. label: '联行号/SWIFT Code',
  283. placeholder: '',
  284. disabled: true
  285. },
  286. {
  287. type: 'input',
  288. itemType: 'textarea',
  289. prop: 'useRemark',
  290. label: '用款说明',
  291. rows: 3,
  292. span: 24,
  293. placeholder: '',
  294. disabled: true
  295. },
  296. {
  297. type: 'upload',
  298. prop: 'atts',
  299. label: '附件',
  300. span: 24
  301. }
  302. ]
  303. const formConfig: FormConfigType[] = [
  304. {
  305. type: 'select',
  306. prop: 'capitalAccountId',
  307. label: '付款账户',
  308. keyName: 'id',
  309. labelName: 'accountAlias',
  310. async option() {
  311. const data = await getCapitalAccountPageApi({ searchAll: true })
  312. return data.records
  313. },
  314. rule: [{ required: true, message: '付款账户不能为空', trigger: 'blur' }]
  315. },
  316. {
  317. type: 'inputNumber',
  318. prop: 'amount',
  319. label: '打款金额',
  320. min: 0.01,
  321. precision: 2,
  322. rule: [{ required: true, message: '打款金额不能为空', trigger: 'blur' }]
  323. },
  324. {
  325. type: 'datePicker',
  326. prop: 'remitTime',
  327. label: '打款时间',
  328. datePickerType: 'datetime',
  329. format: 'YYYY-MM-DD 00:00:00',
  330. valueFormat: 'YYYY-MM-DD 00:00:00',
  331. rule: [{ required: true, message: '打款时间不能为空', trigger: ['blur', 'change'] }]
  332. },
  333. {
  334. type: 'input',
  335. itemType: 'textarea',
  336. prop: 'remark',
  337. label: '摘要',
  338. rows: 5,
  339. span: 24
  340. },
  341. {
  342. type: 'upload',
  343. prop: 'atts',
  344. label: '附件',
  345. span: 24
  346. }
  347. ]
  348. onMounted(() => {
  349. getPage()
  350. selectDeptIdRef.value?.load()
  351. })
  352. function getPage() {
  353. getRemitPageApi(queryData.value).then((resp) => {
  354. tableData.value = resp.records
  355. pageTotal.value = resp.total
  356. })
  357. }
  358. function tableSelectionChange(item: StrAnyObjArr) {
  359. selectKeys.value = item.map((item) => item.id)
  360. }
  361. function formSubmit() {
  362. formRef.value?.validate(() => {
  363. remitApi(formData.value).then(() => {
  364. dialogVisible.value = false
  365. ElMessage.success('打款成功')
  366. getPage()
  367. })
  368. })
  369. }
  370. function formClosed() {
  371. formRef.value?.resetFields()
  372. }
  373. const printObj = ref({
  374. id: 'pdfDom',
  375. popTitle: '',
  376. extraCss:
  377. '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',
  378. extraHead: '<meta http-equiv="Content-Language"content="zh-cn"/>'
  379. })
  380. const clickDownload = () => {
  381. getPdf('请款PDF文件')
  382. }
  383. </script>
  384. <template>
  385. <div>
  386. <el-card v-if="showQuery">
  387. <a-form ref="queryRef" v-model="queryData" :config="queryConfig" :span="6">
  388. <template #deptId>
  389. <dept-tree-select ref="selectDeptIdRef" v-model="queryData.deptId" />
  390. </template>
  391. </a-form>
  392. </el-card>
  393. <a-table
  394. :data="tableData"
  395. :page-total="pageTotal"
  396. :toolbar-config="toolbarConfig"
  397. :column-config="columnConfig"
  398. v-model:showQuery="showQuery"
  399. v-model:page-num="queryData.pageNum"
  400. v-model:page-size="queryData.pageSize"
  401. @page-num-change="getPage"
  402. @page-size-change="getPage"
  403. @selection-change="tableSelectionChange"
  404. >
  405. </a-table>
  406. <a-dialog
  407. v-if="dialogVisible"
  408. v-model="dialogVisible"
  409. :title="dialogTitle"
  410. :footer="!disabled"
  411. @submit="formSubmit"
  412. @closed="formClosed"
  413. width="1400px"
  414. >
  415. <div v-if="disabled">
  416. <a-form v-model="detailData" :config="detailConfig" :span="12" disabled> </a-form>
  417. </div>
  418. <el-card v-if="!disabled" header="请款信息">
  419. <a-form v-model="detailData" :config="detailConfig" :span="12" disabled></a-form>
  420. </el-card>
  421. <el-card v-if="!disabled" header="打款信息" style="margin-top: 10px">
  422. <a-form ref="formRef" v-model="formData" :config="formConfig" :span="12"> </a-form>
  423. </el-card>
  424. </a-dialog>
  425. <a-dialog
  426. :footer="false"
  427. v-if="dialogPrint"
  428. v-model="dialogPrint"
  429. title="打印"
  430. width="840px"
  431. height="200px"
  432. >
  433. <MoneyPDF :rowData="rowData"></MoneyPDF>
  434. <template #footer>
  435. <div>
  436. <el-button @click="dialogPrint = false" size="large">取消</el-button>
  437. <el-button type="primary" v-print="printObj" size="large">打印</el-button>
  438. <el-button type="primary" @click="clickDownload()" size="large">下载PDF</el-button>
  439. </div>
  440. </template>
  441. </a-dialog>
  442. </div>
  443. </template>