合并代码
This commit is contained in:
434
src/views/finance/purchasingrequisition/form.vue
Normal file
434
src/views/finance/purchasingrequisition/form.vue
Normal file
@@ -0,0 +1,434 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
:title="dialogTitle"
|
||||
v-model="visible"
|
||||
width="900px"
|
||||
:close-on-click-modal="false"
|
||||
draggable>
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="dataForm"
|
||||
:rules="dataRules"
|
||||
label-width="140px"
|
||||
v-loading="loading">
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="采购项目名称" prop="projectName">
|
||||
<el-input
|
||||
v-model="dataForm.projectName"
|
||||
placeholder="请输入采购项目名称"
|
||||
clearable
|
||||
:disabled="isView" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="项目类别" prop="projectType">
|
||||
<el-select
|
||||
v-model="dataForm.projectType"
|
||||
placeholder="请选择项目类别"
|
||||
clearable
|
||||
:disabled="isView"
|
||||
style="width: 100%">
|
||||
<el-option label="货物" value="A" />
|
||||
<el-option label="工程" value="B" />
|
||||
<el-option label="服务" value="C" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="品目编码" prop="categoryCode">
|
||||
<el-tree-select
|
||||
v-model="dataForm.categoryCode"
|
||||
:data="categoryTreeData"
|
||||
:props="{ value: 'code', label: 'name', children: 'children' }"
|
||||
placeholder="请选择品目编码"
|
||||
clearable
|
||||
check-strictly
|
||||
:render-after-expand="false"
|
||||
:disabled="isView"
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="填报日期" prop="applyDate">
|
||||
<el-date-picker
|
||||
v-model="dataForm.applyDate"
|
||||
type="date"
|
||||
placeholder="请选择填报日期"
|
||||
format="YYYY-MM-DD"
|
||||
value-format="YYYY-MM-DD"
|
||||
:disabled="isView"
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-form-item label="采购内容" prop="projectContent" class="mb20">
|
||||
<el-input
|
||||
v-model="dataForm.projectContent"
|
||||
type="textarea"
|
||||
:rows="3"
|
||||
placeholder="请输入采购内容"
|
||||
clearable
|
||||
:disabled="isView" />
|
||||
</el-form-item>
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="资金来源" prop="fundSource">
|
||||
<el-input
|
||||
v-model="dataForm.fundSource"
|
||||
placeholder="请输入资金来源"
|
||||
clearable
|
||||
:disabled="isView" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="预算金额(元)" prop="budget">
|
||||
<el-input-number
|
||||
v-model="dataForm.budget"
|
||||
:min="0.01"
|
||||
:precision="2"
|
||||
placeholder="请输入预算金额"
|
||||
:disabled="isView"
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="是否集采" prop="isCentralized">
|
||||
<el-select
|
||||
v-model="dataForm.isCentralized"
|
||||
placeholder="请选择是否集采"
|
||||
clearable
|
||||
:disabled="isView"
|
||||
style="width: 100%">
|
||||
<el-option label="否" value="0" />
|
||||
<el-option label="是" value="1" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="是否特殊情况" prop="isSpecial">
|
||||
<el-select
|
||||
v-model="dataForm.isSpecial"
|
||||
placeholder="请选择是否特殊情况"
|
||||
clearable
|
||||
:disabled="isView"
|
||||
style="width: 100%">
|
||||
<el-option label="否" value="0" />
|
||||
<el-option label="紧急" value="1" />
|
||||
<el-option label="单一" value="2" />
|
||||
<el-option label="进口" value="3" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="采购形式" prop="purchaseMode">
|
||||
<el-select
|
||||
v-model="dataForm.purchaseMode"
|
||||
placeholder="请选择采购形式"
|
||||
clearable
|
||||
:disabled="isView"
|
||||
style="width: 100%">
|
||||
<el-option label="部门自行采购" value="0" />
|
||||
<el-option label="学校统一采购" value="2" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="学校统一采购方式" prop="purchaseSchool">
|
||||
<el-select
|
||||
v-model="dataForm.purchaseSchool"
|
||||
placeholder="请选择学校统一采购方式"
|
||||
clearable
|
||||
:disabled="isView || dataForm.purchaseMode !== '2'"
|
||||
style="width: 100%">
|
||||
<el-option label="无" value="0" />
|
||||
<el-option label="政府采购" value="1" />
|
||||
<el-option label="学校自主采购" value="2" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-form-item label="采购方式" prop="purchaseType" class="mb20">
|
||||
<el-input
|
||||
v-model="dataForm.purchaseType"
|
||||
placeholder="请输入采购方式"
|
||||
clearable
|
||||
:disabled="isView" />
|
||||
</el-form-item>
|
||||
<el-form-item label="附件" prop="fileIds" class="mb20">
|
||||
<upload-file
|
||||
v-model="dataForm.fileIds"
|
||||
:limit="10"
|
||||
:disabled="isView"
|
||||
upload-file-url="/purchase/purchasingfiles/upload" />
|
||||
</el-form-item>
|
||||
<el-form-item label="备注" prop="remark">
|
||||
<el-input
|
||||
v-model="dataForm.remark"
|
||||
type="textarea"
|
||||
:rows="3"
|
||||
placeholder="请输入备注"
|
||||
clearable
|
||||
:disabled="isView" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="visible = false">{{ isView ? '关闭' : '取消' }}</el-button>
|
||||
<template v-if="!isView">
|
||||
<el-button v-if="dataForm.id && dataForm.status === '-1'" type="warning" @click="handleTempStore" :disabled="loading">暂存</el-button>
|
||||
<el-button type="primary" @click="handleSubmit" :disabled="loading">{{ dataForm.id ? '保存' : '提交' }}</el-button>
|
||||
</template>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="PurchasingRequisitionForm">
|
||||
import { reactive, ref, nextTick, computed } from 'vue'
|
||||
import { getObj, addObj, editObj, tempStore, submitObj } from '/@/api/finance/purchasingrequisition';
|
||||
import { getTree } from '/@/api/finance/purchasingcategory';
|
||||
import { useMessage } from '/@/hooks/message';
|
||||
import UploadFile from '/@/components/Upload/index.vue';
|
||||
|
||||
// 定义子组件向父组件传值/事件
|
||||
const emit = defineEmits(['refresh']);
|
||||
|
||||
// 定义变量内容
|
||||
const formRef = ref();
|
||||
const dataForm = reactive({
|
||||
id: '',
|
||||
projectName: '',
|
||||
projectType: '',
|
||||
projectContent: '',
|
||||
applyDate: '',
|
||||
fundSource: '',
|
||||
budget: null as number | null,
|
||||
isCentralized: '',
|
||||
isSpecial: '',
|
||||
purchaseMode: '',
|
||||
purchaseSchool: '',
|
||||
purchaseType: '',
|
||||
categoryCode: '',
|
||||
fileIds: '',
|
||||
remark: '',
|
||||
status: '',
|
||||
});
|
||||
const categoryTreeData = ref<any[]>([]);
|
||||
const visible = ref(false);
|
||||
const loading = ref(false);
|
||||
const dialogType = ref<'add' | 'edit' | 'view'>('add');
|
||||
|
||||
const isView = computed(() => dialogType.value === 'view');
|
||||
|
||||
const dialogTitle = computed(() => {
|
||||
if (dialogType.value === 'view') return '查看采购申请';
|
||||
if (dialogType.value === 'edit') return '编辑采购申请';
|
||||
return '新增采购申请';
|
||||
});
|
||||
|
||||
const dataRules = reactive({
|
||||
projectContent: [
|
||||
{ required: true, message: '采购内容不能为空', trigger: 'blur' }
|
||||
],
|
||||
budget: [
|
||||
{ required: true, message: '预算金额不能为空', trigger: 'blur' },
|
||||
{ type: 'number', min: 0.01, message: '预算金额必须大于0.01', trigger: 'blur' }
|
||||
],
|
||||
isCentralized: [
|
||||
{ required: true, message: '请选择是否集采', trigger: 'change' }
|
||||
],
|
||||
isSpecial: [
|
||||
{ required: true, message: '请选择是否特殊情况', trigger: 'change' }
|
||||
],
|
||||
});
|
||||
|
||||
// 打开弹窗
|
||||
const openDialog = async (type: 'add' | 'edit' | 'view', rowData?: any) => {
|
||||
dialogType.value = type;
|
||||
visible.value = true;
|
||||
|
||||
// 重置表单
|
||||
dataForm.id = '';
|
||||
dataForm.projectName = '';
|
||||
dataForm.projectType = '';
|
||||
dataForm.projectContent = '';
|
||||
dataForm.applyDate = '';
|
||||
dataForm.fundSource = '';
|
||||
dataForm.budget = null;
|
||||
dataForm.isCentralized = '';
|
||||
dataForm.isSpecial = '';
|
||||
dataForm.purchaseMode = '';
|
||||
dataForm.purchaseSchool = '';
|
||||
dataForm.purchaseType = '';
|
||||
dataForm.categoryCode = '';
|
||||
dataForm.fileIds = '';
|
||||
dataForm.remark = '';
|
||||
dataForm.status = '';
|
||||
|
||||
await getCategoryTreeData();
|
||||
|
||||
nextTick(() => {
|
||||
formRef.value?.resetFields();
|
||||
if (type === 'edit' || type === 'view') {
|
||||
loading.value = true;
|
||||
getObj(rowData.id)
|
||||
.then((res) => {
|
||||
Object.assign(dataForm, {
|
||||
id: res.data.id || '',
|
||||
projectName: res.data.projectName || '',
|
||||
projectType: res.data.projectType || '',
|
||||
projectContent: res.data.projectContent || '',
|
||||
applyDate: res.data.applyDate || '',
|
||||
fundSource: res.data.fundSource || '',
|
||||
budget: res.data.budget || null,
|
||||
isCentralized: res.data.isCentralized || '',
|
||||
isSpecial: res.data.isSpecial || '',
|
||||
purchaseMode: res.data.purchaseMode || '',
|
||||
purchaseSchool: res.data.purchaseSchool || '',
|
||||
purchaseType: res.data.purchaseType || '',
|
||||
categoryCode: res.data.categoryCode || '',
|
||||
fileIds: res.data.fileIds ? (Array.isArray(res.data.fileIds) ? res.data.fileIds.join(',') : res.data.fileIds) : '',
|
||||
remark: res.data.remark || '',
|
||||
status: res.data.status || '',
|
||||
});
|
||||
})
|
||||
.catch((err: any) => {
|
||||
useMessage().error(err.msg || '获取详情失败');
|
||||
})
|
||||
.finally(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// 获取品目树形数据
|
||||
const getCategoryTreeData = async () => {
|
||||
try {
|
||||
const res = await getTree();
|
||||
categoryTreeData.value = [];
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
categoryTreeData.value = res.data;
|
||||
}
|
||||
} catch (err: any) {
|
||||
console.error('获取品目树形数据失败', err);
|
||||
categoryTreeData.value = [];
|
||||
}
|
||||
};
|
||||
|
||||
// 处理文件ID字符串转数组
|
||||
// 从URL中提取文件ID,URL格式通常为: /admin/sys-file/show?fileName=xxx&id=xxx
|
||||
const getFileIdsArray = (): string[] => {
|
||||
if (!dataForm.fileIds) return [];
|
||||
if (Array.isArray(dataForm.fileIds)) return dataForm.fileIds;
|
||||
|
||||
// 如果是逗号分隔的URL字符串,需要从URL中提取文件ID
|
||||
const urls = dataForm.fileIds.split(',').filter(url => url.trim());
|
||||
const fileIds: string[] = [];
|
||||
|
||||
urls.forEach(url => {
|
||||
try {
|
||||
// 尝试从URL参数中提取id
|
||||
const urlObj = new URL(url, window.location.origin);
|
||||
const id = urlObj.searchParams.get('id') || urlObj.searchParams.get('fileName');
|
||||
if (id) {
|
||||
fileIds.push(id);
|
||||
} else {
|
||||
// 如果没有id参数,尝试从路径中提取
|
||||
const pathParts = urlObj.pathname.split('/');
|
||||
const lastPart = pathParts[pathParts.length - 1];
|
||||
if (lastPart) {
|
||||
fileIds.push(lastPart);
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
// 如果URL解析失败,直接使用原始值
|
||||
fileIds.push(url);
|
||||
}
|
||||
});
|
||||
|
||||
return fileIds;
|
||||
};
|
||||
|
||||
// 提交(新增或编辑)
|
||||
const handleSubmit = async () => {
|
||||
if (loading.value) return;
|
||||
loading.value = true;
|
||||
|
||||
try {
|
||||
const valid = await formRef.value?.validate().catch(() => {});
|
||||
if (!valid) {
|
||||
loading.value = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
const submitData = {
|
||||
...dataForm,
|
||||
fileIds: getFileIdsArray(),
|
||||
};
|
||||
|
||||
if (dataForm.id) {
|
||||
// 编辑
|
||||
await editObj(submitData);
|
||||
useMessage().success('保存成功');
|
||||
} else {
|
||||
// 新增(暂存,不启动流程)
|
||||
await addObj(submitData);
|
||||
useMessage().success('提交成功');
|
||||
}
|
||||
visible.value = false;
|
||||
emit('refresh');
|
||||
} catch (err: any) {
|
||||
useMessage().error(err.msg || (dataForm.id ? '保存失败' : '提交失败'));
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 暂存
|
||||
const handleTempStore = async () => {
|
||||
if (loading.value) return;
|
||||
loading.value = true;
|
||||
|
||||
try {
|
||||
const valid = await formRef.value?.validate().catch(() => {});
|
||||
if (!valid) {
|
||||
loading.value = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
const submitData = {
|
||||
...dataForm,
|
||||
fileIds: getFileIdsArray(),
|
||||
};
|
||||
|
||||
await tempStore(submitData);
|
||||
useMessage().success('暂存成功');
|
||||
visible.value = false;
|
||||
emit('refresh');
|
||||
} catch (err: any) {
|
||||
useMessage().error(err.msg || '暂存失败');
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 暴露变量
|
||||
defineExpose({
|
||||
openDialog,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.mb20 {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user