purPaymentRequestForm.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378
  1. <template>
  2. <a-spin :spinning="loading">
  3. <JFormContainer :disabled="disabled">
  4. <template #detail>
  5. <a-form v-bind="formItemLayout" name="purPaymnetRequest" ref="formRef">
  6. <a-row>
  7. <a-col :span="12">
  8. <a-form-item label="申请单编号(bill code)" v-bind="validateInfos.billCode" id="purPaymnetRequest-billCode" name="billCode">
  9. <a-input v-model:value="formData.billCode" placeholder="自动生成" disabled></a-input>
  10. </a-form-item>
  11. </a-col>
  12. <a-col :span="12">
  13. <a-form-item label="申请日期(bill date)" v-bind="validateInfos.billDate" id="purPaymnetRequest-billDate" name="billDate">
  14. <a-date-picker placeholder="请选择发票日期(bill date)" v-model:value="formData.billDate" value-format="YYYY-MM-DD" style="width: 100%" allow-clear />
  15. </a-form-item>
  16. </a-col>
  17. <a-col :span="12">
  18. <a-form-item label="供应商(supplier)" v-bind="validateInfos.supplier" id="purPaymnetRequest-supplier" name="supplier">
  19. <JSelect v-model:value="formData.supplier" :get-option-url="supplierOption" :showField="showField" @change="changeSupplier"></JSelect>
  20. </a-form-item>
  21. </a-col>
  22. <a-col :span="12">
  23. <a-form-item label="预计付款日期(expected payment date)" v-bind="validateInfos.expectedPaymentDate" id="purPaymnetRequest-expectedPaymentDate" name="expectedPaymentDate">
  24. <a-date-picker placeholder="请选择预计付款日期(expected payment date)" v-model:value="formData.expectedPaymentDate" value-format="YYYY-MM-DD" style="width: 100%" allow-clear />
  25. </a-form-item>
  26. </a-col>
  27. <a-col :span="12">
  28. <a-form-item label="收款人(payee)" v-bind="validateInfos.payee" id="purPaymnetRequest-payee" name="payee">
  29. <a-input v-model:value="formData.payee" placeholder="" AutoComplete="off"></a-input>
  30. </a-form-item>
  31. </a-col>
  32. <a-col :span="12">
  33. <a-form-item label="开户行(opening bank)" v-bind="validateInfos.openingBank" id="purPaymnetRequest-openingBank" name="openingBank">
  34. <a-input v-model:value="formData.openingBank" placeholder="请输入" allow-clear AutoComplete="off"></a-input>
  35. </a-form-item>
  36. </a-col>
  37. <a-col :span="12">
  38. <a-form-item label="银行账号(bank account)" v-bind="validateInfos.bankAccount" id="purPaymnetRequest-bankAccount" name="bankAccount">
  39. <a-input v-model:value="formData.bankAccount" placeholder="请输入" allow-clear AutoComplete="off"></a-input>
  40. </a-form-item>
  41. </a-col>
  42. <a-col :span="12">
  43. <a-form-item label="银行代码(swift code)" v-bind="validateInfos.swiftCode" id="purPaymnetRequest-swiftCode" name="swiftCode">
  44. <a-input v-model:value="formData.swiftCode" placeholder="请输入" allow-clear AutoComplete="off"></a-input>
  45. </a-form-item>
  46. </a-col>
  47. <a-col :span="12">
  48. <a-form-item label="币种(currency)" v-bind="validateInfos.currency" id="purPaymnetRequest-currency" name="currency">
  49. <JDictSelectTag v-model:value="formData.currency" placeholder="请选择" dictCode="currency" style="width: 100%;"/>
  50. </a-form-item>
  51. </a-col>
  52. <a-col :span="12">
  53. <a-form-item label="备注(notes)" v-bind="validateInfos.notes" id="purPaymnetRequest-notes" name="notes">
  54. <a-input v-model:value="formData.notes" placeholder="请输入备注(notes)" allow-clear AutoComplete="off"></a-input>
  55. </a-form-item>
  56. </a-col>
  57. <a-col :span="12">
  58. <a-form-item label="委托收款证明(entrusted certificate)" v-bind="validateInfos.collectionCertificate" name="collectionCertificate" >
  59. <JUpload v-model:value="formData.collectionCertificate"></JUpload>
  60. </a-form-item>
  61. </a-col>
  62. </a-row>
  63. </a-form>
  64. </template>
  65. </JFormContainer>
  66. <!-- 子表单区域 -->
  67. <a-tabs v-model:activeKey="activeKey" animated style=" padding: 24px;padding-top: 0px;">
  68. <a-tab-pane tab="采购付款申请 - 付款明细(payment details)" key="paymentDetails" :forceRender="true">
  69. <a-button type="primary" style="margin-right: 1%;margin-bottom: 1%;" @click="selectOrder"> 选择采购订单(select purchase order)</a-button>
  70. <j-vxe-table
  71. :keep-source="true"
  72. resizable
  73. ref="paymentDetailsTableRef"
  74. :loading="paymentDetailsTable.loading"
  75. :columns="paymentDetailsTable.columns"
  76. :dataSource="paymentDetailsTable.dataSource"
  77. :maxHeight="340"
  78. :disabled="disabled"
  79. :rowNumber="true"
  80. :rowSelection="true"
  81. asyncRemove
  82. @valueChange="changeValues"
  83. >
  84. <template #action="props">
  85. <a-popconfirm title="确定删除吗?" @confirm="handleDelete1(props)">
  86. <a>删除(delete)</a>
  87. </a-popconfirm>
  88. </template>
  89. <template #viewDetail="props">
  90. <a>查看(view)</a>
  91. </template>
  92. <template #invoice="props">
  93. <JUpload v-model:value="props.row.invoice"></JUpload>
  94. </template>
  95. </j-vxe-table>
  96. </a-tab-pane>
  97. </a-tabs>
  98. <SelectPurchaseOrderModal ref="SelectPurchaseOrderModalRef" @selectPurchaseOrderMian="addDetailList"></SelectPurchaseOrderModal>
  99. </a-spin>
  100. </template>
  101. <script lang="ts">
  102. import { defineComponent, ref, reactive, computed, toRaw, onMounted } from 'vue';
  103. import { defHttp } from '/@/utils/http/axios';
  104. import { useValidateAntFormAndTable } from '/@/hooks/system/useJvxeMethods';
  105. import { supplierOption,queryPaymentDetailListByMainId,queryDataById, saveOrUpdate } from '../purPaymentRequestForm.api';
  106. import { JVxeTable } from '/@/components/jeecg/JVxeTable';
  107. import { paymentDetailColumns} from '../purPaymentRequest.data';
  108. import SelectPurchaseOrderModal from '../../../publicComponents/SelectPurchaseOrderMainModal.vue';
  109. import JFormContainer from '/@/components/Form/src/container/JFormContainer.vue';
  110. import JUpload from '/@/components/Form/src/jeecg/components/JUpload/JUpload.vue';
  111. import { JDictSelectTag,JSelect,ApiSelect} from '/@/components/Form';
  112. import { Form,message } from 'ant-design-vue';
  113. import { useUserStore } from '/@/store/modules/user';
  114. import moment from 'moment';
  115. const userStore = useUserStore();
  116. const useForm = Form.useForm;
  117. export default defineComponent({
  118. name: "purPaymentRequestForm",
  119. components:{
  120. JVxeTable,
  121. JFormContainer,
  122. JUpload,
  123. JDictSelectTag,
  124. SelectPurchaseOrderModal,
  125. ApiSelect,
  126. JSelect
  127. },
  128. props:{
  129. formDisabled:{
  130. type: Boolean,
  131. default: false
  132. },
  133. formData: { type: Object, default: ()=>{} },
  134. formBpm: { type: Boolean, default: true }
  135. },
  136. emits:['success'],
  137. setup(props, {emit}) {
  138. var showField = ref('currency+name');
  139. const loading = ref(false);
  140. const formRef = ref();
  141. const SelectPurchaseOrderModalRef = ref()
  142. const paymentDetailsTableRef = ref();
  143. const paymentDetailsTable = reactive<Record<string, any>>({
  144. loading: false,
  145. columns: paymentDetailColumns,
  146. dataSource: []
  147. });
  148. const activeKey = ref('paymentDetails');
  149. var notAllowEdit = ref(false);
  150. const formData = reactive<Record<string, any>>({
  151. id: '',
  152. status: undefined,
  153. delFlag: undefined,
  154. sourceCode:'',
  155. billDate: moment(new Date()).format('YYYY-MM-DD'),
  156. billCode: '',
  157. supplier: '',
  158. supplierName: '',
  159. expectedPaymentDate: '',
  160. payee: '',
  161. openingBank: '',
  162. bankAccount: '',
  163. swiftCode: '',
  164. currency: '',
  165. notes:'',
  166. collectionCertificate:''
  167. });
  168. //表单验证
  169. const validatorRules = reactive({
  170. supplier: [
  171. { required: true, message: '请选择供应商(select supplier)' },
  172. ],
  173. currency: [
  174. { required: true, message: '请选择币种(select currency)' }
  175. ],
  176. });
  177. const {resetFields, validate, validateInfos} = useForm(formData, validatorRules, {immediate: false});
  178. const dbData = {};
  179. const formItemLayout = {
  180. labelCol: {xs: {span: 24}, sm: {span: 8}},
  181. wrapperCol: {xs: {span: 24}, sm: {span: 13}},
  182. labelCol1: {xs: {span: 24}, sm: {span: 8}},
  183. wrapperCol1: {xs: {span: 24}, sm: {span: 13}},
  184. };
  185. // 表单禁用
  186. const disabled = computed(()=>{
  187. if(props.formBpm === true){
  188. if(props.formData.disabled === false){
  189. return false;
  190. }else{
  191. return true;
  192. }
  193. }
  194. return props.formDisabled;
  195. });
  196. //新增方法
  197. function add() {
  198. resetFields();
  199. paymentDetailsTable.dataSource = [];
  200. activeKey.value = 'paymentDetails'
  201. notAllowEdit.value = false
  202. }
  203. //编辑方法
  204. async function edit(row) {
  205. //主表数据
  206. await queryMainData(row.id);
  207. const paymentDetailsDataList = await queryPaymentDetailListByMainId(row['id']);
  208. paymentDetailsTable.dataSource = [...paymentDetailsDataList];
  209. notAllowEdit.value=true
  210. }
  211. //获取主表
  212. async function queryMainData(id) {
  213. const row = await queryDataById(id);
  214. resetFields();
  215. const tmpData = {};
  216. Object.keys(formData).forEach((key) => {
  217. if(row.hasOwnProperty(key)){
  218. tmpData[key] = row[key]
  219. }
  220. })
  221. //赋值
  222. Object.assign(formData,tmpData);
  223. }
  224. const {getSubFormAndTableData, transformData} = useValidateAntFormAndTable(activeKey, {
  225. 'purPaymentRequestDetails': paymentDetailsTableRef,
  226. });
  227. //获取表单信息
  228. async function getFormData() {
  229. try {
  230. // 触发表单验证
  231. await validate();
  232. } catch ({ errorFields }) {
  233. if (errorFields) {
  234. const firstField = errorFields[0];
  235. if (firstField) {
  236. formRef.value.scrollToField(firstField.name, { behavior: 'smooth', block: 'center' });
  237. }
  238. }
  239. return Promise.reject(errorFields);
  240. }
  241. return transformData(toRaw(formData))
  242. }
  243. //保存
  244. async function submitForm() {
  245. var xTable = paymentDetailsTableRef.value!.getXTable()
  246. if(xTable.data.length==0){
  247. message.warning('请添加付款明细')
  248. }else{
  249. paymentDetailsTableRef.value!.validateTable().then(async (errMap) => {
  250. if (errMap) {
  251. console.log('表单验证未通过:', { errMap });
  252. } else {
  253. const mainData = await getFormData();
  254. const subData = await getSubFormAndTableData();
  255. const values = Object.assign({}, dbData, mainData, subData);
  256. console.log('表单提交数据', values)
  257. const isUpdate = values.id ? true : false
  258. await saveOrUpdate(values, isUpdate);
  259. //关闭弹窗
  260. emit('success');
  261. }
  262. })
  263. }
  264. }
  265. function setFieldsValue(values) {
  266. if(values){
  267. Object.keys(values).map(k=>{
  268. formData[k] = values[k];
  269. });
  270. }
  271. }
  272. /**
  273. * 值改变事件触发-树控件回调
  274. * @param key
  275. * @param value
  276. */
  277. function handleFormChange(key, value) {
  278. formData[key] = value;
  279. }
  280. //产品明细-删除行
  281. async function handleDelete1(prop) {
  282. var xTable = paymentDetailsTableRef.value!.getXTable()
  283. var newArray = [...xTable.data]
  284. newArray.splice(prop.rowIndex, 1)
  285. paymentDetailsTable.dataSource = newArray
  286. }
  287. function changeValues(prop){
  288. }
  289. function selectOrder(){
  290. SelectPurchaseOrderModalRef.value.getTable()
  291. }
  292. function addDetailList(data){
  293. var billCodeArr=[]
  294. data.map(item=>{
  295. item.sourceId = item.id
  296. item.purchaseCode = item.billCode
  297. billCodeArr.push(item.billCode)
  298. item.purchaseId = item.id
  299. item.orderMoney = item.totalAmount
  300. item.applyMoney = item.totalAmountUsed
  301. item.id = undefined
  302. })
  303. formData.sourceCode = formData.sourceCode+','+billCodeArr.join(',')
  304. var xTable = paymentDetailsTableRef.value!.getXTable()
  305. var arrSonFormDelivery = xTable.data.concat(data)
  306. paymentDetailsTable.dataSource=arrSonFormDelivery
  307. }
  308. async function changeSupplier(value){
  309. debugger
  310. var param={id:value}
  311. var result=await supplierOption(param)
  312. formData.supplierName =result.records[0].name
  313. debugger
  314. }
  315. return {
  316. supplierOption,
  317. paymentDetailsTableRef,
  318. paymentDetailsTable,
  319. validatorRules,
  320. validateInfos,
  321. activeKey,
  322. loading,
  323. formData,
  324. setFieldsValue,
  325. handleFormChange,
  326. formItemLayout,
  327. disabled,
  328. getFormData,
  329. submitForm,
  330. add,
  331. edit,
  332. formRef,
  333. handleDelete1,
  334. notAllowEdit,
  335. changeValues,
  336. SelectPurchaseOrderModalRef,
  337. selectOrder,
  338. addDetailList,
  339. changeSupplier,
  340. showField
  341. }
  342. }
  343. });
  344. </script>
  345. <style lang="less" scoped>
  346. /** 时间和数字输入框样式 */
  347. :deep(.ant-input-number) {
  348. width: 100%;
  349. }
  350. :deep(.ant-calendar-picker) {
  351. width: 100%;
  352. }
  353. /deep/.vxe-table--body-wrapper{
  354. height: 100% !important;
  355. }
  356. /deep/.ant-modal-body{
  357. padding: 24px !important;
  358. }
  359. /deep/.ant-form-item{
  360. margin-bottom: 8px !important;
  361. }
  362. /deep/.vxe-cell--valid-error-msg{
  363. color: white !important;
  364. background-color: white !important;
  365. }
  366. </style>