Files
supervision-test-frontend-repo/src/views/gh/improvementProposal/components/ImprovementProposalForm.vue
T

470 lines
18 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<a-spin :spinning="loading">
<JFormContainer :disabled="disabled">
<template #detail>
<a-form v-bind="formItemLayout" name="ImprovementProposalForm" ref="formRef">
<a-row>
<a-col :span="12">
<a-form-item label="提案编号" :required="false" id="ImprovementProposalForm-proposalNo" name="proposalNo">
<a-input v-model:value="formData.proposalNo" :disabled="true" allow-clear></a-input>
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="提出日期" id="ImprovementProposalForm-proposalDate" name="proposalDate">
<a-input v-model:value="formData.proposalDate" :disabled="true" allow-clear></a-input>
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="提案名称" v-bind="validateInfos.proposalName" id="ImprovementProposalForm-proposalName" name="proposalName">
<a-input v-model:value="formData.proposalName" placeholder="请输入提案名称" allow-clear ></a-input>
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="提案类别" v-bind="validateInfos.proposalCategory" id="ImprovementProposalForm-proposalCategory" name="proposalCategory">
<j-dict-select-tag v-model:value="formData.proposalCategory" dictCode="proposal_category" placeholder="请选择提案类别" allow-clear />
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="提案部门" :required="false" id="ImprovementProposalForm-proposalDeptId" name="proposalDeptId">
<a-input v-model:value="formData.proposalDeptName" :disabled="true" allow-clear></a-input>
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="提案人" v-bind="validateInfos.applicantName" id="ImprovementProposalForm-applicantName" name="applicantName">
<a-input v-model:value="formData.applicantName" placeholder="请输入申请人姓名" allow-clear ></a-input>
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="团队名称" v-bind="validateInfos.teamName" id="ImprovementProposalForm-teamName" name="teamName">
<a-input v-model:value="formData.teamName" placeholder="请输入团队名称" allow-clear ></a-input>
</a-form-item>
</a-col>
<a-col :span="24">
<a-form-item label="问题描述" v-bind="validateInfos.problemDesc" id="ImprovementProposalForm-problemDesc" name="problemDesc" :labelCol="longLabelCol" :wrapperCol="longWrapperCol">
<a-textarea v-model:value="formData.problemDesc" :rows="4" placeholder="请输入问题描述" />
</a-form-item>
</a-col>
<a-col :span="24">
<a-form-item label="改善方法及措施" v-bind="validateInfos.improvementMethod" id="ImprovementProposalForm-improvementMethod" name="improvementMethod" :labelCol="longLabelCol" :wrapperCol="longWrapperCol">
<a-textarea v-model:value="formData.improvementMethod" :rows="4" placeholder="请输入改善方法及措施" />
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="改善前情况描述" v-bind="validateInfos.beforeDesc" id="ImprovementProposalForm-beforeDesc" name="beforeDesc" :labelCol="halfLabelCol" :wrapperCol="halfWrapperCol">
<a-textarea v-model:value="formData.beforeDesc" :rows="4" placeholder="请输入改善前情况描述" />
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="改善前图片" :labelCol="halfLabelCol" :wrapperCol="halfWrapperCol">
<SUploadFile ref="beforeFileRef" :bussiness-id="formData.id ? `${formData.id}:before` : ''" :multiple="true" :disabled="disabled" />
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="改善后情况描述" v-bind="validateInfos.afterDesc" id="ImprovementProposalForm-afterDesc" name="afterDesc" :labelCol="halfLabelCol" :wrapperCol="halfWrapperCol">
<a-textarea v-model:value="formData.afterDesc" :rows="4" placeholder="请输入改善后情况描述" />
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="改善后图片" :labelCol="halfLabelCol" :wrapperCol="halfWrapperCol">
<SUploadFile ref="afterFileRef" :bussiness-id="formData.id ? `${formData.id}:after` : ''" :multiple="true" :disabled="disabled" />
</a-form-item>
</a-col>
<a-col :span="24">
<a-form-item label="改善效果" v-bind="validateInfos.improvementEffect" id="ImprovementProposalForm-improvementEffect" name="improvementEffect" :labelCol="longLabelCol" :wrapperCol="longWrapperCol">
<a-textarea v-model:value="formData.improvementEffect" :rows="4" placeholder="请输入改善效果" />
</a-form-item>
</a-col>
</a-row>
</a-form>
</template>
</JFormContainer>
<!-- 新增申请只填写主表子表由后续评分和投票流程维护 -->
<a-tabs v-if="showSubTables" v-model:activeKey="activeKey" animated style="overflow:hidden;">
<a-tab-pane tab="部门评议评分表" key="improvementDeptScore" :forceRender="true">
<j-vxe-table
:keep-source="true"
resizable
ref="improvementDeptScoreTableRef"
:loading="improvementDeptScoreTable.loading"
:columns="improvementDeptScoreTable.columns"
:dataSource="improvementDeptScoreTable.dataSource"
:height="340"
:disabled="disabled"
:rowNumber="true"
:rowSelection="true"
:toolbar="true"/>
</a-tab-pane>
<a-tab-pane tab="所级评议投票表" key="improvementInstituteVote" :forceRender="true">
<j-vxe-table
:keep-source="true"
resizable
ref="improvementInstituteVoteTableRef"
:loading="improvementInstituteVoteTable.loading"
:columns="improvementInstituteVoteTable.columns"
:dataSource="improvementInstituteVoteTable.dataSource"
:height="340"
:disabled="disabled"
:rowNumber="true"
:rowSelection="true"
:toolbar="true"/>
</a-tab-pane>
</a-tabs>
<div v-if="showFlowSubmitButton" :span="24" style="width: 100%;text-align: center;margin-top: 10px">
<a-button preIcon="ant-design:check-outlined" style="width: 126px" type="primary" @click="submitForm"> </a-button>
</div>
</a-spin>
</template>
<script lang="ts">
import { defineComponent, ref, reactive, computed, toRaw, onMounted, nextTick } from 'vue';
import { defHttp } from '/@/utils/http/axios';
import { useValidateAntFormAndTable } from '/@/hooks/system/useJvxeMethods';
import { queryImprovementDeptScoreListByMainId, queryImprovementInstituteVoteListByMainId, queryDataById, saveOrUpdate, getLatestProposalSequence } from '../ImprovementProposal.api';
import { JVxeTable } from '/@/components/jeecg/JVxeTable';
import {improvementDeptScoreColumns, improvementInstituteVoteColumns} from '../ImprovementProposal.data';
import JFormContainer from '/@/components/Form/src/container/JFormContainer.vue';
import { Form } from 'ant-design-vue';
import JDictSelectTag from '/@/components/Form/src/jeecg/components/JDictSelectTag.vue';
import SUploadFile from '/@/components/semri/fileComponent/SUploadFile.vue';
import { useUserStore } from '/@/store/modules/user';
const useForm = Form.useForm;
export default defineComponent({
name: "ImprovementProposalForm",
components:{
JVxeTable,
JFormContainer,
JDictSelectTag,
SUploadFile,
},
props:{
formDisabled:{
type: Boolean,
default: false
},
formData: { type: Object, default: ()=>{} },
formBpm: { type: Boolean, default: true }
},
emits:['success'],
setup(props, {emit}) {
const loading = ref(false);
const formRef = ref();
const beforeFileRef = ref();
const afterFileRef = ref();
const improvementDeptScoreTableRef = ref();
const improvementDeptScoreTable = reactive<Record<string, any>>({
loading: false,
columns: improvementDeptScoreColumns,
dataSource: []
});
const improvementInstituteVoteTableRef = ref();
const improvementInstituteVoteTable = reactive<Record<string, any>>({
loading: false,
columns: improvementInstituteVoteColumns,
dataSource: []
});
const activeKey = ref('improvementDeptScore');
const userStore = useUserStore();
const formData = reactive<Record<string, any>>({
id: '',
proposalNo: '',
proposalName: '',
proposalDate: '',
proposalDeptId: '',
proposalDeptName: '',
proposalDeptCode: '',
applicantId: '',
applicantName: '',
teamName: '',
proposalCategory: '',
problemDesc: '',
improvementMethod: '',
beforeDesc: '',
afterDesc: '',
improvementEffect: '',
finalAward: '',
});
//表单验证
const validatorRules = reactive({
proposalName: [{ required: true, message: '请输入提案名称!'},],
applicantName: [{ required: true, message: '请输入申请人姓名!'},],
proposalCategory: [{ required: true, message: '请选择提案类别!'},],
problemDesc: [{ required: true, message: '请输入问题描述!'},],
improvementMethod: [{ required: true, message: '请输入改善方法及措施!'},],
});
const {resetFields, validate, validateInfos} = useForm(formData, validatorRules, {immediate: false});
const dbData = {};
const formItemLayout = {
labelCol: {xs: {span: 24}, sm: {span: 5}},
wrapperCol: {xs: {span: 24}, sm: {span: 16}},
};
const longLabelCol = {
xs: {span: 24},
sm: {span: 4},
};
const longWrapperCol = {
xs: {span: 24},
sm: {span: 20},
};
const halfLabelCol = {
xs: {span: 24},
sm: {span: 8},
};
const halfWrapperCol = {
xs: {span: 24},
sm: {span: 16},
};
const disabled = computed(()=>{
if(props.formBpm === true){
if(props.formData.disabled === false){
return false;
}else{
return true;
}
}
return props.formDisabled;
});
// 普通新增没有业务 ID,不展示评分和投票子表;已有数据及流程表单正常展示。
const showSubTables = computed(() => Boolean(formData.id || props.formData?.dataId));
function getCurrentDate() {
const now = new Date();
const year = now.getFullYear();
const month = String(now.getMonth() + 1).padStart(2, '0');
const day = String(now.getDate()).padStart(2, '0');
return `${year}-${month}-${day}`;
}
function getCurrentLoginDepart() {
const userInfo = (userStore.getUserInfo || {}) as Record<string, any>;
const loginInfo = (userStore.getLoginInfo || {}) as Record<string, any>;
let departs: any[] = [];
if (Array.isArray(loginInfo.departs)) {
departs = loginInfo.departs;
} else if (Array.isArray(userInfo.departs)) {
departs = userInfo.departs;
} else if (loginInfo.userInfo && Array.isArray(loginInfo.userInfo.departs)) {
departs = loginInfo.userInfo.departs;
}
if (userInfo.orgCode) {
const found = departs.find((item) => item && item.orgCode === userInfo.orgCode);
if (found) return found;
}
if (departs.length === 1) {
return departs[0];
}
if (departs.length > 0) {
return departs[0];
}
return undefined;
}
async function getCurrentDepartInfo() {
const userInfo = (userStore.getUserInfo || {}) as Record<string, any>;
const loginDepart = getCurrentLoginDepart();
if (loginDepart) {
return {
id: loginDepart.id || '',
departName: loginDepart.departName || loginDepart.name || '',
orgCode: loginDepart.orgCode || '',
};
}
if (userInfo.orgCode) {
try {
const depart = await defHttp.get({ url: '/sys/sysDepart/getDepartName', params: { orgCode: userInfo.orgCode } }, { successMessageMode: 'none' });
if (depart && (depart.id || depart.departName)) {
return {
id: depart.id || '',
departName: depart.departName || depart.depart_name || '',
orgCode: userInfo.orgCode,
};
}
} catch (e) {
// ignore
}
}
const deptId = userInfo.departIds || userInfo.deptId || userInfo.deptid || '';
const deptName = userInfo.departIds_dictText || userInfo.orgCodeTxt || userInfo.deptName || '';
return { id: deptId, departName: deptName, orgCode: userInfo.orgCode || '' };
}
async function applyCurrentUserDeptInfo() {
const departInfo = await getCurrentDepartInfo();
formData.proposalDeptId = departInfo.id;
formData.proposalDeptName = departInfo.departName;
formData.proposalDeptCode = departInfo.orgCode;
}
async function getProposalSequence() {
const year = new Date().getFullYear();
const latestSequence = await getLatestProposalSequence(year);
// return Number(latestSequence) + 1;
return String(Number(latestSequence) + 1).padStart(4, '0');
}
async function generateProposalNo() {
const deptCode = formData.proposalDeptName || '';
const year = new Date().getFullYear();
const proposalSequence = await getProposalSequence();
return `${deptCode}-${year}年-${proposalSequence}`;
}
onMounted(()=>{
initFormData();
});
const queryByIdUrl = '/improvementproposal/improvementProposal/queryById';
async function initFormData(){
if(props.formBpm === true){
let params = {id: props.formData.dataId};
const row = await defHttp.get({url: queryByIdUrl, params});
Object.keys(row).map(k => {
formData[k] = row[k];
});
const improvementDeptScoreDataList = await queryImprovementDeptScoreListByMainId(row['id']);
improvementDeptScoreTable.dataSource = [...improvementDeptScoreDataList];
const improvementInstituteVoteDataList = await queryImprovementInstituteVoteListByMainId(row['id']);
improvementInstituteVoteTable.dataSource = [...improvementInstituteVoteDataList];
}
}
const showFlowSubmitButton = computed(()=>{
if(props.formBpm === true){
if(props.formData.disabled === false){
return true
}
}
return false
});
async function add() {
resetFields();
improvementDeptScoreTable.dataSource = [];
improvementInstituteVoteTable.dataSource = [];
formData.proposalDate = getCurrentDate();
await applyCurrentUserDeptInfo();
formData.proposalNo = await generateProposalNo();
}
async function edit(row) {
//主表数据
await queryMainData(row.id);
//子表数据
const improvementDeptScoreDataList = await queryImprovementDeptScoreListByMainId(row['id']);
improvementDeptScoreTable.dataSource = [...improvementDeptScoreDataList];
const improvementInstituteVoteDataList = await queryImprovementInstituteVoteListByMainId(row['id']);
improvementInstituteVoteTable.dataSource = [...improvementInstituteVoteDataList];
}
async function queryMainData(id) {
const row = await queryDataById(id);
resetFields();
const tmpData = {};
Object.keys(formData).forEach((key) => {
if(row.hasOwnProperty(key)){
tmpData[key] = row[key]
}
})
//赋值
Object.assign(formData,tmpData);
}
const {getSubFormAndTableData, transformData} = useValidateAntFormAndTable(activeKey, {
'improvementDeptScore': improvementDeptScoreTableRef,
'improvementInstituteVote': improvementInstituteVoteTableRef,
});
async function getFormData() {
try {
// 触发表单验证
await validate();
} catch ({ errorFields }) {
if (errorFields) {
const firstField = errorFields[0];
if (firstField) {
formRef.value.scrollToField(firstField.name, { behavior: 'smooth', block: 'center' });
}
}
return Promise.reject(errorFields);
}
return transformData(toRaw(formData))
}
async function submitForm() {
const mainData = await getFormData();
const isUpdate = Boolean(mainData.id);
const values = Object.assign({}, dbData, mainData);
// 新增提案只保存主表;已有提案编辑或流程提交时才采集子表数据。
if (isUpdate) {
const subData = await getSubFormAndTableData();
Object.assign(values, subData);
}
console.log('表单提交数据', values)
const result = await saveOrUpdate(values, isUpdate);
// 新增时,保存成功后绑定附件的 bussinessId
if (!isUpdate) {
const newId = typeof result === 'string' ? result : (result?.id || result);
if (newId) {
formData.id = newId;
await beforeFileRef.value?.bindBussinessId(`${newId}:before`);
await afterFileRef.value?.bindBussinessId(`${newId}:after`);
}
}
emit('success');
}
function setFieldsValue(values) {
if(values){
Object.keys(values).map(k=>{
formData[k] = values[k];
});
}
}
function handleFormChange(key, value) {
formData[key] = value;
}
return {
improvementDeptScoreTableRef,
improvementDeptScoreTable,
improvementInstituteVoteTableRef,
improvementInstituteVoteTable,
validatorRules,
validateInfos,
activeKey,
loading,
formData,
setFieldsValue,
handleFormChange,
formItemLayout,
longLabelCol,
longWrapperCol,
halfLabelCol,
halfWrapperCol,
disabled,
showSubTables,
showFlowSubmitButton,
getFormData,
submitForm,
add,
edit,
formRef,
beforeFileRef,
afterFileRef,
}
}
});
</script>
<style lang="less" scoped>
.ant-tabs-tabpane.sub-one-form {
max-height: 340px;
overflow: auto;
}
</style>