SendFunds.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498
  1. <template>
  2. <div style="width: 100%; padding: 0px 15px">
  3. <el-form
  4. :model="formData.data"
  5. :rules="rules"
  6. ref="formDom"
  7. label-position="top"
  8. >
  9. <div class="_t">基础信息</div>
  10. <el-row :gutter="10">
  11. <el-col :span="6">
  12. <el-form-item label="归属公司" prop="corporationId">
  13. <el-select
  14. v-model="formData.data.corporationId"
  15. placeholder="请选择"
  16. filterable
  17. style="width: 100%"
  18. >
  19. <el-option
  20. v-for="item in companyData"
  21. :label="item.name"
  22. :value="item.id"
  23. >
  24. </el-option>
  25. </el-select>
  26. </el-form-item>
  27. </el-col>
  28. <el-col :span="6">
  29. <el-form-item label="归属部门" prop="departmentId">
  30. <el-cascader
  31. v-model="formData.data.departmentId"
  32. :options="deptTreeData"
  33. :props="{
  34. value: 'deptId',
  35. }"
  36. clearable
  37. filterable
  38. style="width: 100%"
  39. @change="handleChangeDept"
  40. />
  41. </el-form-item>
  42. </el-col>
  43. </el-row>
  44. <el-row :gutter="10">
  45. <el-col :span="6">
  46. <el-form-item label="请款类型" prop="type">
  47. <el-select
  48. v-model="formData.data.type"
  49. placeholder="请选择"
  50. filterable
  51. style="width: 100%"
  52. >
  53. <el-option
  54. v-for="item in fundsType"
  55. :label="item.dictValue"
  56. :value="item.dictKey"
  57. >
  58. </el-option>
  59. </el-select>
  60. </el-form-item>
  61. </el-col>
  62. <el-col :span="6">
  63. <el-form-item label="币种" prop="currency">
  64. <el-select
  65. v-model="formData.data.currency"
  66. placeholder="请选择"
  67. filterable
  68. style="width: 100%"
  69. >
  70. <el-option
  71. v-for="item in currencyType"
  72. :label="item.dictValue"
  73. :value="item.dictKey"
  74. >
  75. </el-option>
  76. </el-select>
  77. </el-form-item>
  78. </el-col>
  79. </el-row>
  80. <el-row>
  81. <el-col :span="6">
  82. <el-form-item label="用款时间" prop="paymentTime">
  83. <el-date-picker
  84. v-model="formData.data.paymentTime"
  85. type="datetime"
  86. placeholder="请选择"
  87. value-format="YYYY-MM-DD HH:mm:ss"
  88. />
  89. </el-form-item>
  90. </el-col>
  91. </el-row>
  92. <el-form-item label="用款说明" prop="paymentRemarks">
  93. <el-input
  94. v-model="formData.data.paymentRemarks"
  95. placeholder="请输入"
  96. type="textarea"
  97. >
  98. </el-input>
  99. </el-form-item>
  100. <el-form-item label="上传附件">
  101. <el-upload
  102. v-model="formData.data.fileList"
  103. :show-file-list="false"
  104. class="upload-demo"
  105. action="https://winfaster.obs.cn-south-1.myhuaweicloud.com"
  106. :data="uploadData"
  107. :on-preview="handlePreview"
  108. :before-upload="handleBeforeUpload"
  109. >
  110. <el-button type="primary">选择</el-button>
  111. </el-upload>
  112. </el-form-item>
  113. <div style="margin-bottom: 15px">
  114. <el-tag
  115. style="margin-right: 10px"
  116. class="ml-2"
  117. type="info"
  118. v-for="(item, index) in formData.data.fileList"
  119. :key="index"
  120. closable
  121. @close="handleClose(index)"
  122. >{{ item.fileName }}</el-tag
  123. >
  124. </div>
  125. <div class="_t">请款明细</div>
  126. <el-form-item>
  127. <el-button type="primary" @click="handleAddRow" style="margin: 10px 0">
  128. 添加行
  129. </el-button>
  130. <el-table :data="formData.data.accountRequestFundsDetailList">
  131. <el-table-column prop="count" label="费用类型" min-width="150">
  132. <template #default="{ row, $index }">
  133. <el-form-item
  134. :prop="'accountRequestFundsDetailList.' + $index + '.costType'"
  135. :rules="rules.costType"
  136. :inline-message="true"
  137. >
  138. <el-select
  139. v-model="row.costType"
  140. placeholder="请选择"
  141. filterable
  142. style="width: 100%"
  143. >
  144. <el-option
  145. v-for="item in fundsCostType"
  146. :label="item.dictValue"
  147. :value="item.dictKey"
  148. >
  149. </el-option>
  150. </el-select>
  151. </el-form-item>
  152. </template>
  153. </el-table-column>
  154. <el-table-column prop="count" label="款项说明" min-width="150">
  155. <template #default="{ row, $index }">
  156. <el-form-item
  157. :prop="'accountRequestFundsDetailList.' + $index + '.remarks'"
  158. :rules="rules.remarks"
  159. :inline-message="true"
  160. >
  161. <el-input
  162. v-model="row.remarks"
  163. placeholder="请输入"
  164. type="textarea"
  165. />
  166. </el-form-item>
  167. </template>
  168. </el-table-column>
  169. <el-table-column prop="amount" label="请款金额" min-width="150">
  170. <template #default="{ row, $index }">
  171. <el-form-item
  172. :prop="'accountRequestFundsDetailList.' + $index + '.amount'"
  173. :rules="rules.amount"
  174. :inline-message="true"
  175. >
  176. <el-input-number
  177. v-model="row.amount"
  178. :precision="4"
  179. :controls="false"
  180. :min="0"
  181. @change="handleChangeAmount"
  182. />
  183. </el-form-item>
  184. </template>
  185. </el-table-column>
  186. <el-table-column prop="zip" label="操作" width="100">
  187. <template #default="{ $index }">
  188. <el-button type="primary" link @click="handleRemove($index)"
  189. >删除</el-button
  190. >
  191. </template>
  192. </el-table-column>
  193. </el-table>
  194. </el-form-item>
  195. <el-row :gutter="10">
  196. <el-col :span="6">
  197. <el-form-item label="请款总额" prop="total">
  198. <el-input
  199. v-model="formData.data.total"
  200. placeholder="请输入"
  201. disabled
  202. />
  203. </el-form-item>
  204. </el-col>
  205. <el-col :span="6">
  206. <el-form-item label="单据数量" prop="quantity">
  207. <el-input v-model="formData.data.quantity" placeholder="请输入" />
  208. </el-form-item>
  209. </el-col>
  210. </el-row>
  211. <div class="_t">收付款信息</div>
  212. <el-row :gutter="10">
  213. <el-col :span="6">
  214. <el-form-item label="付款方式" prop="paymentMethod">
  215. <el-select
  216. v-model="formData.data.paymentMethod"
  217. placeholder="请选择"
  218. filterable
  219. style="width: 100%"
  220. >
  221. <el-option
  222. v-for="item in fundsPaymentMethod"
  223. :label="item.dictValue"
  224. :value="item.dictKey"
  225. >
  226. </el-option>
  227. </el-select>
  228. </el-form-item>
  229. </el-col>
  230. <el-col :span="6">
  231. <el-form-item label="付款账户" prop="accountManagementId">
  232. <el-select
  233. v-model="formData.data.accountManagementId"
  234. placeholder="请选择"
  235. filterable
  236. style="width: 100%"
  237. >
  238. <el-option
  239. v-for="item in accountData"
  240. :label="item.alias"
  241. :value="item.id"
  242. >
  243. </el-option>
  244. </el-select>
  245. </el-form-item>
  246. </el-col>
  247. </el-row>
  248. <el-row :gutter="10">
  249. <el-col :span="6">
  250. <el-form-item label="户名" prop="name">
  251. <el-input v-model="formData.data.name" placeholder="请输入" />
  252. </el-form-item>
  253. </el-col>
  254. <el-col :span="6">
  255. <el-form-item label="银行账号" prop="accountOpening">
  256. <el-input
  257. v-model="formData.data.accountOpening"
  258. placeholder="请输入"
  259. />
  260. </el-form-item>
  261. </el-col>
  262. </el-row>
  263. <el-row :gutter="10">
  264. <el-col :span="6">
  265. <el-form-item label="开户银行" prop="openingBank">
  266. <el-input
  267. v-model="formData.data.openingBank"
  268. placeholder="请输入"
  269. />
  270. </el-form-item>
  271. </el-col>
  272. <el-col :span="6">
  273. <el-form-item label="联行号" prop="interbankNumber">
  274. <el-input
  275. v-model="formData.data.interbankNumber"
  276. placeholder="请输入"
  277. />
  278. </el-form-item>
  279. </el-col>
  280. </el-row>
  281. </el-form>
  282. </div>
  283. </template>
  284. <script setup>
  285. import { ElMessage, ElMessageBox } from "element-plus";
  286. import useUserStore from "@/store/modules/user";
  287. const { proxy } = getCurrentInstance();
  288. let formData = reactive({
  289. data: {
  290. paymentTime: "",
  291. accountRequestFundsDetailList: [],
  292. fileList: [],
  293. },
  294. });
  295. let rules = ref({
  296. corporationId: [
  297. { required: true, message: "请选择归属公司", trigger: "change" },
  298. ],
  299. departmentId: [
  300. { required: true, message: "请选择归属部门", trigger: "change" },
  301. ],
  302. type: [{ required: true, message: "请选择请款类型", trigger: "change" }],
  303. paymentTime: [
  304. { required: true, message: "请选择用款时间", trigger: "change" },
  305. ],
  306. currency: [{ required: true, message: "请选择币种", trigger: "change" }],
  307. paymentMethod: [
  308. { required: true, message: "请选择付款方式", trigger: "change" },
  309. ],
  310. accountManagementId: [
  311. { required: true, message: "请选择付款账号", trigger: "change" },
  312. ],
  313. costType: [{ required: true, message: "请选择费用类型", trigger: "change" }],
  314. remarks: [{ required: true, message: "请输入款项说明", trigger: "blur" }],
  315. amount: [{ required: true, message: "请输入请款金额", trigger: "blur" }],
  316. });
  317. const handleAddRow = () => {
  318. formData.data.accountRequestFundsDetailList.push({
  319. costType: "",
  320. remarks: "",
  321. amount: 0,
  322. });
  323. };
  324. const handleRemove = (index) => {
  325. formData.data.accountRequestFundsDetailList.splice(index, 1);
  326. handleChangeAmount();
  327. };
  328. // 提交方法
  329. const formDom = ref(null);
  330. const handleSubmit = async () => {
  331. const vaild = await formDom.value.validate();
  332. if (vaild) {
  333. if (formData.data.accountRequestFundsDetailList.length > 0) {
  334. return true;
  335. }
  336. ElMessage({
  337. message: "请添加请款明细!",
  338. type: "info",
  339. });
  340. return false;
  341. }
  342. return false;
  343. };
  344. // 获取用户信息并赋默认值
  345. const userInfo = useUserStore().user;
  346. const tenantId = "@福建宏星!#¥%……&*()";
  347. // const tenantId = userInfo.tenantId;
  348. onMounted(() => {
  349. formData.data.paymentTime = proxy.parseTime(new Date());
  350. getDictData();
  351. });
  352. const companyData = ref([]);
  353. const accountData = ref([]);
  354. const deptTreeData = ref([]);
  355. const fundsType = ref([]);
  356. const fundsCostType = ref([]);
  357. const fundsPaymentMethod = ref([]);
  358. const currencyType = ref([]);
  359. const getDictData = () => {
  360. // 获取归属公司数据
  361. proxy
  362. .post("/corporation/page", { pageNum: 1, pageSize: 9999 })
  363. .then((res) => {
  364. companyData.value = res.rows;
  365. });
  366. // 账户数据
  367. proxy
  368. .post("/accountManagement/page", { pageNum: 1, pageSize: 9999 })
  369. .then((res) => {
  370. accountData.value = res.rows;
  371. });
  372. // 部门树
  373. proxy
  374. .get("/tenantDept/list", {
  375. pageNum: 1,
  376. pageSize: 9999,
  377. tenantId: userInfo.tenantId,
  378. })
  379. .then((message) => {
  380. recursive(message.data);
  381. deptTreeData.value = proxy.handleTree(message.data, "corporationId");
  382. });
  383. // 请款类型数据
  384. proxy
  385. .post("/dictTenantData/page", {
  386. pageNum: 1,
  387. pageSize: 999,
  388. tenantId: tenantId,
  389. dictCode: "founds_type",
  390. })
  391. .then((res) => {
  392. fundsType.value = res.rows;
  393. });
  394. // 请款费用类型数据
  395. proxy
  396. .post("/dictTenantData/page", {
  397. pageNum: 1,
  398. pageSize: 999,
  399. tenantId: tenantId,
  400. dictCode: "funds_cost_type",
  401. })
  402. .then((res) => {
  403. fundsCostType.value = res.rows;
  404. });
  405. // 请款付款方式数据
  406. proxy
  407. .post("/dictTenantData/page", {
  408. pageNum: 1,
  409. pageSize: 999,
  410. tenantId: tenantId,
  411. dictCode: "funds_payment_method",
  412. })
  413. .then((res) => {
  414. fundsPaymentMethod.value = res.rows;
  415. });
  416. // 币种数据
  417. proxy
  418. .post("/dictTenantData/page", {
  419. pageNum: 1,
  420. pageSize: 999,
  421. tenantId: tenantId,
  422. dictCode: "account_currency",
  423. })
  424. .then((res) => {
  425. currencyType.value = res.rows;
  426. });
  427. };
  428. const recursive = (data) => {
  429. data.map((item) => {
  430. item.label = item.deptName;
  431. item.id = item.corporationId;
  432. if (item.children) {
  433. recursive(item.children);
  434. } else {
  435. item.children = [];
  436. }
  437. });
  438. };
  439. // 接收父组件的传值
  440. const props = defineProps({
  441. queryData: String,
  442. });
  443. // 部门变更逻辑
  444. const handleChangeDept = (val) => {
  445. formData.data.departmentId = val[val.length - 1];
  446. };
  447. // 计算请款总金额
  448. const handleChangeAmount = () => {
  449. let sum = 0;
  450. for (let i = 0; i < formData.data.accountRequestFundsDetailList.length; i++) {
  451. const e = formData.data.accountRequestFundsDetailList[i];
  452. sum += e.amount;
  453. }
  454. formData.data.total = sum;
  455. };
  456. // 上传附件
  457. const uploadData = ref({});
  458. const handleBeforeUpload = async (file) => {
  459. const res = await proxy.post("/fileInfo/getSing", { fileName: file.name });
  460. uploadData.value = res.uploadBody;
  461. formData.data.fileList.push({
  462. id: res.id,
  463. fileName: res.fileName,
  464. path: res.fileUrl,
  465. url: res.fileUrl,
  466. uid: file.uid,
  467. });
  468. };
  469. const handleClose = (index) => {
  470. formData.data.fileList.splice(index, 1);
  471. };
  472. // 向父组件暴露
  473. defineExpose({
  474. submitData: formData.data,
  475. handleSubmit,
  476. });
  477. </script>
  478. <style lang="scss" scoped>
  479. ._t {
  480. margin-bottom: 5px;
  481. font-size: 14px;
  482. }
  483. </style>