purchaseInForm.vue 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462
  1. <template>
  2. <a-spin :spinning="loading">
  3. <JFormContainer :disabled="disabled">
  4. <template #detail>
  5. <a-form v-bind="formItemLayout" name="SaleOrderForm" ref="formRef">
  6. <a-row>
  7. <a-col :span="12">
  8. <a-form-item label="入库单号(bill code)" v-bind="validateInfos.billCode" id="SaleOrderForm-billCode" name="billCode">
  9. <a-input v-model:value="formData.billCode" placeholder="自动生成" disabled />
  10. </a-form-item>
  11. </a-col>
  12. <a-col :span="12">
  13. <a-form-item label="入库日期(bill date)" v-bind="validateInfos.billDate" id="SaleOrderForm-billDate" name="billDate">
  14. <a-date-picker
  15. placeholder="请选择入库日期(bill date)"
  16. v-model:value="formData.billDate"
  17. value-format="YYYY-MM-DD"
  18. style="width: 100%"
  19. allow-clear
  20. />
  21. </a-form-item>
  22. </a-col>
  23. <a-col :span="12">
  24. <a-form-item label="项目(project)" v-bind="validateInfos.projectName" id="SaleOrderForm-projectName" name="projectName">
  25. <a-input v-model:value="formData.projectName" placeholder="请输入项目(project)" disabled allow-clear />
  26. </a-form-item>
  27. </a-col>
  28. <a-col :span="12">
  29. <a-form-item label="供应商(supplier)" v-bind="validateInfos.supplierName" id="SaleOrderForm-supplierName" name="supplierName">
  30. <a-input v-model:value="formData.supplierName" placeholder="请输入" disabled allow-clear />
  31. </a-form-item>
  32. </a-col>
  33. <a-col :span="12">
  34. <a-form-item label="发货方式(delivery)" v-bind="validateInfos.delivery" id="SaleOrderForm-delivery" name="delivery">
  35. <JDictSelectTag v-model:value="formData.delivery" placeholder="请选择" dictCode="delivery_methods" disabled />
  36. </a-form-item>
  37. </a-col>
  38. <a-col :span="12">
  39. <a-form-item
  40. label="产品分类(production class)"
  41. v-bind="validateInfos.productionClass"
  42. id="SaleOrderForm-productionClass"
  43. name="productionClass"
  44. >
  45. <ApiSelect
  46. :api="ClassList"
  47. showSearch
  48. v-model:value="formData.productionClass"
  49. optionFilterProp="label"
  50. resultField="records"
  51. labelField="name"
  52. valueField="id"
  53. :params="{ pageSize: -1 }"
  54. disabled
  55. />
  56. </a-form-item>
  57. </a-col>
  58. <a-col :span="12">
  59. <a-form-item label="机型(model)" v-bind="validateInfos.model" id="SaleOrderForm-model" name="model">
  60. <a-input v-model:value="formData.model" placeholder="请输入" allow-clear disabled />
  61. </a-form-item>
  62. </a-col>
  63. <a-col :span="12">
  64. <a-form-item label="厂家(maker)" v-bind="validateInfos.maker" id="SaleOrderForm-maker" name="maker">
  65. <a-input v-model:value="formData.maker" placeholder="请输入厂家(maker)" allow-clear disabled />
  66. </a-form-item>
  67. </a-col>
  68. <a-col :span="12">
  69. <a-form-item
  70. label="货位(goods allocation)"
  71. v-bind="validateInfos.goodsAllocation"
  72. id="SaleOrderForm-goodsAllocation"
  73. name="goodsAllocation"
  74. >
  75. <JDictSelectTag v-model:value="formData.goodsAllocation" placeholder="请选择" dictCode="goods_allocation" />
  76. </a-form-item>
  77. </a-col>
  78. <a-col :span="12">
  79. <a-form-item label="仓库(warehouse)" v-bind="validateInfos.warehouse" id="SaleOrderForm-warehouse" name="warehouse">
  80. <JDictSelectTag v-model:value="formData.warehouse" placeholder="请选择" dictCode="warehouse" />
  81. </a-form-item>
  82. </a-col>
  83. <a-col :span="12">
  84. <a-form-item label="包装详情(packaging details)" v-bind="validateInfos.method" id="SaleOrderForm-method" name="method">
  85. <a-textarea v-model:value="formData.method" placeholder="请输入" allow-clear row="3"/>
  86. </a-form-item>
  87. </a-col>
  88. <a-col :span="12">
  89. <a-form-item label="备注(notes)" v-bind="validateInfos.notes" id="SaleOrderForm-notes" name="notes">
  90. <a-textarea v-model:value="formData.notes" AutoComplete="off" row="3"/>
  91. </a-form-item>
  92. </a-col>
  93. <a-col :span="12">
  94. <a-form-item
  95. label="到货详情(arrival details)"
  96. v-bind="validateInfos.arrivalDetails"
  97. id="PuechaseInquiryFormForm-attachs"
  98. name="arrivalDetails"
  99. >
  100. <a :href="baseUrl + formData.arrivalDetails">{{ formData.arrivalDetails }}</a>
  101. </a-form-item>
  102. </a-col>
  103. <a-col :span="12">
  104. <a-form-item label="附件(attachs)" v-bind="validateInfos.attachs" id="PuechaseInquiryFormForm-attachs" name="attachs">
  105. <JUpload v-model:value="formData.attachs" />
  106. </a-form-item>
  107. </a-col>
  108. </a-row>
  109. </a-form>
  110. </template>
  111. </JFormContainer>
  112. <!-- 子表单区域 -->
  113. <a-tabs v-model:activeKey="activeKey" animated style="padding: 24px; padding-top: 0px">
  114. <a-tab-pane tab="采购入库 - 入库明细(stock in details)" key="stockIn" :forceRender="true">
  115. <a-button type="primary" style="margin-right: 1%; margin-bottom: 1%" @click="selectArrivalList"> 选择到货单(select arrival)</a-button>
  116. <j-vxe-table
  117. :keep-source="true"
  118. resizable
  119. ref="stockInTableRef"
  120. :loading="stockInTable.loading"
  121. :columns="stockInTable.columns"
  122. :dataSource="stockInTable.dataSource"
  123. :maxHeight="340"
  124. :disabled="disabled"
  125. :rowNumber="true"
  126. :rowSelection="true"
  127. asyncRemove
  128. >
  129. <template #action="props">
  130. <a-popconfirm title="确定删除吗?" @confirm="handleDelete(props)">
  131. <a>删除(delete)</a>
  132. </a-popconfirm>
  133. <!-- 逻辑不通暂时取消次功能 -->
  134. <!-- <a>复制(copy)</a> -->
  135. </template>
  136. </j-vxe-table>
  137. </a-tab-pane>
  138. <a-tab-pane tab="采购入库 - 船明细(ship details)" key="purInShip" :forceRender="true">
  139. <j-vxe-table
  140. :keep-source="true"
  141. resizable
  142. ref="purInShipTableRef"
  143. :loading="purInShipTable.loading"
  144. :columns="purInShipTable.columns"
  145. :dataSource="purInShipTable.dataSource"
  146. :maxHeight="340"
  147. :disabled="disabled"
  148. :rowNumber="true"
  149. :rowSelection="true"
  150. >
  151. <template #action="props">
  152. <a @click="viewAccessory(props)">查看配件信息(view accessory information)</a>
  153. </template>
  154. </j-vxe-table>
  155. </a-tab-pane>
  156. </a-tabs>
  157. <BaseShipArchiveAccessoriesModal ref="BaseShipArchiveAccessoriesModalRef" />
  158. <selectArrivalList ref="SelectArrivalListRef" @select-arrrival-order="addStockInList" />
  159. </a-spin>
  160. </template>
  161. <script lang="ts">
  162. import { defineComponent, ref, reactive, computed, toRaw } from 'vue';
  163. import { defHttp } from '/@/utils/http/axios';
  164. import { useValidateAntFormAndTable } from '/@/hooks/system/useJvxeMethods';
  165. import { queryPurInFormShipFormShippTable, querystockInByMainId, queryDataById, saveOrUpdate, ClassList } from '../purchaseInForm.api';
  166. import { JVxeTable } from '/@/components/jeecg/JVxeTable';
  167. import { purInShipColumns, stockInColumns } from '../puechaseInForm.data';
  168. import BaseShipArchiveAccessoriesModal from '../../../publicComponents/BaseShipArchiveAccessoriesModal.vue';
  169. import selectArrivalList from '../../../publicComponents/selectArrivalList.vue';
  170. import JFormContainer from '/@/components/Form/src/container/JFormContainer.vue';
  171. import JUpload from '/@/components/Form/src/jeecg/components/JUpload/JUpload.vue';
  172. import { JDictSelectTag } from '/@/components/Form';
  173. import { Form, message } from 'ant-design-vue';
  174. import { useGlobSetting } from '/@/hooks/setting';
  175. import { ApiSelect } from '/@/components/Form/index';
  176. import { initDictOptions } from '/@/utils/dict';
  177. import moment from 'moment';
  178. const useForm = Form.useForm;
  179. export default defineComponent({
  180. name: 'PurchaseInForm',
  181. components: {
  182. JVxeTable,
  183. JFormContainer,
  184. JUpload,
  185. JDictSelectTag,
  186. BaseShipArchiveAccessoriesModal,
  187. selectArrivalList,
  188. ApiSelect,
  189. },
  190. props: {
  191. formDisabled: {
  192. type: Boolean,
  193. default: false,
  194. },
  195. formData: { type: Object, default: () => {} },
  196. formBpm: { type: Boolean, default: true },
  197. },
  198. emits: ['success'],
  199. setup(props, { emit }) {
  200. const { domainUrl } = useGlobSetting();
  201. const baseUrl = domainUrl + '/sys/common/static/';
  202. const loading = ref(false);
  203. const formRef = ref();
  204. const SelectArrivalListRef = ref();
  205. const purInShipTableRef = ref();
  206. const BaseShipArchiveAccessoriesModalRef = ref();
  207. const purInShipTable = reactive<Record<string, any>>({
  208. loading: false,
  209. columns: purInShipColumns,
  210. dataSource: [],
  211. });
  212. const stockInTableRef = ref();
  213. const stockInTable = reactive<Record<string, any>>({
  214. loading: false,
  215. columns: stockInColumns,
  216. dataSource: [],
  217. });
  218. const activeKey = ref('stockIn');
  219. const formData = reactive<Record<string, any>>({
  220. id: '',
  221. status: undefined,
  222. delFlag: undefined,
  223. sourceCode: '',
  224. billCode: '',
  225. billDate: moment(new Date()).format('YYYY-MM-DD'),
  226. project: '',
  227. projectName: '',
  228. supplier: '',
  229. supplierName: '',
  230. delivery: '',
  231. productionClass: '',
  232. model: '',
  233. maker: '',
  234. goodsAllocation: '',
  235. warehouse: '',
  236. notes: '',
  237. attachs: '',
  238. arrivalDetails: '',
  239. typr: '1',
  240. method: '',
  241. });
  242. //表单验证
  243. const validatorRules = reactive({});
  244. const { resetFields, validate, validateInfos } = useForm(formData, validatorRules, { immediate: false });
  245. const dbData = {};
  246. const formItemLayout = {
  247. labelCol: { xs: { span: 24 }, sm: { span: 5 } },
  248. wrapperCol: { xs: { span: 24 }, sm: { span: 16 } },
  249. labelCol1: { xs: { span: 24 }, sm: { span: 7 } },
  250. wrapperCol1: { xs: { span: 24 }, sm: { span: 15 } },
  251. };
  252. // 表单禁用
  253. const disabled = computed(() => {
  254. if (props.formBpm === true) {
  255. if (props.formData.disabled === false) {
  256. return false;
  257. } else {
  258. return true;
  259. }
  260. }
  261. return props.formDisabled;
  262. });
  263. async function add() {
  264. resetFields();
  265. purInShipTable.dataSource = [];
  266. stockInTable.dataSource = [];
  267. activeKey.value = 'stockIn';
  268. var warehouseArr = await initDictOptions('warehouse');
  269. var goodsAllocationArr = await initDictOptions('goods_allocation');
  270. formData.warehouse = warehouseArr[0].value;
  271. formData.goodsAllocation = goodsAllocationArr[0].value;
  272. }
  273. async function edit(row) {
  274. //主表数据
  275. await queryMainData(row.id);
  276. //子表数据
  277. const purInShipDataList = await queryPurInFormShipFormShippTable(row['id']);
  278. purInShipTable.dataSource = [...purInShipDataList];
  279. const stockInDataList = await querystockInByMainId(row['id']);
  280. stockInTable.dataSource = [...stockInDataList];
  281. }
  282. async function queryMainData(id) {
  283. const row = await queryDataById(id);
  284. resetFields();
  285. const tmpData = {};
  286. Object.keys(formData).forEach((key) => {
  287. if (row.hasOwnProperty(key)) {
  288. tmpData[key] = row[key];
  289. }
  290. });
  291. //赋值
  292. Object.assign(formData, tmpData);
  293. }
  294. const { getSubFormAndTableData, transformData } = useValidateAntFormAndTable(activeKey, {
  295. storePurchaseInShip: purInShipTableRef,
  296. storePurchaseInDetails: stockInTableRef,
  297. });
  298. async function getFormData() {
  299. try {
  300. // 触发表单验证
  301. await validate();
  302. } catch ({ errorFields }) {
  303. if (errorFields) {
  304. const firstField = errorFields[0];
  305. if (firstField) {
  306. formRef.value.scrollToField(firstField.name, { behavior: 'smooth', block: 'center' });
  307. }
  308. }
  309. return Promise.reject(errorFields);
  310. }
  311. return transformData(toRaw(formData));
  312. }
  313. async function submitForm() {
  314. if (formData.sourceCode == '') {
  315. message.error('请添加入库明细!');
  316. } else {
  317. stockInTableRef.value!.validateTable().then(async (errMap) => {
  318. if (errMap) {
  319. console.log('表单验证未通过:', { errMap });
  320. } else {
  321. const mainData = await getFormData();
  322. const subData = await getSubFormAndTableData();
  323. const values = Object.assign({}, dbData, mainData, subData);
  324. console.log('表单提交数据', values);
  325. const isUpdate = values.id ? true : false;
  326. await saveOrUpdate(values, isUpdate);
  327. //关闭弹窗
  328. emit('success');
  329. }
  330. })
  331. }
  332. }
  333. function setFieldsValue(values) {
  334. if (values) {
  335. Object.keys(values).map((k) => {
  336. formData[k] = values[k];
  337. });
  338. }
  339. }
  340. function getShipList(id) {
  341. let params = { id: id };
  342. let url = '/purCode/purDeliveryNote/queryPurDeliveryNodeShipByMainId';
  343. defHttp.get({ url: url, params }, { isTransformResponse: false }).then((res) => {
  344. if (res) {
  345. purInShipTable.dataSource = res.result;
  346. }
  347. });
  348. }
  349. //查看配件信息
  350. function viewAccessory(prop) {
  351. BaseShipArchiveAccessoriesModalRef.value.getTable(prop.row);
  352. }
  353. //产品明细-删除行
  354. function handleDelete(prop) {
  355. var xTable = stockInTableRef.value!.getXTable()
  356. var newArray = [...xTable.data];
  357. newArray.splice(prop.rowIndex, 1);
  358. stockInTable.dataSource = newArray;
  359. if (stockInTable.dataSource.length == 0) {
  360. formData.sourceCode = '';
  361. add();
  362. }
  363. }
  364. function selectArrivalList() {
  365. SelectArrivalListRef.value.getTable(formData);
  366. }
  367. function addStockInList(data) {
  368. formData.project = data[0].project;
  369. formData.projectName = data[0].projectName;
  370. formData.supplier = data[0].supplier;
  371. formData.supplierName = data[0].supplierName;
  372. formData.delivery = data[0].delivery;
  373. formData.productionClass = data[0].productionClass;
  374. formData.model = data[0].model;
  375. formData.maker = data[0].maker;
  376. formData.sourceCode = data[0].billCode;
  377. formData.arrivalDetails = data[0].arrivalDetails;
  378. getShipList(data[0].headId);
  379. data.map((item) => {
  380. item.model = item.childModel;
  381. item.sourceId = item.childId;
  382. item.arrivalQuantity = item.quantity;
  383. item.stockInQuantity = item.quantity;
  384. });
  385. var xTable = stockInTableRef.value!.getXTable()
  386. var arr = xTable.data.concat(data);
  387. stockInTable.dataSource = arr;
  388. }
  389. /**
  390. * 值改变事件触发-树控件回调
  391. * @param key
  392. * @param value
  393. */
  394. function handleFormChange(key, value) {
  395. formData[key] = value;
  396. }
  397. return {
  398. purInShipTableRef,
  399. purInShipTable,
  400. stockInTableRef,
  401. stockInTable,
  402. validatorRules,
  403. validateInfos,
  404. activeKey,
  405. loading,
  406. formData,
  407. setFieldsValue,
  408. handleFormChange,
  409. formItemLayout,
  410. disabled,
  411. getFormData,
  412. submitForm,
  413. add,
  414. edit,
  415. formRef,
  416. handleDelete,
  417. BaseShipArchiveAccessoriesModalRef,
  418. viewAccessory,
  419. SelectArrivalListRef,
  420. selectArrivalList,
  421. addStockInList,
  422. baseUrl,
  423. ClassList,
  424. };
  425. },
  426. });
  427. </script>
  428. <style lang="less" scoped>
  429. /** 时间和数字输入框样式 */
  430. :deep(.ant-input-number) {
  431. width: 100%;
  432. }
  433. :deep(.ant-calendar-picker) {
  434. width: 100%;
  435. }
  436. /deep/.vxe-table--body-wrapper {
  437. height: 100% !important;
  438. }
  439. /deep/.ant-modal-body {
  440. padding: 24px !important;
  441. }
  442. /deep/.ant-form-item {
  443. margin-bottom: 8px !important;
  444. }
  445. /deep/.vxe-cell--valid-error-msg{
  446. color: white !important;
  447. background-color: white !important;
  448. }
  449. </style>