SelectQuotationFormForm.vue 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482
  1. <template>
  2. <a-spin :spinning="loading">
  3. <JFormContainer :disabled="disabled">
  4. <template #detail>
  5. <a-form v-bind="formItemLayout" name="SelectQuotationFormForm" ref="formRef">
  6. <a-row>
  7. <a-col :span="12">
  8. <a-form-item label="选定单号(bill code)" v-bind="validateInfos.billCode" id="SelectQuotationFormForm-billCode" name="billCode">
  9. <a-input v-model:value="formData.billCode" placeholder="请输入报价单号(bill code)" 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="SelectQuotationFormForm-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="询价项目(inquiry project)" v-bind="validateInfos.projectName" id="SelectQuotationFormForm-projectName" name="projectName">
  19. <a-input-search v-model:value="formData.projectName" placeholder="请输入询价项目(inquiry project)" allow-clear enter-button="Search" @search="onSearchProject"></a-input-search>
  20. </a-form-item>
  21. </a-col>
  22. <a-col :span="12">
  23. <a-form-item label="优先级(priority)" v-bind="validateInfos.priority" id="SelectQuotationFormForm-priority" name="priority">
  24. <JDictSelectTag v-model:value="formData.priority" placeholder="请选择" dictCode="priority" disabled/>
  25. </a-form-item>
  26. </a-col>
  27. <a-col :span="12">
  28. <a-form-item label="产品分类(production class)" v-bind="validateInfos.productionClass" id="SelectQuotationFormForm-productionClass" name="productionClass">
  29. <a-input v-model:value="formData.productionClass" placeholder="请输入" allow-clear disabled></a-input>
  30. </a-form-item>
  31. </a-col>
  32. <a-col :span="12">
  33. <a-form-item label="机型(model)" v-bind="validateInfos.model" id="SelectQuotationFormForm-model" name="model">
  34. <JDictSelectTag v-model:value="formData.model" placeholder="请选择" dictCode="model_typer" disabled/>
  35. </a-form-item>
  36. </a-col>
  37. <a-col :span="12">
  38. <a-form-item label="厂家(maker)" v-bind="validateInfos.maker" id="SelectQuotationFormForm-maker" name="maker">
  39. <a-input v-model:value="formData.maker" placeholder="请输入厂家(maker)" allow-clear disabled></a-input>
  40. </a-form-item>
  41. </a-col>
  42. <a-col :span="12">
  43. <a-form-item label="选定备注(selection notes)" v-bind="validateInfos.selectionNotes" id="SelectQuotationFormForm-selectionNotes" name="selectionNotes">
  44. <a-input v-model:value="formData.selectionNotes" placeholder="请输入选定备注备注(selection notes)" allow-clear ></a-input>
  45. </a-form-item>
  46. </a-col>
  47. <a-col :span="12">
  48. <a-form-item label="附件(attachs)" v-bind="validateInfos.attachs" id="SelectQuotationFormForm-attachs" name="attachs">
  49. <JUpload v-model:value="formData.attachs"></JUpload>
  50. </a-form-item>
  51. </a-col>
  52. </a-row>
  53. </a-form>
  54. </template>
  55. </JFormContainer>
  56. <!-- 子表单区域 -->
  57. <a-tabs v-model:activeKey="activeKey" animated style=" padding: 24px;padding-top: 0px;">
  58. <a-tab-pane tab="采购报价单选定 - 产品明细(product details)" key="SelectQuotationFormProduct" :forceRender="true">
  59. <j-vxe-table
  60. :keep-source="true"
  61. resizable
  62. ref="SelectQuotationFormProductTableRef"
  63. :loading="SelectQuotationFormProductTable.loading"
  64. :columns="SelectQuotationFormProductTable.columns"
  65. :dataSource="SelectQuotationFormProductTable.dataSource"
  66. :height="340"
  67. :disabled="disabled"
  68. :rowNumber="true"
  69. :rowSelection="true"
  70. asyncRemove
  71. >
  72. <template #selectionSupplier="props">
  73. <a-select v-model:value="props.row.selectionSupplier" style="width: 100%;" @change="selectSupplier(props)">
  74. <a-select-option v-for="item in supplierList" :key="item.value" >{{ item.label }}</a-select-option>
  75. </a-select>
  76. </template>
  77. <template #action="props">
  78. <a-popconfirm title="确定删除吗?" @confirm="handleDelete1(props)">
  79. <a>删除(delete)</a>
  80. </a-popconfirm>
  81. </template>
  82. </j-vxe-table>
  83. </a-tab-pane>
  84. <a-tab-pane tab="采购报价单选定 - 船明细(ship details)" key="SelectQuotationFormShip" :forceRender="true">
  85. <j-vxe-table
  86. :keep-source="true"
  87. resizable
  88. ref="SelectQuotationFormShipTableRef"
  89. :loading="SelectQuotationFormShipTable.loading"
  90. :columns="SelectQuotationFormShipTable.columns"
  91. :dataSource="SelectQuotationFormShipTable.dataSource"
  92. :height="340"
  93. :disabled="disabled"
  94. :rowNumber="true"
  95. :rowSelection="true"
  96. >
  97. <template #action="props" >
  98. <a @click="viewAccessory(props)" >查看配件信息(view accessory information)</a>
  99. </template>
  100. </j-vxe-table>
  101. </a-tab-pane>
  102. <a-tab-pane tab="采购报价单选定 - 供应商报价明细(supplier quotation details)" key="SupplierQuotationDetails" :forceRender="true">
  103. <j-vxe-table
  104. :keep-source="true"
  105. resizable
  106. ref="SupplierQuotationDetailsTableRef"
  107. :loading="SupplierQuotationDetailsTable.loading"
  108. :columns="SupplierQuotationDetailsTable.columns"
  109. :dataSource="SupplierQuotationDetailsTable.dataSource"
  110. :rowKey="record => record.childId"
  111. :height="340"
  112. :disabled="disabled"
  113. :rowNumber="true"
  114. :rowSelection="true"
  115. asyncRemove
  116. >
  117. </j-vxe-table>
  118. </a-tab-pane>
  119. <a-tab-pane tab="采购报价单选定 - 供应商汇总金额(supplier summary amount)" key="SupplierSummaryAmount" :forceRender="true">
  120. <j-vxe-table
  121. :keep-source="true"
  122. resizable
  123. ref="SupplierSummaryAmountTableRef"
  124. :loading="SupplierSummaryAmountTable.loading"
  125. :columns="SupplierSummaryAmountTable.columns"
  126. :dataSource="SupplierSummaryAmountTable.dataSource"
  127. :height="340"
  128. :disabled="disabled"
  129. :rowNumber="true"
  130. :rowSelection="true"
  131. asyncRemove
  132. >
  133. </j-vxe-table>
  134. </a-tab-pane>
  135. </a-tabs>
  136. <BaseShipArchiveAccessoriesModal ref="BaseShipArchiveAccessoriesListRef"></BaseShipArchiveAccessoriesModal>
  137. <SelectProjectModal ref="SelectProjectModalRef" @selectProject="addProject"></SelectProjectModal>
  138. </a-spin>
  139. </template>
  140. <script lang="ts">
  141. import { defineComponent, ref, reactive, computed, toRaw, onMounted } from 'vue';
  142. import { defHttp } from '/@/utils/http/axios';
  143. import { useValidateAntFormAndTable } from '/@/hooks/system/useJvxeMethods';
  144. import { SelectQuotationFormShippTable, SelectQuotationFormProductListByMainId, queryDataById, saveOrUpdate } from '../SelectionQuotationForm.api';
  145. import { JVxeTable } from '/@/components/jeecg/JVxeTable';
  146. import {SelectQuotationFormShipTableCloumn, SelectQuotationFormProductColumns,SupplierQuotationColumns,SupplierSummaryAmountColumns} from '../SelectionQuotationForm.data';
  147. import BaseShipArchiveAccessoriesModal from '../../../publicComponents/BaseShipArchiveAccessoriesModal.vue';
  148. import SelectProjectModal from '../../../publicComponents/SelectProjectModal.vue';
  149. import JFormContainer from '/@/components/Form/src/container/JFormContainer.vue';
  150. import JUpload from '/@/components/Form/src/jeecg/components/JUpload/JUpload.vue';
  151. import { JDictSelectTag} from '/@/components/Form';
  152. import JSelectInput from '/@/components/Form/src/jeecg/components/JSelectInput.vue';
  153. import { Form ,message} from 'ant-design-vue';
  154. import moment from 'moment';
  155. import { log } from 'console';
  156. const useForm = Form.useForm;
  157. export default defineComponent({
  158. name: "SelectQuotationFormForm",
  159. components:{
  160. JVxeTable,
  161. JFormContainer,
  162. BaseShipArchiveAccessoriesModal,
  163. JUpload,
  164. SelectProjectModal,
  165. JDictSelectTag,
  166. JSelectInput,
  167. },
  168. props:{
  169. formDisabled:{
  170. type: Boolean,
  171. default: false
  172. },
  173. formData: { type: Object, default: ()=>{} },
  174. formBpm: { type: Boolean, default: true }
  175. },
  176. emits:['success'],
  177. setup(props, {emit}) {
  178. const loading = ref(false);
  179. const formRef = ref();
  180. var SelectProjectModalRef = ref()
  181. const SelectQuotationFormShipTableRef = ref();
  182. const SelectQuotationFormShipTable = reactive<Record<string, any>>({
  183. loading: false,
  184. columns: SelectQuotationFormShipTableCloumn,
  185. dataSource: []
  186. });
  187. const SelectQuotationFormProductTableRef = ref();
  188. const SupplierQuotationDetailsTableRef = ref();
  189. const SupplierSummaryAmountTableRef = ref();
  190. const SelectQuotationFormProductTable = reactive<Record<string, any>>({
  191. loading: false,
  192. columns: SelectQuotationFormProductColumns,
  193. dataSource: []
  194. });
  195. const SupplierQuotationDetailsTable = reactive<Record<string, any>>({
  196. loading: false,
  197. columns: SupplierQuotationColumns,
  198. dataSource: []
  199. });
  200. const SupplierSummaryAmountTable = reactive<Record<string, any>>({
  201. loading: false,
  202. columns: SupplierSummaryAmountColumns,
  203. dataSource: []
  204. });
  205. var BaseShipArchiveAccessoriesListRef = ref();
  206. var supplierList = ref([]);
  207. const activeKey = ref('SelectQuotationFormProduct');
  208. const formData = reactive<Record<string, any>>({
  209. id: '',
  210. status: undefined,
  211. delFlag: undefined,
  212. submit: '',
  213. billDate: moment(new Date()).format('YYYY-MM-DD'),
  214. billCode: '',
  215. inquiryProject: '',
  216. projectName:'',
  217. priority: '',
  218. productionClass: '',
  219. model: '',
  220. maker: '',
  221. selectionNotes:'',
  222. attachs:'',
  223. });
  224. //表单验证
  225. const validatorRules = reactive({
  226. });
  227. const {resetFields, validate, validateInfos} = useForm(formData, validatorRules, {immediate: false});
  228. const dbData = {};
  229. const formItemLayout = {
  230. labelCol: {xs: {span: 24}, sm: {span: 5}},
  231. wrapperCol: {xs: {span: 24}, sm: {span: 16}},
  232. };
  233. // 表单禁用
  234. const disabled = computed(()=>{
  235. if(props.formBpm === true){
  236. if(props.formData.disabled === false){
  237. return false;
  238. }else{
  239. return true;
  240. }
  241. }
  242. return props.formDisabled;
  243. });
  244. function add() {
  245. resetFields();
  246. SelectQuotationFormShipTable.dataSource = [];
  247. SelectQuotationFormProductTable.dataSource = [];
  248. SupplierQuotationDetailsTable.dataSource = []
  249. SupplierSummaryAmountTable.dataSource = []
  250. activeKey.value = 'SelectQuotationFormProduct'
  251. }
  252. async function edit(row) {
  253. //主表数据
  254. await queryMainData(row.id);
  255. //子表数据
  256. const SelectQuotationFormShipDataList = await SelectQuotationFormShippTable(row['id']);
  257. SelectQuotationFormShipTable.dataSource = [...SelectQuotationFormShipDataList];
  258. const SelectQuotationFormProductDataList = await SelectQuotationFormProductListByMainId(row['id']);
  259. SelectQuotationFormProductTable.dataSource = [...SelectQuotationFormProductDataList];
  260. getSupplierQuotationDetail(formData.inquiryProject)
  261. getSupplierSummaryAmount(formData.inquiryProject)
  262. }
  263. async function queryMainData(id) {
  264. const row = await queryDataById(id);
  265. resetFields();
  266. const tmpData = {};
  267. Object.keys(formData).forEach((key) => {
  268. if(row.hasOwnProperty(key)){
  269. tmpData[key] = row[key]
  270. }
  271. })
  272. //赋值
  273. Object.assign(formData,tmpData);
  274. }
  275. const {getSubFormAndTableData, transformData} = useValidateAntFormAndTable(activeKey, {
  276. 'purQuotationSelectionShip': SelectQuotationFormShipTableRef,
  277. 'purQuotationSelectionProduct': SelectQuotationFormProductTableRef,
  278. });
  279. async function getFormData() {
  280. try {
  281. // 触发表单验证
  282. await validate();
  283. } catch ({ errorFields }) {
  284. if (errorFields) {
  285. const firstField = errorFields[0];
  286. if (firstField) {
  287. formRef.value.scrollToField(firstField.name, { behavior: 'smooth', block: 'center' });
  288. }
  289. }
  290. return Promise.reject(errorFields);
  291. }
  292. return transformData(toRaw(formData))
  293. }
  294. async function submitForm() {
  295. const mainData = await getFormData();
  296. const subData = await getSubFormAndTableData();
  297. const values = Object.assign({}, dbData, mainData, subData);
  298. console.log('表单提交数据', values)
  299. const isUpdate = values.id ? true : false
  300. await saveOrUpdate(values, isUpdate);
  301. //关闭弹窗
  302. emit('success');
  303. }
  304. function setFieldsValue(values) {
  305. if(values){
  306. Object.keys(values).map(k=>{
  307. formData[k] = values[k];
  308. });
  309. }
  310. }
  311. /**
  312. * 值改变事件触发-树控件回调
  313. * @param key
  314. * @param value
  315. */
  316. function handleFormChange(key, value) {
  317. formData[key] = value;
  318. }
  319. async function handleDelete1(prop) {
  320. var newArray = [...SelectQuotationFormProductTable.dataSource]
  321. newArray.splice(prop.rowIndex, 1)
  322. SelectQuotationFormProductTable.dataSource = newArray
  323. }
  324. async function addProject(data) {
  325. if(data.length!==0){
  326. formData.inquiryProject = data[0].id
  327. formData.projectName = data[0].name
  328. await getShipDetail(data[0].id)
  329. await getSupplierQuotationDetail(data[0].id)
  330. await getSupplierSummaryAmount(data[0].id)
  331. var arr = [...SelectQuotationFormProductTable.dataSource]
  332. arr.map(item=>{
  333. try {
  334. SupplierQuotationDetailsTable.dataSource.map(event=>{
  335. if(item.productCode==event.productCode){
  336. item.selectionSupplier = event.quotationSuppiler
  337. throw 'break'
  338. }
  339. })
  340. }catch (e) {
  341. if (e === 'break') {
  342. return; // 捕获到退出标志,返回结束当前循环
  343. }
  344. }
  345. })
  346. SelectQuotationFormProductTable.dataSource = arr
  347. }else{
  348. formData.inquiryProject = ''
  349. formData.projectName = ''
  350. }
  351. }
  352. async function getShipDetail(id){
  353. let params = {projectId:id}
  354. await defHttp.get({url:'/purCode/purInquiryForm/getPurInquiryFormByProject',params}, { isTransformResponse: false }).then(res=>{
  355. if(res!==''){
  356. formData.priority = res.priority
  357. formData.productionClass = res.productionClass
  358. formData.model = res.model
  359. formData.maker = res.maker
  360. SelectQuotationFormShipTable.dataSource = res.purInquiryFormShipList
  361. SelectQuotationFormProductTable.dataSource = res.purInquiryFormProductList
  362. }else if(res==''){
  363. message.warning('当前项目还没有报价')
  364. }
  365. })
  366. }
  367. async function getSupplierQuotationDetail(id){
  368. let params = {quotationProject:id}
  369. await defHttp.get({url:'/purCode/purPurchaseQuotation/supplierQuotationDetails',params}, { isTransformResponse: false }).then(res=>{
  370. if(res){
  371. SupplierQuotationDetailsTable.dataSource=res.result.records
  372. supplierList.value= []
  373. res.result.records.map(item=>{
  374. supplierList.value.push({label:item.suppilerName,value:item.quotationSuppiler})
  375. })
  376. supplierList.value = supplierList.value.filter((item, index, self) => {
  377. return index === self.findIndex(obj => obj.value === item.value && obj.label === item.label);
  378. });
  379. }
  380. })
  381. }
  382. function getSupplierSummaryAmount(id){
  383. let params = {quotationProject:id}
  384. defHttp.get({url:'/purCode/purPurchaseQuotation/supplierQuotationTotal',params}, { isTransformResponse: false }).then(res=>{
  385. if(res){
  386. SupplierSummaryAmountTable.dataSource=res.result.records
  387. }
  388. })
  389. }
  390. function viewAccessory(prop){
  391. BaseShipArchiveAccessoriesListRef.value.getTable(prop.row)
  392. }
  393. function onSearchProject(){
  394. SelectProjectModalRef.value.getTable()
  395. }
  396. function selectSupplier(prop){
  397. SupplierQuotationDetailsTable.dataSource.map(item=>{
  398. if(item.productCode==prop.row.productCode&&item.quotationSuppiler==prop.row.selectionSupplier){
  399. var arr = [...SelectQuotationFormProductTable.dataSource]
  400. arr.map((event,index)=>{
  401. if(prop.rowIndex==index){
  402. arr[index]={...item}
  403. arr[index].selectionSupplier=item.quotationSuppiler
  404. arr[index].deliveryTime=item.childDeliveryTime
  405. }
  406. })
  407. SelectQuotationFormProductTable.dataSource = [...arr]
  408. }
  409. })
  410. }
  411. return {
  412. SelectQuotationFormShipTableRef,
  413. SelectQuotationFormShipTable,
  414. SelectQuotationFormProductTableRef,
  415. SelectQuotationFormProductTable,
  416. validatorRules,
  417. validateInfos,
  418. activeKey,
  419. loading,
  420. formData,
  421. setFieldsValue,
  422. handleFormChange,
  423. formItemLayout,
  424. disabled,
  425. getFormData,
  426. submitForm,
  427. add,
  428. edit,
  429. formRef,
  430. BaseShipArchiveAccessoriesListRef,
  431. viewAccessory,
  432. handleDelete1,
  433. SelectProjectModalRef,
  434. onSearchProject,
  435. addProject,
  436. SupplierQuotationDetailsTableRef,
  437. SupplierQuotationDetailsTable,
  438. SupplierSummaryAmountTableRef,
  439. SupplierSummaryAmountTable,
  440. supplierList,
  441. selectSupplier
  442. }
  443. }
  444. });
  445. </script>
  446. <style lang="less" scoped>
  447. /** 时间和数字输入框样式 */
  448. :deep(.ant-input-number) {
  449. width: 100%;
  450. }
  451. :deep(.ant-calendar-picker) {
  452. width: 100%;
  453. }
  454. /deep/.vxe-table--body-wrapper{
  455. height: 100% !important;
  456. }
  457. /deep/.ant-modal-body{
  458. padding: 24px !important;
  459. }
  460. /deep/.ant-form-item{
  461. margin-bottom: 8px !important;
  462. }
  463. </style>