first commit

This commit is contained in:
2025-08-19 10:19:29 +08:00
commit 3b61e84a7f
3014 changed files with 2640574 additions and 0 deletions

View File

@ -0,0 +1,285 @@
<template>
<div class="p-2">
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
<div v-show="showSearch" class="mb-[10px]">
<el-card shadow="hover">
<el-form ref="queryFormRef" :model="queryParams" :inline="true" label-width="110px">
<el-form-item label="申请单编号" prop="formNo">
<el-input v-model="queryParams.formNo" placeholder="请输入申请单编号" clearable @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item label="工程名称" prop="projectName">
<el-input v-model="queryParams.projectName" placeholder="请输入工程名称" clearable @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item label="卷册号" prop="volumeNo">
<el-input v-model="queryParams.volumeNo" placeholder="请输入卷册号" clearable @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery" v-hasPermi="['design:designChange:list']">搜索</el-button>
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
</el-card>
</div>
</transition>
<el-card shadow="never">
<template #header>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button type="primary" plain icon="ChatRound" @click="handleAdd" v-hasPermi="['design:designChange:add']">下发变更通知</el-button>
</el-col>
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
</template>
<el-table v-loading="loading" :data="designChangeList">
<el-table-column label="序号" type="index" width="60" align="center" />
<el-table-column label="申请单编号" align="center" prop="formNo" width="150" />
<el-table-column label="工程名称" align="center" prop="projectName" width="150" />
<el-table-column label="提出单位" align="center" prop="submitUnit" width="150" />
<el-table-column label="专业" align="center" prop="specialtyName" width="120" />
<el-table-column label="提出日期" align="center" prop="submitDate" width="150">
<template #default="scope">
<span>{{ parseTime(scope.row.submitDate, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column label="卷册号" align="center" prop="volumeNo" width="150" />
<el-table-column label="流程状态" align="center">
<template #default="scope">
<dict-tag v-if="scope.row.fileId != null" :options="wf_business_status" :value="scope.row.status" />
</template>
</el-table-column>
<el-table-column label="变更文件" align="center" width="150">
<template #default="scope">
<el-button
link
type="primary"
v-if="scope.row.ossVoList && scope.row.ossVoList.length > 0"
icon="View"
@click="handleDesignView(scope.row)"
>查看文件</el-button
>
</template>
</el-table-column>
<el-table-column label="变更原因" align="center" prop="changeReason" width="150">
<template #default="scope">
<dict-tag :options="design_change_reason_type" :value="scope.row.changeReason ? scope.row.changeReason.split(',') : []" />
</template>
</el-table-column>
<el-table-column label="变更内容" align="center" prop="changeContent" width="150" />
<el-table-column label="备注" align="center" prop="remark" width="150" />
<el-table-column label="操作" fixed="right" width="300">
<template #default="scope">
<el-button
type="primary"
link
icon="Upload"
@click="handleAddChange(scope.row)"
v-if="scope.row.status == 'draft' || scope.row.status == 'back'"
>上传</el-button
>
<el-button
type="success"
link
icon="View"
v-if="scope.row.status != 'draft'"
v-hasPermi="['design:designChange:query']"
@click="handleViewInfo(scope.row)"
>查看</el-button
>
<el-button type="success" link icon="View" v-hasPermi="['design:designChange:query']" @click="handleViewDetail(scope.row)"
>通知单</el-button
>
<el-button
type="warning"
link
icon="View"
v-hasPermi="['design:designChange:query']"
v-if="scope.row.status == 'back' || scope.row.status == 'termination'"
@click="handleViewHistory(scope.row)"
>查看单据</el-button
>
</template>
</el-table-column>
</el-table>
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
</el-card>
<wordDetial ref="wordDetialRef"></wordDetial>
<el-dialog draggable title="文件列表" v-model="viewVisible" width="500px">
<el-table v-if="fileList.length > 0" :data="fileList" style="width: 100%" border>
<el-table-column prop="fileName" label="文件名称" align="center">
<template #default="scope">
<el-link
:key="scope.row.fileId"
:href="scope.row.fileUrl"
target="_blank"
:type="scope.row.status == '1' ? 'primary' : 'info'"
:underline="false"
>
{{ scope.row.originalName }}
</el-link>
</template>
</el-table-column>
<el-table-column label="操作" width="170" align="center">
<template #default="scope">
<el-button type="success" link icon="View" @click="handleDownload(scope.row)"> 查看 </el-button>
</template>
</el-table-column>
</el-table>
<div v-else class="empty-list text-center">暂无文件</div>
<template #footer>
<span>
<el-button type="primary" @click="viewVisible = false">关闭</el-button>
</span>
</template>
</el-dialog>
<el-dialog title="单据" v-model="viewDetailVisible" width="800px">
<histroy ref="histroyRef"></histroy>
</el-dialog>
</div>
</template>
<script setup name="DesignChange" lang="ts">
import { listDesignChange, delDesignChange } from '@/api/design/designChange';
import { DesignChangeVO } from '@/api/design/designChange/types';
import { useUserStoreHook } from '@/store/modules/user';
import wordDetial from '@/components/wordDetial/index';
import histroy from '../volumeCatalog/comm/histroy.vue';
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const { design_change_reason_type } = toRefs<any>(proxy?.useDict('design_change_reason_type'));
// 获取用户 store
const userStore = useUserStoreHook();
// 从 store 中获取项目列表和当前选中的项目
const currentProject = computed(() => userStore.selectedProject);
const designChangeList = ref<DesignChangeVO[]>([]);
const wordDetialRef = ref<InstanceType<typeof wordDetial>>();
const histroyRef = ref<InstanceType<typeof histroy>>();
const loading = ref(true);
const showSearch = ref(true);
const total = ref(0);
const { wf_business_status } = toRefs<any>(proxy?.useDict('wf_business_status'));
const queryFormRef = ref<ElFormInstance>();
const uploadUrl = computed(() => {
return `/design/collectFile/upload`;
});
const viewVisible = ref(false);
const fileList = ref([]);
const ossid = ref(null);
const viewDetailVisible = ref(false);
const data = reactive({
queryParams: {
pageNum: 1,
pageSize: 10,
projectId: currentProject.value?.id,
formNo: undefined,
projectName: undefined,
submitUnit: undefined,
specialty: undefined,
submitDate: undefined,
volumeName: undefined,
volumeNo: undefined,
changeReason: undefined,
status: undefined,
params: {}
}
});
const { queryParams } = toRefs(data);
/** 查询设计变更管理列表 */
const getList = async () => {
loading.value = true;
const res = await listDesignChange(queryParams.value);
designChangeList.value = res.rows;
total.value = res.total;
loading.value = false;
};
/** 搜索按钮操作 */
const handleQuery = () => {
queryParams.value.pageNum = 1;
getList();
};
/** 重置按钮操作 */
const resetQuery = () => {
queryFormRef.value?.resetFields();
handleQuery();
};
/** 下发通知 */
const handleAdd = () => {
proxy.$tab.closePage(proxy.$route);
proxy.$router.push({
path: `/approval/designChange/indexEdit`,
query: {
type: 'add'
}
});
};
/** 查看详情 */
const handleViewDetail = (row) => {
proxy.$tab.closePage(proxy.$route);
proxy.$router.push({
path: `/approval/designChange/indexEdit`,
query: {
id: row.id,
type: 'view'
}
});
};
// 上传变更图纸
const handleAddChange = (row) => {
proxy.$tab.closePage(proxy.$route);
proxy.$router.push({
path: `/approval/drawing/indexEdit`,
query: {
id: row.id,
type: 'add'
}
});
};
/** 查看流程操作 */
const handleViewInfo = (row) => {
proxy.$tab.closePage(proxy.$route);
proxy.$router.push({
path: `/approval/drawing/indexEdit`,
query: {
id: row.id,
type: 'view'
}
});
};
/** 删除按钮操作 */
const handleDesignView = async (row?: DesignChangeVO) => {
fileList.value = row.ossVoList;
viewVisible.value = true;
};
const handleViewHistory = async (row) => {
// 查看历史流程记录
viewDetailVisible.value = true;
nextTick(() => {
histroyRef.value?.getList(row.id);
});
};
// 预览
const onOpen = (path: string) => {
window.open(path, '_blank');
};
const handleDownload = (row: any) => {
window.open(row.url, '_blank');
};
onMounted(() => {
getList();
});
//监听项目id刷新数据
const listeningProject = watch(
() => currentProject.value?.id,
(nid, oid) => {
queryParams.value.projectId = nid;
getList();
}
);
onUnmounted(() => {
listeningProject();
});
</script>

View File

@ -0,0 +1,437 @@
<template>
<div class="p-4 bg-gray-50 designChangeForm">
<div class="max-w-4xl mx-auto">
<!-- 表单区域 -->
<div v-if="routeParams.type == 'view'" style="width: 100%; text-align: right; margin-bottom: 10px">
<el-button @click="goBack" size="large" class="px-4 py-2 border border-gray-300 rounded-md text-gray-700 hover:bg-gray-50 transition-colors"
>返回</el-button
>
</div>
<el-card class="rounded-lg shadow-sm bg-white border border-gray-100 transition-all hover:shadow-md overflow-hidden">
<div class="p-4 bg-gradient-to-r from-blue-50 to-indigo-50 border-b border-gray-100">
<h3 class="text-lg font-semibold text-gray-800">下发变更通知信息</h3>
</div>
<div class="p-6">
<el-form
ref="leaveFormRef"
:disabled="routeParams.type === 'view' || form.status == 'waiting'"
:model="form"
:rules="rules"
label-width="100px"
class="space-y-4"
>
<div class="grid grid-cols-1 gap-4">
<el-row>
<el-col :span="12">
<el-form-item label="申请单编号" prop="formNo">
<el-input v-model="form.formNo" placeholder="请输入申请单编号" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="工程名称" prop="projectName">
<el-input v-model="form.projectName" placeholder="请输入工程名称" /> </el-form-item
></el-col>
<el-col :span="12">
<el-form-item label="原卷册号" prop="volumeNo">
<el-select
id="projectSelect"
v-model="form.volumeNo"
placeholder="请选择原卷册号"
clearable
filterable
@change="handleSelect"
style="width: 150px; margin-right: 20px"
>
<el-option
v-for="project in volumeCatalogList"
:key="project.volumeNumber"
:label="project.volumeNumber"
:value="project.volumeNumber"
/>
</el-select> </el-form-item
></el-col>
<el-col :span="12">
<el-form-item label="提出单位" prop="submitUnit">
<el-input v-model="form.submitUnit" placeholder="请输入提出单位" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="专业" prop="specialtyName">
<el-input disabled v-model="form.specialtyName" placeholder="请输入专业" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="提出日期" prop="submitDate">
<el-date-picker clearable v-model="form.submitDate" type="date" value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择提出日期">
</el-date-picker> </el-form-item
></el-col>
<!-- <el-col :span="12">
<el-form-item label="卷册名称" prop="volumeName"> <el-input v-model="form.volumeName" placeholder="请输入卷册名称" /> </el-form-item
></el-col> -->
<el-col :span="12">
<el-form-item label="子项名称" prop="subName">
<el-input disabled v-model="form.extendDetail.subName" placeholder="请输入子项名称" /> </el-form-item
></el-col>
<el-col :span="24">
<el-form-item label="原设计处置" prop="designDisposal">
<el-radio-group v-model="form.extendDetail.designDisposal">
<el-radio value="1" size="large">原图作废</el-radio>
<el-radio value="2" size="large">原图保留部分修改</el-radio>
<el-radio value="3" size="large">原图保留补充设计</el-radio>
</el-radio-group>
</el-form-item></el-col
>
<el-col :span="24" v-if="form.extendDetail.designDisposal == 2 && form.volumeNo">
<el-form-item label="选择保留文件" prop="designPhase">
<el-select
id="projectSelect"
v-model="form.saveFile"
placeholder="请选择保留文件"
multiple
style="width: 150px; margin-right: 20px"
>
<el-option v-for="project in fileVoList" :key="project.id" :label="project.fileName" :value="project.id" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="设计阶段" prop="designPhase">
<el-input v-model="form.extendDetail.designPhase" placeholder="请输入设计阶段" /> </el-form-item
></el-col>
<el-col :span="24">
<el-form-item label="变更类别" prop="changeCategory">
<el-radio-group v-model="form.extendDetail.changeCategory">
<el-radio value="1" size="large">重大设计变更</el-radio>
<el-radio value="2" size="large">一般设计变更</el-radio>
</el-radio-group>
</el-form-item></el-col
>
<el-col :span="24">
<el-form-item label="实施程序" prop="ImpProcedure">
<el-radio-group v-model="form.extendDetail.ImpProcedure">
<el-radio value="1" size="large">建设单位重新申报初步设计审批</el-radio>
<el-radio value="2" size="large">建设单位送原施工图审查机构审查建设主管部分备案后交付实施</el-radio>
<el-radio value="3" size="large">建设单位确认后交付实施</el-radio>
</el-radio-group>
</el-form-item></el-col
>
<el-col :span="12">
<el-form-item label="更改相关专业" prop="involvingProfessions">
<el-input v-model="form.extendDetail.involvingProfessions" placeholder="请输入更改相关专业" /> </el-form-item
></el-col>
<el-col :span="24">
<el-form-item label="附图" prop="attachmentPic"> <image-upload v-model="form.attachmentPic" :fileSize="100" /> </el-form-item
></el-col>
<el-col :span="24">
<el-form-item label="变更原因" prop="changeReason">
<el-checkbox-group v-model="form.changeReason">
<el-checkbox v-for="dict in design_change_reason_type" :key="dict.value" :value="dict.value">
{{ dict.label }}
</el-checkbox>
</el-checkbox-group>
</el-form-item></el-col
>
<el-col :span="24">
<el-form-item label="变更内容" prop="changeContent">
<el-input v-model="form.changeContent" type="textarea" placeholder="请输入内容" /> </el-form-item
></el-col>
<el-col :span="12">
<el-form-item label="费用" prop="costEstimation">
<el-input v-model="form.costEstimation" type="number" placeholder="请输入费用" /> </el-form-item
></el-col>
<el-col :span="24">
<el-form-item label="变更费用估算表" label-width="110px" prop="costEstimationFile">
<file-upload v-model="form.costEstimationFile" :fileSize="100" /> </el-form-item
></el-col>
<!-- <el-col :span="24">
<el-form-item label="变更文件" prop="fileId"> <file-upload v-model="form.fileId" :fileSize="100" /> </el-form-item
></el-col> -->
<el-col :span="24"
><el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容" /> </el-form-item
></el-col>
</el-row>
</div>
</el-form>
</div>
<div class="flex justify-center gap-4 mt-8">
<el-button
v-if="routeParams.type != 'view'"
@click="goBack"
size="large"
class="px-4 py-2 border border-gray-300 rounded-md text-gray-700 hover:bg-gray-50 transition-colors"
>返回</el-button
>
<el-button
type="primary"
size="large"
v-if="routeParams.type != 'view'"
@click="submitForm"
class="px-4 py-2 bg-primary text-white rounded-md hover:bg-primary/90 transition-colors"
>确认</el-button
>
</div>
</el-card>
</div>
</div>
</template>
<script setup name="Leave" lang="ts">
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
import { useUserStoreHook } from '@/store/modules/user';
import { addDesignChange, getDesignChange } from '@/api/design/designChange';
import { listVolumeCatalog } from '@/api/design/volumeCatalog';
const { design_change_reason_type } = toRefs<any>(proxy?.useDict('design_change_reason_type'));
const route = useRoute();
const router = useRouter();
// 获取用户 store
const userStore = useUserStoreHook();
// 从 store 中获取项目列表和当前选中的项目
const currentProject = computed(() => userStore.selectedProject);
const buttonLoading = ref(false);
const volumeCatalogList = ref([]);
let volumeMap = new Map();
//路由参数
const routeParams = ref<Record<string, any>>({});
const leaveFormRef = ref<ElFormInstance>();
const dialog = reactive({
visible: false,
title: '',
isEdit: false
});
const fileVoList = ref([]);
const initFormData = {
id: undefined,
projectId: currentProject.value?.id,
formNo: undefined,
projectName: undefined,
submitUnit: undefined,
specialty: undefined,
specialtyName: undefined,
submitDate: undefined,
volumeName: undefined,
volumeNo: undefined,
attachmentPic: undefined,
changeReason: [],
changeContent: undefined,
costEstimation: undefined,
costEstimationFile: undefined,
fileId: undefined,
status: undefined,
remark: undefined,
saveFile: undefined,
extendDetail: {
changeCategory: undefined,
ImpProcedure: undefined,
involvingProfessions: undefined,
subName: undefined,
designDisposal: undefined,
designPhase: undefined
}
};
const data = reactive({
form: { ...initFormData },
queryParams: {
pageNum: 1,
pageSize: 10,
projectId: currentProject.value?.id,
fileName: undefined,
fileType: undefined,
fileSuffix: undefined,
fileStatus: undefined,
originalName: undefined,
newest: undefined,
params: {}
},
rules: {
// 卷册号
volumeNo: [{ required: true, message: '请请选择卷册号', trigger: 'change' }]
}
});
const { form, rules } = toRefs(data);
/** 表单重置 */
const reset = () => {
form.value = { ...initFormData };
leaveFormRef.value?.resetFields();
};
//返回
const goBack = () => {
proxy.$tab.closePage(route);
router.go(-1);
};
/** 提交按钮 */
const submitForm = () => {
var changeReason = '';
if (form.value.changeReason && form.value.changeReason.length > 0) {
changeReason = form.value.changeReason.join(',');
}
var saveFile = '';
if (form.value.saveFile && form.value.saveFile.length > 0) {
saveFile = form.value.saveFile.join(',');
}
leaveFormRef.value?.validate(async (valid: boolean) => {
if (valid) {
var res;
res = await addDesignChange({ ...form.value, changeReason, saveFile }).finally(() => (buttonLoading.value = false));
if (res.code == 200) {
ElMessage.success('通知成功');
goBack();
} else {
ElMessage.error(res.msg);
}
}
});
};
/** 查询卷册目录列表 */
const getList = async () => {
const res = await listVolumeCatalog({ projectId: currentProject.value?.id, auditStatus: 'finish' });
volumeCatalogList.value = res.rows;
volumeCatalogList.value.forEach((e) => {
volumeMap.set(e.volumeNumber, e);
});
};
const handleSelect = (val) => {
let obj = volumeMap.get(val);
console.log(obj);
fileVoList.value = obj.fileVoList;
form.value.volumeName = obj.volumeName;
form.value.specialty = obj.specialty;
form.value.specialtyName = obj.specialtyName;
form.value.extendDetail.subName = obj.designSubitem;
};
/** 获取详情 */
const getInfo = () => {
buttonLoading.value = false;
nextTick(async () => {
const res = await getDesignChange(routeParams.value.id);
Object.assign(form.value, res.data);
if (form.value.changeReason.length > 0) {
form.value.changeReason = form.value.changeReason.split(',');
}
buttonLoading.value = false;
});
};
onMounted(() => {
nextTick(async () => {
routeParams.value = proxy.$route.query;
reset();
getList();
if (routeParams.value.type != 'add') {
getInfo();
}
});
});
</script>
<style scoped lang="scss">
.designChangeForm {
.el-select {
width: 300px !important;
}
}
/* 全局样式 */
:root {
--primary: #409eff;
--primary-light: #66b1ff;
--primary-dark: #3a8ee6;
--success: #67c23a;
--warning: #e6a23c;
--danger: #f56c6c;
--info: #909399;
}
/* 表单样式优化 */
.el-form-item {
.el-form-item__label {
color: #606266;
font-weight: 500;
}
.el-input__inner,
.el-select .el-input__inner {
border-radius: 4px;
transition:
border-color 0.2s,
box-shadow 0.2s;
&:focus {
border-color: var(--primary-light);
box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.1);
}
}
.el-textarea__inner {
border-radius: 4px;
transition:
border-color 0.2s,
box-shadow 0.2s;
&:focus {
border-color: var(--primary-light);
box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.1);
}
}
}
/* 按钮样式优化 */
.el-button {
border-radius: 4px;
transition: all 0.2s;
&.is-primary {
background-color: var(--primary);
border-color: var(--primary);
&:hover {
background-color: var(--primary-light);
border-color: var(--primary-light);
}
&:active {
background-color: var(--primary-dark);
border-color: var(--primary-dark);
}
}
&.is-text {
color: var(--primary);
&:hover {
color: var(--primary-light);
background-color: rgba(64, 158, 255, 0.05);
}
}
}
/* 卡片样式优化 */
.el-card {
transition: all 0.3s ease;
&:hover {
/* transform: translateY(-2px); */
}
}
/* 对话框样式优化 */
.el-dialog {
.el-dialog__header {
background-color: #f5f7fa;
border-bottom: 1px solid #ebeef5;
padding: 15px 20px;
}
.el-dialog__title {
font-size: 16px;
font-weight: 600;
color: #303133;
}
.el-dialog__footer {
padding: 15px 20px;
border-top: 1px solid #ebeef5;
}
}
</style>