This commit is contained in:
tcy
2025-08-27 15:00:20 +08:00
81 changed files with 3791 additions and 2266 deletions

BIN
public/catalog.xlsx Normal file

Binary file not shown.

BIN
public/enterRoad.xlsx Normal file

Binary file not shown.

BIN
public/landBlock.xlsx Normal file

Binary file not shown.

View File

@ -91,3 +91,11 @@ export const getDetailsList = (query: any): AxiosPromise<any> => {
params: query params: query
}); });
}; };
//获取版本详情
export const getVersionDetails = (id: any): AxiosPromise<any> => {
return request({
url: '/tender/tenderPlanLimitList/getVersionDetail/' + id,
method: 'get'
});
};

View File

@ -5,6 +5,7 @@ import {
FormalitiesAreConsolidatedForm, FormalitiesAreConsolidatedForm,
FormalitiesAreConsolidatedQuery FormalitiesAreConsolidatedQuery
} from '@/api/formalities/formalitiesAreConsolidated/types'; } from '@/api/formalities/formalitiesAreConsolidated/types';
import { ListOfFormalitiesQuery, ListOfFormalitiesVO } from '../listOfFormalities/types';
/** /**
* 查询合规性手续合账列表 * 查询合规性手续合账列表
@ -101,3 +102,17 @@ export const delFormalitiesAnnex = (id: string | number | Array<string | number>
method: 'delete' method: 'delete'
}); });
}; };
/**
* 查询手续办理清单模板属性列表
* @param query
* @returns {*}
*/
export const getTemplateTreeList = (query?: any): AxiosPromise<ListOfFormalitiesVO[]> => {
return request({
url: '/formalities/formalitiesAreConsolidated/getTree',
method: 'get',
params: query
});
};

View File

@ -15,7 +15,7 @@ export const totalAmount = () => {
/** /**
* 查询项目位置列表 * 查询项目位置列表
* *
*/ export const projectGis = (clientid) => { */ export const projectGis = (clientid?: any) => {
return request({ return request({
url: '/money/big/screen/project/gis', url: '/money/big/screen/project/gis',
method: 'get', method: 'get',
@ -57,7 +57,8 @@ export const totalAmount = () => {
/** /**
* 支出合同分析 * 支出合同分析
* *
*/ export const expensesAnalyze = (clientid) => { */
export const expensesAnalyze = (clientid) => {
return request({ return request({
url: '/money/big/screen/expenses/analyze', url: '/money/big/screen/expenses/analyze',
method: 'get', method: 'get',
@ -79,14 +80,14 @@ export const totalAmount = () => {
export const monthMoney = () => { export const monthMoney = () => {
return request({ return request({
url: '/money/big/screen/monthMoney', url: '/money/big/screen/monthMoney',
method: 'get', method: 'get'
}); });
}; };
// 现金流 // 现金流
export const monthCash = () => { export const monthCash = () => {
return request({ return request({
url: '/money/big/screen/monthCash', url: '/money/big/screen/monthCash',
method: 'get', method: 'get'
}); });
}; };
// 现金流总和 // 现金流总和
@ -94,6 +95,6 @@ export const monthCash = () => {
export const cashTotal = () => { export const cashTotal = () => {
return request({ return request({
url: '/money/big/screen/cashTotal', url: '/money/big/screen/cashTotal',
method: 'get', method: 'get'
}); });
}; };

View File

@ -61,3 +61,16 @@ export const delMaterialReceive = (id: string | number | Array<string | number>)
method: 'delete' method: 'delete'
}); });
}; };
/**
* 获取合同列表数据
* @param id
*/
export const getContractNameList = (id: string | number | Array<string | number>) => {
return request({
url: '/materials/materialReceive/ctrList',
params: {
projectId: id
},
method: 'get'
});
};

View File

@ -0,0 +1,63 @@
import request from '@/utils/request';
import { AxiosPromise } from 'axios';
import { NoticeVO, NoticeForm, NoticeQuery } from '@/api/message/notice/types';
/**
* 查询消息列表
* @param query
* @returns {*}
*/
export const listNotice = (query?: NoticeQuery): AxiosPromise<NoticeVO[]> => {
return request({
url: '/message/notice/list',
method: 'get',
params: query
});
};
/**
* 查询消息详细
* @param id
*/
export const getNotice = (id: string | number): AxiosPromise<NoticeVO> => {
return request({
url: '/message/notice/' + id,
method: 'get'
});
};
/**
* 新增消息
* @param data
*/
export const addNotice = (data: NoticeForm) => {
return request({
url: '/message/notice',
method: 'post',
data: data
});
};
/**
* 修改消息
* @param data
*/
export const updateNotice = (data: NoticeForm) => {
return request({
url: '/message/notice',
method: 'put',
data: data
});
};
/**
* 删除消息
* @param id
*/
export const delNotice = (id: string | number | Array<string | number>) => {
return request({
url: '/message/notice/' + id,
method: 'delete'
});
};

View File

@ -0,0 +1,156 @@
export interface NoticeVO {
/**
* 主键ID
*/
id: string | number;
/**
* 项目ID
*/
projectId: string | number;
/**
* 接收通知的用户ID
*/
recipientId: string | number;
/**
* 发送通知的用户ID系统通知 0
*/
senderId: string | number;
/**
* 配置id
*/
configId: string | number;
/**
* 详情id
*/
detailId: string | number;
/**
* 通知内容
*/
content: string;
/**
* 查看状态(0未读 1已读)
*/
viewStatus: string;
/**
* 查看时间
*/
viewTime: string;
/**
* 备注
*/
remark: string;
}
export interface NoticeForm extends BaseEntity {
/**
* 主键ID
*/
id?: string | number;
/**
* 项目ID
*/
projectId?: string | number;
/**
* 接收通知的用户ID
*/
recipientId?: string | number;
/**
* 发送通知的用户ID系统通知 0
*/
senderId?: string | number;
/**
* 配置id
*/
configId?: string | number;
/**
* 详情id
*/
detailId?: string | number;
/**
* 通知内容
*/
content?: string;
/**
* 查看状态(0未读 1已读)
*/
viewStatus?: string;
/**
* 查看时间
*/
viewTime?: string;
/**
* 备注
*/
remark?: string;
}
export interface NoticeQuery extends PageQuery {
/**
* 项目ID
*/
projectId?: string | number;
/**
* 接收通知的用户ID
*/
recipientId?: string | number;
/**
* 发送通知的用户ID系统通知 0
*/
senderId?: string | number;
/**
* 配置id
*/
configId?: string | number;
/**
* 详情id
*/
detailId?: string | number;
/**
* 通知内容
*/
content?: string;
/**
* 查看状态(0未读 1已读)
*/
viewStatus?: string;
/**
* 查看时间
*/
viewTime?: string;
/**
* 日期范围参数
*/
params?: any;
}

View File

@ -8,11 +8,10 @@ import { ProgressCategoryVO, ProgressCategoryForm, ProgressCategoryQuery } from
* @returns {*} * @returns {*}
*/ */
export const listProgressCategory = (query?: ProgressCategoryQuery): AxiosPromise<ProgressCategoryVO[]> => { export const listProgressCategory = (id?: string | number): AxiosPromise<any[]> => {
return request({ return request({
url: '/progress/progressCategory/list', url: '/progress/progressCategory/listByParent/' + id,
method: 'get', method: 'get'
params: query
}); });
}; };
@ -70,3 +69,30 @@ export const downloadProgressCategory = (data) => {
data data
}); });
}; };
/**
* 查询分项工程单价下拉树结构
* @param query
* @returns {*}
*/
export const getCategoryTabList = (id?: string | number): AxiosPromise<any[]> => {
return request({
url: '/progress/progressCategory/listTopBySubProjectId/' + id,
method: 'get'
});
};
/**
* 查询分项工程单价外层结构
* @param query
* @returns {*}
*/
export const getCategoryList = (id?: string | number): AxiosPromise<any[]> => {
return request({
url: '/progress/progressCategory/list',
method: 'get',
params: {
parentId: id
}
});
};

View File

@ -97,6 +97,8 @@ export interface ProgressCategoryForm extends BaseEntity {
id?: string | number; id?: string | number;
constructionPrice?: string | number; constructionPrice?: string | number;
ownerPrice?: string | number; ownerPrice?: string | number;
relevancyStructure?: string;
/** /**
* 父类别id * 父类别id
*/ */

View File

@ -1,6 +1,10 @@
import request from '@/utils/request'; import request from '@/utils/request';
import { AxiosPromise } from 'axios'; import { AxiosPromise } from 'axios';
import { ProgressCategoryTemplateVO, ProgressCategoryTemplateForm, ProgressCategoryTemplateQuery } from '@/api/progress/progressCategoryTemplate/types'; import {
ProgressCategoryTemplateVO,
ProgressCategoryTemplateForm,
ProgressCategoryTemplateQuery
} from '@/api/progress/progressCategoryTemplate/types';
/** /**
* 查询进度类别模版列表 * 查询进度类别模版列表
@ -61,3 +65,22 @@ export const delProgressCategoryTemplate = (id: string | number | Array<string |
method: 'delete' method: 'delete'
}); });
}; };
export const getTabList = (id: string) => {
return request({
url: '/progress/progressCategoryTemplate/listSystemTop/' + id,
method: 'get'
});
};
/**
* 筛选查询进度类别模版列表
* @param parentId
* @returns {*}
*/
export const listProgressCategoryTemplateByParent = (parentId: string | number): AxiosPromise<ProgressCategoryTemplateVO[]> => {
return request({
url: '/progress/progressCategoryTemplate/listByParent/' + parentId,
method: 'get'
});
};

View File

@ -12,7 +12,7 @@ export interface ProgressCategoryTemplateVO {
* 计量方式0无 1数量 2百分比 * 计量方式0无 1数量 2百分比
*/ */
unitType: string; unitType: string;
parentId?: string | number;
/** /**
* 工作类型 * 工作类型
*/ */
@ -39,7 +39,9 @@ export interface ProgressCategoryTemplateForm extends BaseEntity {
* 主键id * 主键id
*/ */
id?: string | number; id?: string | number;
parentId?: string | number;
constructionType?: string;
relevancyStructure?: string;
/** /**
* 父类别id * 父类别id
*/ */
@ -76,7 +78,8 @@ export interface ProgressCategoryTemplateQuery {
* 父类别id * 父类别id
*/ */
pid?: string | number; pid?: string | number;
parentId?: string | number;
constructionType?: string;
/** /**
* 类别名称 * 类别名称
*/ */

View File

@ -61,3 +61,12 @@ export const delEnterRoad = (id: string | number | Array<string | number>) => {
method: 'delete' method: 'delete'
}); });
}; };
// 道路信息导入
export const importEnterRoad = (projectId: any, data: any) => {
return request({
url: '/land/enterRoad/upload/' + projectId,
method: 'post',
data: data
});
};

View File

@ -76,3 +76,12 @@ export const delLandBlock = (id: string | number | Array<string | number>) => {
method: 'delete' method: 'delete'
}); });
}; };
// 地块信息导入
export const importLandBlock = (projectId:any,data: any) => {
return request({
url: '/land/landBlock/upload/'+projectId,
method: 'post',
data: data
});
};

View File

@ -69,3 +69,13 @@ export const delLandTransferLedger = (id: string | number | Array<string | numbe
method: 'delete' method: 'delete'
}); });
}; };
/**
* 获取详情
* @param id
*/
export const landTransferLedgerCount = (id: string | number | Array<string | number>) => {
return request({
url: '/land/landTransferLedger/count/' + id,
method: 'get'
});
};

View File

@ -122,11 +122,10 @@ export const editStatus = (query: any): AxiosPromise<any> => {
data: query data: query
}); });
}; };
//获取审核状态 //获取版本详情
export const getApproval = (id) => { export const getVersionDetail = (id: any) => {
return request({ return request({
url: '/tender/tenderPlanLimitList/getVersionDetail', url: '/tender/tenderPlanLimitList/getVersionDetail/' + id,
method: 'get', method: 'get'
params: { versions: id }
}); });
}; };

View File

@ -11,6 +11,7 @@
:on-exceed="handleExceed" :on-exceed="handleExceed"
:on-success="handleUploadSuccess" :on-success="handleUploadSuccess"
:show-file-list="showFileList" :show-file-list="showFileList"
:on-preview="handlePreview"
:headers="headers" :headers="headers"
class="upload-file-uploader" class="upload-file-uploader"
:list-type="isConstruction ? 'picture-card' : 'text'" :list-type="isConstruction ? 'picture-card' : 'text'"
@ -48,7 +49,13 @@
tag="ul" tag="ul"
@click.stop @click.stop
> >
<li style="margin-top: 10px" v-for="(file, index) in fileList" :key="file.uid" class="el-upload-list__item ele-upload-list__item-content"> <li
style="margin-top: 10px"
v-for="(file, index) in fileList"
:key="file.uid"
class="el-upload-list__item ele-upload-list__item-content"
v-if="autoUpload"
>
<el-link :href="`${file.url}`" :underline="false" target="_blank"> <el-link :href="`${file.url}`" :underline="false" target="_blank">
<span class="el-icon-document"> {{ getFileName(file.name) }} </span> <span class="el-icon-document"> {{ getFileName(file.name) }} </span>
</el-link> </el-link>
@ -213,31 +220,27 @@ watch(
); );
// 上传前校检格式和大小 // 上传前校检格式和大小
const handleBeforeUpload = (file: any) => { const handleBeforeUpload = (file: any) => {
// 校检文件类型 if (!validateFile(file)) return false;
if (props.fileType.length) { proxy?.$modal.loading('正在上传文件,请稍候...');
const fileName = file.name.split('.'); number.value++;
const fileExt = fileName[fileName.length - 1]; return true;
const isTypeOk = props.fileType.indexOf(fileExt) >= 0; };
if (!isTypeOk) {
proxy?.$modal.msgError(`文件格式不正确, 请上传${props.fileType.join('/')}格式文件!`); //校检格式和大小
return false; const validateFile = (file: File) => {
} const ext = file.name.split('.').pop()?.toLowerCase();
if (props.fileType.length && !props.fileType.includes(ext!)) {
proxy?.$modal.msgError(`文件格式不正确,请上传 ${props.fileType.join('/')} 格式文件!`);
return false;
} }
// 校检文件名是否包含特殊字符
if (file.name.includes(',')) { if (file.name.includes(',')) {
proxy?.$modal.msgError('文件名不正确,不能包含英文逗号!'); proxy?.$modal.msgError('文件名不正确,不能包含英文逗号!');
return false; return false;
} }
// 校检文件大小 if (props.fileSize && file.size / 1024 / 1024 > props.fileSize) {
if (props.fileSize) { proxy?.$modal.msgError(`上传文件大小不能超过 ${props.fileSize} MB!`);
const isLt = file.size / 1024 / 1024 < props.fileSize; return false;
if (!isLt) {
proxy?.$modal.msgError(`上传文件大小不能超过 ${props.fileSize} MB!`);
return false;
}
} }
proxy?.$modal.loading('正在上传文件,请稍候...');
number.value++;
return true; return true;
}; };
@ -278,13 +281,25 @@ const handleUploadSuccess = (res: any, file: UploadFileWithOssId) => {
uploadedSuccessfully(res); uploadedSuccessfully(res);
}; };
const handleChange = (file: any, fileList: any) => { const handleChange = (file: any, filelist: any) => {
if (!props.autoUpload) {
// 手动上传模式:在选中文件时拦截非法文件
const isValid = validateFile(file.raw || file);
if (!isValid) {
fileUploadRef.value?.handleRemove(file); // 直接移除非法文件
console.log(file, filelist, fileList.value);
fileList.value = [...fileList.value]; // 触发列表更新
return;
}
}
// 记录 status = 'ready' 的文件 // 记录 status = 'ready' 的文件
if (file.status === 'ready') { if (file.status === 'ready') {
pendingFiles.value.push(file); pendingFiles.value.push(file);
fileList.value = pendingFiles.value;
} }
console.log(fileList.value);
emit('handleChange', file, fileList); emit('handleChange', file, filelist);
}; };
// 删除文件 // 删除文件
@ -294,6 +309,12 @@ const handleRemove = (file: any, fileList: any) => {
emit('handleRemove', file, fileList); emit('handleRemove', file, fileList);
}; };
const handlePreview = (file: any) => {
if (file.url) {
window.open(file.url);
}
};
// 删除文件 // 删除文件
const handleDelete = async (index: string | number, type?: string) => { const handleDelete = async (index: string | number, type?: string) => {
await proxy?.$modal.confirm('是否确认删除此文件?').finally(); await proxy?.$modal.confirm('是否确认删除此文件?').finally();
@ -332,11 +353,6 @@ const uploadedSuccessfully = (res: any) => {
emit('update:modelValue', listToString(fileList.value)); emit('update:modelValue', listToString(fileList.value));
proxy?.$modal.closeLoading(); proxy?.$modal.closeLoading();
} }
// if (props.autoUpload && props.limit === fileList.value.length) {
// fileUploadRef.value?.clearFiles();
// fileList.value = [];
// emit('update:modelValue', ''); // 同步到外部 v-model
// }
props.onUploadSuccess?.(fileList.value, res); props.onUploadSuccess?.(fileList.value, res);
}; };
@ -400,6 +416,11 @@ const submitUpload = async () => {
if (!pendingFiles.value.length) { if (!pendingFiles.value.length) {
return 'noFile'; return 'noFile';
} }
const validFiles = pendingFiles.value.filter((f: any) => validateFile(f.raw || f));
if (!validFiles.length) {
proxy?.$modal.msgError('没有符合条件的文件可上传');
return;
}
try { try {
proxy?.$modal.loading('正在上传文件,请稍候...'); proxy?.$modal.loading('正在上传文件,请稍候...');
const formData = new FormData(); const formData = new FormData();

View File

@ -51,11 +51,12 @@ const getTableData = async () => {
//点击消息,写入已读 //点击消息,写入已读
const onNewsClick = (item: any) => { const onNewsClick = (item: any) => {
newsList.value[item].read = true; newsList.value[item].read = true;
console.log('🚀 ~ onNewsClick ~ newsList.value[item]:', newsList.value[item]);
//并且写入pinia //并且写入pinia
noticeStore.state.value.notices = newsList.value; noticeStore.state.value.notices = newsList.value;
//如果有formPath就前往 //如果有formPath就前往
if (newsList.value[item].route) { if (newsList.value[item].route) {
proxy?.$tab.openPage('/' + newsList.value[item].route, '', { id: newsList.value[item].detailId, type: 'view' }); proxy?.$tab.openPage(newsList.value[item].route, '', { id: newsList.value[item].detailId, type: 'view' });
} }
}; };

View File

@ -25,15 +25,16 @@ export const initSSE = (url: any) => {
}); });
watch(data, () => { watch(data, () => {
console.log('🚀 ~ initSSE ~ data:', JSON.parse(data.value));
let label = ''; let label = '';
let route1 = ''; let route1 = '';
let detailId = ''; let detailId = '';
try { try {
if (JSON.parse(data.value)) { if (JSON.parse(data.value)) {
const obj = JSON.parse(data.value); const obj = JSON.parse(data.value);
route1 = obj.route; route1 = obj.type;
label = obj.message; label = obj.content;
detailId = obj.detailId; // detailId = obj.detailId;
data.value = null; data.value = null;
} }
} catch (error) { } catch (error) {

View File

@ -10,12 +10,11 @@
@click="isDisabled = false" @click="isDisabled = false"
class="px-8 py-2.5 transition-all duration-300 font-medium" class="px-8 py-2.5 transition-all duration-300 font-medium"
v-if="isDisabled" v-if="isDisabled"
v-hasPermi="['cailiaoshebei:purchaseUser:addOrUpdate']" v-hasPermi="['bidding:biddingUser:add']"
> >
点击编辑 点击编辑
</el-button> </el-button>
</div> </div>
<!-- 表单内容区域 --> <!-- 表单内容区域 -->
<el-form ref="leaveFormRef" :model="form" :rules="rules" label-width="120px" class="p-6 pt30 space-y-6 h75" :disabled="isDisabled"> <el-form ref="leaveFormRef" :model="form" :rules="rules" label-width="120px" class="p-6 pt30 space-y-6 h75" :disabled="isDisabled">
<!-- 设计负责人 --> <!-- 设计负责人 -->
@ -30,7 +29,6 @@
</el-select> </el-select>
</el-form-item> </el-form-item>
</div> </div>
<!-- 提交按钮区域 --> <!-- 提交按钮区域 -->
<div class="flex justify-center space-x-6 mt-8 pt-6 border-t border-gray-100" v-if="!isDisabled"> <div class="flex justify-center space-x-6 mt-8 pt-6 border-t border-gray-100" v-if="!isDisabled">
<el-button <el-button
@ -38,7 +36,7 @@
@click="submitForm" @click="submitForm"
icon="Check" icon="Check"
class="px-8 py-2.5 transition-all duration-300 transform hover:scale-105 bg-blue-500 hover:bg-blue-600 text-white font-medium" class="px-8 py-2.5 transition-all duration-300 transform hover:scale-105 bg-blue-500 hover:bg-blue-600 text-white font-medium"
v-hasPermi="['cailiaoshebei:purchaseUser:addOrUpdate']" v-hasPermi="['bidding:biddingUser:add']"
> >
确认提交 确认提交
</el-button> </el-button>
@ -53,22 +51,14 @@
<script setup name="PersonnelForm" lang="ts"> <script setup name="PersonnelForm" lang="ts">
import { ref, reactive, computed, onMounted, toRefs } from 'vue'; import { ref, reactive, computed, onMounted, toRefs } from 'vue';
import { getCurrentInstance } from 'vue';
import type { ComponentInternalInstance } from 'vue';
import { useUserStoreHook } from '@/store/modules/user'; import { useUserStoreHook } from '@/store/modules/user';
import { ElMessage, ElLoading } from 'element-plus'; import { ElMessage, ElLoading } from 'element-plus';
import { biddingGetUser, AddbiddingUser, biddingUserList } from '@/api/bidding/appointment'; import { biddingGetUser, AddbiddingUser, biddingUserList } from '@/api/bidding/appointment';
import { getProject } from '@/api/project/project';
// 获取当前实例
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
// 获取用户 store // 获取用户 store
const userStore = useUserStoreHook(); const userStore = useUserStoreHook();
// 从 store 中获取当前选中的项目 // 从 store 中获取当前选中的项目
const currentProject = computed(() => userStore.selectedProject); const currentProject = computed(() => userStore.selectedProject);
// 专业字典数据
const { des_user_major } = toRefs<any>(proxy?.useDict('des_user_major'));
const isDisabled = ref(false); const isDisabled = ref(false);
const projectInfo = ref({}); //项目信息
// 表单数据 // 表单数据
const form = reactive({ const form = reactive({
id: null, id: null,

View File

@ -19,13 +19,35 @@
<h3 class="text-lg font-semibold text-gray-800">成本核算清单</h3> <h3 class="text-lg font-semibold text-gray-800">成本核算清单</h3>
</div> </div>
<div class="p-6"> <div class="p-6">
<el-form ref="leaveFormRef" disabled :model="form" :rules="rules" label-width="100px" class="space-y-4"> <el-form ref="leaveFormRef" v-loading="loading" :model="form" :rules="rules" label-width="100px" class="space-y-4">
<div class="grid grid-cols-1 md:grid-cols-2 gap-4" v-for="item in sheets" :key="item"> <div class="grid grid-cols-1 gap-4">
<el-form-item label="表格文件"> <el-row>
<span style="color: #8d8d8d">{{ item }}</span> <el-col :span="12">
</el-form-item> <el-form-item label="版本号" prop="formNo">
<el-input :disabled="true" v-model="form.versions" placeholder="请输入文件名称" />
</el-form-item>
<el-form-item label="表名" prop="sheet">
<el-select v-model="form.sheet" placeholder="选择表名" @change="changeSheet">
<el-option v-for="item in sheets" :key="item" :label="item" :value="item" />
</el-select>
</el-form-item>
</el-col>
</el-row>
</div> </div>
</el-form> </el-form>
<el-table :data="tableData" style="width: 100%; margin-bottom: 20px; height: calc(100vh - 305px)" row-key="id" default-expand-all border>
<el-table-column prop="num" label="编号" />
<el-table-column prop="name" label="名称" />
<el-table-column prop="specification" label="规格" />
<el-table-column prop="unit" label="单位" />
<el-table-column prop="quantity" label="数量" />
<el-table-column prop="unitPrice" label="单价" align="center" />
<el-table-column prop="price" label="总价" align="center">
<template #default="scope">
{{ scope.row.price != 0 ? Number(scope.row.price).toFixed(2) : null }}
</template>
</el-table-column>
</el-table>
</div> </div>
</el-card> </el-card>
<!-- 提交组件 --> <!-- 提交组件 -->
@ -68,9 +90,9 @@ import SubmitVerify from '@/components/Process/submitVerify.vue';
import ApprovalRecord from '@/components/Process/approvalRecord.vue'; import ApprovalRecord from '@/components/Process/approvalRecord.vue';
import ApprovalButton from '@/components/Process/approvalButton.vue'; import ApprovalButton from '@/components/Process/approvalButton.vue';
import { StartProcessBo } from '@/api/workflow/workflowCommon/types'; import { StartProcessBo } from '@/api/workflow/workflowCommon/types';
const { proxy } = getCurrentInstance() as ComponentInternalInstance; const { proxy } = getCurrentInstance() as any;
import { useUserStoreHook } from '@/store/modules/user'; import { useUserStoreHook } from '@/store/modules/user';
import { getVersionDetail, sheetList } from '@/api/bidding/biddingLimit'; import { getVersionDetail, sheetList, getTreeLimit } from '@/api/bidding/biddingLimit';
// 获取用户 store // 获取用户 store
const userStore = useUserStoreHook(); const userStore = useUserStoreHook();
@ -99,7 +121,6 @@ const submitVerifyRef = ref<InstanceType<typeof SubmitVerify>>();
const approvalRecordRef = ref<InstanceType<typeof ApprovalRecord>>(); const approvalRecordRef = ref<InstanceType<typeof ApprovalRecord>>();
//按钮组件 //按钮组件
const approvalButtonRef = ref<InstanceType<typeof ApprovalButton>>(); const approvalButtonRef = ref<InstanceType<typeof ApprovalButton>>();
const sheets = ref([]);
const versions = ref({}); const versions = ref({});
const leaveFormRef = ref<ElFormInstance>(); const leaveFormRef = ref<ElFormInstance>();
const dialog = reactive({ const dialog = reactive({
@ -124,7 +145,10 @@ const initFormData = {
fileSuffix: undefined, fileSuffix: undefined,
originalName: undefined, originalName: undefined,
remark: undefined, remark: undefined,
fileId: undefined fileId: undefined,
status: undefined,
versions: undefined,
sheet: undefined
}; };
const data = reactive({ const data = reactive({
form: { ...initFormData }, form: { ...initFormData },
@ -150,24 +174,46 @@ const getInfo = () => {
buttonLoading.value = false; buttonLoading.value = false;
nextTick(async () => { nextTick(async () => {
const res = await getVersionDetail(routeParams.value.id); const res = await getVersionDetail(routeParams.value.id);
console.log(res);
Object.assign(form.value, res.data); Object.assign(form.value, res.data);
getSheetName(res.data.versions);
loading.value = false; loading.value = false;
buttonLoading.value = false; buttonLoading.value = false;
getSheetName();
}); });
}; };
const sheets = ref([]);
//获取表名 //获取表名
const getSheetName = async (versions) => { const getSheetName = async () => {
const params = { try {
projectId: currentProject.value?.id, const params = {
versions projectId: currentProject.value?.id,
}; versions: form.value.versions
const res = await sheetList(params); };
if (res.code == 200) { const res = await sheetList(params);
sheets.value = res.data; if (res.code == 200) {
if (res.data.length > 0) {
sheets.value = res.data; sheets.value = res.data;
if (res.data.length > 0) {
form.value.sheet = res.data[0];
}
getListTable();
} }
} catch (error) {}
};
//选择表名
const changeSheet = () => {
getListTable();
};
const tableData = ref([]);
//获取列表
const getListTable = async () => {
const res = await getTreeLimit({
projectId: currentProject.value?.id,
versions: form.value.versions,
sheet: form.value.sheet
});
if (res.code == 200) {
tableData.value = res.data;
} }
}; };
/** 提交按钮 */ /** 提交按钮 */
@ -185,7 +231,7 @@ const submitFlow = async () => {
const handleStartWorkFlow = async (data: LeaveForm) => { const handleStartWorkFlow = async (data: LeaveForm) => {
try { try {
submitFormData.value.flowCode = flowCode.value; submitFormData.value.flowCode = flowCode.value;
submitFormData.value.businessId = data.versions + '_abc'; submitFormData.value.businessId = data.id;
//流程变量 //流程变量
taskVariables.value = { taskVariables.value = {
// leave4/5 使用的流程变量 // leave4/5 使用的流程变量
@ -203,7 +249,7 @@ const handleStartWorkFlow = async (data: LeaveForm) => {
}; };
//审批记录 //审批记录
const handleApprovalRecord = () => { const handleApprovalRecord = () => {
approvalRecordRef.value.init(form.value.versions + '_abc'); approvalRecordRef.value.init(form.value.id);
}; };
//提交回调 //提交回调
const submitCallback = async () => { const submitCallback = async () => {
@ -242,9 +288,10 @@ onMounted(() => {
reset(); reset();
routeParams.value = proxy.$route.query; routeParams.value = proxy.$route.query;
loading.value = false; loading.value = false;
// if (routeParams.value.type === 'update' || routeParams.value.type === 'view' || routeParams.value.type === 'approval') { if (routeParams.value.type === 'update' || routeParams.value.type === 'view' || routeParams.value.type === 'approval') {
getInfo(); getInfo();
// } console.log('routeParams.value', routeParams.value);
}
}); });
}); });
</script> </script>

View File

@ -1,8 +1,7 @@
<template> <template>
<div class="p-4 bg-gray-50 min-h-screen"> <div class="p-4 bg-gray-50 min-h-screen">
<!-- 卡片容器控制最大宽度+居中+圆角阴影 --> <!-- 卡片容器控制最大宽度+居中+圆角阴影 -->
<el-card shadow="hover" class="max-w-6xl mx-auto rounded-xl overflow-hidden border-0" <el-card shadow="hover" class="max-w-6xl mx-auto rounded-xl overflow-hidden border-0" style="background-color: #ffffff">
style="background-color: #ffffff">
<!-- 卡片头部项目信息展示区 --> <!-- 卡片头部项目信息展示区 -->
<template #header> <template #header>
<div class="bg-blue-50 px-6 rounded-t-xl" style="padding: 10px 20px"> <div class="bg-blue-50 px-6 rounded-t-xl" style="padding: 10px 20px">
@ -64,8 +63,15 @@
</div> --> </div> -->
</template> </template>
<!-- 中标信息表单区域 --> <!-- 中标信息表单区域 -->
<el-form :disabled="isDisabled" ref="listOfWinningBidsFormRef" :model="form" :rules="rules" label-width="150px" <el-form
class="p-6 pt-4" style="background-color: #ffffff"> :disabled="isDisabled"
ref="listOfWinningBidsFormRef"
:model="form"
:rules="rules"
label-width="150px"
class="p-6 pt-4"
style="background-color: #ffffff"
>
<el-row :gutter="32"> <el-row :gutter="32">
<!-- 招标代理机构 --> <!-- 招标代理机构 -->
<el-col :span="12"> <el-col :span="12">
@ -82,15 +88,25 @@
<!-- 投标截止时间 --> <!-- 投标截止时间 -->
<el-col :span="12"> <el-col :span="12">
<el-form-item label="投标截止时间" prop="biddingDeadline" class="rounded-lg border border-gray-100 p-1 mb-5"> <el-form-item label="投标截止时间" prop="biddingDeadline" class="rounded-lg border border-gray-100 p-1 mb-5">
<el-date-picker v-model="form.biddingDeadline" format="YYYY-MM-DD HH:mm:ss" <el-date-picker
value-format="YYYY-MM-DD HH:mm:ss" type="datetime" placeholder="请选择投标截止时间" /> v-model="form.biddingDeadline"
format="YYYY-MM-DD HH:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss"
type="datetime"
placeholder="请选择投标截止时间"
/>
</el-form-item> </el-form-item>
</el-col> </el-col>
<!-- 开标时间 --> <!-- 开标时间 -->
<el-col :span="12"> <el-col :span="12">
<el-form-item label="开标时间" prop="bidopeningTime" class="rounded-lg border border-gray-100 p-1 mb-5"> <el-form-item label="开标时间" prop="bidopeningTime" class="rounded-lg border border-gray-100 p-1 mb-5">
<el-date-picker v-model="form.bidopeningTime" format="YYYY-MM-DD HH:mm:ss" <el-date-picker
value-format="YYYY-MM-DD HH:mm:ss" type="datetime" placeholder="请选择开标时间" /> v-model="form.bidopeningTime"
format="YYYY-MM-DD HH:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss"
type="datetime"
placeholder="请选择开标时间"
/>
</el-form-item> </el-form-item>
</el-col> </el-col>
@ -108,17 +124,26 @@
</el-col> </el-col>
<!-- 答疑截止时间 --> <!-- 答疑截止时间 -->
<el-col :span="12"> <el-col :span="12">
<el-form-item label="答疑截止时间" prop="answeringDeadlineTime" <el-form-item label="答疑截止时间" prop="answeringDeadlineTime" class="rounded-lg border border-gray-100 p-1 mb-5">
class="rounded-lg border border-gray-100 p-1 mb-5"> <el-date-picker
<el-date-picker v-model="form.answeringDeadlineTime" type="datetime" format="YYYY-MM-DD HH:mm:ss" v-model="form.answeringDeadlineTime"
value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择答疑截止时间" /> type="datetime"
format="YYYY-MM-DD HH:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss"
placeholder="请选择答疑截止时间"
/>
</el-form-item> </el-form-item>
</el-col> </el-col>
<!-- 澄清截止时间 --> <!-- 澄清截止时间 -->
<el-col :span="12"> <el-col :span="12">
<el-form-item label="澄清截止时间" prop="clarifyDeadlineTime" class="rounded-lg border border-gray-100 p-1 mb-5"> <el-form-item label="澄清截止时间" prop="clarifyDeadlineTime" class="rounded-lg border border-gray-100 p-1 mb-5">
<el-date-picker format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss " <el-date-picker
v-model="form.clarifyDeadlineTime" type="datetime" placeholder="请选择澄清截止时间" /> format="YYYY-MM-DD HH:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss "
v-model="form.clarifyDeadlineTime"
type="datetime"
placeholder="请选择澄清截止时间"
/>
</el-form-item> </el-form-item>
</el-col> </el-col>
<!-- 项目概况 --> <!-- 项目概况 -->
@ -131,22 +156,31 @@
<!-- 操作按钮区域 --> <!-- 操作按钮区域 -->
<el-row v-if="!form.id" class="mt-4"> <el-row v-if="!form.id" class="mt-4">
<el-col :span="24" class="text-center"> <el-col :span="24" class="text-center">
<el-button :loading="buttonLoading" type="primary" @click="submitForm" <el-button
v-hasPermi="['bidding:listOfWinningBids:add', 'bidding:listOfWinningBids:edit']" class="rounded-full px-8" :loading="buttonLoading"
size="large"> type="primary"
@click="submitForm"
v-hasPermi="['bidding:listOfWinningBids:add', 'bidding:listOfWinningBids:edit']"
class="rounded-full px-8"
size="large"
>
确认提交 确认提交
</el-button> </el-button>
<el-button type="default" @click="resetForm" class="ml-6 rounded-full px-8" size="large"> 重置 </el-button> <el-button type="default" @click="resetForm" class="ml-6 rounded-full px-8" size="large"> 重置 </el-button>
</el-col> </el-col>
</el-row> </el-row>
</el-form> </el-form>
<div style="margin-top: 20px;" v-if="form.id"> <div style="margin-top: 20px" v-if="form.id">
<span style=" color: rgb(38 153 255); <span style="color: rgb(38 153 255); display: inline-block; margin-left: 40px; font-weight: 700">是否中标配置</span>
display: inline-block; <el-form
margin-left: 40px; ref="listOfWinningBidsFormRef"
font-weight: 700;">是否中标配置</span> :disabled="iswhetherBid"
<el-form ref="listOfWinningBidsFormRef" :disabled="iswhetherBid" :model="form" :rules="rules" :model="form"
label-width="150px" class="p-6 pt-4" style="background-color: #ffffff"> :rules="rules"
label-width="150px"
class="p-6 pt-4"
style="background-color: #ffffff"
>
<el-row> <el-row>
<!-- 是否中标必填 --> <!-- 是否中标必填 -->
<el-col :span="12"> <el-col :span="12">
@ -174,9 +208,14 @@
<!-- 操作按钮区域 --> <!-- 操作按钮区域 -->
<el-row class="mt-4" v-if="!iswhetherBid && form.whetherBid == '0'"> <el-row class="mt-4" v-if="!iswhetherBid && form.whetherBid == '0'">
<el-col :span="24" class="text-center"> <el-col :span="24" class="text-center">
<el-button :loading="buttonLoading1" type="primary" @click="submitForm" <el-button
:loading="buttonLoading1"
type="primary"
@click="submitForm"
v-hasPermi="['bidding:listOfWinningBids:add', 'bidding:listOfWinningBids:edit']" v-hasPermi="['bidding:listOfWinningBids:add', 'bidding:listOfWinningBids:edit']"
class="rounded-full px-8" size="large"> class="rounded-full px-8"
size="large"
>
中标 中标
</el-button> </el-button>
</el-col> </el-col>
@ -205,10 +244,6 @@ const fileList = ref([]);
const userStore = useUserStoreHook(); const userStore = useUserStoreHook();
const iswhetherBid = ref(false); // 是否中标 const iswhetherBid = ref(false); // 是否中标
const currentProject = computed(() => userStore.selectedProject); const currentProject = computed(() => userStore.selectedProject);
// const realUploadUrl = computed(() => {
// const search = new URLSearchParams().toString();
// return search ? `${baseUrl}${props.uploadUrl}?${search}` : `${baseUrl}${props.uploadUrl}`;
// });
// 项目信息(仅展示,非表单编辑) // 项目信息(仅展示,非表单编辑)
const projectInfo = reactive({ const projectInfo = reactive({
principal: undefined, principal: undefined,
@ -323,14 +358,7 @@ const getDictLabel = (dictList: any[], value: any) => {
const dictItem = dictList.find((item) => item.value === value); const dictItem = dictList.find((item) => item.value === value);
return dictItem ? dictItem.label : ''; return dictItem ? dictItem.label : '';
}; };
const upload = ref<UploadInstance>();
const handleExceed: UploadProps['onExceed'] = (files) => {
upload.value!.clearFiles();
const file = files[0] as UploadRawFile;
file.uid = genFileId();
upload.value!.handleStart(file);
};
/** /**
* 初始化中标数据根据项目ID查询已有记录 * 初始化中标数据根据项目ID查询已有记录
*/ */

View File

@ -38,16 +38,16 @@
v-if="versionObj.status == 'draft'" v-if="versionObj.status == 'draft'"
icon="Edit" icon="Edit"
@click="handleAudit" @click="handleAudit"
v-hasPermi="['desibiddinggn:biddingLimitList:query']" v-hasPermi="['bidding:biddingLimitList:getVersionDetail']"
>审核</el-button >审核</el-button
> >
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-button <el-button
type="primary" type="warning"
icon="view" icon="view"
@click="handleViewInfo" @click="handleViewInfo"
v-hasPermi="['desibiddinggn:biddingLimitList:query']" v-hasPermi="['bidding:biddingLimitList:getVersionDetail']"
v-if="versionObj.status != 'draft'" v-if="versionObj.status != 'draft'"
>查看流程</el-button >查看流程</el-button
> >
@ -76,10 +76,10 @@
</el-table-column> </el-table-column>
<el-table-column prop="price" label="总价" align="center"> <el-table-column prop="price" label="总价" align="center">
<template #default="scope"> <template #default="scope">
{{ scope.row.price }} {{ scope.row.price != 0 ? Number(scope.row.price).toFixed(2) : null }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="price" label="操作" align="center"> <el-table-column prop="operate" label="操作" align="center">
<template #default="scope"> <template #default="scope">
<el-button <el-button
type="primary" type="primary"
@ -174,7 +174,8 @@ const getTableData = async () => {
loading.value = true; loading.value = true;
const params = { const params = {
projectId: currentProject.value?.id, projectId: currentProject.value?.id,
sheet: queryForm.value.sheet sheet: queryForm.value.sheet,
versions: queryForm.value.versions
}; };
const res = await getTreeLimit(params); const res = await getTreeLimit(params);
loading.value = false; loading.value = false;
@ -267,7 +268,7 @@ const handleAudit = () => {
path: `/approval/biddingLimit/indexEdit`, path: `/approval/biddingLimit/indexEdit`,
query: { query: {
id, id,
type: 'add', type: 'update',
sheets: sheets.value, sheets: sheets.value,
versions: versionObj.value versions: versionObj.value
} }

View File

@ -39,7 +39,14 @@
<el-button type="primary" v-if="reviewStatus == 'draft'" @click="clickApprovalSheet()">审核</el-button> <el-button type="primary" v-if="reviewStatus == 'draft'" @click="clickApprovalSheet()">审核</el-button>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-button type="primary" v-if="reviewStatus != 'draft'" @click="clickApprovalSheet()">查看流程</el-button> <el-button
type="warning"
icon="view"
v-if="reviewStatus != 'draft'"
@click="clickApprovalSheet()"
v-hasPermi="['tender:tenderPlanLimitList:getVersionDetail']"
>查看流程</el-button
>
</el-form-item> </el-form-item>
</el-form> </el-form>
</el-card> </el-card>
@ -55,7 +62,11 @@
<el-input-number <el-input-number
:disabled="reviewStatus != 'draft'" :disabled="reviewStatus != 'draft'"
:model-value="scope.row.unitPrice" :model-value="scope.row.unitPrice"
@change="(val) => (scope.row.unitPrice = val)" @change="
(val) => {
scope.row.unitPrice = val;
}
"
:precision="2" :precision="2"
:step="0.1" :step="0.1"
:controls="false" :controls="false"
@ -65,10 +76,12 @@
</el-table-column> </el-table-column>
<el-table-column prop="price" label="总价" align="center"> <el-table-column prop="price" label="总价" align="center">
<template #default="scope"> <template #default="scope">
{{ scope.row.price }} <!-- {{ scope.row.children.length > 0 ? scope.row.children.reduce((sum, child) => sum + child.price, 0) : scope.row.price }} -->
{{ scope.row.price != 0 ? Number(scope.row.price).toFixed(2) : null }}
<!-- {{ scope.row.price }} -->
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="price" label="操作" align="center"> <el-table-column prop="operate" label="操作" align="center">
<template #default="scope"> <template #default="scope">
<el-button <el-button
type="primary" type="primary"
@ -103,7 +116,8 @@ const sheets = ref<any[]>([]);
const tableData = ref<any[]>([]); const tableData = ref<any[]>([]);
const isExpandAll = ref(false); const isExpandAll = ref(false);
const reviewStatus = ref(''); const reviewStatus = ref('');
const versionObj: any = ref({});
const versionMap = new Map();
//获取版本号 //获取版本号
const getVersionNums = async () => { const getVersionNums = async () => {
try { try {
@ -118,9 +132,11 @@ const getVersionNums = async () => {
if (res.code == 200) { if (res.code == 200) {
options.value = res.data; options.value = res.data;
if (res.data.length > 0) { if (res.data.length > 0) {
res.data.forEach((item: any) => {
versionMap.set(item.versions, item);
});
queryForm.value.versions = res.data[0].versions; queryForm.value.versions = res.data[0].versions;
reviewStatus.value = res.data[0].status; reviewStatus.value = res.data[0].status;
getSheetName(); getSheetName();
} else { } else {
queryForm.value.versions = ''; queryForm.value.versions = '';
@ -283,20 +299,19 @@ const handleExport = () => {
// 审批 // 审批
const clickApprovalSheet = () => { const clickApprovalSheet = () => {
proxy.$tab.closePage(proxy?.$route); proxy.$tab.closePage(proxy?.$route);
let id = versionMap.get(queryForm.value.versions).id;
proxy?.$router.push({ proxy?.$router.push({
path: `/approval/contractLimitPrice/indexEdit`, path: `/approval/contractLimitPrice/indexEdit`,
query: { query: {
projectId: currentProject.value?.id, id: id,
versions: queryForm.value.versions,
sheet: queryForm.value.sheet,
type: 'update', type: 'update',
status: reviewStatus.value sheets: queryForm.value.sheet
} }
}); });
}; };
onUnmounted(() => { onUnmounted(() => {
listeningProject(); listeningProject();
console.log(11111111); // console.log(11111111);
}); });
onMounted(() => { onMounted(() => {
getVersionNums(); getVersionNums();

View File

@ -16,26 +16,20 @@
<!-- 表单区域 --> <!-- 表单区域 -->
<el-card class="rounded-lg shadow-sm bg-white border border-gray-100 transition-all hover:shadow-md overflow-hidden"> <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"> <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> <h3 class="text-lg font-semibold text-gray-800">限价审核</h3>
</div> </div>
<div class="p-6"> <div class="p-6">
<el-form <el-form ref="leaveFormRef" v-loading="loading" :model="form" :rules="rules" label-width="100px" class="space-y-4">
ref="leaveFormRef"
v-loading="loading"
: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"> <div class="grid grid-cols-1 gap-4">
<el-row> <el-row>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="版本号" prop="formNo"> <el-form-item label="版本号" prop="formNo">
<el-input disabled v-model="form.versions" placeholder="请输入文件名称" /> <el-input :disabled="true" v-model="form.versions" placeholder="请输入文件名称" />
</el-form-item> </el-form-item>
<el-form-item label="表名" prop="formNo"> <el-form-item label="表名" prop="sheet">
<el-input disabled v-model="form.sheet" placeholder="请输入文件名称" /> <el-select v-model="form.sheet" placeholder="选择表名" @change="changeSheet">
<el-option v-for="item in sheets" :key="item" :label="item" :value="item" />
</el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
@ -50,7 +44,7 @@
<el-table-column prop="unitPrice" label="单价" align="center" /> <el-table-column prop="unitPrice" label="单价" align="center" />
<el-table-column prop="price" label="总价" align="center"> <el-table-column prop="price" label="总价" align="center">
<template #default="scope"> <template #default="scope">
{{ scope.row.price }} {{ scope.row.price != 0 ? Number(scope.row.price).toFixed(2) : null }}
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
@ -76,12 +70,8 @@
</div> </div>
<template #footer> <template #footer>
<div class="dialog-footer p-4 border-t border-gray-100 flex justify-end space-x-3"> <div class="dialog-footer p-4 border-t border-gray-100 flex justify-end space-x-3">
<el-button @click="handleClose" class="px-4 py-2 border border-gray-300 rounded-md text-gray-700 hover:bg-gray-50 transition-colors" <el-button @click="handleClose" class="px-4 py-2 border border-gray-300 rounded-md text-gray-700 hover:bg-gray-50 transition-colors">取消</el-button>
>取消</el-button <el-button type="primary" @click="submitFlow()" class="px-4 py-2 bg-primary text-white rounded-md hover:bg-primary/90 transition-colors">确认</el-button>
>
<el-button type="primary" @click="submitFlow()" class="px-4 py-2 bg-primary text-white rounded-md hover:bg-primary/90 transition-colors"
>确认</el-button
>
</div> </div>
</template> </template>
</el-dialog> </el-dialog>
@ -99,7 +89,7 @@ import { StartProcessBo } from '@/api/workflow/workflowCommon/types';
const { proxy } = getCurrentInstance() as any; const { proxy } = getCurrentInstance() as any;
import { useUserStoreHook } from '@/store/modules/user'; import { useUserStoreHook } from '@/store/modules/user';
const { design_change_reason_type } = toRefs<any>(proxy?.useDict('design_change_reason_type')); const { design_change_reason_type } = toRefs<any>(proxy?.useDict('design_change_reason_type'));
import { listBillofquantitiesLimitList } from '@/api/contract/index'; import { listBillofquantitiesLimitList, getVersionDetails, sheetList } from '@/api/contract/index';
// 获取用户 store // 获取用户 store
const userStore = useUserStoreHook(); const userStore = useUserStoreHook();
// 从 store 中获取项目列表和当前选中的项目 // 从 store 中获取项目列表和当前选中的项目
@ -143,7 +133,8 @@ const taskVariables = ref<Record<string, any>>({});
const initFormData = { const initFormData = {
versions: '', versions: '',
sheet: '', sheet: '',
status: '' status: '',
id: ''
}; };
const data = reactive({ const data = reactive({
form: { ...initFormData }, form: { ...initFormData },
@ -169,21 +160,47 @@ const getInfo = () => {
loading.value = true; loading.value = true;
buttonLoading.value = false; buttonLoading.value = false;
nextTick(async () => { nextTick(async () => {
const res = await listBillofquantitiesLimitList({ const res = await getVersionDetails(routeParams.value.id);
projectId: routeParams.value?.id, console.log(res);
versions: routeParams.value.versions, Object.assign(form.value, res.data);
sheet: routeParams.value.sheet
});
console.log('res.data', res.data);
Object.assign(form.value, routeParams.value);
console.log('form', form.value);
tableData.value = res.data;
console.log('tableData', tableData.value);
loading.value = false; loading.value = false;
buttonLoading.value = false; buttonLoading.value = false;
getSheetName();
}); });
}; };
const sheets = ref([]);
//获取表名
const getSheetName = async () => {
try {
const params = {
projectId: currentProject.value?.id,
versions: form.value.versions
};
const res = await sheetList(params);
if (res.code == 200) {
sheets.value = res.data;
if (res.data.length > 0) {
form.value.sheet = res.data[0];
}
getListTable();
}
} catch (error) {}
};
//选择表名
const changeSheet = () => {
getListTable();
};
//获取列表
const getListTable = async () => {
const res = await listBillofquantitiesLimitList({
projectId: currentProject.value?.id,
versions: form.value.versions,
sheet: form.value.sheet
});
if (res.code == 200) {
tableData.value = res.data;
}
};
/** 提交按钮 */ /** 提交按钮 */
const submitForm = (status1: string) => { const submitForm = (status1: string) => {
status.value = status1; status.value = status1;
@ -198,7 +215,7 @@ const submitFlow = async () => {
const handleStartWorkFlow = async (data: any) => { const handleStartWorkFlow = async (data: any) => {
try { try {
submitFormData.value.flowCode = flowCode.value; submitFormData.value.flowCode = flowCode.value;
submitFormData.value.businessId = data.versions + '_xianjiayilan'; submitFormData.value.businessId = data.id;
//流程变量 //流程变量
taskVariables.value = { taskVariables.value = {
// leave4/5 使用的流程变量 // leave4/5 使用的流程变量
@ -216,7 +233,7 @@ const handleStartWorkFlow = async (data: any) => {
}; };
//审批记录 //审批记录
const handleApprovalRecord = () => { const handleApprovalRecord = () => {
approvalRecordRef.value.init(form.value.versions); approvalRecordRef.value.init(form.value.id);
}; };
//提交回调 //提交回调
const submitCallback = async () => { const submitCallback = async () => {
@ -255,7 +272,6 @@ onMounted(() => {
reset(); reset();
loading.value = false; loading.value = false;
console.log(routeParams.value); console.log(routeParams.value);
if (routeParams.value.type === 'update' || routeParams.value.type === 'view' || routeParams.value.type === 'approval') { if (routeParams.value.type === 'update' || routeParams.value.type === 'view' || routeParams.value.type === 'approval') {
getInfo(); getInfo();
console.log('routeParams.value', routeParams.value); console.log('routeParams.value', routeParams.value);

View File

@ -1,66 +1,28 @@
<template> <template>
<div class="p-2"> <div class="p-2">
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" <el-card shadow="never">
:leave-active-class="proxy?.animate.searchAnimate.leave"> <template #header>
<div v-show="showSearch" class="mb-[10px]"> <el-row :gutter="10" class="mb8">
<el-card shadow="hover">
<el-form ref="queryFormRef" :model="queryParams" :inline="true"> <el-form ref="queryFormRef" :model="queryParams" :inline="true">
<!-- <el-form-item label="项目ID" prop="projectId">
<el-input v-model="queryParams.projectId" placeholder="请输入项目ID" clearable @keyup.enter="handleQuery" />
</el-form-item> -->
<el-form-item label="合同编号" prop="contractCode"> <el-form-item label="合同编号" prop="contractCode">
<el-input v-model="queryParams.contractCode" placeholder="请输入合同编号" clearable @keyup.enter="handleQuery" /> <el-input v-model="queryParams.contractCode" placeholder="请输入合同编号" clearable @keyup.enter="handleQuery" />
</el-form-item> </el-form-item>
<el-form-item label="供应商" prop="contractSupplier"> <el-form-item label="供应商" prop="contractSupplier">
<el-input v-model="queryParams.contractSupplier" placeholder="请输入供应商" clearable <el-input v-model="queryParams.contractSupplier" placeholder="请输入供应商" clearable @keyup.enter="handleQuery" />
@keyup.enter="handleQuery" />
</el-form-item> </el-form-item>
<!-- <el-form-item label="合同金额" prop="amount">
<el-input v-model="queryParams.amount" placeholder="请输入合同金额" clearable @keyup.enter="handleQuery" />
</el-form-item> -->
<!-- <el-form-item label="招标Id" prop="tenderId">
<el-input v-model="queryParams.tenderId" placeholder="请输入招标Id" clearable @keyup.enter="handleQuery" />
</el-form-item> -->
<el-form-item> <el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button> <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
<el-button icon="Refresh" @click="resetQuery">重置</el-button> <el-button icon="Refresh" @click="resetQuery">重置</el-button>
</el-form-item> </el-form-item>
</el-form> </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="Plus" @click="handleAdd"
v-hasPermi="['ctr:expensesContract:add']">新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()"
v-hasPermi="['ctr:expensesContract:edit']">修改</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()"
v-hasPermi="['ctr:expensesContract:remove']">删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="warning" plain icon="Download" @click="handleExport"
v-hasPermi="['ctr:expensesContract:export']">导出</el-button>
</el-col>-->
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar> <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row> </el-row>
</template> </template>
<el-table v-loading="loading" :data="expensesContractList" @selection-change="handleSelectionChange"> <el-table v-loading="loading" :data="expensesContractList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" /> <el-table-column type="selection" width="55" align="center" />
<!-- <el-table-column label="主键ID" align="center" prop="id" v-if="true" /> -->
<el-table-column type="index" width="50" label="序号" /> <el-table-column type="index" width="50" label="序号" />
<!-- <el-table-column label="项目ID" align="center" prop="projectId" /> -->
<el-table-column label="合同编号" align="center" prop="contractCode" /> <el-table-column label="合同编号" align="center" prop="contractCode" />
<!-- <el-table-column label="合同类型" align="center" prop="contractType" /> -->
<el-table-column label="合同类型" align="center" prop="contractType"> <el-table-column label="合同类型" align="center" prop="contractType">
<template #default="scope"> <template #default="scope">
<dict-tag :options="expenses_contract_type" :value="scope.row.contractType" /> <dict-tag :options="expenses_contract_type" :value="scope.row.contractType" />
@ -73,37 +35,23 @@
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="供应商" align="center" prop="contractSupplier" /> <el-table-column label="供应商" align="center" prop="contractSupplier" />
<!-- <el-table-column label="分包内容" align="center" prop="contractedContent" /> -->
<el-table-column label="合同金额" align="center" prop="amount" /> <el-table-column label="合同金额" align="center" prop="amount" />
<el-table-column label="预付款比例(%)" align="center" prop="advancePayRatio" /> <el-table-column label="预付款比例(%)" align="center" prop="advancePayRatio" />
<el-table-column label="尾款比例(%)" align="center" prop="balancePayRatio" /> <el-table-column label="尾款比例(%)" align="center" prop="balancePayRatio" />
<el-table-column label="质保金比例(%)" align="center" prop="assuranceDepositRatio" /> <el-table-column label="质保金比例(%)" align="center" prop="assuranceDepositRatio" />
<el-table-column label="付款比例(%)" align="center" prop="payRatio" /> <el-table-column label="付款比例(%)" align="center" prop="payRatio" />
<!-- <el-table-column label="招标Id" align="center" prop="tenderId" /> -->
<el-table-column label="备注" align="center" prop="remark" /> <el-table-column label="备注" align="center" prop="remark" />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width"> <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template #default="scope"> <template #default="scope">
<!-- <el-tooltip content="修改" placement="top"> <el-button link type="success" icon="View" @click="handleShowDetail(scope.row)">查看分包内容</el-button>
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" <el-button link type="primary" v-hasPermi="['ctr:expensesContract:query']" icon="View" @click="handleShowFileList(scope.row)"
v-hasPermi="['ctr:expensesContract:edit']"></el-button> >查看附件列表</el-button
</el-tooltip> >
<el-tooltip content="删除" placement="top">
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)"
v-hasPermi="['ctr:expensesContract:remove']"></el-button>
</el-tooltip> -->
<div>
<el-button link type="success" icon="View" @click="handleShowDetail(scope.row)">查看分包内容</el-button>
</div>
<div>
<el-button link type="primary" icon="View" @click="handleShowFileList(scope.row)">查看附件列表</el-button>
</div>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
v-model:limit="queryParams.pageSize" @pagination="getList" />
</el-card> </el-card>
<!-- 添加或修改支出合同对话框 --> <!-- 添加或修改支出合同对话框 -->
<el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body> <el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
@ -143,9 +91,7 @@
<template #footer> <template #footer>
<div class="dialog-footer"> <div class="dialog-footer">
<el-button type="primary" @click="detailVisible = false"> <el-button type="primary" @click="detailVisible = false"> 关闭 </el-button>
关闭
</el-button>
</div> </div>
</template> </template>
</el-dialog> </el-dialog>
@ -153,15 +99,20 @@
</template> </template>
<script setup name="ExpensesContract" lang="ts"> <script setup name="ExpensesContract" lang="ts">
import { listExpensesContract, getExpensesContract, delExpensesContract, addExpensesContract, updateExpensesContract, getFileList } from '@/api/ctr/expensesContract'; import {
listExpensesContract,
getExpensesContract,
delExpensesContract,
addExpensesContract,
updateExpensesContract,
getFileList
} from '@/api/ctr/expensesContract';
import { ExpensesContractVO, ExpensesContractQuery, ExpensesContractForm } from '@/api/ctr/expensesContract/types'; import { ExpensesContractVO, ExpensesContractQuery, ExpensesContractForm } from '@/api/ctr/expensesContract/types';
import FileList from '@/components/FileList/index.vue'; import FileList from '@/components/FileList/index.vue';
import useUserStore from '@/store/modules/user'; import useUserStore from '@/store/modules/user';
const { proxy } = getCurrentInstance() as ComponentInternalInstance; const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const { expenses_contract_type, income_contract_type } = toRefs( const { expenses_contract_type, income_contract_type } = toRefs(proxy?.useDict('income_contract_type', 'expenses_contract_type'));
proxy?.useDict('income_contract_type', 'expenses_contract_type')
);
const expensesContractList = ref<ExpensesContractVO[]>([]); const expensesContractList = ref<ExpensesContractVO[]>([]);
const buttonLoading = ref(false); const buttonLoading = ref(false);
const loading = ref(true); const loading = ref(true);
@ -193,8 +144,8 @@ const initFormData: ExpensesContractForm = {
contractedContent: undefined, contractedContent: undefined,
amount: undefined, amount: undefined,
tenderId: undefined, tenderId: undefined,
remark: undefined, remark: undefined
} };
const data = reactive<PageData<ExpensesContractForm, ExpensesContractQuery>>({ const data = reactive<PageData<ExpensesContractForm, ExpensesContractQuery>>({
form: { ...initFormData }, form: { ...initFormData },
queryParams: { queryParams: {
@ -207,16 +158,11 @@ const data = reactive<PageData<ExpensesContractForm, ExpensesContractQuery>>({
contractedContent: undefined, contractedContent: undefined,
amount: undefined, amount: undefined,
tenderId: undefined, tenderId: undefined,
params: { params: {}
}
}, },
rules: { rules: {
id: [ id: [{ required: true, message: '主键ID不能为空', trigger: 'blur' }],
{ required: true, message: "主键ID不能为空", trigger: "blur" } projectId: [{ required: true, message: '项目ID不能为空', trigger: 'blur' }]
],
projectId: [
{ required: true, message: "项目ID不能为空", trigger: "blur" }
],
} }
}); });
@ -229,55 +175,55 @@ const getList = async () => {
expensesContractList.value = res.rows; expensesContractList.value = res.rows;
total.value = res.total; total.value = res.total;
loading.value = false; loading.value = false;
} };
/** 取消按钮 */ /** 取消按钮 */
const cancel = () => { const cancel = () => {
reset(); reset();
dialog.visible = false; dialog.visible = false;
} };
/** 表单重置 */ /** 表单重置 */
const reset = () => { const reset = () => {
form.value = { ...initFormData }; form.value = { ...initFormData };
expensesContractFormRef.value?.resetFields(); expensesContractFormRef.value?.resetFields();
} };
/** 搜索按钮操作 */ /** 搜索按钮操作 */
const handleQuery = () => { const handleQuery = () => {
queryParams.value.pageNum = 1; queryParams.value.pageNum = 1;
getList(); getList();
} };
/** 重置按钮操作 */ /** 重置按钮操作 */
const resetQuery = () => { const resetQuery = () => {
queryFormRef.value?.resetFields(); queryFormRef.value?.resetFields();
handleQuery(); handleQuery();
} };
/** 多选框选中数据 */ /** 多选框选中数据 */
const handleSelectionChange = (selection: ExpensesContractVO[]) => { const handleSelectionChange = (selection: ExpensesContractVO[]) => {
ids.value = selection.map(item => item.id); ids.value = selection.map((item) => item.id);
single.value = selection.length != 1; single.value = selection.length != 1;
multiple.value = !selection.length; multiple.value = !selection.length;
} };
/** 新增按钮操作 */ /** 新增按钮操作 */
const handleAdd = () => { const handleAdd = () => {
reset(); reset();
dialog.visible = true; dialog.visible = true;
dialog.title = "添加支出合同"; dialog.title = '添加支出合同';
} };
/** 修改按钮操作 */ /** 修改按钮操作 */
const handleUpdate = async (row?: ExpensesContractVO) => { const handleUpdate = async (row?: ExpensesContractVO) => {
reset(); reset();
const _id = row?.id || ids.value[0] const _id = row?.id || ids.value[0];
const res = await getExpensesContract(_id); const res = await getExpensesContract(_id);
Object.assign(form.value, res.data); Object.assign(form.value, res.data);
dialog.visible = true; dialog.visible = true;
dialog.title = "修改支出合同"; dialog.title = '修改支出合同';
} };
/** 提交按钮 */ /** 提交按钮 */
const submitForm = () => { const submitForm = () => {
@ -285,46 +231,51 @@ const submitForm = () => {
if (valid) { if (valid) {
buttonLoading.value = true; buttonLoading.value = true;
if (form.value.id) { if (form.value.id) {
await updateExpensesContract(form.value).finally(() => buttonLoading.value = false); await updateExpensesContract(form.value).finally(() => (buttonLoading.value = false));
} else { } else {
await addExpensesContract(form.value).finally(() => buttonLoading.value = false); await addExpensesContract(form.value).finally(() => (buttonLoading.value = false));
} }
proxy?.$modal.msgSuccess("操作成功"); proxy?.$modal.msgSuccess('操作成功');
dialog.visible = false; dialog.visible = false;
await getList(); await getList();
} }
}); });
} };
/** 删除按钮操作 */ /** 删除按钮操作 */
const handleDelete = async (row?: ExpensesContractVO) => { const handleDelete = async (row?: ExpensesContractVO) => {
const _ids = row?.id || ids.value; const _ids = row?.id || ids.value;
await proxy?.$modal.confirm('是否确认删除支出合同编号为"' + _ids + '"的数据项?').finally(() => loading.value = false); await proxy?.$modal.confirm('是否确认删除支出合同编号为"' + _ids + '"的数据项?').finally(() => (loading.value = false));
await delExpensesContract(_ids); await delExpensesContract(_ids);
proxy?.$modal.msgSuccess("删除成功"); proxy?.$modal.msgSuccess('删除成功');
await getList(); await getList();
} };
/** 导出按钮操作 */ /** 导出按钮操作 */
const handleExport = () => { const handleExport = () => {
proxy?.download('ctr/expensesContract/export', { proxy?.download(
...queryParams.value 'ctr/expensesContract/export',
}, `expensesContract_${new Date().getTime()}.xlsx`) {
} ...queryParams.value
},
`expensesContract_${new Date().getTime()}.xlsx`
);
};
// 查看附件列表操作 // 查看附件列表操作
const handleShowFileList = async (row: ExpensesContractVO) => { const handleShowFileList = async (row: ExpensesContractVO) => {
await getFileList({ contractId: row.id }).then(res => { await getFileList({ contractId: row.id })
fileList.value = res.rows .then((res) => {
fileListVisible.value = true; fileList.value = res.rows;
}).catch(() => { fileListVisible.value = true;
proxy?.$modal.error("获取文件列表失败"); })
}); .catch(() => {
proxy?.$modal.error('获取文件列表失败');
} });
};
const handleShowDetail = (data) => { const handleShowDetail = (data) => {
detailContent.value = data.contractedContent detailContent.value = data.contractedContent;
detailVisible.value = true; detailVisible.value = true;
} };
onMounted(() => { onMounted(() => {
getList(); getList();
}); });

View File

@ -1,60 +1,26 @@
<template> <template>
<div class="p-2"> <div class="p-2">
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" <el-card shadow="never">
:leave-active-class="proxy?.animate.searchAnimate.leave"> <template #header>
<div v-show="showSearch" class="mb-[10px]"> <el-row :gutter="10" class="mb8">
<el-card shadow="hover">
<el-form ref="queryFormRef" :model="queryParams" :inline="true"> <el-form ref="queryFormRef" :model="queryParams" :inline="true">
<!-- <el-form-item label="项目ID" prop="projectId">
<el-input v-model="queryParams.projectId" placeholder="请输入项目ID" clearable @keyup.enter="handleQuery" />
</el-form-item> -->
<el-form-item label="合同编号" prop="contractCode"> <el-form-item label="合同编号" prop="contractCode">
<el-input v-model="queryParams.contractCode" placeholder="请输入合同编号" clearable @keyup.enter="handleQuery" /> <el-input v-model="queryParams.contractCode" placeholder="请输入合同编号" clearable @keyup.enter="handleQuery" />
</el-form-item> </el-form-item>
<el-form-item label="业主单位" prop="contractOwner"> <el-form-item label="业主单位" prop="contractOwner">
<el-input v-model="queryParams.contractOwner" placeholder="请输入业主单位" clearable <el-input v-model="queryParams.contractOwner" placeholder="请输入业主单位" clearable @keyup.enter="handleQuery" />
@keyup.enter="handleQuery" />
</el-form-item> </el-form-item>
<!-- <el-form-item label="合同金额" prop="amount">
<el-input v-model="queryParams.amount" placeholder="请输入合同金额" clearable @keyup.enter="handleQuery" />
</el-form-item> -->
<el-form-item> <el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button> <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
<el-button icon="Refresh" @click="resetQuery">重置</el-button> <el-button icon="Refresh" @click="resetQuery">重置</el-button>
</el-form-item> </el-form-item>
</el-form> </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="Plus" @click="handleAdd"
v-hasPermi="['ctr:incomeContract:add']">新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()"
v-hasPermi="['ctr:incomeContract:edit']">修改</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()"
v-hasPermi="['ctr:incomeContract:remove']">删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="warning" plain icon="Download" @click="handleExport"
v-hasPermi="['ctr:incomeContract:export']">导出</el-button>
</el-col>-->
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar> <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row> </el-row>
</template> </template>
<el-table v-loading="loading" :data="incomeContractList" @selection-change="handleSelectionChange"> <el-table v-loading="loading" :data="incomeContractList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<!-- <el-table-column label="主键ID" align="center" prop="id" v-if="true" /> -->
<el-table-column type="index" width="50" label="序号" /> <el-table-column type="index" width="50" label="序号" />
<!-- <el-table-column label="项目ID" align="center" prop="projectId" /> -->
<el-table-column label="合同编号" align="center" prop="contractCode" /> <el-table-column label="合同编号" align="center" prop="contractCode" />
<el-table-column label="合同类型" align="center" prop="contractType"> <el-table-column label="合同类型" align="center" prop="contractType">
<template #default="scope"> <template #default="scope">
@ -68,7 +34,6 @@
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="业主单位" align="center" prop="contractOwner" /> <el-table-column label="业主单位" align="center" prop="contractOwner" />
<!-- <el-table-column label="承包内容" align="center" prop="contractedContent" /> -->
<el-table-column label="合同金额" align="center" prop="amount" /> <el-table-column label="合同金额" align="center" prop="amount" />
<el-table-column label="预付款比例(%)" align="center" prop="advancePayRatio" /> <el-table-column label="预付款比例(%)" align="center" prop="advancePayRatio" />
<el-table-column label="尾款比例(%)" align="center" prop="balancePayRatio" /> <el-table-column label="尾款比例(%)" align="center" prop="balancePayRatio" />
@ -77,34 +42,24 @@
<el-table-column label="备注" align="center" prop="remark" /> <el-table-column label="备注" align="center" prop="remark" />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="200"> <el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="200">
<template #default="scope"> <template #default="scope">
<!-- <el-tooltip content="修改" placement="top"> <el-button
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" link
v-hasPermi="['ctr:incomeContract:edit']"></el-button> type="primary"
</el-tooltip> v-hasPermi="['ctr:incomeContract:edit']"
<el-tooltip content="删除" placement="top"> icon="edit"
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" @click="handleEdit(scope.row)"
v-hasPermi="['ctr:incomeContract:remove']"></el-button> v-if="scope.row.isUpdate"
</el-tooltip> --> >修改合同</el-button
<!-- <el-tooltip content="查看承包内容" placement="top"> >
<el-button link type="primary" icon="View" @click="handleDetail(scope.row)">详情</el-button> <el-button link type="success" icon="View" @click="handleShowDetail(scope.row)">查看合同内容</el-button>
</el-tooltip> --> <el-button link type="primary" v-hasPermi="['ctr:incomeContract:query']" icon="View" @click="handleShowFileList(scope.row)"
<div> >查看附件列表</el-button
<el-button link type="primary" icon="edit" @click="handleEdit(scope.row)" >
v-if="scope.row.isUpdate">修改合同</el-button>
</div>
<div>
<el-button link type="success" icon="View" @click="handleShowDetail(scope.row)">查看合同内容</el-button>
</div>
<div>
<el-button link type="primary" icon="View" @click="handleShowFileList(scope.row)">查看附件列表</el-button>
</div>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
v-model:limit="queryParams.pageSize" @pagination="getList" />
</el-card> </el-card>
<!-- 添加或修改收入合同对话框 --> <!-- 添加或修改收入合同对话框 -->
<el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body> <el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
@ -141,9 +96,7 @@
<template #footer> <template #footer>
<div class="dialog-footer"> <div class="dialog-footer">
<el-button type="primary" @click="detailVisible = false"> <el-button type="primary" @click="detailVisible = false"> 关闭 </el-button>
关闭
</el-button>
</div> </div>
</template> </template>
</el-dialog> </el-dialog>
@ -151,20 +104,26 @@
</template> </template>
<script setup name="IncomeContract" lang="ts"> <script setup name="IncomeContract" lang="ts">
import { listIncomeContract, getIncomeContract, delIncomeContract, addIncomeContract, updateIncomeContract, getFileList, getInfoByProjectId } from '@/api/ctr/incomeContract'; import {
listIncomeContract,
getIncomeContract,
delIncomeContract,
addIncomeContract,
updateIncomeContract,
getFileList,
getInfoByProjectId
} from '@/api/ctr/incomeContract';
import { IncomeContractVO, IncomeContractQuery, IncomeContractForm } from '@/api/ctr/incomeContract/types'; import { IncomeContractVO, IncomeContractQuery, IncomeContractForm } from '@/api/ctr/incomeContract/types';
import FileList from '@/components/FileList/index.vue'; import FileList from '@/components/FileList/index.vue';
import useUserStore from '@/store/modules/user'; import useUserStore from '@/store/modules/user';
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router';
const { proxy } = getCurrentInstance(); const { proxy } = getCurrentInstance();
const userStore = useUserStore(); const userStore = useUserStore();
const currentProject = computed(() => userStore.selectedProject); const currentProject = computed(() => userStore.selectedProject);
const router = useRouter(); const router = useRouter();
const { expenses_contract_type, income_contract_type } = toRefs( const { expenses_contract_type, income_contract_type } = toRefs(proxy?.useDict('income_contract_type', 'expenses_contract_type'));
proxy?.useDict('income_contract_type', 'expenses_contract_type')
);
const incomeContractList = ref<IncomeContractVO[]>([]); const incomeContractList = ref<IncomeContractVO[]>([]);
const buttonLoading = ref(false); const buttonLoading = ref(false);
const loading = ref(true); const loading = ref(true);
@ -191,8 +150,8 @@ const initFormData: IncomeContractForm = {
contractOwner: undefined, contractOwner: undefined,
contractedContent: undefined, contractedContent: undefined,
amount: undefined, amount: undefined,
remark: undefined, remark: undefined
} };
const data = reactive<PageData<IncomeContractForm, IncomeContractQuery>>({ const data = reactive<PageData<IncomeContractForm, IncomeContractQuery>>({
form: { ...initFormData }, form: { ...initFormData },
queryParams: { queryParams: {
@ -204,16 +163,11 @@ const data = reactive<PageData<IncomeContractForm, IncomeContractQuery>>({
contractOwner: undefined, contractOwner: undefined,
contractedContent: undefined, contractedContent: undefined,
amount: undefined, amount: undefined,
params: { params: {}
}
}, },
rules: { rules: {
id: [ id: [{ required: true, message: '主键ID不能为空', trigger: 'blur' }],
{ required: true, message: "主键ID不能为空", trigger: "blur" } projectId: [{ required: true, message: '项目ID不能为空', trigger: 'blur' }]
],
projectId: [
{ required: true, message: "项目ID不能为空", trigger: "blur" }
],
} }
}); });
@ -226,55 +180,55 @@ const getList = async () => {
incomeContractList.value = res.rows; incomeContractList.value = res.rows;
total.value = res.total; total.value = res.total;
loading.value = false; loading.value = false;
} };
/** 取消按钮 */ /** 取消按钮 */
const cancel = () => { const cancel = () => {
reset(); reset();
dialog.visible = false; dialog.visible = false;
} };
/** 表单重置 */ /** 表单重置 */
const reset = () => { const reset = () => {
form.value = { ...initFormData }; form.value = { ...initFormData };
incomeContractFormRef.value?.resetFields(); incomeContractFormRef.value?.resetFields();
} };
/** 搜索按钮操作 */ /** 搜索按钮操作 */
const handleQuery = () => { const handleQuery = () => {
queryParams.value.pageNum = 1; queryParams.value.pageNum = 1;
getList(); getList();
} };
/** 重置按钮操作 */ /** 重置按钮操作 */
const resetQuery = () => { const resetQuery = () => {
queryFormRef.value?.resetFields(); queryFormRef.value?.resetFields();
handleQuery(); handleQuery();
} };
/** 多选框选中数据 */ /** 多选框选中数据 */
const handleSelectionChange = (selection: IncomeContractVO[]) => { const handleSelectionChange = (selection: IncomeContractVO[]) => {
ids.value = selection.map(item => item.id); ids.value = selection.map((item) => item.id);
single.value = selection.length != 1; single.value = selection.length != 1;
multiple.value = !selection.length; multiple.value = !selection.length;
} };
/** 新增按钮操作 */ /** 新增按钮操作 */
const handleAdd = () => { const handleAdd = () => {
reset(); reset();
dialog.visible = true; dialog.visible = true;
dialog.title = "添加收入合同"; dialog.title = '添加收入合同';
} };
/** 修改按钮操作 */ /** 修改按钮操作 */
const handleUpdate = async (row?: IncomeContractVO) => { const handleUpdate = async (row?: IncomeContractVO) => {
reset(); reset();
const _id = row?.id || ids.value[0] const _id = row?.id || ids.value[0];
const res = await getIncomeContract(_id); const res = await getIncomeContract(_id);
Object.assign(form.value, res.data); Object.assign(form.value, res.data);
dialog.visible = true; dialog.visible = true;
dialog.title = "修改收入合同"; dialog.title = '修改收入合同';
} };
/** 提交按钮 */ /** 提交按钮 */
const submitForm = () => { const submitForm = () => {
@ -282,58 +236,63 @@ const submitForm = () => {
if (valid) { if (valid) {
buttonLoading.value = true; buttonLoading.value = true;
if (form.value.id) { if (form.value.id) {
await updateIncomeContract(form.value).finally(() => buttonLoading.value = false); await updateIncomeContract(form.value).finally(() => (buttonLoading.value = false));
} else { } else {
await addIncomeContract(form.value).finally(() => buttonLoading.value = false); await addIncomeContract(form.value).finally(() => (buttonLoading.value = false));
} }
proxy?.$modal.msgSuccess("操作成功"); proxy?.$modal.msgSuccess('操作成功');
dialog.visible = false; dialog.visible = false;
await getList(); await getList();
} }
}); });
} };
/** 删除按钮操作 */ /** 删除按钮操作 */
const handleDelete = async (row?: IncomeContractVO) => { const handleDelete = async (row?: IncomeContractVO) => {
const _ids = row?.id || ids.value; const _ids = row?.id || ids.value;
await proxy?.$modal.confirm('是否确认删除收入合同编号为"' + _ids + '"的数据项?').finally(() => loading.value = false); await proxy?.$modal.confirm('是否确认删除收入合同编号为"' + _ids + '"的数据项?').finally(() => (loading.value = false));
await delIncomeContract(_ids); await delIncomeContract(_ids);
proxy?.$modal.msgSuccess("删除成功"); proxy?.$modal.msgSuccess('删除成功');
await getList(); await getList();
} };
/** 导出按钮操作 */ /** 导出按钮操作 */
const handleExport = () => { const handleExport = () => {
proxy?.download('ctr/incomeContract/export', { proxy?.download(
...queryParams.value 'ctr/incomeContract/export',
}, `incomeContract_${new Date().getTime()}.xlsx`) {
} ...queryParams.value
},
`incomeContract_${new Date().getTime()}.xlsx`
);
};
// 查看附件列表操作 // 查看附件列表操作
const handleShowFileList = async (row: IncomeContractVO) => { const handleShowFileList = async (row: IncomeContractVO) => {
console.log(row.id); console.log(row.id);
await getFileList({ contractId: row.id }).then(res => { await getFileList({ contractId: row.id })
fileList.value = res.rows .then((res) => {
fileListVisible.value = true; fileList.value = res.rows;
}).catch(() => { fileListVisible.value = true;
proxy?.$modal.error("获取文件列表失败"); })
}); .catch(() => {
proxy?.$modal.error('获取文件列表失败');
} });
};
const handleEdit = (row: IncomeContractVO) => { const handleEdit = (row: IncomeContractVO) => {
// console.log(router); // console.log(router);
router.push({ router.push({
path: "/ctr/update", path: '/ctr/update',
query: { query: {
id: row.id, id: row.id
} }
}) });
} };
const handleShowDetail = (data) => { const handleShowDetail = (data) => {
detailContent.value = data.contractedContent detailContent.value = data.contractedContent;
detailVisible.value = true; detailVisible.value = true;
} };
onMounted(() => { onMounted(() => {
getList(); getList();
}); });

View File

@ -155,8 +155,8 @@
</template> </template>
<script setup> <script setup>
import FileUpload from '@/components/FileUpload'; import FileUpload from '@/components/FileUpload';
import { listExpensesContract, getExpensesContract, delExpensesContract, addExpensesContract, updateExpensesContract, getTenderPlan } from '@/api/ctr/expensesContract'; import { addExpensesContract, getTenderPlan } from '@/api/ctr/expensesContract';
import { listIncomeContract, getIncomeContract, delIncomeContract, addIncomeContract, updateIncomeContract, getInfoByProjectId } from '@/api/ctr/incomeContract'; import { addIncomeContract, getInfoByProjectId } from '@/api/ctr/incomeContract';
import { useUserStore } from '@/store/modules/user'; import { useUserStore } from '@/store/modules/user';
const active = ref(0); const active = ref(0);

View File

@ -9,9 +9,6 @@
<template v-if="active == 1"> <template v-if="active == 1">
<h1>修改收入合同</h1> <h1>修改收入合同</h1>
<el-form ref="incomeContractFormRef" :model="form" :rules="incomeContractFormRules" label-width="80px"> <el-form ref="incomeContractFormRef" :model="form" :rules="incomeContractFormRules" label-width="80px">
<!-- <el-form-item label="项目名称">
<el-input :model-value="project.name" disabled />
</el-form-item> -->
<el-form-item label="合同编号" prop="contractCode"> <el-form-item label="合同编号" prop="contractCode">
<el-input v-model="form.contractCode" placeholder="请输入合同编号" /> <el-input v-model="form.contractCode" placeholder="请输入合同编号" />
</el-form-item> </el-form-item>
@ -80,23 +77,19 @@
</template> </template>
<script setup> <script setup>
import FileUpload from '@/components/FileUpload'; import FileUpload from '@/components/FileUpload';
import { listExpensesContract, getExpensesContract, delExpensesContract, addExpensesContract, updateExpensesContract, getTenderPlan } from '@/api/ctr/expensesContract'; import { getTenderPlan } from '@/api/ctr/expensesContract';
import { listIncomeContract, getIncomeContract, delIncomeContract, addIncomeContract, updateIncomeContract } from '@/api/ctr/incomeContract'; import { updateIncomeContract } from '@/api/ctr/incomeContract';
import { useUserStore } from '@/store/modules/user'; import { useUserStore } from '@/store/modules/user';
const active = ref(1); const active = ref(1);
const contract_type = ref("income") const contract_type = ref('income');
const form = ref({ payType: 1 }) const form = ref({ payType: 1 });
const fileList = ref([]) const fileList = ref([]);
const tempFileList = ref([]) const tempFileList = ref([]);
const { proxy } = getCurrentInstance(); const { proxy } = getCurrentInstance();
const userStore = useUserStore(); const userStore = useUserStore();
const planList = ref([]); const planList = ref([]);
const dialogVisible = ref(false); const dialogVisible = ref(false);
const route = useRoute(); const { income_contract_type } = toRefs(proxy?.useDict('income_contract_type', 'expenses_contract_type'));
const router = useRouter();
const { expenses_contract_type, income_contract_type } = toRefs(
proxy?.useDict('income_contract_type', 'expenses_contract_type')
);
const fileRef = ref(null); const fileRef = ref(null);
const incomeContractFormRef = ref(null); const incomeContractFormRef = ref(null);
const expensesContractFormRef = ref(null); const expensesContractFormRef = ref(null);
@ -106,7 +99,7 @@ const incomeContractFormRules = {
contractType: [{ required: true, message: '请选择合同类型', trigger: 'change' }], contractType: [{ required: true, message: '请选择合同类型', trigger: 'change' }],
contractOwner: [{ required: true, message: '请输入业主单位', trigger: 'blur' }], contractOwner: [{ required: true, message: '请输入业主单位', trigger: 'blur' }],
amount: [{ required: true, message: '请输入合同金额', trigger: 'blur' }], amount: [{ required: true, message: '请输入合同金额', trigger: 'blur' }],
remark: [{ required: false, message: '请输入备注', trigger: 'blur' }], remark: [{ required: false, message: '请输入备注', trigger: 'blur' }]
}; };
const expensesContractFormRules = { const expensesContractFormRules = {
contractCode: [{ required: true, message: '请输入合同编号', trigger: 'blur' }], contractCode: [{ required: true, message: '请输入合同编号', trigger: 'blur' }],
@ -116,18 +109,17 @@ const expensesContractFormRules = {
amount: [{ required: true, message: '请输入合同金额', trigger: 'blur' }], amount: [{ required: true, message: '请输入合同金额', trigger: 'blur' }],
tenderId: [{ required: true, message: '请选择招标计划', trigger: 'blur' }], tenderId: [{ required: true, message: '请选择招标计划', trigger: 'blur' }],
remark: [{ required: false, message: '请输入备注', trigger: 'blur' }], remark: [{ required: false, message: '请输入备注', trigger: 'blur' }]
}; };
const payMentRules = { const payMentRules = {
payType: [{ required: true, message: '请选择支付方式', trigger: 'change' }], payType: [{ required: true, message: '请选择支付方式', trigger: 'change' }],
advancePayRatio: [{ required: true, message: '请输入预付款比例', trigger: 'blur' }], advancePayRatio: [{ required: true, message: '请输入预付款比例', trigger: 'blur' }],
balancePayRatio: [{ required: true, message: '请输入尾款比例', trigger: 'blur' }], balancePayRatio: [{ required: true, message: '请输入尾款比例', trigger: 'blur' }],
assuranceDepositRatio: [{ required: true, message: '请输入质保金比例', trigger: 'blur' }], assuranceDepositRatio: [{ required: true, message: '请输入质保金比例', trigger: 'blur' }]
}; };
const project = computed(() => { const project = computed(() => {
return JSON.parse(localStorage.getItem("selectedProject")) return JSON.parse(localStorage.getItem('selectedProject'));
}); });
const payRatioComputed = computed({ const payRatioComputed = computed({
@ -142,8 +134,8 @@ const payRatioComputed = computed({
}); });
const onUploadSuccess = (data) => { const onUploadSuccess = (data) => {
fileList.value = data fileList.value = data;
} };
const next = async () => { const next = async () => {
if (contract_type.value === 'income') { if (contract_type.value === 'income') {
@ -170,9 +162,7 @@ const next = async () => {
const submitForm = async () => { const submitForm = async () => {
await payMentRef.value.validate(async (valid) => { await payMentRef.value.validate(async (valid) => {
if (valid) { if (valid) {
if (payRatioComputed.value < 0) { if (payRatioComputed.value < 0) {
ElMessage.error('四项付款比例之和必须等于100%'); ElMessage.error('四项付款比例之和必须等于100%');
return; return;
} }
@ -186,9 +176,9 @@ const submitForm = async () => {
return { return {
...data, ...data,
fileName: data.name, fileName: data.name,
fileUrl: data.url, fileUrl: data.url
} };
}) });
if (contract_type.value === 'income') { if (contract_type.value === 'income') {
await updateIncomeContract({ ...form.value }); await updateIncomeContract({ ...form.value });
} }
@ -197,8 +187,7 @@ const submitForm = async () => {
ElMessage.error('请填写完整的付款信息'); ElMessage.error('请填写完整的付款信息');
} }
}); });
};
}
const handleChoose = async () => { const handleChoose = async () => {
if (!form.value.contractType) { if (!form.value.contractType) {
ElMessage.error('请先选择合同类型'); ElMessage.error('请先选择合同类型');
@ -207,17 +196,16 @@ const handleChoose = async () => {
const formData = { const formData = {
projectId: userStore.selectedProject.id, projectId: userStore.selectedProject.id,
dictName: form.value.contractType, dictName: form.value.contractType,
status: 1, status: 1
} };
const { data } = await getTenderPlan(formData) const { data } = await getTenderPlan(formData);
if (data.length === 0) { if (data.length === 0) {
ElMessage.warning('当前没有招标计划,请先创建招标计划'); ElMessage.warning('当前没有招标计划,请先创建招标计划');
return; return;
} }
planList.value = data planList.value = data;
dialogVisible.value = true; dialogVisible.value = true;
};
}
onMounted(async () => { onMounted(async () => {
const id = route.query.id; const id = route.query.id;

View File

@ -19,7 +19,7 @@
<template #header> <template #header>
<el-row :gutter="10" class="mb8"> <el-row :gutter="10" class="mb8">
<el-col :span="1.5"> <el-col :span="1.5">
<el-button type="primary" plain icon="Plus" @click="handleAdd">新增</el-button> <el-button type="primary" plain icon="Plus" v-hasPermi="['design:extract:add']" @click="handleAdd">新增</el-button>
</el-col> </el-col>
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar> <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row> </el-row>
@ -187,7 +187,7 @@ const handleDownload = (row) => {
{ {
id: row.id id: row.id
}, },
`互提资料.zip` `互提资料.docx`
); );
}; };
const handleViewFile = (row) => { const handleViewFile = (row) => {

View File

@ -6,7 +6,7 @@
<el-col :span="1.5"> <el-col :span="1.5">
<div class="box_btn"> <div class="box_btn">
<file-upload :limit="1" :uploadUrl="uploadUrl" :params="uploadParams" :on-upload-success="uploadFile" :fileType="[]"> <file-upload :limit="1" :uploadUrl="uploadUrl" :params="uploadParams" :on-upload-success="uploadFile" :fileType="[]">
<el-button type="primary" style="float: left"> <el-button type="primary" style="float: left" v-hasPermi="['design:collectFile:add']">
<el-icon size="small"><Upload /></el-icon>上传文件 <el-icon size="small"><Upload /></el-icon>上传文件
</el-button> </el-button>
</file-upload> </file-upload>
@ -17,7 +17,13 @@
</template> </template>
<el-table :data="FileList" style="width: 100%" height="64vh"> <el-table :data="FileList" style="width: 100%" height="64vh">
<el-table-column type="index" align="center" label="序号" width="180" /> <el-table-column type="index" align="center" label="序号" width="180" />
<el-table-column prop="fileName" align="center" label="文件名称" /> <el-table-column align="center" label="文件名称">
<template #default="scope">
<el-link :key="scope.row.fileName" :href="scope.row.fileUrl" target="_blank" type="primary" :underline="false">
{{ scope.row.fileName }}
</el-link>
</template>
</el-table-column>
<el-table-column label="流程状态" align="center" prop="status"> <el-table-column label="流程状态" align="center" prop="status">
<template #default="scope"> <template #default="scope">
<dict-tag :options="wf_business_status" :value="scope.row.status" /> <dict-tag :options="wf_business_status" :value="scope.row.status" />

View File

@ -14,7 +14,7 @@
<el-input v-model="queryParams.volumeNo" placeholder="请输入卷册号" clearable @keyup.enter="handleQuery" /> <el-input v-model="queryParams.volumeNo" placeholder="请输入卷册号" clearable @keyup.enter="handleQuery" />
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery" v-hasPermi="['design:designChange:list']">搜索</el-button> <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
<el-button icon="Refresh" @click="resetQuery">重置</el-button> <el-button icon="Refresh" @click="resetQuery">重置</el-button>
</el-form-item> </el-form-item>
</el-form> </el-form>
@ -93,7 +93,7 @@
type="warning" type="warning"
link link
icon="View" icon="View"
v-hasPermi="['design:designChange:query']" v-hasPermi="['design:drawingreviewReceipts:list']"
v-if="scope.row.status != 'draft'" v-if="scope.row.status != 'draft'"
@click="handleViewHistory(scope.row)" @click="handleViewHistory(scope.row)"
>查看单据</el-button >查看单据</el-button

View File

@ -3,19 +3,30 @@
<div class="max-w-4xl mx-auto"> <div class="max-w-4xl mx-auto">
<!-- 顶部按钮区域 --> <!-- 顶部按钮区域 -->
<el-card class="mb-4 rounded-lg shadow-sm bg-white border border-gray-100 transition-all hover:shadow-md"> <el-card class="mb-4 rounded-lg shadow-sm bg-white border border-gray-100 transition-all hover:shadow-md">
<approvalButton @submitForm="submitForm" @approvalVerifyOpen="approvalVerifyOpen" <approvalButton
@handleApprovalRecord="handleApprovalRecord" :buttonLoading="buttonLoading" :id="form.id" @submitForm="submitForm"
:status="form.status" :pageType="routeParams.type" /> @approvalVerifyOpen="approvalVerifyOpen"
@handleApprovalRecord="handleApprovalRecord"
:buttonLoading="buttonLoading"
:id="form.id"
:status="form.status"
:pageType="routeParams.type"
/>
</el-card> </el-card>
<!-- 表单区域 --> <!-- 表单区域 -->
<el-card <el-card class="rounded-lg shadow-sm bg-white border border-gray-100 transition-all hover:shadow-md overflow-hidden">
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"> <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> <h3 class="text-lg font-semibold text-gray-800">变更图纸信息</h3>
</div> </div>
<div class="p-6"> <div class="p-6">
<el-form ref="leaveFormRef" :disabled="routeParams.type === 'view' || form.status == 'waiting'" :model="form" <el-form
:rules="rules" label-width="100px" class="space-y-4"> 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"> <div class="grid grid-cols-1 gap-4">
<el-row> <el-row>
<el-col :span="12"> <el-col :span="12">
@ -25,14 +36,32 @@
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="工程名称" prop="projectName"> <el-form-item label="工程名称" prop="projectName">
<el-input v-model="form.projectName" placeholder="请输入工程名称" /> </el-form-item></el-col> <el-input v-model="form.projectName" placeholder="请输入工程名称" /> </el-form-item
></el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="原卷册号" prop="volumeNo"> <el-form-item label="原卷册号" prop="volumeNo">
<el-select id="projectSelect" v-model="form.volumeNo" placeholder="请选择原卷册号" clearable filterable <el-select
@change="handleSelect" style="width: 150px; margin-right: 20px"> id="projectSelect"
<el-option v-for="project in volumeCatalogList" :key="project.volumeNumber" v-model="form.volumeNo"
:label="project.volumeNumber" :value="project.volumeNumber" /> placeholder="请选择原卷册号"
</el-select> </el-form-item></el-col> 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-tooltip class="box-item" effect="dark" content="只有通过审核的蓝图才能选择" placement="top-start">
<el-icon size="22" class="no-inherit">
<QuestionFilled />
</el-icon>
</el-tooltip> </el-form-item
></el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="提出单位" prop="submitUnit"> <el-form-item label="提出单位" prop="submitUnit">
<el-input v-model="form.submitUnit" placeholder="请输入提出单位" /> <el-input v-model="form.submitUnit" placeholder="请输入提出单位" />
@ -45,16 +74,16 @@
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="提出日期" prop="submitDate"> <el-form-item label="提出日期" prop="submitDate">
<el-date-picker clearable v-model="form.submitDate" type="date" value-format="YYYY-MM-DD HH:mm:ss" <el-date-picker clearable v-model="form.submitDate" type="date" value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择提出日期">
placeholder="请选择提出日期"> </el-date-picker> </el-form-item
</el-date-picker> </el-form-item></el-col> ></el-col>
<!-- <el-col :span="12"> <!-- <el-col :span="12">
<el-form-item label="卷册名称" prop="volumeName"> <el-input v-model="form.volumeName" placeholder="请输入卷册名称" /> </el-form-item <el-form-item label="卷册名称" prop="volumeName"> <el-input v-model="form.volumeName" placeholder="请输入卷册名称" /> </el-form-item
></el-col> --> ></el-col> -->
<el-col :span="12"> <el-col :span="12">
<el-form-item label="子项名称" prop="subName"> <el-form-item label="子项名称" prop="subName">
<el-input disabled v-model="form.extendDetail.subName" placeholder="请输入子项名称" /> <el-input disabled v-model="form.extendDetail.subName" placeholder="请输入子项名称" /> </el-form-item
</el-form-item></el-col> ></el-col>
<el-col :span="24"> <el-col :span="24">
<el-form-item label="原设计处置" prop="designDisposal"> <el-form-item label="原设计处置" prop="designDisposal">
<el-radio-group v-model="form.extendDetail.designDisposal" @change="handleRadio"> <el-radio-group v-model="form.extendDetail.designDisposal" @change="handleRadio">
@ -62,7 +91,8 @@
<el-radio value="2" :disabled="!designId" size="large">原图保留部分修改</el-radio> <el-radio value="2" :disabled="!designId" size="large">原图保留部分修改</el-radio>
<el-radio value="3" size="large">原图保留补充设计</el-radio> <el-radio value="3" size="large">原图保留补充设计</el-radio>
</el-radio-group> </el-radio-group>
</el-form-item></el-col> </el-form-item></el-col
>
<el-col :span="24" v-if="form.extendDetail.designDisposal == 2"> <el-col :span="24" v-if="form.extendDetail.designDisposal == 2">
<el-form-item label="保留文件" prop="saveFile"> <el-form-item label="保留文件" prop="saveFile">
<el-checkbox-group v-model="form.saveFile"> <el-checkbox-group v-model="form.saveFile">
@ -70,17 +100,20 @@
{{ dict.fileName }} {{ dict.fileName }}
</el-checkbox> </el-checkbox>
</el-checkbox-group> </el-checkbox-group>
</el-form-item></el-col> </el-form-item></el-col
>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="设计阶段" prop="designPhase"> <el-form-item label="设计阶段" prop="designPhase">
<el-input v-model="form.extendDetail.designPhase" placeholder="请输入设计阶段" /> </el-form-item></el-col> <el-input v-model="form.extendDetail.designPhase" placeholder="请输入设计阶段" /> </el-form-item
></el-col>
<el-col :span="24"> <el-col :span="24">
<el-form-item label="变更类别" prop="changeCategory"> <el-form-item label="变更类别" prop="changeCategory">
<el-radio-group v-model="form.extendDetail.changeCategory"> <el-radio-group v-model="form.extendDetail.changeCategory">
<el-radio value="1" size="large">重大设计变更</el-radio> <el-radio value="1" size="large">重大设计变更</el-radio>
<el-radio value="2" size="large">一般设计变更</el-radio> <el-radio value="2" size="large">一般设计变更</el-radio>
</el-radio-group> </el-radio-group>
</el-form-item></el-col> </el-form-item></el-col
>
<el-col :span="24"> <el-col :span="24">
<el-form-item label="实施程序" prop="ImpProcedure"> <el-form-item label="实施程序" prop="ImpProcedure">
<el-radio-group v-model="form.extendDetail.ImpProcedure"> <el-radio-group v-model="form.extendDetail.ImpProcedure">
@ -88,14 +121,15 @@
<el-radio value="2" size="large">建设单位送原施工图审查机构审查建设主管部分备案后交付实施</el-radio> <el-radio value="2" size="large">建设单位送原施工图审查机构审查建设主管部分备案后交付实施</el-radio>
<el-radio value="3" size="large">建设单位确认后交付实施</el-radio> <el-radio value="3" size="large">建设单位确认后交付实施</el-radio>
</el-radio-group> </el-radio-group>
</el-form-item></el-col> </el-form-item></el-col
>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="更改相关专业" prop="involvingProfessions"> <el-form-item label="更改相关专业" prop="involvingProfessions">
<el-input v-model="form.extendDetail.involvingProfessions" placeholder="请输入更改相关专业" /> <el-input v-model="form.extendDetail.involvingProfessions" placeholder="请输入更改相关专业" /> </el-form-item
</el-form-item></el-col> ></el-col>
<el-col :span="24"> <el-col :span="24">
<el-form-item label="附图" prop="attachmentPic"> <image-upload v-model="form.attachmentPic" <el-form-item label="附图" prop="attachmentPic"> <image-upload v-model="form.attachmentPic" :fileSize="100" /> </el-form-item
:fileSize="100" /> </el-form-item></el-col> ></el-col>
<el-col :span="24"> <el-col :span="24">
<el-form-item label="变更原因" prop="changeReason"> <el-form-item label="变更原因" prop="changeReason">
<el-checkbox-group v-model="form.changeReason"> <el-checkbox-group v-model="form.changeReason">
@ -103,23 +137,27 @@
{{ dict.label }} {{ dict.label }}
</el-checkbox> </el-checkbox>
</el-checkbox-group> </el-checkbox-group>
</el-form-item></el-col> </el-form-item></el-col
>
<el-col :span="24"> <el-col :span="24">
<el-form-item label="变更内容" prop="changeContent"> <el-form-item label="变更内容" prop="changeContent">
<el-input v-model="form.changeContent" type="textarea" placeholder="请输入内容" /> <el-input v-model="form.changeContent" type="textarea" placeholder="请输入内容" /> </el-form-item
</el-form-item></el-col> ></el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="费用" prop="costEstimation"> <el-form-item label="费用" prop="costEstimation">
<el-input v-model="form.costEstimation" type="number" placeholder="请输入费用" /> <el-input v-model="form.costEstimation" type="number" placeholder="请输入费用" /> </el-form-item
</el-form-item></el-col> ></el-col>
<el-col :span="24"> <el-col :span="24">
<el-form-item label="变更费用估算表" label-width="110px" prop="costEstimationFile"> <el-form-item label="变更费用估算表" label-width="110px" prop="costEstimationFile">
<file-upload v-model="form.costEstimationFile" :fileSize="100" /> </el-form-item></el-col> <file-upload v-model="form.costEstimationFile" :fileSize="100" /> </el-form-item
></el-col>
<!-- <el-col :span="24"> <!-- <el-col :span="24">
<el-form-item label="变更文件" prop="fileId"> <file-upload v-model="form.fileId" :fileSize="100" /> </el-form-item <el-form-item label="变更文件" prop="fileId"> <file-upload v-model="form.fileId" :fileSize="100" /> </el-form-item
></el-col> --> ></el-col> -->
<el-col :span="24"><el-form-item label="备注" prop="remark"> <el-col :span="24"
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容" /> </el-form-item></el-col> ><el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容" /> </el-form-item
></el-col>
</el-row> </el-row>
</div> </div>
</el-form> </el-form>
@ -129,8 +167,14 @@
<submitVerify ref="submitVerifyRef" :task-variables="taskVariables" @submit-callback="submitCallback" /> <submitVerify ref="submitVerifyRef" :task-variables="taskVariables" @submit-callback="submitCallback" />
<approvalRecord ref="approvalRecordRef"></approvalRecord> <approvalRecord ref="approvalRecordRef"></approvalRecord>
<!-- 流程选择对话框 --> <!-- 流程选择对话框 -->
<el-dialog draggable v-model="dialogVisible.visible" :title="dialogVisible.title" :before-close="handleClose" <el-dialog
width="500" class="rounded-lg shadow-lg"> draggable
v-model="dialogVisible.visible"
:title="dialogVisible.title"
:before-close="handleClose"
width="500"
class="rounded-lg shadow-lg"
>
<div class="p-4"> <div class="p-4">
<p class="text-gray-600 mb-4">请选择要启动的流程</p> <p class="text-gray-600 mb-4">请选择要启动的流程</p>
<el-select v-model="flowCode" placeholder="请选择流程" style="width: 100%"> <el-select v-model="flowCode" placeholder="请选择流程" style="width: 100%">
@ -139,10 +183,12 @@
</div> </div>
<template #footer> <template #footer>
<div class="dialog-footer p-4 border-t border-gray-100 flex justify-end space-x-3"> <div class="dialog-footer p-4 border-t border-gray-100 flex justify-end space-x-3">
<el-button @click="handleClose" <el-button @click="handleClose" class="px-4 py-2 border border-gray-300 rounded-md text-gray-700 hover:bg-gray-50 transition-colors"
class="px-4 py-2 border border-gray-300 rounded-md text-gray-700 hover:bg-gray-50 transition-colors">取消</el-button> >取消</el-button
<el-button type="primary" @click="submitFlow()" >
class="px-4 py-2 bg-primary text-white rounded-md hover:bg-primary/90 transition-colors">确认</el-button> <el-button type="primary" @click="submitFlow()" class="px-4 py-2 bg-primary text-white rounded-md hover:bg-primary/90 transition-colors"
>确认</el-button
>
</div> </div>
</template> </template>
</el-dialog> </el-dialog>

View File

@ -24,8 +24,8 @@
<el-input v-model="queryParams.documentName" placeholder="请输入资料名称" clearable @keyup.enter="handleQuery" /> <el-input v-model="queryParams.documentName" placeholder="请输入资料名称" clearable @keyup.enter="handleQuery" />
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery" v-hasPermi="['design:volumeCatalog:query']">搜索</el-button> <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
<el-button icon="Refresh" @click="resetQuery" v-hasPermi="['design:volumeCatalog:query']">重置</el-button> <el-button icon="Refresh" @click="resetQuery">重置</el-button>
</el-form-item> </el-form-item>
</el-form> </el-form>
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar> <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
@ -47,6 +47,7 @@
target="_blank" target="_blank"
type="primary" type="primary"
:underline="false" :underline="false"
v-hasPermi="['design:volumeFileViewer:add']"
@click="handleBookFile(scope.row)" @click="handleBookFile(scope.row)"
> >
{{ scope.row.fileName }} {{ scope.row.fileName }}
@ -55,8 +56,10 @@
</el-table-column> </el-table-column>
<el-table-column label="操作" align="center" prop="remark" width="300"> <el-table-column label="操作" align="center" prop="remark" width="300">
<template #default="scope"> <template #default="scope">
<el-button link type="primary" icon="view" @click="handleViewHis(scope.row)">查阅记录</el-button> <el-button link type="primary" icon="view" v-hasPermi="['design:drawing:list']" @click="handleViewHis(scope.row)">查阅记录</el-button>
<el-button type="warning" link icon="Download" @click="handleDownload(scope.row)"> 下载 </el-button> <el-button type="warning" link icon="Download" v-hasPermi="['design:volumeFileViewer:add']" @click="handleDownload(scope.row)">
下载
</el-button>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>

View File

@ -48,7 +48,7 @@
v-if="scope.row.status !== 'draft'" v-if="scope.row.status !== 'draft'"
icon="Edit" icon="Edit"
@click="handleView(scope.row)" @click="handleView(scope.row)"
v-hasPermi="['design:PrelimScheme:query']" v-hasPermi="['design:prelimScheme:query']"
>查看流程</el-button >查看流程</el-button
> >
<el-button <el-button
@ -57,7 +57,7 @@
v-if="scope.row.status === 'draft'" v-if="scope.row.status === 'draft'"
icon="Edit" icon="Edit"
@click="handleUpdate(scope.row)" @click="handleUpdate(scope.row)"
v-hasPermi="['design:PrelimScheme:edit']" v-hasPermi="['design:prelimScheme:edit']"
>修改</el-button >修改</el-button
> >
<!-- <el-button <!-- <el-button
@ -109,7 +109,7 @@ const dialog = reactive<DialogOption>({
const initFormData: PrelimSchemeForm = { const initFormData: PrelimSchemeForm = {
id: undefined, id: undefined,
projectId: undefined, projectId: currentProject.value?.id,
ossId: undefined, ossId: undefined,
fileName: undefined, fileName: undefined,
fileUrl: undefined, fileUrl: undefined,
@ -120,7 +120,8 @@ const data = reactive<PageData<PrelimSchemeForm, PrelimSchemeQuery>>({
queryParams: { queryParams: {
pageNum: 1, pageNum: 1,
pageSize: 10, pageSize: 10,
projectId: undefined, projectId: currentProject.value?.id,
ossId: undefined, ossId: undefined,
fileName: undefined, fileName: undefined,
fileUrl: undefined, fileUrl: undefined,

View File

@ -173,8 +173,6 @@ const getInfo = () => {
const res = await getPrelimScheme(routeParams.value.id); const res = await getPrelimScheme(routeParams.value.id);
Object.assign(form.value, res.data); Object.assign(form.value, res.data);
form.value.file = res.data.ossId; form.value.file = res.data.ossId;
showFileList.value = false;
loading.value = false; loading.value = false;
buttonLoading.value = false; buttonLoading.value = false;
}); });
@ -188,11 +186,10 @@ const submitForm = async (status1: string) => {
if (form.value.id) { if (form.value.id) {
if (!updateFileStatus.value) return proxy?.$modal.msgError('请上传图纸文件'); if (!updateFileStatus.value) return proxy?.$modal.msgError('请上传图纸文件');
buttonLoading.value = true; buttonLoading.value = true;
let data = { id: form.value.id, projectId: form.value.id, file: form.value.file }; let data = { id: form.value.id, projectId: form.value.projectId, file: form.value.file };
if (form.value.file === form.value.ossId) { if (form.value.file === form.value.ossId && !isUpdateFile.value) {
data.file = ''; data.file = '';
res = await updatePrelimScheme(data).finally(() => (buttonLoading.value = false)); res = await updatePrelimScheme(data).finally(() => (buttonLoading.value = false));
if (res.code == 200) { if (res.code == 200) {
dialog.visible = false; dialog.visible = false;
submit(status.value, form.value); submit(status.value, form.value);
@ -286,10 +283,11 @@ const handleUploadSuccess = (list, res) => {
const fileStatus = ref(false); const fileStatus = ref(false);
const updateFileStatus = ref(true); const updateFileStatus = ref(true);
const isUpdateFile = ref(false); //记录是否在修改页面时是否有新上传的文件
const handleFileChange = (file, fileList) => { const handleFileChange = (file, fileList) => {
if (form.value.id) { if (form.value.id) {
updateFileStatus.value = true; updateFileStatus.value = true;
isUpdateFile.value = true; //记录是否在修改页面时是否有新上传的文件
} }
fileStatus.value = true; fileStatus.value = true;
}; };
@ -297,6 +295,7 @@ const handleFileChange = (file, fileList) => {
const handleFileRemove = (file, fileList) => { const handleFileRemove = (file, fileList) => {
if (form.value.id) { if (form.value.id) {
updateFileStatus.value = false; updateFileStatus.value = false;
isUpdateFile.value = false; //记录是否在修改页面时是否有新上传的文件
} }
showFileList.value = true; showFileList.value = true;

View File

@ -1,86 +1,172 @@
<template> <template>
<div class="p-6 bg-gray-50"> <div class="p-6 bg-gray-50 min-h-screen">
<div <div class="received mx-auto bg-white rounded-xl shadow-sm overflow-hidden transition-all duration-300 hover:shadow-md">
class="received mx-auto bg-white rounded-xl shadow-sm overflow-hidden transition-all duration-300 hover:shadow-md">
<!-- 表单标题区域 --> <!-- 表单标题区域 -->
<div class="bg-gradient-to-r from-blue-500 to-blue-600 text-white p-6"> <div class="bg-gradient-to-r from-blue-500 to-blue-600 text-white p-6">
<h2 class="text-2xl font-bold flex items-center"><i class="el-icon-user-circle mr-3"></i>收集资料清单</h2> <h2 class="text-2xl font-bold flex items-center"><i class="el-icon-user-circle mr-3"></i>收集资料清单</h2>
<p class="text-blue-100 mt-2 opacity-90">请填写相关资料信息</p> <p class="text-blue-100 mt-2 opacity-90">请填写相关资料信息</p>
</div> </div>
<!-- 表单内容区域 --> <el-form ref="mainFormRef" :model="form" :rules="mainRules" label-width="120px" class="p-6 md:p-8">
<el-form ref="mainFormRef" :model="form" :rules="mainRules" label-width="120px" class="p-6">
<!-- 基本信息区域 --> <!-- 基本信息区域 -->
<div class="bg-blue-50 p-4 rounded-lg mb-6"> <div class="bg-blue-50 p-4 rounded-lg mb-6 md:mb-8">
<h3 class="text-lg font-semibold text-blue-700 mb-4">基本信息</h3> <h3 class="text-lg font-semibold text-blue-700 mb-4">基本信息</h3>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4"> <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<el-form-item label="收资人" prop="userId" class="mb-4"> <el-form-item label="收资人" prop="userId" class="mb-0">
<el-select :disabled="disabledAll" v-model="form.userId" placeholder="请选择收资人" <el-select
class="w-full transition-all duration-300 border-gray-300 focus:border-blue-400 focus:ring-1 focus:ring-blue-400"> :disabled="disabledAll"
v-model="form.userId"
placeholder="请选择收资人"
class="w-full transition-all duration-300 border-gray-300 focus:border-blue-400 focus:ring-1 focus:ring-blue-400"
>
<el-option v-for="item in userList" :key="item.userId" :label="item.nickName" :value="item.userId" /> <el-option v-for="item in userList" :key="item.userId" :label="item.nickName" :value="item.userId" />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="专业" prop="user_major" class="mb-4">
<el-select :disabled="disabledAll" v-model="form.user_major" placeholder="请选择专业" <el-form-item label="专业" prop="user_major" class="mb-0">
class="transition-all duration-300 border-gray-300" <el-select
:rules="{ required: true, message: '请选择专业', trigger: 'change' }"> :disabled="disabledAll"
v-model="form.user_major"
placeholder="请选择专业"
class="w-full transition-all duration-300 border-gray-300 focus:border-blue-400 focus:ring-1 focus:ring-blue-400"
>
<el-option v-for="item in des_user_major" :key="item.value" :label="item.label" :value="item.value" /> <el-option v-for="item in des_user_major" :key="item.value" :label="item.label" :value="item.value" />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="电话" prop="phone" class="mb-4"> <el-form-item label="电话" prop="phone" class="mb-0">
<el-input :disabled="disabledAll" placeholder="请输入电话" v-model="form.phone" autocomplete="off" /> <el-input :disabled="disabledAll" placeholder="请输入电话" v-model="form.phone" autocomplete="off" class="w-full" />
</el-form-item> </el-form-item>
<el-form-item label="邮箱" prop="email" class="mb-4"> <el-form-item label="邮箱" prop="email" class="mb-0">
<el-input :disabled="disabledAll" placeholder="请输入邮箱" v-model="form.email" autocomplete="off" /> <el-input :disabled="disabledAll" placeholder="请输入邮箱" v-model="form.email" autocomplete="off" class="w-full" />
</el-form-item> </el-form-item>
</div> </div>
</div> </div>
<!-- 资料文件区域 --> <!-- 资料文件区域 -->
<div class="mb-6"> <div class="mb-8">
<div class="flex items-center justify-between mb-4"> <div class="flex items-center justify-between mb-5">
<h3 class="text-lg font-semibold text-blue-700">资料文件清单</h3> <h3 class="text-lg font-semibold text-blue-700">资料文件清单</h3>
<el-button type="primary" size="small" @click="addDocumentItem" v-if="!disabledAll" icon="Plus"> 添加资料 <el-button type="primary" size="small" @click="addDocumentItem" v-if="!disabledAll" icon="Plus" class="transition-all hover:bg-blue-600">
添加资料
</el-button> </el-button>
</div> </div>
<el-form ref="documentsFormRef" :model="form" class="space-y-4">
<div v-for="(item, index) in form.documents" :key="item.id" <!-- 资料列表表单 -->
class="bg-gray-50 p-4 rounded-lg transition-all duration-200 hover:shadow-sm"> <el-form ref="documentsFormRef" :model="form" class="space-y-5">
<div class="flex justify-between items-start mb-2"> <div
<span class="text-sm font-medium text-gray-600">资料 {{ index + 1 }}</span> v-for="(item, index) in form.documents"
<el-button type="text" size="small" text-color="#ff4d4f" @click="removeDocumentItem(index)" :key="item.id"
icon="el-icon-delete" v-if="form.documents.length > 1 && !disabledAll"> class="bg-gray-50 p-5 rounded-lg transition-all duration-200 hover:shadow-sm border border-gray-100"
>
<div class="flex justify-between items-center mb-4 pb-3 border-b border-gray-200">
<span class="text-sm font-medium text-gray-700">资料 {{ index + 1 }}</span>
<el-button
type="text"
size="small"
text-color="#ff4d4f"
@click="removeDocumentItem(index)"
icon="el-icon-delete"
v-if="form.documents.length > 1 && !disabledAll"
class="transition-all hover:text-red-600"
>
删除 删除
</el-button> </el-button>
</div> </div>
<div class="flex flex-col md:flex-row gap-5 items-stretch">
<div class="grid grid-cols-1 md:grid-cols-2 gap-4"> <el-form-item
<el-form-item label="文件目录名称" :prop="`documents.${index}.catalogueName`" label="文件目录名称"
:rules="[{ required: true, message: '请输入文件目录名称', trigger: 'blur' }]" class="mb-4"> :prop="`documents.${index}.catalogueName`"
<el-input :disabled="disabledAll" placeholder="请输入文件目录名称" v-model="item.catalogueName" :rules="[{ required: true, message: '请输入文件目录名称', trigger: 'blur' }]"
autocomplete="off" /> class="flex-1 min-w-[280px] mb-0"
>
<el-input :disabled="disabledAll" placeholder="请输入文件目录名称" v-model="item.catalogueName" autocomplete="off" class="w-full" />
</el-form-item> </el-form-item>
<el-form-item label="备注" :prop="`documents.${index}.remark`" class="mb-4"> <el-form-item
<el-input :disabled="disabledAll" placeholder="请输入备注" v-model="item.remark" autocomplete="off" /> label="人员"
:prop="`documents.${index}.userId`"
:rules="[{ required: true, message: '请选择人员', trigger: 'blur' }]"
class="flex-1 min-w-[220px] mb-0"
>
<el-select
:disabled="disabledAll"
v-model="item.userId"
placeholder="请选择人员"
class="w-full transition-all duration-300 border-gray-300 focus:border-blue-400 focus:ring-1 focus:ring-blue-400"
>
<el-option v-for="user in userList" :key="user.userId" :label="user.nickName" :value="user.userId" />
</el-select>
</el-form-item>
<el-form-item label="备注" :prop="`documents.${index}.remark`" class="flex-1 min-w-[220px] mb-0">
<el-input :disabled="disabledAll" placeholder="请输入备注" v-model="item.remark" autocomplete="off" class="w-full" />
</el-form-item> </el-form-item>
</div> </div>
</div> </div>
</el-form> </el-form>
</div> </div>
<!-- 操作按钮区域 -->
<div class="flex justify-center gap-4 mt-8"> <!-- 操作按钮区域居中+间距优化 -->
<el-button type="primary" @click="submitForm" v-hasPermi="['design:collect:add']" <div class="flex flex-wrap justify-center gap-4 md:gap-6 mt-10">
v-if="!form.id || form.status == 'draft'" size="large">确认提交</el-button> <el-button
<el-button type="primary" @click="update" v-hasPermi="['design:collect:query']" type="primary"
v-show="form.id && form.status == 'draft'" icon="Edit" size="large">审核</el-button> @click="submitForm"
<el-button type="primary" @click="update" v-hasPermi="['design:collect:query']" v-show="form.status == 'back'" v-hasPermi="['design:collect:add']"
size="large" icon="Edit">重新发起审核</el-button> v-if="!form.id || form.status == 'draft'"
<el-button type="primary" @click="onView" v-hasPermi="['design:collect:query']" size="large"
v-show="form.id && form.status != 'draft'" icon="view" size="large">查看流程</el-button> class="px-8 transition-all hover:bg-blue-600"
<el-button type="success" v-hasPermi="['design:collect:export']" @click="onLoad" >
v-show="form.id && form.status != 'draft'" icon="Download" size="large">导出</el-button> 确认提交
</el-button>
<el-button
type="primary"
@click="update"
v-hasPermi="['design:collect:query']"
v-show="form.id && form.status == 'draft'"
icon="Edit"
size="large"
class="px-8 transition-all hover:bg-blue-600"
>
审核
</el-button>
<el-button
type="primary"
@click="update"
v-hasPermi="['design:collect:query']"
v-show="form.status == 'back'"
size="large"
icon="Edit"
class="px-8 transition-all hover:bg-blue-600"
>
重新发起审核
</el-button>
<el-button
type="primary"
@click="onView"
v-hasPermi="['design:collect:query']"
v-show="form.id && form.status != 'draft'"
icon="view"
size="large"
class="px-8 transition-all hover:bg-blue-600"
>
查看流程
</el-button>
<el-button
type="success"
v-hasPermi="['design:collect:export']"
@click="onLoad"
v-show="form.id && form.status != 'draft'"
icon="Download"
size="large"
class="px-8 transition-all hover:bg-green-600"
>
导出
</el-button>
</div> </div>
</el-form> </el-form>
</div> </div>
@ -88,51 +174,59 @@
</template> </template>
<script setup name="DataCollectionForm" lang="ts"> <script setup name="DataCollectionForm" lang="ts">
import { ref, reactive, computed, onMounted } from 'vue'; import { ref, reactive, computed, onMounted, onUnmounted, watch, getCurrentInstance } from 'vue';
import { useUserStoreHook } from '@/store/modules/user'; import { useUserStoreHook } from '@/store/modules/user';
import { ElMessage, ElLoading } from 'element-plus'; import { ElMessage, ElLoading, FormRules } from 'element-plus';
import { systemUserList } from '@/api/design/appointment'; import { systemUserList } from '@/api/design/appointment';
import { collectBatch, byProjectId, exportWord } from '@/api/design/received'; import { collectBatch, byProjectId, exportWord } from '@/api/design/received';
import { getUser } from '@/api/system/user'; import { getUser } from '@/api/system/user';
// 用户状态管理 import type { ComponentInternalInstance, ElFormInstance } from 'element-plus';
// 获取用户 store
// 全局实例与状态管理
const { proxy } = getCurrentInstance() as ComponentInternalInstance; const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const userStore = useUserStoreHook(); const userStore = useUserStoreHook();
// 从 store 中获取当前选中的项目
const currentProject = computed(() => userStore.selectedProject); const currentProject = computed(() => userStore.selectedProject);
const { des_user_major } = toRefs<any>(proxy?.useDict('des_user_major')); const { des_user_major } = toRefs<any>(proxy?.useDict('des_user_major'));
const userId = computed(() => userStore.userId); const userId = computed(() => userStore.userId);
// 表单引用 // 表单引用
const mainFormRef = ref(); const mainFormRef = ref<ElFormInstance>();
// 用户列表 const documentsFormRef = ref<ElFormInstance>();
const userList = ref([]);
const userMap = new Map(); // 数据定义
const disabledAll = ref(false); const userList = ref<any[]>([]);
// 表单数据 const userMap = new Map<string, string>(); // 存储用户ID与昵称映射
const disabledAll = ref(false); // 表单是否全部禁用
// 表单核心数据
const form = reactive({ const form = reactive({
projectId: currentProject.value?.id, projectId: currentProject.value?.id,
userId: '', // 收资人 userId: '', // 收资人
user_major: '', // 专业 user_major: '', // 专业
phone: '', // 电话 phone: '', // 电话
email: '', // 邮箱 email: '', // 邮箱
id: '', id: '', // 表单ID
status: '', status: '', // 表单状态
documents: [ documents: [
{ {
id: Date.now(), id: Date.now(),
catalogueName: '', // 文件目录名称 catalogueName: '', // 文件目录名称
remark: '' // 备注 remark: '', // 备注
userId: '' // 负责人员
} }
] as Array<{ ] as Array<{
id: number; id: number;
catalogueName: string; catalogueName: string;
remark: string; remark: string;
userId: string;
num?: number; // 序号(提交时用)
userName?: string; // 人员名称(提交时用)
}> }>
}); });
// 主表单验证规则 // 主表单验证规则
const mainRules = reactive({ const mainRules = reactive({
userId: [{ required: true, message: '请输入收资人', trigger: 'blur' }], userId: [{ required: true, message: '请选择收资人', trigger: 'blur' }],
user_major: [{ required: true, message: '请选择专业', trigger: 'change' }], user_major: [{ required: true, message: '请选择专业', trigger: 'change' }],
phone: [ phone: [
{ required: true, message: '请输入电话', trigger: 'blur' }, { required: true, message: '请输入电话', trigger: 'blur' },
@ -144,138 +238,160 @@ const mainRules = reactive({
] ]
}); });
// 添加资料项 /** 添加资料项 */
const addDocumentItem = () => { const addDocumentItem = () => {
form.documents.push({ form.documents.push({
id: Date.now(), id: Date.now(), // 用时间戳保证ID唯一
catalogueName: '', catalogueName: '',
remark: '' remark: '',
userId: ''
}); });
}; };
// 删除资料项 /** 删除资料项 */
const removeDocumentItem = (index: number) => { const removeDocumentItem = (index: number) => {
if (form.documents.length <= 1) {
ElMessage.warning('至少需要保留一条资料记录');
return;
}
form.documents.splice(index, 1); form.documents.splice(index, 1);
}; };
// 查询数据 再次回显
/** 回显项目对应的表单数据 */
const byProjectIdAll = async () => { const byProjectIdAll = async () => {
// 调用接口获取数据
const res = await byProjectId(currentProject.value?.id);
console.log(res);
form.documents = [
{
id: Date.now(),
catalogueName: '',
remark: ''
}
];
disabledAll.value = false;
if (res.code === 200 && res.data) {
const data = res.data;
// 回显基本信息
form.userId = data.userId || '';
form.user_major = data.userMajor || '';
form.phone = data.phone || '';
form.email = data.email || '';
form.id = data.id || '';
form.status = data.status || '';
if (form.status == 'finish') {
// 表单全部禁用
disabledAll.value = true;
}
// 回显资料文件列表
if (data.catalogueList && data.catalogueList.length > 0) {
// 清空现有列表
form.documents = [];
// 填充新数据
data.catalogueList.forEach((item: any, index: number) => {
form.documents.push({
id: item.id || Date.now() + index, // 确保id唯一
catalogueName: item.catalogueName || '',
remark: item.remark || ''
});
});
} else {
console.log(11111111);
// 如果没有资料,保持一个空项
form.documents = [
{
id: Date.now(),
catalogueName: '',
remark: ''
}
];
console.log(form.documents);
}
}
};
// 提交表单
const submitForm = async () => {
if (!mainFormRef.value) return;
try { try {
const valid = await mainFormRef.value.validate(); const res = await byProjectId(currentProject.value?.id);
if (valid) { // 重置表单默认值
// 这里可以添加提交逻辑 form.documents = [
form.documents.map((item, i) => { {
item.num = i + 1; id: Date.now(),
}); catalogueName: '',
let body = { remark: '',
desCollectBo: { userId: ''
projectId: currentProject.value?.id, }
userId: form.userId, // 收资人 ];
userMajor: form.user_major, // 专业 disabledAll.value = false;
id: form.id,
phone: form.phone, // 电话 if (res.code == 200 && res.data) {
email: form.email, // 邮箱 const data = res.data;
userName: userMap.get(form.userId) // 回显基本信息
}, form.userId = data.userId || '';
catalogueList: form.documents form.user_major = data.userMajor || '';
}; form.phone = data.phone || '';
let res = await collectBatch(body); form.email = data.email || '';
if (res.code == 200) { form.id = data.id || '';
byProjectIdAll(); form.status = data.status || '';
ElMessage.success('表单提交成功');
} else { // 已完成状态禁用所有输入
ElMessage.success(res.msg); if (form.status === 'finish') {
disabledAll.value = true;
}
// 回显资料列表
if (data.catalogueList && data.catalogueList.length > 0) {
form.documents = data.catalogueList.map((item: any, index: number) => ({
id: item.id || Date.now() + index, // 确保ID唯一
catalogueName: item.catalogueName || '',
remark: item.remark || '',
userId: item.userId || ''
}));
} }
} }
console.log(form);
} catch (error) { } catch (error) {
ElMessage.error('请完善表单信息后再提交'); ElMessage.error('获取表单数据失败,请刷新重试');
console.error('数据回显错误:', error);
} }
}; };
// 重置表单
/** 提交表单 */
const submitForm = async () => {
if (!mainFormRef.value) return;
try {
// 先验证主表单
await mainFormRef.value.validate();
// 再验证资料列表表单(如果存在)
if (documentsFormRef.value) {
await documentsFormRef.value.validate();
}
// 处理提交数据(补充序号和人员名称)
const submitDocuments = form.documents.map((item, i) => ({
...item,
num: i + 1,
userName: userMap.get(item.userId) || ''
}));
const submitData = {
desCollectBo: {
projectId: currentProject.value?.id,
userId: form.userId,
userMajor: form.user_major,
id: form.id,
phone: form.phone,
email: form.email,
userName: userMap.get(form.userId) || ''
},
catalogueList: submitDocuments
};
// 调用接口提交
const res = await collectBatch(submitData);
if (res.code === 200) {
ElMessage.success('表单提交成功');
byProjectIdAll(); // 重新拉取最新数据
} else {
ElMessage.warning(res.msg || '提交失败,请重试');
}
} catch (error) {
ElMessage.error('请完善表单必填信息后再提交');
console.error('表单验证失败:', error);
}
};
/** 重置表单 */
const resetForm = () => { const resetForm = () => {
if (mainFormRef.value) { if (mainFormRef.value) {
mainFormRef.value.resetFields(); mainFormRef.value.resetFields();
// form表单数据重置
form.userId = '';
form.user_major = '';
form.phone = '';
form.email = '';
form.id = '';
form.status = '';
} }
// 重置资料列表,保留一个空项 // 重置资料列表为1条空记录
form.documents = [ form.documents = [
{ {
id: Date.now(), id: Date.now(),
catalogueName: '', catalogueName: '',
remark: '' remark: '',
userId: ''
} }
]; ];
}; };
/** 查询当前部门的所有用户 */
const getDeptAllUser = async (deptId: any) => { /** 获取当前部门的所有用户 */
const getDeptAllUser = async (deptId: string | number) => {
try { try {
const res = await systemUserList({ deptId }); const res = await systemUserList({ deptId });
// 实际项目中使用接口返回的数据 userList.value = res.rows || [];
userList.value = res.rows; // 构建用户ID-昵称映射
userList.value.forEach((user) => { userList.value.forEach((user) => {
userMap.set(user.userId, user.nickName); userMap.set(user.userId, user.nickName);
}); });
} catch (error) { } catch (error) {
ElMessage.error('获取用户列表失败'); ElMessage.error('获取用户列表失败,请刷新重试');
console.error('用户列表获取错误:', error);
} }
}; };
/** 跳转审核页面 */
const update = () => { const update = () => {
proxy.$tab.closePage(proxy.$route); proxy?.$tab.closePage(proxy?.$route);
proxy.$router.push({ proxy?.$router.push({
path: `/approval/received/indexEdit`, path: `/approval/received/indexEdit`,
query: { query: {
id: form.id, id: form.id,
@ -283,9 +399,11 @@ const update = () => {
} }
}); });
}; };
/** 跳转流程查看页面 */
const onView = () => { const onView = () => {
proxy.$tab.closePage(proxy.$route); proxy?.$tab.closePage(proxy?.$route);
proxy.$router.push({ proxy?.$router.push({
path: `/approval/received/indexEdit`, path: `/approval/received/indexEdit`,
query: { query: {
id: form.id, id: form.id,
@ -293,96 +411,158 @@ const onView = () => {
} }
}); });
}; };
/** 获取当前用户详情 */
/** 获取当前用户详情(回显个人信息) */
const getUserDetail = async () => { const getUserDetail = async () => {
try { try {
const res = await getUser(userId.value); const res = await getUser(userId.value);
// userInfo.value = res.data.user; if (res.data?.user) {
form.userId = res.data.user.userId; form.userId = res.data.user.userId;
form.phone = res.data.user.phonenumber; form.phone = res.data.user.phonenumber || '';
form.email = res.data.user.email; form.email = res.data.user.email || '';
}
} catch (err) { } catch (err) {
ElMessage.error('获取用户信息失败'); ElMessage.error('获取个人信息失败,部分字段需手动填写');
console.error('用户详情获取错误:', err);
} }
}; };
// 页面挂载时初始化数据 /** 导出文件 */
onMounted(() => {
// 可以在这里添加初始化逻辑
getUserDetail();
getDeptAllUser(userStore.deptId).then(() => {
byProjectIdAll();
});
});
const onLoad = async () => { const onLoad = async () => {
// 导出接口 if (!form.id) {
proxy?.download( ElMessage.warning('请先保存表单再导出');
'design/collect/exportWord', return;
{ }
id: form.id try {
}, proxy?.download('design/collect/exportWord', { id: form.id }, `收资清单_${new Date().getTime()}.zip`);
`收资清单.zip` } catch (error) {
); ElMessage.error('导出失败,请重试');
console.error('文件导出错误:', error);
}
}; };
//监听项目id刷新数据
const listeningProject = watch( /** 页面挂载初始化 */
() => currentProject.value?.id, onMounted(() => {
(nid, oid) => { // 先获取当前用户信息,再获取部门用户列表,最后回显表单数据
getUserDetail(); getUserDetail().then(() => {
getDeptAllUser(userStore.deptId).then(() => { getDeptAllUser(userStore.deptId).then(() => {
byProjectIdAll(); byProjectIdAll();
}); });
});
});
/** 监听项目切换,刷新数据 */
const listeningProject = watch(
() => currentProject.value?.id,
(newId, oldId) => {
if (newId !== oldId) {
resetForm();
form.projectId = newId;
getUserDetail().then(() => {
getDeptAllUser(userStore.deptId).then(() => {
byProjectIdAll();
});
});
}
} }
); );
/** 页面卸载清理监听 */
onUnmounted(() => { onUnmounted(() => {
listeningProject(); listeningProject();
}); });
</script> </script>
<style lang="scss"> <style lang="scss" scoped>
// 主容器样式
.received { .received {
width: 90%; width: 95%;
max-width: 1000px; max-width: 1200px;
margin-top: 20px;
margin-bottom: 40px;
} }
// 全局样式调整,使界面更柔和 // 自定义滚动条(优化长列表体验)
::-webkit-scrollbar {
width: 8px;
height: 8px;
}
::-webkit-scrollbar-thumb {
background-color: #e5e7eb;
border-radius: 4px;
}
::-webkit-scrollbar-thumb:hover {
background-color: #d1d5db;
}
// Element 组件样式覆盖(统一风格)
::v-deep .el-input__inner, ::v-deep .el-input__inner,
::v-deep .el-select__input { ::v-deep .el-select__input,
border-radius: 6px; ::v-deep .el-select-dropdown__item {
border-color: #dcdfe6; border-radius: 6px !important;
transition: all 0.2s ease; border-color: #dcdfe6 !important;
transition: all 0.2s ease !important;
} }
::v-deep .el-input__inner:focus, ::v-deep .el-input__inner:focus,
::v-deep .el-select__input:focus { ::v-deep .el-select__input:focus {
border-color: #409eff; border-color: #409eff !important;
box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.2); box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.2) !important;
outline: none !important;
} }
::v-deep .el-button { ::v-deep .el-form-item {
border-radius: 6px; margin-bottom: 0 !important;
transition: all 0.2s ease;
} }
::v-deep .el-form-item__label { ::v-deep .el-form-item__label {
font-weight: 500; font-weight: 500 !important;
color: #606266; color: #606266 !important;
padding-right: 12px !important;
} }
// 响应式调整 ::v-deep .el-button--primary {
@media (max-width: 768px) { background-color: #409eff !important;
.received { border-color: #409eff !important;
width: 95%; }
}
::v-deep .el-form-item { ::v-deep .el-button--primary:hover {
margin-bottom: 16px; background-color: #3390e0 !important;
border-color: #3390e0 !important;
}
::v-deep .el-button--success {
background-color: #52c41a !important;
border-color: #52c41a !important;
}
::v-deep .el-button--success:hover {
background-color: #47b811 !important;
border-color: #47b811 !important;
}
// 响应式适配(小屏幕调整)
@media (max-width: 768px) {
.p-6.md\:p-8 {
padding: 4px !important;
} }
::v-deep .el-form-item__label { ::v-deep .el-form-item__label {
width: 100px; width: 100px !important;
font-size: 14px !important;
}
.flex.flex-col.md\:flex-row.gap-5 {
gap: 3px !important;
}
.el-button--large {
padding: 8px 16px !important;
font-size: 14px !important;
}
.bg-blue-50.p-4 {
padding: 15px !important;
} }
} }
</style> </style>

View File

@ -8,7 +8,7 @@
<el-input v-model="queryParams.fileName" placeholder="请输入文件名称" clearable @keyup.enter="handleQuery" /> <el-input v-model="queryParams.fileName" placeholder="请输入文件名称" clearable @keyup.enter="handleQuery" />
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-button type="primary" icon="Search" v-hasPermi="['design:scheme:add']" @click="handleQuery">搜索</el-button> <el-button type="primary" icon="Search" v-hasPermi="['design:scheme:list']" @click="handleQuery">搜索</el-button>
<el-button icon="Refresh" @click="resetQuery">重置</el-button> <el-button icon="Refresh" @click="resetQuery">重置</el-button>
</el-form-item> </el-form-item>
</el-form> </el-form>
@ -42,15 +42,7 @@
</el-table-column> </el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width"> <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template #default="scope"> <template #default="scope">
<el-button <el-button link type="primary" v-if="scope.row.status !== 'draft'" icon="Edit" @click="handleView(scope.row)">查看流程</el-button>
link
type="primary"
v-if="scope.row.status !== 'draft'"
icon="Edit"
@click="handleView(scope.row)"
v-hasPermi="['design:PrelimScheme:query']"
>查看流程</el-button
>
<el-button <el-button
link link
type="primary" type="primary"

View File

@ -31,7 +31,11 @@
> >
<div class="grid grid-cols-1 md:grid-cols-2 gap-4"> <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<el-form-item label="设计方案" prop="fileUrl" class="mb-2"> <el-form-item label="设计方案" prop="fileUrl" class="mb-2">
<el-link v-if="form.fileUrl" :href="form.fileUrl" target="_blank" type="primary" :underline="false">
{{ form.fileName }}
</el-link>
<file-upload <file-upload
v-else
:limit="1" :limit="1"
:fileType="['pdf']" :fileType="['pdf']"
:fileSize="100" :fileSize="100"
@ -181,8 +185,6 @@ const getInfo = () => {
const res = await getScheme(routeParams.value.id); const res = await getScheme(routeParams.value.id);
Object.assign(form.value, res.data); Object.assign(form.value, res.data);
form.value.file = res.data.ossId; form.value.file = res.data.ossId;
showFileList.value = false;
loading.value = false; loading.value = false;
buttonLoading.value = false; buttonLoading.value = false;
}); });
@ -198,7 +200,7 @@ const submitForm = async (status1: string) => {
buttonLoading.value = true; buttonLoading.value = true;
let data = { id: form.value.id, projectId: form.value.id, file: form.value.file }; let data = { id: form.value.id, projectId: form.value.id, file: form.value.file };
if (form.value.file === form.value.ossId) { if (form.value.file === form.value.ossId && !isUpdateFile.value) {
data.file = ''; data.file = '';
res = await updateScheme(data).finally(() => (buttonLoading.value = false)); res = await updateScheme(data).finally(() => (buttonLoading.value = false));
if (res.code == 200) { if (res.code == 200) {
@ -294,10 +296,11 @@ const handleUploadSuccess = (list, res) => {
}; };
const fileStatus = ref(false); const fileStatus = ref(false);
const updateFileStatus = ref(true); const updateFileStatus = ref(true);
const isUpdateFile = ref(false);
const handleFileChange = (file, fileList) => { const handleFileChange = (file, fileList) => {
if (form.value.id) { if (form.value.id) {
updateFileStatus.value = true; updateFileStatus.value = true;
isUpdateFile.value = true;
} }
fileStatus.value = true; fileStatus.value = true;
}; };
@ -305,6 +308,7 @@ const handleFileChange = (file, fileList) => {
const handleFileRemove = (file, fileList) => { const handleFileRemove = (file, fileList) => {
if (form.value.id) { if (form.value.id) {
updateFileStatus.value = false; updateFileStatus.value = false;
isUpdateFile.value = false;
} }
showFileList.value = true; showFileList.value = true;

View File

@ -8,7 +8,7 @@
<el-input v-model="queryParams.subContent" placeholder="请输入分包内容" clearable @keyup.enter="handleQuery" /> <el-input v-model="queryParams.subContent" placeholder="请输入分包内容" clearable @keyup.enter="handleQuery" />
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery" v-hasPermi="['design:subcontract:add']">搜索</el-button> <el-button type="primary" icon="Search" @click="handleQuery" v-hasPermi="['design:subcontract:list']">搜索</el-button>
<el-button icon="Refresh" @click="resetQuery">重置</el-button> <el-button icon="Refresh" @click="resetQuery">重置</el-button>
</el-form-item> </el-form-item>
</el-form> </el-form>

View File

@ -29,7 +29,10 @@
class="space-y-4" class="space-y-4"
> >
<el-form-item label="图纸文件" prop="fileId" class="mb-2 md:col-span-2"> <el-form-item label="图纸文件" prop="fileId" class="mb-2 md:col-span-2">
<el-input v-model="form.fileName" disabled placeholder="图纸名称" /> <el-link v-if="form.fileUrl" :href="form.fileUrl" target="_blank" type="primary" :underline="false">
{{ form.fileName }}
</el-link>
<!-- <el-input v-model="form.fileName" disabled placeholder="图纸名称" /> -->
</el-form-item> </el-form-item>
</el-form> </el-form>
</div> </div>
@ -96,7 +99,7 @@ const dialogVisible = reactive<DialogOption>({
const submitVerifyRef = ref<InstanceType<typeof SubmitVerify>>(); const submitVerifyRef = ref<InstanceType<typeof SubmitVerify>>();
//审批记录组件 //审批记录组件
const approvalRecordRef = ref<InstanceType<typeof ApprovalRecord>>(); const approvalRecordRef = ref<InstanceType<typeof ApprovalRecord>>();
//按钮组件 //按钮组件 approvalReadonly =ref(false);
const flowCodeOptions = [ const flowCodeOptions = [
{ {
value: currentProject.value?.id + '_bpDesignFile', value: currentProject.value?.id + '_bpDesignFile',
@ -123,7 +126,8 @@ const initFormData = {
fileUrl: undefined, fileUrl: undefined,
status: undefined, status: undefined,
originalName: undefined, originalName: undefined,
fileVoList: [] fileVoList: [],
auditStatus: undefined
}; };
const data = reactive({ const data = reactive({
form: { ...initFormData }, form: { ...initFormData },

View File

@ -75,44 +75,6 @@
资料名称: {{ info.projectName || '未定义' }} | 卷册号: {{ info.volumeNumber || '未定义' }} 资料名称: {{ info.projectName || '未定义' }} | 卷册号: {{ info.volumeNumber || '未定义' }}
</p> </p>
</div> </div>
<!-- 基本信息区域 - 缩小间隔增强label与内容区分 -->
<div class="p-3 md:p-4 border-b border-gray-100 dark:border-gray-700/50">
<h3 class="text-base md:text-lg font-semibold mb-2 flex items-center text-gray-800 dark:text-gray-200">
<el-icon style="margin-right: 10px" :size="24" color="#409EFF">
<Document />
</el-icon>
基本信息
</h3>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-2 md:gap-3">
<InfoItem label="项目名称" value="projectName" :data="info" />
<InfoItem label="资料名称" value="documentName" :data="info" />
<InfoItem label="卷册号" value="volumeNumber" :data="info" />
<InfoItem label="设计子项名称" value="designSubitem" :data="info" />
<InfoItem label="专业名称" value="specialtyName" :data="info" />
<InfoItem label="文件格式" value="fileType" :data="info" />
</div>
</div>
<!-- 人员信息区域 -->
<div class="p-3 md:p-4 border-b border-gray-100 dark:border-gray-700/50">
<h3 class="text-base md:text-lg font-semibold mb-2 flex items-center text-gray-800 dark:text-gray-200">
<el-icon style="margin-right: 10px" :size="24" color="#409EFF">
<Document />
</el-icon>
人员信息
</h3>
<div class="grid grid-cols-1 md:grid-cols-2 gap-2 md:gap-3">
<InfoItem label="负责人" value="principal" :data="info" />
<InfoItem label="设计人员" value="principalName" :data="info" />
<InfoItem label="审核人员" value="reviewerName" :data="info" />
<InfoItem label="创建时间" value="createTime" :data="info" />
</div>
</div>
<!-- 状态信息区域 --> <!-- 状态信息区域 -->
<div class="p-3 md:p-4"> <div class="p-3 md:p-4">
<h3 class="text-base md:text-lg font-semibold mb-2 flex items-center text-gray-800 dark:text-gray-200"> <h3 class="text-base md:text-lg font-semibold mb-2 flex items-center text-gray-800 dark:text-gray-200">
@ -150,13 +112,13 @@
</div> </div>
</div> </div>
<div class="info-item"> <!-- <div class="info-item">
<span class="info-label">文件大小</span> <span class="info-label">文件大小</span>
<div class="info-value mt-0.5 flex items-center"> <div class="info-value mt-0.5 flex items-center">
<i class="fa fa-hdd-o text-gray-400 dark:text-gray-500 mr-1.5"></i> <i class="fa fa-hdd-o text-gray-400 dark:text-gray-500 mr-1.5"></i>
{{ info.fileSize || '未知' }} {{ info.fileSize || '未知' }}
</div> </div>
</div> </div> -->
<div class="info-item"> <div class="info-item">
<span class="info-label">更新时间</span> <span class="info-label">更新时间</span>
@ -189,6 +151,42 @@
</div> </div>
</div> </div>
</div> </div>
<!-- 基本信息区域 - 缩小间隔增强label与内容区分 -->
<div class="p-3 md:p-4 border-b border-gray-100 dark:border-gray-700/50">
<h3 class="text-base md:text-lg font-semibold mb-2 flex items-center text-gray-800 dark:text-gray-200">
<el-icon style="margin-right: 10px" :size="24" color="#409EFF">
<Document />
</el-icon>
基本信息
</h3>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-2 md:gap-3">
<InfoItem label="项目名称" value="projectName" :data="info" />
<InfoItem label="资料名称" value="documentName" :data="info" />
<InfoItem label="卷册号" value="volumeNumber" :data="info" />
<InfoItem label="设计子项名称" value="designSubitem" :data="info" />
<InfoItem label="专业名称" value="specialtyName" :data="info" />
<InfoItem label="文件格式" value="fileType" :data="info" />
</div>
</div>
<!-- 人员信息区域 -->
<div class="p-3 md:p-4 border-b border-gray-100 dark:border-gray-700/50">
<h3 class="text-base md:text-lg font-semibold mb-2 flex items-center text-gray-800 dark:text-gray-200">
<el-icon style="margin-right: 10px" :size="24" color="#409EFF">
<Document />
</el-icon>
人员信息
</h3>
<div class="grid grid-cols-1 md:grid-cols-2 gap-2 md:gap-3">
<InfoItem label="负责人" value="principal" :data="info" />
<InfoItem label="设计人员" value="principalName" :data="info" />
<InfoItem label="审核人员" value="reviewerName" :data="info" />
<InfoItem label="创建时间" value="createTime" :data="info" />
</div>
</div>
</div> </div>
</main> </main>

View File

@ -39,9 +39,12 @@
:file-size="50" :file-size="50"
:onUploadSuccess="handleUploadSuccess" :onUploadSuccess="handleUploadSuccess"
> >
<el-button type="warning" plain icon="Upload">导入</el-button> <el-button v-hasPermi="['design:volumeCatalog:importData']" type="warning" plain icon="Upload">导入</el-button>
</file-upload> </file-upload>
</el-col> </el-col>
<el-col :span="1.5">
<el-button type="success" plain icon="Download" @click="exportFile">导出模版</el-button>
</el-col>
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar> <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row> </el-row>
</template> </template>
@ -60,7 +63,9 @@
<el-table-column label="计划出图时间" align="center" prop="plannedCompletion" width="200" /> <el-table-column label="计划出图时间" align="center" prop="plannedCompletion" width="200" />
<el-table-column label="图纸文件" align="center" prop="remark" width="150"> <el-table-column label="图纸文件" align="center" prop="remark" width="150">
<template #default="scope"> <template #default="scope">
<el-button link type="primary" icon="View" @click="handleView(scope.row)" v-hasPermi="['design:volumeFile:query']">查看文件</el-button> <el-button link type="primary" icon="View" @click="handleView(scope.row)" v-hasPermi="['design:volumeCatalog:listFile']"
>查看文件</el-button
>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="外部意见" align="center"> <el-table-column label="外部意见" align="center">
@ -82,7 +87,9 @@
v-hasPermi="['design:volumeFile:add']" v-hasPermi="['design:volumeFile:add']"
>上传图纸</el-button >上传图纸</el-button
> >
<el-button link type="primary" icon="Upload" @click="handleOpinion(scope.row)">外部意见</el-button> <el-button link type="primary" v-hasPermi="['design:volumeFile:edit']" icon="Upload" @click="handleOpinion(scope.row)"
>外部意见</el-button
>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
@ -607,6 +614,24 @@ const getVolumeFileList = async (type) => {
fileList.value = res.rows; fileList.value = res.rows;
} }
}; };
const exportFile = () => {
// 导出模版文件
try {
// 创建a标签
const link = document.createElement('a');
// 设置PDF文件路径 - 相对于public目录
link.href = '/catalog.xlsx';
// 设置下载后的文件名
link.download = '设计出图计划导入模版.xlsx';
// 触发点击
document.body.appendChild(link);
link.click();
// 清理
document.body.removeChild(link);
} catch (error) {
alert('下载失败,请重试');
}
};
// 切换 // 切换
const handleClick = (val) => { const handleClick = (val) => {
getVolumeFileList(val.props.name); getVolumeFileList(val.props.name);

View File

@ -46,6 +46,9 @@
<el-card shadow="never"> <el-card shadow="never">
<template #header> <template #header>
<el-row :gutter="10" class="mb8"> <el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button type="primary" plain icon="Plus" @click="handleAdd()" v-hasPermi="['formalities:listOfFormalities:add']">新增</el-button>
</el-col>
<el-col :span="1.5"> <el-col :span="1.5">
<el-button <el-button
type="success" type="success"
@ -213,6 +216,28 @@
</span> </span>
</template> </template>
</el-dialog> </el-dialog>
<el-dialog title="新增合规性手续合账" v-model="templateVisbile" width="450">
<el-form-item label="合规性手续模板">
<el-cascader
v-model="tempValue"
:options="tempTreeList"
:props="{
multiple: true,
value: 'id',
label: 'name',
disabled: (node: any) => {
return (node.pid == 0 && !node.children.length) || node.status == 1; // 有 parent 的是二级,没有 parent 的是一级,禁用一级
}
}"
/>
</el-form-item>
<template #footer>
<span>
<el-button @click="templateVisbile = false">取消</el-button>
<el-button type="primary" @click="setTemp">确定</el-button>
</span>
</template>
</el-dialog>
</div> </div>
</template> </template>
@ -225,7 +250,8 @@ import {
updateFormalitiesAreConsolidated, updateFormalitiesAreConsolidated,
listFormalitiesAnnex, listFormalitiesAnnex,
delFormalitiesAnnex, delFormalitiesAnnex,
editStatus editStatus,
getTemplateTreeList
} from '@/api/formalities/formalitiesAreConsolidated'; } from '@/api/formalities/formalitiesAreConsolidated';
import { import {
FormalitiesAreConsolidatedVO, FormalitiesAreConsolidatedVO,
@ -272,6 +298,8 @@ const statusForm = ref({
projectId: currentProject.value?.id, projectId: currentProject.value?.id,
processingStatus: undefined processingStatus: undefined
}); });
const templateVisbile = ref(false);
const tempTreeList = ref([]);
const initFormData: FormalitiesAreConsolidatedForm = { const initFormData: FormalitiesAreConsolidatedForm = {
id: undefined, id: undefined,
@ -307,6 +335,8 @@ const data = reactive<PageData<FormalitiesAreConsolidatedForm, FormalitiesAreCon
const { queryParams, form, rules } = toRefs(data); const { queryParams, form, rules } = toRefs(data);
const tempValue = ref(null);
/** 查询合规性手续合账列表 */ /** 查询合规性手续合账列表 */
const getList = async () => { const getList = async () => {
loading.value = true; loading.value = true;
@ -367,6 +397,39 @@ const handleUpdate = async (row?: FormalitiesAreConsolidatedVO) => {
dialog.title = '修改合规性手续合账'; dialog.title = '修改合规性手续合账';
}; };
//新增
const handleAdd = async () => {
tempValue.value = null;
const res = await getTemplateTreeList({ projectId: currentProject.value.id });
tempTreeList.value = res.data;
templateVisbile.value = true;
};
// 选择模板
const setTemp = async () => {
// form.value.formalitiesPid = tempValue.value[tempValue.value.length - 1];
if (!tempValue.value || !tempValue.value.length) {
proxy?.$modal.msgWarning('请选择模板');
return;
}
let addBusFormalitiesAreConsolidatedBos = tempValue.value.map((item) => {
return {
formalitiesId: item[1],
formalitiesPid: item[0]
};
});
const data = {
addBusFormalitiesAreConsolidatedBos,
projectId: currentProject.value.id
};
const res = await addFormalitiesAreConsolidated(data);
if (res.code == 200) {
proxy?.$modal.msgSuccess('操作成功');
templateVisbile.value = false;
getList();
}
};
/** 上传按钮操作 */ /** 上传按钮操作 */
const handleUpload = (row) => { const handleUpload = (row) => {
form.value.id = row.id; form.value.id = row.id;

View File

@ -23,7 +23,7 @@ const props = defineProps({
}, },
// 数值 // 数值
value: { value: {
type: Number, type: Number || String,
default: 205805.17 default: 205805.17
}, },
// 单位 // 单位

View File

@ -147,14 +147,21 @@ const initEcharts = () => {
}, },
tooltip: { tooltip: {
trigger: 'item', trigger: 'item',
formatter: (params: any) => { backgroundColor: 'rgba(3, 26, 52, 0.8)',
// 自定义提示框内容,显示更多项目信息 borderColor: '#1e3a6e',
const data = params.data; textStyle: {
return ` color: '#fff'
<div style="font-weight: bold;">${data.name}</div> },
<div>地点:${data.projectSite}</div> formatter: function (params: any) {
<div>经纬度:${data.value[0].toFixed(6)}, ${data.value[1].toFixed(6)}</div> if (params.data) {
`; // 处理散点数据
const data = params.data;
return `
<div style="font-weight: bold;">${data.name}</div>
<div>地点:${data.projectSite}</div>
<div>经纬度:${data.value[0].toFixed(6)}, ${data.value[1].toFixed(6)}</div>
`;
}
} }
}, },
series: [ series: [

View File

@ -1,3 +1,4 @@
import { to } from 'await-to-js';
import * as echarts from 'echarts/core'; import * as echarts from 'echarts/core';
import { text } from 'stream/consumers'; import { text } from 'stream/consumers';
// import { PictorialBarChart } from 'echarts/charts' // import { PictorialBarChart } from 'echarts/charts'
@ -255,7 +256,6 @@ export const getLineOption = (lineData: any) => {
const maxData = Math.max(...lineData.line1.flat()); const maxData = Math.max(...lineData.line1.flat());
const option = { const option = {
backgroundColor: '', backgroundColor: '',
tooltip: { tooltip: {
trigger: 'axis', trigger: 'axis',
@ -313,7 +313,7 @@ export const getLineOption = (lineData: any) => {
axisLabel: { axisLabel: {
textStyle: { textStyle: {
color: '#fff' color: '#fff'
}, }
} }
}, },
yAxis: { yAxis: {
@ -579,10 +579,10 @@ export const getDishesOption = (data?: any) => {
// 菜品库存图 // 菜品库存图
export const getInventoryOption = () => { export const getInventoryOption = () => {
const res = { const res = {
data: [2800, 300, 3900, 3000, 2450, 2670, 3320], data: [2800, 300, 3900, 3000, 2450, 2670, 3320],
name: ['麻辣牛肉', '水煮肉片', '酸菜鱼', '辣子鸡丁', '烧白', '冬瓜排骨汤', '清炒油麦菜'], name: ['麻辣牛肉', '水煮肉片', '酸菜鱼', '辣子鸡丁', '烧白', '冬瓜排骨汤', '清炒油麦菜'],
ratio: [4000, 4000, 4000, 4000, 4000, 4000, 4000] ratio: [4000, 4000, 4000, 4000, 4000, 4000, 4000]
}, },
dataIndex = 1; dataIndex = 1;
const option = { const option = {
xAxis: { xAxis: {
@ -698,13 +698,13 @@ export const getBarOptions = (data: any) => {
const option = { const option = {
backgroundColor: '', backgroundColor: '',
grid: { grid: {
left: '8%', left: '9%',
top: '10%', // 顶部留一点空间给 legend top: '10%', // 顶部留一点空间给 legend
bottom: '8%', bottom: '8%',
right: '2%' right: '2%'
}, },
legend: { legend: {
data: ['现金流入', '现金流出'], // 与 series.name 对应 data: ['现金流入', '现金流出'], // 与 series.name 对应
top: '0%', top: '0%',
textStyle: { color: '#fff', fontSize: 12 } textStyle: { color: '#fff', fontSize: 12 }
}, },
@ -716,7 +716,8 @@ export const getBarOptions = (data: any) => {
formatter: (params: any) => { formatter: (params: any) => {
// params 是数组,对应每条柱子 // params 是数组,对应每条柱子
return params return params
.map((p: any) => `${p.seriesName}${p.value} 万元`) .map((p: any) => `${p.seriesName}${Number(p.value).toFixed(2)} 万元`)
.join('<br/>'); .join('<br/>');
}, },
textStyle: { textStyle: {
@ -758,8 +759,11 @@ export const getBarOptions = (data: any) => {
{ {
axisLabel: { axisLabel: {
formatter: function (value) { formatter: function (value) {
value = value + '万'; if (value >= 1000) {
return value; return value / 1000 + '千万';
} else {
return value + '万';
}
}, },
color: 'rgba(255, 255, 255, 0.8)' color: 'rgba(255, 255, 255, 0.8)'
}, },
@ -825,7 +829,9 @@ export const getBarOptions = (data: any) => {
}, },
label: { label: {
show: false, show: false,
formatter: '{c}', formatter: function (params) {
return Number(params.value).toFixed(2);
},
position: 'top', position: 'top',
color: '#fff', color: '#fff',
fontSize: 10 fontSize: 10
@ -864,11 +870,12 @@ export const getBarOptions = (data: any) => {
}, },
label: { label: {
show: true, show: true,
formatter: '{c}', formatter: function (params) {
return Number(params.value).toFixed(2);
},
position: 'top', position: 'top',
color: '#fff', color: '#fff',
fontSize: 10, fontSize: 10
padding: 5
} }
} }
] ]
@ -898,7 +905,6 @@ export const getBarOptions2 = (data: any) => {
tooltip: { tooltip: {
trigger: 'item', trigger: 'item',
show: true show: true
}, },
legend: { legend: {
top: '5%', top: '5%',
@ -929,10 +935,10 @@ export const getBarOptions2 = (data: any) => {
{ value: 3, name: '100万以下' }, { value: 3, name: '100万以下' },
{ value: 4, name: '100-500万' }, { value: 4, name: '100-500万' },
{ value: 5, name: '500-1000万' }, { value: 5, name: '500-1000万' },
{ value: 4, name: '1000万以上' }, { value: 4, name: '1000万以上' }
] ]
} }
] ]
}; };
return option; return option;
} };

View File

@ -38,16 +38,11 @@
@click="submitForm" @click="submitForm"
icon="Check" icon="Check"
class="px-8 py-2.5 transition-all duration-300 transform hover:scale-105 bg-blue-500 hover:bg-blue-600 text-white font-medium" class="px-8 py-2.5 transition-all duration-300 transform hover:scale-105 bg-blue-500 hover:bg-blue-600 text-white font-medium"
v-hasPermi="['ailiaoshebei:purchaseUser:byProject']" v-hasPermi="['cailiaoshebei:purchaseUser:add']"
> >
确认提交 确认提交
</el-button> </el-button>
<el-button <el-button @click="resetForm" icon="Refresh" class="px-8 py-2.5 transition-all duration-300 border-gray-300 hover:bg-gray-100 font-medium">
@click="resetForm"
v-hasPermi="['ailiaoshebei:purchaseUser:byProject']"
icon="Refresh"
class="px-8 py-2.5 transition-all duration-300 border-gray-300 hover:bg-gray-100 font-medium"
>
重置 重置
</el-button> </el-button>
</div> </div>

View File

@ -6,20 +6,44 @@
<el-card shadow="hover"> <el-card shadow="hover">
<template #header> <template #header>
<el-row :gutter="10" class="mb8"> <el-row :gutter="10" class="mb8">
<el-col :span="1.5" :offset="0"><el-button type="primary" <el-col :span="1.5" :offset="0"
v-hasPermi="['cailiaoshebei:materialbatchdemandplan:add']" size="default" @click="handleAdd" ><el-button
icon="FolderAdd" plain>新增</el-button></el-col> type="primary"
<el-col :span="1.5" :offset="0"><el-button type="danger" size="default" v-hasPermi="['cailiaoshebei:materialbatchdemandplan:add']"
v-hasPermi="['cailiaoshebei:materialbatchdemandplan:remove']" @click="handleDeleteBatch" size="default"
icon="FolderDelete" plain>删除</el-button></el-col> @click="handleAdd"
icon="FolderAdd"
plain
>新增</el-button
></el-col
>
<el-col :span="1.5" :offset="0"
><el-button
type="danger"
size="default"
v-hasPermi="['cailiaoshebei:materialbatchdemandplan:remove']"
@click="handleDeleteBatch"
:disabled="form.mrpBaseBo.status != 'draft'"
icon="FolderDelete"
plain
>删除</el-button
></el-col
>
</el-row> </el-row>
</template> </template>
<el-input v-model="batchNumber" placeholder="请输入批次号" @input="searchBatchList" prefix-icon="Search" <el-input v-model="batchNumber" placeholder="请输入批次号" @input="searchBatchList" prefix-icon="Search" clearable />
clearable /> <el-tree
<el-tree ref="batchTreeRef" class="mt-2" node-key="id" :data="batchOptions" ref="batchTreeRef"
:props="{ label: 'planCode', children: 'children' }" :expand-on-click-node="false" highlight-current class="mt-2"
default-expand-all @node-click="handleNodeClick"> node-key="id"
:data="batchOptions"
:props="{ label: 'planCode', children: 'children' }"
:expand-on-click-node="false"
highlight-current
default-expand-all
@node-click="handleNodeClick"
>
<template #default="{ node, data }"> <template #default="{ node, data }">
<div class="custom-tree-node"> <div class="custom-tree-node">
{{ node.label }} {{ node.label }}
@ -27,8 +51,14 @@
</div> </div>
</template> </template>
</el-tree> </el-tree>
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.batchData.pageNum" <pagination
v-model:limit="queryParams.batchData.pageSize" @pagination="getList" layout="prev, pager, next,jumper" /> v-show="total > 0"
:total="total"
v-model:page="queryParams.batchData.pageNum"
v-model:limit="queryParams.batchData.pageSize"
@pagination="getList"
layout="prev, pager, next,jumper"
/>
</el-card> </el-card>
</el-col> </el-col>
<el-col :span="19"> <el-col :span="19">
@ -36,12 +66,14 @@
<template #header> <template #header>
<el-row :gutter="10" class="mb8"> <el-row :gutter="10" class="mb8">
<el-col :span="1.5" v-if="form.mrpBaseBo.status == 'draft'"> <el-col :span="1.5" v-if="form.mrpBaseBo.status == 'draft'">
<el-button type="primary" plain icon="Edit" @click="handleUpdata" <el-button type="primary" plain icon="Edit" @click="handleUpdata" v-hasPermi="['cailiaoshebei:materialbatchdemandplan:edit']"
v-hasPermi="['cailiaoshebei:materialbatchdemandplan:edit']">修改</el-button> >修改</el-button
>
</el-col> </el-col>
<el-col :span="1.5"> <el-col :span="1.5">
<el-button plain type="warning" icon="Finished" @click="handleAudit()" <el-button plain type="warning" icon="Finished" @click="handleAudit()" v-hasPermi="['cailiaoshebei:materialbatchdemandplan:query']"
v-hasPermi="['cailiaoshebei:materialbatchdemandplan:query']">审核</el-button> >审核</el-button
>
</el-col> </el-col>
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar> <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
@ -59,8 +91,13 @@
<el-table-column label="需求到货时间" align="center" prop="arrivalTime" width="250" /> <el-table-column label="需求到货时间" align="center" prop="arrivalTime" width="250" />
<el-table-column label="备注" align="center" prop="remark" /> <el-table-column label="备注" align="center" prop="remark" />
</el-table> </el-table>
<pagination v-show="mainTotal > 0" :total="mainTotal" v-model:page="queryParams.mainData.pageNum" <pagination
v-model:limit="queryParams.mainData.pageSize" @pagination="getMainList" /> v-show="mainTotal > 0"
:total="mainTotal"
v-model:page="queryParams.mainData.pageNum"
v-model:limit="queryParams.mainData.pageSize"
@pagination="getMainList"
/>
</el-card> </el-card>
</el-col> </el-col>
</el-row> </el-row>
@ -77,8 +114,7 @@
</el-col> </el-col>
<el-col :span="8" :offset="0"> <el-col :span="8" :offset="0">
<el-form-item label="编制日期" prop="mrpBaseBo.preparedDate"> <el-form-item label="编制日期" prop="mrpBaseBo.preparedDate">
<el-date-picker v-model="form.mrpBaseBo.preparedDate" type="date" value-format="YYYY-MM-DD" <el-date-picker v-model="form.mrpBaseBo.preparedDate" type="date" value-format="YYYY-MM-DD" placeholder="请选择编制日期" />
placeholder="请选择编制日期" />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="8" :offset="0"> <el-col :span="8" :offset="0">
@ -91,20 +127,20 @@
<el-divider>主要信息</el-divider> <el-divider>主要信息</el-divider>
<el-table :data="form.planList"> <el-table :data="form.planList">
<el-table-column prop="name" align="center" label="版本号 " width="150"> <el-table-column prop="name" align="center" label="版本号 " width="150">
<template #default="scope"> <template #default="scope">
<el-select v-model="scope.row.versions" placeholder="请选择" <el-select v-model="scope.row.versions" placeholder="请选择" @change="(val) => selectNameVersion(val, scope.row)">
@change="(val) => selectNameVersion(val, scope.row)"> <el-option v-for="item in versionList" :key="item.versions" :label="item.versions" :value="item.versions" />
<el-option v-for="item in versionList" :key="item.versions" :label="item.versions"
:value="item.versions" />
</el-select> </el-select>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="name" align="center" label="物资名称"> <el-table-column prop="name" align="center" label="物资名称">
<template #default="scope"> <template #default="scope">
<el-select :disabled="!scope.row.versions" v-model="scope.row.suppliespriceId" placeholder="请选择" <el-select
@change="(val) => selectName(val, scope.row)"> :disabled="!scope.row.versions"
v-model="scope.row.suppliespriceId"
placeholder="请选择"
@change="(val) => selectName(val, scope.row)"
>
<el-option v-for="item in nameList" :key="item.id" :label="item.name" :value="item.id" /> <el-option v-for="item in nameList" :key="item.id" :label="item.name" :value="item.id" />
</el-select> </el-select>
</template> </template>
@ -125,14 +161,16 @@
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="qs" align="center" label="质量标准" width="150"> <el-table-column prop="qs" align="center" label="质量标准" width="150">
<template #header> <span class="text-red">*</span> 质量标准 </template>
<template #default="scope"> <template #default="scope">
<el-input v-model="scope.row.qs" placeholder="请输入质量标准" /> <el-input v-model="scope.row.qs" placeholder="请输入质量标准" />
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="arrivalTime" align="center" label="需求到货时间"> <el-table-column prop="arrivalTime" align="center" label="需求到货时间">
<template #header> <span class="text-red">*</span> 需求到货时间 </template>
<template #default="scope"> <template #default="scope">
<el-date-picker v-model="scope.row.arrivalTime" type="date" value-format="YYYY-MM-DD" placeholder="请选择" <el-date-picker v-model="scope.row.arrivalTime" type="date" value-format="YYYY-MM-DD" placeholder="请选择" style="width: 140px" />
style="width: 140px" />
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="remark" align="center" label="备注" width="150"> <el-table-column prop="remark" align="center" label="备注" width="150">
@ -165,8 +203,10 @@ import {
listBatch, listBatch,
getBatch, getBatch,
delBatch, delBatch,
listSelectCailiaoshebei, obtainTheVersion, listSelectCailiaoshebei,
getDictList, coryEngineeringList obtainTheVersion,
getDictList,
coryEngineeringList
} from '@/api/materials/batchPlan'; } from '@/api/materials/batchPlan';
import { CailiaoshebeiVO, CailiaoshebeiQuery, CailiaoshebeiForm } from '@/api/materials/batchPlan/types'; import { CailiaoshebeiVO, CailiaoshebeiQuery, CailiaoshebeiForm } from '@/api/materials/batchPlan/types';
import { useUserStoreHook } from '@/store/modules/user'; import { useUserStoreHook } from '@/store/modules/user';
@ -392,11 +432,11 @@ const handleUpdata = () => {
/** 提交数据 */ /** 提交数据 */
const submitTransferForm = async () => { const submitTransferForm = async () => {
const result = validateAndClean(form.value.planList); const result = validateAndClean(form.value.planList);
console.log('🚀 ~ submitTransferForm ~ form.value.planList:', form.value.planList);
if (!result.valid) { if (!result.valid) {
proxy?.$modal.msgError('验证失败,主要信息存在部分字段缺失的数据项'); proxy?.$modal.msgError(result.message);
return; return;
} }
cailiaoshebeiFormRef.value?.validate(async (valid: boolean) => { cailiaoshebeiFormRef.value?.validate(async (valid: boolean) => {
if (valid) { if (valid) {
buttonLoading.value = true; buttonLoading.value = true;
@ -408,7 +448,6 @@ const submitTransferForm = async () => {
} }
}); });
}; };
/** 删除批次 */ /** 删除批次 */
const handleDeleteBatch = async () => { const handleDeleteBatch = async () => {
const _ids = batchTreeRef.value.getCurrentNode()?.id; const _ids = batchTreeRef.value.getCurrentNode()?.id;
@ -419,29 +458,49 @@ const handleDeleteBatch = async () => {
await getList(); await getList();
}; };
//检测主要信息填写状况 interface ValidateResult {
function validateAndClean(arr) { valid: boolean;
data: any[];
errors: { index: number; field: string; message: string }[];
}
function validateAndClean(arr: any[]) {
// 过滤掉全空的数据项 // 过滤掉全空的数据项
const cleanedArr = arr.filter((item) => !Object.values(item).every((v) => v === '' || v == null)); const cleanedArr = arr.filter((item) => !Object.values(item).every((v) => v === '' || v == null));
let hasFullItem = false; // 是否有一条全填数据
for (const item of cleanedArr) { let hasFullItem = false; // 是否有至少一条全填数据
for (let idx = 0; idx < cleanedArr.length; idx++) {
const item = cleanedArr[idx];
const keys = Object.keys(item).filter((k) => k !== 'remark' && k !== 'id'); const keys = Object.keys(item).filter((k) => k !== 'remark' && k !== 'id');
const allFilled = keys.every((k) => item[k] !== '' && item[k] != null); const allFilled = keys.every((k) => item[k] !== '' && item[k] != null);
if (allFilled) {
hasFullItem = true; // 有一条全填
}
const allEmpty = Object.values(item).every((v) => v === '' || v == null); const allEmpty = Object.values(item).every((v) => v === '' || v == null);
// 如果不是全填,也不是全空(部分填) → 直接返回失败
// 单独检查 qs 和 arrivalTime
if (!item.qs) {
return { valid: false, message: `${idx + 1}行:质量标准不能为空`, data: cleanedArr };
}
if (!item.arrivalTime) {
return { valid: false, message: `${idx + 1}行:需求到货时间不能为空`, data: cleanedArr };
}
// 检查其他字段是否部分填
if (!allFilled && !allEmpty) { if (!allFilled && !allEmpty) {
return { valid: false, data: cleanedArr }; return { valid: false, message: `${idx + 1}行:主要信息存在部分字段缺失的数据项`, data: cleanedArr };
}
if (allFilled) {
hasFullItem = true;
} }
} }
// 如果没有至少一条全填,返回失败
// 检查是否至少有一条完整的数据
if (!hasFullItem) { if (!hasFullItem) {
return { valid: false, data: cleanedArr }; return { valid: false, message: '至少需要一条完整的数据', data: cleanedArr };
} }
return { valid: true, data: cleanedArr };
return { valid: true, message: '', data: cleanedArr };
} }
/** 审核按钮操作 */ /** 审核按钮操作 */

View File

@ -26,8 +26,8 @@
<el-input v-model="queryParams.storageUnit" placeholder="请输入保管单位" clearable @keyup.enter="handleQuery" /> <el-input v-model="queryParams.storageUnit" placeholder="请输入保管单位" clearable @keyup.enter="handleQuery" />
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-button type="primary" v-hasPermi="['materials:materialIssue:list']" icon="Search" @click="handleQuery">搜索</el-button> <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
<el-button icon="Refresh" v-hasPermi="['materials:materialIssue:list']" @click="resetQuery">重置</el-button> <el-button icon="Refresh" @click="resetQuery">重置</el-button>
</el-form-item> </el-form-item>
</el-form> </el-form>
</el-card> </el-card>
@ -39,16 +39,11 @@
<el-col :span="1.5"> <el-col :span="1.5">
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['materials:materialIssue:add']">新增</el-button> <el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['materials:materialIssue:add']">新增</el-button>
</el-col> </el-col>
<el-col :span="1.5">
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['materials:materialIssue:remove']"
>删除</el-button
>
</el-col>
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar> <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row> </el-row>
</template> </template>
<el-table v-loading="loading" :data="materialIssueList" @selection-change="handleSelectionChange"> <el-table v-loading="loading" :data="materialIssueList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" /> <el-table-column type="index" width="60" label="序号" align="center" />
<el-table-column label="表单编号" align="center" prop="formCode" /> <el-table-column label="表单编号" align="center" prop="formCode" />
<el-table-column label="工程名称" align="center" prop="projectName" /> <el-table-column label="工程名称" align="center" prop="projectName" />
<el-table-column label="设备材料名称" align="center" prop="materialName" /> <el-table-column label="设备材料名称" align="center" prop="materialName" />
@ -58,23 +53,13 @@
<el-table-column label="保管单位" align="center" prop="storageUnit" /> <el-table-column label="保管单位" align="center" prop="storageUnit" />
<el-table-column label="缺陷情况" align="center" prop="defectDescription" /> <el-table-column label="缺陷情况" align="center" prop="defectDescription" />
<el-table-column label="备注" align="center" prop="remark" /> <el-table-column label="备注" align="center" prop="remark" />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width"> <el-table-column label="操作" align="center" min-width="150" fixed="right">
<template #default="scope"> <template #default="scope">
<el-tooltip content="查看" placement="top"> <el-button link type="primary" icon="View" @click="handleView(scope.row)" v-hasPermi="['materials:materialIssue:query']">查看</el-button>
<el-button link type="primary" icon="View" @click="handleView(scope.row)" v-hasPermi="['materials:materialIssue:query']"></el-button> <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['materials:materialIssue:edit']">修改</el-button>
</el-tooltip> <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['materials:materialIssue:remove']"
<el-tooltip content="修改" placement="top"> >删除</el-button
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['materials:materialIssue:edit']"></el-button> >
</el-tooltip>
<el-tooltip content="删除" placement="top">
<el-button
link
type="primary"
icon="Delete"
@click="handleDelete(scope.row)"
v-hasPermi="['materials:materialIssue:remove']"
></el-button>
</el-tooltip>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
@ -144,7 +129,7 @@
:prop="`itemList.${index}.name`" :prop="`itemList.${index}.name`"
:rules="[{ required: true, message: '名称不能为空', trigger: 'blur' }]" :rules="[{ required: true, message: '名称不能为空', trigger: 'blur' }]"
> >
<el-select v-model="item.name" placeholder="请输入名称" @change="(value) => getNameChange(value, index, item)"> <el-select v-model="item.name" placeholder="请选择名称" @change="(value) => getNameChange(value, index, item)">
<el-option v-for="item in optionsName" :key="item.id" :label="item.materialsName" :value="item.id" /> <el-option v-for="item in optionsName" :key="item.id" :label="item.materialsName" :value="item.id" />
</el-select> </el-select>
</el-form-item> </el-form-item>

View File

@ -1,7 +1,6 @@
<template> <template>
<div class="p-2"> <div class="p-2">
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
:leave-active-class="proxy?.animate.searchAnimate.leave">
<div v-show="showSearch" class="mb-[10px]"> <div v-show="showSearch" class="mb-[10px]">
<el-card shadow="hover"> <el-card shadow="hover">
<el-form ref="queryFormRef" :model="queryParams" :inline="true"> <el-form ref="queryFormRef" :model="queryParams" :inline="true">
@ -12,11 +11,10 @@
<el-input v-model="queryParams.projectName" placeholder="请输入工程名称" clearable @keyup.enter="handleQuery" /> <el-input v-model="queryParams.projectName" placeholder="请输入工程名称" clearable @keyup.enter="handleQuery" />
</el-form-item> </el-form-item>
<el-form-item label="材料名称" prop="materialName"> <el-form-item label="材料名称" prop="materialName">
<el-input v-model="queryParams.materialName" placeholder="请输入设备材料名称" clearable <el-input v-model="queryParams.materialName" placeholder="请输入设备材料名称" clearable @keyup.enter="handleQuery" />
@keyup.enter="handleQuery" />
</el-form-item> </el-form-item>
<el-form-item label="合同名称" prop="contractName"> <el-form-item label="合同编号" prop="contractName">
<el-input v-model="queryParams.contractName" placeholder="请输入合同名称" clearable @keyup.enter="handleQuery" /> <el-input v-model="queryParams.contractName" placeholder="请输入合同编号" clearable @keyup.enter="handleQuery" />
</el-form-item> </el-form-item>
<el-form-item label="订货单位" prop="orderingUnit"> <el-form-item label="订货单位" prop="orderingUnit">
<el-input v-model="queryParams.orderingUnit" placeholder="请输入订货单位" clearable @keyup.enter="handleQuery" /> <el-input v-model="queryParams.orderingUnit" placeholder="请输入订货单位" clearable @keyup.enter="handleQuery" />
@ -25,11 +23,8 @@
<el-input v-model="queryParams.supplierUnit" placeholder="请输入供货单位" clearable @keyup.enter="handleQuery" /> <el-input v-model="queryParams.supplierUnit" placeholder="请输入供货单位" clearable @keyup.enter="handleQuery" />
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-button type="primary" v-hasPermi="['materials:materialReceive:list']" icon="Search" <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
@click="handleQuery">搜索</el-button> <el-button icon="Refresh" @click="resetQuery">重置</el-button>
<el-button icon="Refresh" v-hasPermi="['materials:materialReceive:list']"
@click="resetQuery">重置</el-button>
</el-form-item> </el-form-item>
</el-form> </el-form>
</el-card> </el-card>
@ -40,19 +35,14 @@
<template #header> <template #header>
<el-row :gutter="10" class="mb8"> <el-row :gutter="10" class="mb8">
<el-col :span="1.5"> <el-col :span="1.5">
<el-button type="primary" plain icon="Plus" @click="handleAdd" <el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['materials:materialReceive:add']">新增</el-button>
v-hasPermi="['materials:materialReceive:add']">新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()"
v-hasPermi="['materials:materialReceive:remove']">删除</el-button>
</el-col> </el-col>
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar> <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row> </el-row>
</template> </template>
<el-table v-loading="loading" :data="materialReceiveList" @selection-change="handleSelectionChange"> <el-table v-loading="loading" :data="materialReceiveList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" /> <el-table-column type="index" width="60" label="序号" align="center" />
<el-table-column label="表单编号" align="center" prop="formCode" /> <el-table-column label="表单编号" align="center" prop="formCode" />
<el-table-column label="工程名称" align="center" prop="projectName" /> <el-table-column label="工程名称" align="center" prop="projectName" />
<el-table-column label="设备材料名称" align="center" prop="materialName" /> <el-table-column label="设备材料名称" align="center" prop="materialName" />
@ -65,25 +55,24 @@
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="备注" align="center" prop="remark" /> <el-table-column label="备注" align="center" prop="remark" />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width"> <el-table-column label="操作" align="center" min-width="120" fixed="right">
<template #default="scope"> <template #default="scope">
<el-tooltip content="查看" placement="top"> <el-tooltip content="查看" placement="top">
<el-button link type="primary" icon="View" @click="handleView(scope.row)" <el-button link type="primary" icon="View" @click="handleView(scope.row)" v-hasPermi="['materials:materialReceive:query']"
v-hasPermi="['materials:materialReceive:query']"></el-button> >查看</el-button
>
</el-tooltip> </el-tooltip>
<!-- <el-tooltip content="修改" placement="top">
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['materials:materialReceive:edit']"></el-button>
</el-tooltip> -->
<el-tooltip content="删除" placement="top"> <el-tooltip content="删除" placement="top">
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['materials:materialReceive:remove']"
v-hasPermi="['materials:materialReceive:remove']"></el-button> >删除</el-button
>
</el-tooltip> </el-tooltip>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
v-model:limit="queryParams.pageSize" @pagination="getList" />
</el-card> </el-card>
<!-- 添加或修改物料接收单对话框 --> <!-- 添加或修改物料接收单对话框 -->
<el-dialog draggable :title="dialog.title" v-model="dialog.visible" width="800px" append-to-body> <el-dialog draggable :title="dialog.title" v-model="dialog.visible" width="800px" append-to-body>
<el-form ref="materialReceiveFormRef" :model="form" :rules="rules" label-width="110px"> <el-form ref="materialReceiveFormRef" :model="form" :rules="rules" label-width="110px">
@ -92,7 +81,7 @@
<el-form-item label="材料来源" prop="materialSource"> <el-form-item label="材料来源" prop="materialSource">
<el-select v-model="form.materialSource" filterable placeholder="请选择材料来源" style="width: 100%"> <el-select v-model="form.materialSource" filterable placeholder="请选择材料来源" style="width: 100%">
<el-option label="甲供材料" value="1"></el-option> <el-option label="甲供材料" value="1"></el-option>
<el-option label="供材料" value="2"></el-option> <el-option label="供材料" value="2"></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
@ -101,28 +90,39 @@
<el-input v-model="form.formCode" placeholder="请输入表单编号" /> <el-input v-model="form.formCode" placeholder="请输入表单编号" />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"><el-form-item label="采购单编号" prop="docId"><el-select @change="handleSelect" <el-col v-if="form.materialSource == '2'" :span="12">
v-model="form.docId" filterable placeholder="请选择采购单" style="width: 100%"> <el-form-item label="采购单编号" prop="docId">
<el-option v-for="item in purchaseDocList" :key="item.id" :label="item.docCode" <el-select @change="handleSelect" v-model="form.docId" filterable placeholder="请选择采购单" style="width: 100%">
:value="item.id"></el-option> </el-select></el-form-item> <el-option v-for="item in purchaseDocList" :key="item.id" :label="item.docCode" :value="item.id"></el-option>
</el-select>
</el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col v-if="form.materialSource == '2'" :span="12">
<el-form-item label="供货单位" prop="supplierUnit"> <el-form-item label="供货单位" prop="supplierUnit">
<el-input disabled v-model="form.supplierUnit" placeholder="请输入供货单位" /> <el-input disabled v-model="form.supplierUnit" placeholder="请输入供货单位" />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col v-if="form.materialSource == '2'" :span="12">
<el-form-item label="订货单位" prop="orderingUnit"> <el-form-item label="订货单位" prop="orderingUnit">
<el-input v-model="form.orderingUnit" placeholder="请输入订货单位" /> <el-input v-model="form.orderingUnit" placeholder="请输入订货单位" />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"><el-form-item label="工程名称" prop="projectName"> <el-col :span="12">
<el-input v-model="form.projectName" placeholder="请输入工程名称" /> <el-form-item label="工程名称" prop="projectName">
<el-input disabled v-model="form.projectName" placeholder="请输入工程名称" />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="合同名称" prop="contractName"> <el-form-item label="合同编号" prop="contractName">
<el-input v-model="form.contractName" placeholder="请输入合同名称" /> <el-select v-model="form.contractName" filterable placeholder="请选择合同" style="width: 100%">
<el-option
v-for="item in contractNameList"
:key="item.contractCode"
:label="item.contractCode"
:value="item.contractCode"
></el-option>
</el-select>
<!-- <el-input v-model="form.contractName" placeholder="请输入合同名称" /> -->
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="24"> <el-col :span="24">
@ -130,65 +130,79 @@
<el-input v-model="form.defectDescription" type="textarea" placeholder="请输入内容" /> <el-input v-model="form.defectDescription" type="textarea" placeholder="请输入内容" />
</el-form-item> </el-form-item>
</el-col> </el-col>
<!-- 数量验收区域修复v-for key问题 -->
<el-col :span="24"> <el-col :span="24">
<div class="detail"> <div class="detail">
<div class="detail-header"> <div class="detail-header">
<span>数量验收</span> <span>数量验收</span>
<!-- <el-button type="primary" link @click="addItem" icon="Plus">添加数量验收</el-button> --> <el-button type="primary" v-if="form.materialSource == '1'" link @click="addItem" icon="Plus">添加数量验收</el-button>
</div> </div>
<div v-for="(item, index) in form.itemList" :key="index" class="detail-item"> <!-- 关键修复v-for key改为item.id唯一标识而非index -->
<div v-for="(item, index) in form.itemList" :key="item.id" class="detail-item">
<el-row> <el-row>
<el-col :span="12"> <el-col :span="12">
<el-form-item disabled label="名称" :prop="`itemList.${index}.name`" <el-form-item label="名称" :prop="`itemList.${index}.name`" :rules="{ required: true, message: '名称不能为空', trigger: 'blur' }">
:rules="{ required: true, message: '名称不能为空', trigger: 'blur' }"> <el-input :disabled="form.materialSource == '2'" v-model="item.name" placeholder="请输入名称" />
<el-input disabled v-model="item.name" placeholder="请输入名称" />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="规格" :prop="`itemList.${index}.specification`" <el-form-item
:rules="{ required: true, message: '规格不能为空', trigger: 'blur' }"> label="规格"
<el-input disabled v-model="item.specification" placeholder="请输入规格" /> :prop="`itemList.${index}.specification`"
:rules="{ required: true, message: '规格不能为空', trigger: 'blur' }"
>
<el-input :disabled="form.materialSource == '2'" v-model="item.specification" placeholder="请输入规格" />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="单位" :prop="`itemList.${index}.unit`" <el-form-item label="单位" :prop="`itemList.${index}.unit`" :rules="{ required: true, message: '单位不能为空', trigger: 'blur' }">
:rules="{ required: true, message: '单位不能为空', trigger: 'blur' }"> <el-input :disabled="form.materialSource == '2'" v-model="item.unit" placeholder="请输入单位" />
<el-input disabled v-model="item.unit" placeholder="请输入单位" />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="数量" :prop="`itemList.${index}.quantity`" <el-form-item
:rules="{ required: true, message: '数量不能为空', trigger: 'blur' }"> label="数量"
<el-input disabled type="number" v-model="item.quantity" placeholder="请输入数量" /> :prop="`itemList.${index}.quantity`"
:rules="{ required: true, message: '数量不能为空', trigger: 'blur' }"
>
<el-input :disabled="form.materialSource == '2'" type="number" v-model="item.quantity" placeholder="请输入数量" />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="验收" :prop="`itemList.${index}.acceptedQuantity`" <el-form-item
:rules="{ required: true, message: '验收数量不能为空', trigger: 'blur' }"> label="验收"
:prop="`itemList.${index}.acceptedQuantity`"
:rules="{ required: true, message: '验收数量不能为空', trigger: 'blur' }"
>
<el-input type="number" v-model="item.acceptedQuantity" placeholder="请输入验收" /> <el-input type="number" v-model="item.acceptedQuantity" placeholder="请输入验收" />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="缺件" :prop="`itemList.${index}.shortageQuantity`" <el-form-item
:rules="{ required: true, message: '缺件数量不能为空', trigger: 'blur' }"> label="缺件"
:prop="`itemList.${index}.shortageQuantity`"
:rules="{ required: true, message: '缺件数量不能为空', trigger: 'blur' }"
>
<el-input type="number" v-model="item.shortageQuantity" placeholder="自动计算(数量-验收数量)" readonly /> <el-input type="number" v-model="item.shortageQuantity" placeholder="自动计算(数量-验收数量)" readonly />
<span class="tips">*自动计算数量-验收数量</span> <span class="tips">*自动计算数量-验收数量</span>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="备注" prop="remark"> <el-form-item label="备注" :prop="`itemList.${index}.remark`">
<el-input v-model="item.remark" placeholder="请输入备注" /> <el-input v-model="item.remark" placeholder="请输入备注" />
</el-form-item> </el-form-item>
</el-col> </el-col>
<!-- <el-col :span="12" v-if="form.itemList.length > 1"> <el-col :span="12" v-if="form.itemList.length > 1 && form.materialSource == '1'">
<div class="item-actions"> <div class="item-actions">
<el-button type="danger" link @click="removeItem(index)" icon="Delete">删除</el-button> <el-button type="danger" link @click="removeItem(index)" icon="Delete">删除</el-button>
</div> </div>
</el-col> --> </el-col>
</el-row> </el-row>
</div> </div>
</div> </div>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="合格证文件" prop="certCountFileId"> <el-form-item label="合格证文件" prop="certCountFileId">
<file-upload :isShowTip="false" v-model="form.certCountFileId" /> <file-upload :isShowTip="false" v-model="form.certCountFileId" />
@ -210,22 +224,10 @@
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="24"> <el-col :span="24">
<span <span style="color: #ff0000ab; margin-bottom: 10px; display: block">注意请上传doc/xls/ppt/txt/pdf/png/jpg/jpeg/zip格式文件</span>
style="color: #ff0000ab; margin-bottom: 10px; display: block">注意请上传doc/xls/ppt/txt/pdf/png/jpg/jpeg/zip格式文件</span>
</el-col> </el-col>
<el-col :span="24"> <el-col :span="24">
<el-form-item label="设备材料入库/移交" prop="storageType"> <el-form-item label="备注" prop="remark">
<el-radio-group v-model="form.storageType">
<el-radio v-for="dict in storage_type.slice(0, 1)" :key="dict.value" :label="dict.value">
{{ dict.label }}
</el-radio>
</el-radio-group>
<!-- <el-checkbox-group v-model="form.storageType">
<el-checkbox v-for="dict in storage_type" :key="dict.value" :label="dict.value">
{{ dict.label }}
</el-checkbox>
</el-checkbox-group> -->
</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-input v-model="form.remark" type="textarea" placeholder="请输入内容" />
</el-form-item> </el-form-item>
</el-col> </el-col>
@ -248,21 +250,26 @@ import {
getMaterialReceive, getMaterialReceive,
delMaterialReceive, delMaterialReceive,
addMaterialReceive, addMaterialReceive,
updateMaterialReceive updateMaterialReceive,
getContractNameList
} from '@/api/materials/materialReceive'; } from '@/api/materials/materialReceive';
import { MaterialReceiveVO, MaterialReceiveQuery, MaterialReceiveForm } from '@/api/materials/materialReceive/types'; import { MaterialReceiveVO, MaterialReceiveQuery, MaterialReceiveForm } from '@/api/materials/materialReceive/types';
import { useUserStoreHook } from '@/store/modules/user'; import { useUserStoreHook } from '@/store/modules/user';
import wordllReceive from './word/index.vue'; import wordllReceive from './word/index.vue';
import { listPurchaseDoc, purchaseDocPlanList } from '@/api/materials/purchaseDoc'; import { listPurchaseDoc, purchaseDocPlanList } from '@/api/materials/purchaseDoc';
import { watch } from 'vue'; import { watch, onMounted, onUnmounted, ref, reactive, computed, toRefs, getCurrentInstance } from 'vue';
import type { ComponentInternalInstance, ElFormInstance, DialogOption } from 'element-plus';
const { proxy } = getCurrentInstance() as ComponentInternalInstance; const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const { storage_type } = toRefs<any>(proxy?.useDict('storage_type')); const { storage_type } = toRefs<any>(proxy?.useDict('storage_type'));
// 获取用户 store
const userStore = useUserStoreHook(); const userStore = useUserStoreHook();
// 从 store 中获取项目列表和当前选中的项目
const currentProject = computed(() => userStore.selectedProject); const currentProject = computed(() => userStore.selectedProject);
const wordllReceiveRef = ref<InstanceType<typeof wordllReceive>>(); const wordllReceiveRef = ref<InstanceType<typeof wordllReceive>>();
// 核心修复1存储每个验收条目的watch停止函数避免内存泄漏
const itemWatchStopFns = ref<Array<() => void>>([]);
// 列表数据
const materialReceiveList = ref<MaterialReceiveVO[]>([]); const materialReceiveList = ref<MaterialReceiveVO[]>([]);
const buttonLoading = ref(false); const buttonLoading = ref(false);
const loading = ref(true); const loading = ref(true);
@ -272,15 +279,25 @@ const single = ref(true);
const multiple = ref(true); const multiple = ref(true);
const total = ref(0); const total = ref(0);
// 表单引用
const queryFormRef = ref<ElFormInstance>(); const queryFormRef = ref<ElFormInstance>();
const materialReceiveFormRef = ref<ElFormInstance>(); const materialReceiveFormRef = ref<ElFormInstance>();
const purchaseDocList = ref([]); //物资采购单 const purchaseDocList = ref([]); // 物资采购单列表
const purchaseMap = new Map(); const purchaseMap = new Map(); // 采购单映射id -> 采购单对象)
const contractNameList = ref([]); //合同列表
// 对话框配置
const dialog = reactive<DialogOption>({ const dialog = reactive<DialogOption>({
visible: false, visible: false,
title: '' title: ''
}); });
const getInitFormData = () => {
// 生成验收条目唯一ID用于v-for key
const generateItemId = () => {
return Date.now() + Math.random().toString(36).substr(2, 9);
};
// 初始化表单数据修复给验收条目添加唯一ID
const getInitFormData = (): MaterialReceiveForm => {
return { return {
id: undefined, id: undefined,
projectId: currentProject.value?.id, projectId: currentProject.value?.id,
@ -300,12 +317,13 @@ const getInitFormData = () => {
techDocCountFileId: undefined, techDocCountFileId: undefined,
licenseCount: undefined, licenseCount: undefined,
licenseCountFileId: undefined, licenseCountFileId: undefined,
storageType: '', storageType: '1',
remark: undefined, remark: undefined,
docId: undefined, docId: undefined,
docCode: undefined, docCode: undefined,
itemList: [ itemList: [
{ {
id: generateItemId(), // 新增唯一ID解决v-for渲染问题
name: undefined, name: undefined,
specification: undefined, specification: undefined,
unit: undefined, unit: undefined,
@ -317,7 +335,8 @@ const getInitFormData = () => {
] ]
}; };
}; };
const initFormData: MaterialReceiveForm = {};
// 响应式数据
const data = reactive({ const data = reactive({
form: getInitFormData(), form: getInitFormData(),
queryParams: { queryParams: {
@ -334,17 +353,10 @@ const data = reactive({
params: {} params: {}
}, },
rules: { rules: {
// 物资采购单
docId: [{ required: true, message: '请选择物资采购单', trigger: 'change' }],
// 材料来源
materialSource: [{ required: true, message: '请选择材料来源', trigger: 'change' }], materialSource: [{ required: true, message: '请选择材料来源', trigger: 'change' }],
// 表单编号
formCode: [{ required: true, message: '请输入表单编号', trigger: 'blur' }], formCode: [{ required: true, message: '请输入表单编号', trigger: 'blur' }],
// 采购单编号 docId: [{ required: true, message: '请选择物资采购单', trigger: 'change' }],
docCode: [{ required: true, message: '请输入采购单编号', trigger: 'blur' }],
// 供货单位
supplierUnit: [{ required: true, message: '请输入供货单位', trigger: 'blur' }], supplierUnit: [{ required: true, message: '请输入供货单位', trigger: 'blur' }],
// 订货单位
orderingUnit: [{ required: true, message: '请输入订货单位', trigger: 'blur' }] orderingUnit: [{ required: true, message: '请输入订货单位', trigger: 'blur' }]
} }
}); });
@ -354,22 +366,38 @@ const { queryParams, form, rules } = toRefs(data);
/** 查询物料接收单列表 */ /** 查询物料接收单列表 */
const getList = async () => { const getList = async () => {
loading.value = true; loading.value = true;
const res = await listMaterialReceive(queryParams.value); try {
materialReceiveList.value = res.rows; const res = await listMaterialReceive(queryParams.value);
total.value = res.total; materialReceiveList.value = res.rows;
loading.value = false; total.value = res.total;
} finally {
loading.value = false;
}
};
// 获取合同列表数据
const getContractList = async () => {
let res = await getContractNameList(currentProject.value?.id);
contractNameList.value = res.rows;
}; };
/** 取消按钮 */ /** 取消按钮 */
const cancel = () => { const cancel = () => {
reset(); reset();
dialog.visible = false; dialog.visible = false;
}; };
/** 表单重置 */ /** 表单重置(修复:清理验收条目监听) */
const reset = () => { const reset = () => {
// 停止所有验收条目的watch监听
itemWatchStopFns.value.forEach((stopFn) => stopFn());
itemWatchStopFns.value = [];
form.value = getInitFormData(); form.value = getInitFormData();
materialReceiveFormRef.value?.resetFields(); materialReceiveFormRef.value?.resetFields();
// 重新监听初始条目
if (form.value.itemList.length > 0) {
watchItemChanges(0);
}
}; };
/** 搜索按钮操作 */ /** 搜索按钮操作 */
@ -387,7 +415,7 @@ const resetQuery = () => {
/** 多选框选中数据 */ /** 多选框选中数据 */
const handleSelectionChange = (selection: MaterialReceiveVO[]) => { const handleSelectionChange = (selection: MaterialReceiveVO[]) => {
ids.value = selection.map((item) => item.id); ids.value = selection.map((item) => item.id);
single.value = selection.length != 1; single.value = selection.length !== 1;
multiple.value = !selection.length; multiple.value = !selection.length;
}; };
@ -396,25 +424,34 @@ const handleAdd = () => {
reset(); reset();
dialog.visible = true; dialog.visible = true;
dialog.title = '添加物料接收单'; dialog.title = '添加物料接收单';
// 为初始条目添加监听 form.value.projectName = currentProject.value?.name;
if (form.value.itemList.length > 0) {
watchItemChanges(0);
}
}; };
/** 修改按钮操作 */ /** 修改按钮操作(修复:清理旧监听+添加唯一ID */
const handleUpdate = async (row?: MaterialReceiveVO) => { const handleUpdate = async (row?: MaterialReceiveVO) => {
reset(); reset();
const _id = row?.id || ids.value[0]; const _id = row?.id || ids.value[0];
const res = await getMaterialReceive(_id);
Object.assign(form.value, res.data);
// 为每个条目添加监听
form.value.itemList.forEach((_, index) => {
watchItemChanges(index);
});
dialog.visible = true; try {
dialog.title = '修改物料接收单'; const res = await getMaterialReceive(_id);
// 给验收条目补充唯一ID避免后端返回无ID
const formData = res.data;
formData.itemList = formData.itemList.map((item) => ({
...item,
id: item.id || generateItemId()
}));
Object.assign(form.value, formData);
// 重新监听所有条目
form.value.itemList.forEach((_, index) => {
watchItemChanges(index);
});
dialog.visible = true;
dialog.title = '修改物料接收单';
} catch (err) {
proxy?.$modal.msgError('获取详情失败');
}
}; };
/** 提交按钮 */ /** 提交按钮 */
@ -422,14 +459,21 @@ const submitForm = () => {
materialReceiveFormRef.value?.validate(async (valid: boolean) => { materialReceiveFormRef.value?.validate(async (valid: boolean) => {
if (valid) { if (valid) {
buttonLoading.value = true; buttonLoading.value = true;
if (form.value.id) { try {
await updateMaterialReceive({ ...form.value }).finally(() => (buttonLoading.value = false)); if (form.value.id) {
} else { await updateMaterialReceive({ ...form.value });
await addMaterialReceive({ ...form.value }).finally(() => (buttonLoading.value = false)); } else {
form.value.itemList.forEach((item) => {
delete item.id;
});
await addMaterialReceive({ ...form.value });
}
proxy?.$modal.msgSuccess('操作成功');
dialog.visible = false;
await getList();
} finally {
buttonLoading.value = false;
} }
proxy?.$modal.msgSuccess('操作成功');
dialog.visible = false;
await getList();
} }
}); });
}; };
@ -437,15 +481,24 @@ const submitForm = () => {
/** 删除按钮操作 */ /** 删除按钮操作 */
const handleDelete = async (row?: MaterialReceiveVO) => { const handleDelete = async (row?: MaterialReceiveVO) => {
const _ids = row?.id || ids.value; const _ids = row?.id || ids.value;
await proxy?.$modal.confirm('是否确认删除物料接收单编号为"' + _ids + '"的数据项?').finally(() => (loading.value = false)); if (!_ids.length) return;
await delMaterialReceive(_ids);
proxy?.$modal.msgSuccess('删除成功'); try {
await getList(); await proxy?.$modal.confirm(`是否确认删除物料接收单编号为"${_ids}"的数据项?`);
await delMaterialReceive(_ids);
proxy?.$modal.msgSuccess('删除成功');
await getList();
} catch (err) {
// 取消删除时不提示
} finally {
loading.value = false;
}
}; };
// 添加数量验收条目 /** 添加数量验收条目修复添加唯一ID+监听) */
const addItem = () => { const addItem = () => {
const newItem = { const newItem = {
id: generateItemId(), // 唯一ID
name: undefined, name: undefined,
specification: undefined, specification: undefined,
unit: undefined, unit: undefined,
@ -455,110 +508,192 @@ const addItem = () => {
remark: undefined remark: undefined
}; };
form.value.itemList.push(newItem); form.value.itemList.push(newItem);
// 监听新条目数据变化 // 监听新条目变化
watchItemChanges(form.value.itemList.length - 1); watchItemChanges(form.value.itemList.length - 1);
}; };
// 监听条目数据变化,自动计算缺件数量 /** 监听验收条目变化,自动计算缺件数量(修复:存储停止函数) */
const watchItemChanges = (index: number) => { const watchItemChanges = (index: number) => {
watch( // 停止该索引已有的监听(避免重复监听)
if (itemWatchStopFns.value[index]) {
itemWatchStopFns.value[index]();
}
// 监听数量和验收数量变化
const stopFn = watch(
() => [form.value.itemList[index].quantity, form.value.itemList[index].acceptedQuantity], () => [form.value.itemList[index].quantity, form.value.itemList[index].acceptedQuantity],
([quantity, acceptedQuantity]) => { ([quantity, acceptedQuantity]) => {
// 确保数量和验收数量都是数字
const qty = Number(quantity) || 0; const qty = Number(quantity) || 0;
const acceptedQty = Number(acceptedQuantity) || 0; const acceptedQty = Number(acceptedQuantity) || 0;
// 计算缺件数量(数量 - 验收数量)
form.value.itemList[index].shortageQuantity = qty - acceptedQty; form.value.itemList[index].shortageQuantity = qty - acceptedQty;
}, },
{ immediate: true } { immediate: true } // 初始时立即计算
); );
// 存储停止函数,用于后续删除时清理
itemWatchStopFns.value[index] = stopFn;
}; };
// 删除数量验收条目 /** 删除数量验收条目(修复:清理监听+删除条目) */
const removeItem = (index: number) => { const removeItem = (index: number) => {
if (form.value.itemList.length > 1) { if (form.value.itemList.length <= 1) {
form.value.itemList.splice(index, 1);
} else {
proxy?.$modal.msgWarning('至少需要保留一条数量验收记录'); proxy?.$modal.msgWarning('至少需要保留一条数量验收记录');
return;
} }
// 停止该条目的监听
if (itemWatchStopFns.value[index]) {
itemWatchStopFns.value[index]();
}
// 删除条目和对应的停止函数
form.value.itemList.splice(index, 1);
itemWatchStopFns.value.splice(index, 1);
}; };
const handleView = (row) => { /** 查看详情 */
// 查看详情 const handleView = (row: MaterialReceiveVO) => {
wordllReceiveRef.value?.openDialog(row); wordllReceiveRef.value?.openDialog(row);
}; };
/** 查询物资-采购联系单列表 */ /** 查询物资-采购联系单列表 */
const getlistPurchase = async () => { const getlistPurchase = async () => {
const res = await listPurchaseDoc({ try {
projectId: currentProject.value?.id, const res = await listPurchaseDoc({
status: 'finish' projectId: currentProject.value?.id,
}); status: 'finish'
});
purchaseDocList.value = res.rows; purchaseDocList.value = res.rows;
if (purchaseDocList.value && purchaseDocList.value.length > 0) { // 构建采购单映射
purchaseDocList.value.forEach((item) => { purchaseDocList.value.forEach((item) => {
purchaseMap.set(item.id, item); purchaseMap.set(item.id, item);
}); });
} catch (err) {
proxy?.$modal.msgError('获取采购单列表失败');
} }
}; };
// 通过采购单获取需求信息 /** 通过采购单获取需求信息(修复:清理旧监听+添加新监听) */
const getdemandInfo = async (docId: string) => { const getdemandInfo = async (docId: string) => {
let res = await purchaseDocPlanList(docId); if (!docId) return;
if (res.code == 200) {
// 需求表单赋值 try {
form.value.itemList = []; const res = await purchaseDocPlanList(docId);
// form.value.itemList 清空 if (res.code === 200) {
console.log(form.value.itemList); // 清空旧监听和条目
res.data.forEach((item, index) => { itemWatchStopFns.value.forEach((stopFn) => stopFn());
let obj = { itemWatchStopFns.value = [];
quantity: item.demandQuantity, form.value.itemList = [];
acceptedQuantity: 0,
shortageQuantity: item.demandQuantity, // 初始化缺件数量为总数量 // 赋值需求数据并添加监听
planId: item.id, res.data.forEach((item, index) => {
...item const qty = Number(item.demandQuantity) || 0;
}; const newItem = {
obj.id = null; id: generateItemId(), // 唯一ID
form.value.itemList.push(obj); name: item.name,
// 监听每个条目的变化 specification: item.specification,
watchItemChanges(form.value.itemList.length - 1); unit: item.unit,
}); quantity: qty,
acceptedQuantity: 0,
shortageQuantity: qty, // 初始缺件=总数量
remark: item.remark,
planId: item.id,
id: null // 保留后端需要的空id字段
};
form.value.itemList.push(newItem);
// 监听当前条目
watchItemChanges(index);
});
}
} catch (err) {
proxy?.$modal.msgError('获取采购单需求信息失败');
} }
}; };
const handleSelect = (val) => { /** 选择采购单触发 */
// 选择设备 const handleSelect = (val: string) => {
let obj = purchaseMap.get(val); if (!val) return;
const obj = purchaseMap.get(val);
if (obj) {
form.value.docCode = obj.docCode || '';
form.value.supplierUnit = obj.supplier || '';
form.value.materialName = obj.name || '';
}
// 获取采购单对应的需求信息
getdemandInfo(val); getdemandInfo(val);
form.value.docCode = obj?.docCode || '';
form.value.supplierUnit = obj?.supplier || '';
form.value.materialName = obj?.name || '';
}; };
/** 核心修复2监听材料来源变化重置数量验收列表 */
watch(
() => form.value.materialSource,
(newSource, oldSource) => {
if (newSource === oldSource) return;
// 1. 停止所有验收条目的监听
itemWatchStopFns.value.forEach((stopFn) => stopFn());
itemWatchStopFns.value = [];
// 2. 重置数量验收列表为初始状态1条空记录
form.value.itemList = [
{
id: generateItemId(),
name: undefined,
specification: undefined,
unit: undefined,
quantity: undefined,
acceptedQuantity: undefined,
shortageQuantity: undefined,
remark: undefined
}
];
// 3. 重新监听初始条目
watchItemChanges(0);
// 4. 切换到乙供时,清空采购单相关数据
if (newSource === '2') {
form.value.docId = undefined;
form.value.supplierUnit = undefined;
form.value.materialName = undefined;
form.value.docCode = undefined;
}
},
{ immediate: true }
);
/** 页面挂载时初始化 */
onMounted(() => { onMounted(() => {
getContractList();
getList(); getList();
getlistPurchase(); getlistPurchase();
// 为初始条目添加监听 // 监听初始验收条目
if (form.value.itemList.length > 0) { if (form.value.itemList.length > 0) {
watchItemChanges(0); watchItemChanges(0);
} }
}); });
// 监听项目id刷新数据 /** 监听项目变化,刷新数据 */
const listeningProject = watch( const listeningProject = watch(
() => currentProject.value?.id, () => currentProject.value?.id,
(nid, oid) => { (nid) => {
queryParams.value.projectId = nid; queryParams.value.projectId = nid;
form.value.projectId = nid; form.value.projectId = nid;
getContractList();
getList(); getList();
getlistPurchase();
} }
); );
/** 页面卸载时清理监听 */
onUnmounted(() => { onUnmounted(() => {
listeningProject(); listeningProject();
// 清理验收条目监听
itemWatchStopFns.value.forEach((stopFn) => stopFn());
}); });
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
.detail { .detail {
border-bottom: 1px solid #ececec; border-bottom: 1px solid #ececec;
@ -599,4 +734,8 @@ onUnmounted(() => {
color: #666; color: #666;
margin-left: 8px; margin-left: 8px;
} }
.mb8 {
margin-bottom: 8px;
}
</style> </style>

View File

@ -1,20 +1,16 @@
<template> <template>
<div class="p-2"> <div class="p-2">
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
:leave-active-class="proxy?.animate.searchAnimate.leave">
<div v-show="showSearch" class="mb-[10px]"> <div v-show="showSearch" class="mb-[10px]">
<el-card shadow="hover"> <el-card shadow="hover">
<el-form ref="queryFormRef" :model="queryParams" :inline="true"> <el-form ref="queryFormRef" :model="queryParams" :inline="true">
<el-form-item label="材料名称" prop="materialsName"> <el-form-item label="材料名称" prop="materialsName">
<el-input v-model="queryParams.materialsName" placeholder="请输入材料名称" clearable <el-input v-model="queryParams.materialsName" placeholder="请输入材料名称" clearable @keyup.enter="handleQuery" />
@keyup.enter="handleQuery" />
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-button type="primary" v-hasPermi="['materials:materialsInventory:list']" icon="Search" <el-button type="primary" v-hasPermi="['materials:materialsInventory:list']" icon="Search" @click="handleQuery">搜索</el-button>
@click="handleQuery">搜索</el-button>
<el-button icon="Refresh" v-hasPermi="['materials:materialsInventory:list']" <el-button icon="Refresh" v-hasPermi="['materials:materialsInventory:list']" @click="resetQuery">重置</el-button>
@click="resetQuery">重置</el-button>
</el-form-item> </el-form-item>
</el-form> </el-form>
</el-card> </el-card>
@ -25,8 +21,7 @@
<template #header> <template #header>
<el-row :gutter="10" class="mb8"> <el-row :gutter="10" class="mb8">
<el-col :span="1.5"> <el-col :span="1.5">
<el-button type="warning" plain icon="Download" @click="handleExport" <el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['materials:materialsInventory:export']">
v-hasPermi="['materials:materialsInventory:export']">
导出 导出
</el-button> </el-button>
</el-col> </el-col>
@ -45,8 +40,13 @@
<el-table-column label="使用部位" align="center" prop="usePart" /> <el-table-column label="使用部位" align="center" prop="usePart" />
<el-table-column label="备注" align="center" prop="remark" /> <el-table-column label="备注" align="center" prop="remark" />
</el-table> </el-table>
<pagination v-show="totalChild > 0" :total="totalChild" v-model:page="queryParamsChild.pageNum" <pagination
v-model:limit="queryParamsChild.pageSize" @pagination="getListChild" /> v-show="totalChild > 0"
:total="totalChild"
v-model:page="queryParamsChild.pageNum"
v-model:limit="queryParamsChild.pageSize"
@pagination="getListChild"
/>
</div> </div>
</template> </template>
</el-table-column> </el-table-column>
@ -115,8 +115,7 @@
</template> </template>
</el-table-column> --> </el-table-column> -->
</el-table> </el-table>
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
v-model:limit="queryParams.pageSize" @pagination="getList" />
</el-card> </el-card>
<!-- 添加或修改材料出/入库对话框 --> <!-- 添加或修改材料出/入库对话框 -->
<el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body> <el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
@ -130,8 +129,7 @@
<el-input v-model="form.number" placeholder="请输入出/入库的数量" /> <el-input v-model="form.number" placeholder="请输入出/入库的数量" />
</el-form-item> </el-form-item>
<el-form-item label="出/入库操作时间" prop="outPutTime"> <el-form-item label="出/入库操作时间" prop="outPutTime">
<el-date-picker clearable v-model="form.outPutTime" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" <el-date-picker clearable v-model="form.outPutTime" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择出/入库操作时间">
placeholder="请选择出/入库操作时间">
</el-date-picker> </el-date-picker>
</el-form-item> </el-form-item>
<el-form-item label="剩余库存数量" prop="residue"> <el-form-item label="剩余库存数量" prop="residue">
@ -176,9 +174,7 @@ import {
} from '@/api/materials/materialsInventory'; } from '@/api/materials/materialsInventory';
import { MaterialsInventoryForm, MaterialsInventoryQuery, MaterialsInventoryVO } from '@/api/materials/materialsInventory/types'; import { MaterialsInventoryForm, MaterialsInventoryQuery, MaterialsInventoryVO } from '@/api/materials/materialsInventory/types';
import { useUserStoreHook } from '@/store/modules/user'; import { useUserStoreHook } from '@/store/modules/user';
import { import { listMaterialsUseRecord } from '@/api/materials/materialsUseRecord';
listMaterialsUseRecord,
} from '@/api/materials/materialsUseRecord';
const { proxy } = getCurrentInstance() as ComponentInternalInstance; const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const { out_put_type } = toRefs<any>(proxy?.useDict('out_put_type')); const { out_put_type } = toRefs<any>(proxy?.useDict('out_put_type'));

View File

@ -1,7 +1,6 @@
<template> <template>
<div class="p-2"> <div class="p-2">
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave"> </transition>
:leave-active-class="proxy?.animate.searchAnimate.leave"> </transition>
<el-card shadow="never"> <el-card shadow="never">
<template #header> <template #header>
<el-row :gutter="10" class="mb8"> <el-row :gutter="10" class="mb8">
@ -19,8 +18,7 @@
</template> </template>
<!-- 外层表格添加ref用于控制展开状态 --> <!-- 外层表格添加ref用于控制展开状态 -->
<el-table ref="outerTableRef" v-loading="loading" :data="materialsUseInventoryList" <el-table ref="outerTableRef" v-loading="loading" :data="materialsUseInventoryList" @expand-change="handleExpandChange" border>
@expand-change="handleExpandChange" border>
<el-table-column type="expand"> <el-table-column type="expand">
<template #default="props"> <template #default="props">
<div style="margin-left: 60px"> <div style="margin-left: 60px">
@ -32,13 +30,25 @@
<el-table-column label="备注" align="center" prop="remark" /> <el-table-column label="备注" align="center" prop="remark" />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width"> <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template #default="scope"> <template #default="scope">
<el-button link type="primary" icon="delete" v-if="scope.row.ishow" @click="handleDelete(scope.row)" <el-button
v-hasPermi="['materials:materialsUseRecord:remove']">删除</el-button> link
type="primary"
icon="delete"
v-if="scope.row.ishow"
@click="handleDelete(scope.row)"
v-hasPermi="['materials:materialsUseRecord:remove']"
>删除</el-button
>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<pagination v-show="totalChild > 0" :total="totalChild" v-model:page="queryParamsChild.pageNum" <pagination
v-model:limit="queryParamsChild.pageSize" @pagination="getListChild" /> v-show="totalChild > 0"
:total="totalChild"
v-model:page="queryParamsChild.pageNum"
v-model:limit="queryParamsChild.pageSize"
@pagination="getListChild"
/>
</div> </div>
</template> </template>
</el-table-column> </el-table-column>
@ -53,13 +63,13 @@
<el-table-column label="备注" align="center" prop="remark" /> <el-table-column label="备注" align="center" prop="remark" />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width"> <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template #default="scope"> <template #default="scope">
<el-button link type="primary" icon="Plus" @click="handleAdd(scope.row)" <el-button link type="primary" icon="Plus" @click="handleAdd(scope.row)" v-hasPermi="['materials:materialsUseRecord:add']"
v-hasPermi="['materials:materialsUseRecord:add']">添加登记</el-button> >添加登记</el-button
>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
v-model:limit="queryParams.pageSize" @pagination="getList" />
</el-card> </el-card>
<!-- 添加或修改材料使用登记对话框 --> <!-- 添加或修改材料使用登记对话框 -->
<el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body> <el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>

View File

@ -6,10 +6,10 @@
<el-row :gutter="10" class="mb8"> <el-row :gutter="10" class="mb8">
<el-form :inline="true"> <el-form :inline="true">
<el-form-item v-if="state.masterData.status == 'draft'"> <el-form-item v-if="state.masterData.status == 'draft'">
<el-button type="primary" v-hasPermi="['design:totalsupplyplan:queryList']" icon="edit" @click="clickApprovalSheet1()">审批</el-button> <el-button type="primary" icon="edit" @click="clickApprovalSheet1()">审批</el-button>
</el-form-item> </el-form-item>
<el-form-item v-if="state.masterData.status == 'waiting' || state.masterData.status == 'finish'"> <el-form-item v-if="state.masterData.status == 'waiting' || state.masterData.status == 'finish'">
<el-button icon="view" v-hasPermi="['design:totalsupplyplan:queryList']" @click="lookApprovalFlow()" type="warning">查看流程</el-button> <el-button icon="view" @click="lookApprovalFlow()" type="warning">查看流程</el-button>
</el-form-item> </el-form-item>
</el-form> </el-form>
<right-toolbar @queryTable="getMasterDataList"></right-toolbar> <right-toolbar @queryTable="getMasterDataList"></right-toolbar>

View File

@ -110,13 +110,7 @@
>修改</el-button >修改</el-button
> >
<el-button <el-button link type="primary" v-if="scope.row.status == 'finish' && scope.row.feedbackUrl" icon="Share" @click="handleShare(scope.row)"
link
type="primary"
v-if="scope.row.status == 'finish' && scope.row.feedbackUrl"
icon="Share"
@click="handleShare(scope.row)"
v-hasPermi="['cailiaoshebei:purchaseDoc:list']"
>物流单分享</el-button >物流单分享</el-button
> >
<el-button link type="primary" icon="View" @click="handleDetail(scope.row)" v-hasPermi="['cailiaoshebei:purchaseDoc:remove']" <el-button link type="primary" icon="View" @click="handleDetail(scope.row)" v-hasPermi="['cailiaoshebei:purchaseDoc:remove']"
@ -232,7 +226,9 @@
<el-table-column label="物资名称" align="center" prop="name" /> <el-table-column label="物资名称" align="center" prop="name" />
<el-table-column label="规格型号" align="center" prop="specification"> <el-table-column label="规格型号" align="center" prop="specification">
<template #default="scope"> <template #default="scope">
<el-button link type="primary" icon="Finished" @click="getDetailList(scope.row.ltn)"> 查看物流信息</el-button></template <el-button link type="primary" icon="Finished" v-hasPermi="['cailiaoshebei:ltn:logistics']" @click="getDetailList(scope.row.ltn)">
查看物流信息</el-button
></template
> >
</el-table-column> </el-table-column>
</el-table> </el-table>
@ -268,6 +264,7 @@ import { listContractor } from '@/api/project/contractor';
import { useUserStoreHook } from '@/store/modules/user'; import { useUserStoreHook } from '@/store/modules/user';
import { getToken } from '@/utils/auth'; import { getToken } from '@/utils/auth';
import logisticsDetail from './comm/logisticsDetail.vue'; import logisticsDetail from './comm/logisticsDetail.vue';
import { FormRules } from 'element-plus';
const { proxy } = getCurrentInstance() as ComponentInternalInstance; const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const route = useRoute(); const route = useRoute();
const router = useRouter(); const router = useRouter();
@ -349,7 +346,7 @@ const data = reactive({
status: undefined, status: undefined,
params: {} params: {}
}, },
rules: { rules: <FormRules>{
id: [{ required: true, message: '主键ID不能为空', trigger: 'blur' }], id: [{ required: true, message: '主键ID不能为空', trigger: 'blur' }],
docCode: [{ required: true, message: '采购单编号不能为空', trigger: 'blur' }], docCode: [{ required: true, message: '采购单编号不能为空', trigger: 'blur' }],
planId: [{ required: true, message: '需求计划不能为空', trigger: 'blur' }], planId: [{ required: true, message: '需求计划不能为空', trigger: 'blur' }],

View File

@ -23,7 +23,7 @@
style="width: 100%; margin-bottom: 20px; height: calc(100vh - 305px)" style="width: 100%; margin-bottom: 20px; height: calc(100vh - 305px)"
:row-class-name="tableRowClassName" :row-class-name="tableRowClassName"
> >
<el-table-column prop="id" label="ID" width="180" align="center"></el-table-column> <el-table-column type="index" label="序号" width="60" align="center"></el-table-column>
<el-table-column prop="name" label="材料名称" min-width="150"></el-table-column> <el-table-column prop="name" label="材料名称" min-width="150"></el-table-column>
<el-table-column prop="specification" label="规格" min-width="120"></el-table-column> <el-table-column prop="specification" label="规格" min-width="120"></el-table-column>
<el-table-column prop="supplier" label="供应商" min-width="150"></el-table-column> <el-table-column prop="supplier" label="供应商" min-width="150"></el-table-column>
@ -45,31 +45,29 @@
{{ formatDate(scope.row.createTime) }} {{ formatDate(scope.row.createTime) }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="操作" width="180" align="center" fixed="right"> <el-table-column label="操作" width="240" align="center" fixed="right">
<template #default="scope"> <template #default="scope">
<!-- <el-button size="small" icon="Plus" @click="handleAddSon(scope.row)" <el-button size="small" v-hasPermi="['cailiaoshebei:physicalsupply:edit']" icon="Edit" type="primary" link @click="handleEdit(scope.row)"
class="text-blue-600 hover:text-blue-800 transition-colors"></el-button> --> >修改</el-button
<el-button >
size="small"
v-hasPermi="['cailiaoshebei:physicalsupply:edit']"
icon="Edit"
@click="handleEdit(scope.row)"
class="text-blue-600 hover:text-blue-800 transition-colors"
></el-button>
<el-button <el-button
size="small" size="small"
type="primary"
v-hasPermi="['cailiaoshebei:physicalsupplySon:list']" v-hasPermi="['cailiaoshebei:physicalsupplySon:list']"
icon="View" icon="View"
link
@click="jumpRouter(scope.row)" @click="jumpRouter(scope.row)"
class="text-blue-600 hover:text-blue-800 transition-colors" >查看</el-button
></el-button> >
<el-button <el-button
size="small" size="small"
type="primary"
link
v-hasPermi="['cailiaoshebei:physicalsupply:remove']" v-hasPermi="['cailiaoshebei:physicalsupply:remove']"
icon="Delete" icon="Delete"
@click="handleDelete(scope.row)" @click="handleDelete(scope.row)"
class="text-red-600 hover:text-red-800 transition-colors" >删除</el-button
></el-button> >
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>

View File

@ -1,22 +1,36 @@
<template> <template>
<div style="padding: 20px"> <div style="padding: 20px">
<el-card class="mb-5"> <el-card class="mb-5">
<el-button type="primary" v-hasPermi="['cailiaoshebei:physicalsupply:add']" icon="Plus" @click="handleAdd" <el-button
class="transition-all duration-200 hover:shadow-md"> type="primary"
v-hasPermi="['cailiaoshebei:physicalsupply:add']"
icon="Plus"
@click="handleAdd"
class="transition-all duration-200 hover:shadow-md"
>
新增 新增
</el-button> </el-button>
<el-button v-hasPermi="['cailiaoshebei:physicalsupply:list']" icon="Refresh" @click="refreshData" <el-button
class="transition-all duration-200 hover:shadow-md"> v-hasPermi="['cailiaoshebei:physicalsupply:list']"
icon="Refresh"
@click="refreshData"
class="transition-all duration-200 hover:shadow-md"
>
刷新 刷新
</el-button> </el-button>
</el-card> </el-card>
<!-- 数据表格 --> <!-- 数据表格 -->
<div class="bg-white rounded-lg shadow-sm overflow-hidden transition-all duration-300 hover:shadow-md"> <div class="bg-white rounded-lg shadow-sm overflow-hidden transition-all duration-300 hover:shadow-md">
<el-table v-loading="loading" :data="tableData" border stripe <el-table
v-loading="loading"
:data="tableData"
border
stripe
style="width: 100%; margin-bottom: 20px; height: calc(100vh - 305px)" style="width: 100%; margin-bottom: 20px; height: calc(100vh - 305px)"
:header-cell-style="{ 'background-color': '#f5f7fa', 'font-weight': 'bold' }" :header-cell-style="{ 'background-color': '#f5f7fa', 'font-weight': 'bold' }"
:row-class-name="tableRowClassName"> :row-class-name="tableRowClassName"
>
<!-- <el-table-column prop="id" label="ID" width="180" align="center"></el-table-column> --> <!-- <el-table-column prop="id" label="ID" width="180" align="center"></el-table-column> -->
<el-table-column type="index" label="序号" align="center" width="60"></el-table-column> <el-table-column type="index" label="序号" align="center" width="60"></el-table-column>
@ -41,27 +55,53 @@
{{ formatDate(scope.row.createTime) }} {{ formatDate(scope.row.createTime) }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="操作" width="240" align="center" fixed="right"> <el-table-column label="操作" width="300" align="center" fixed="right">
<template #default="scope"> <template #default="scope">
<el-button v-hasPermi="['cailiaoshebei:physicalsupplySon:add']" size="small" icon="Plus" <el-button
@click="handleAddSon(scope.row)" class="text-blue-600 hover:text-blue-800 transition-colors"></el-button> v-hasPermi="['cailiaoshebei:physicalsupplySon:add']"
<el-button v-hasPermi="['cailiaoshebei:physicalsupply:edit']" size="small" icon="Edit" size="small"
@click="handleEdit(scope.row)" class="text-blue-600 hover:text-blue-800 transition-colors"></el-button> icon="Plus"
<el-button v-hasPermi="['cailiaoshebei:physicalsupplySon:list']" size="small" icon="View" type="primary"
@click="jumpRouter(scope.row)" class="text-blue-600 hover:text-blue-800 transition-colors"></el-button> link
<el-button v-hasPermi="['cailiaoshebei:physicalsupply:remove']" size="small" icon="Delete" @click="handleAddSon(scope.row)"
@click="handleDelete(scope.row)" class="text-red-600 hover:text-red-800 transition-colors"></el-button> >添加</el-button
>
<el-button type="primary" v-hasPermi="['cailiaoshebei:physicalsupply:edit']" size="small" icon="Edit" link @click="handleEdit(scope.row)"
>修改</el-button
>
<el-button
type="primary"
v-hasPermi="['cailiaoshebei:physicalsupplySon:list']"
size="small"
icon="View"
link
@click="jumpRouter(scope.row)"
>查看</el-button
>
<el-button
v-hasPermi="['cailiaoshebei:physicalsupply:remove']"
size="small"
icon="Delete"
link
type="primary"
@click="handleDelete(scope.row)"
>删除</el-button
>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<!-- 分页 --> <!-- 分页 -->
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="fetchData" />
v-model:limit="queryParams.pageSize" @pagination="fetchData" />
</div> </div>
<!-- 新增/编辑对话框 --> <!-- 新增/编辑对话框 -->
<el-dialog v-model="dialogVisible" :title="dialogType === 'add' ? '新增记录' : '编辑记录'" :width="dialogWidth" <el-dialog
:fullscreen="isFullscreen" :before-close="handleDialogClose"> v-model="dialogVisible"
:title="dialogType === 'add' ? '新增记录' : '编辑记录'"
:width="dialogWidth"
:fullscreen="isFullscreen"
:before-close="handleDialogClose"
>
<el-form ref="formRef" :model="formData" :rules="formRules" label-width="120px" class="space-y-4"> <el-form ref="formRef" :model="formData" :rules="formRules" label-width="120px" class="space-y-4">
<el-row :gutter="20"> <el-row :gutter="20">
<el-col :span="12"> <el-col :span="12">
@ -105,8 +145,12 @@
<el-row :gutter="20"> <el-row :gutter="20">
<el-col :span="12"> <el-col :span="12">
<el-form-item label="合同签订时间" prop="contractSigning"> <el-form-item label="合同签订时间" prop="contractSigning">
<el-date-picker v-model="formData.contractSigning" type="datetime" placeholder="选择合同签订时间" <el-date-picker
value-format="YYYY-MM-DD HH:mm:ss"></el-date-picker> v-model="formData.contractSigning"
type="datetime"
placeholder="选择合同签订时间"
value-format="YYYY-MM-DD HH:mm:ss"
></el-date-picker>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
@ -119,8 +163,7 @@
<el-row :gutter="20"> <el-row :gutter="20">
<el-col :span="24"> <el-col :span="24">
<el-form-item label="供货要求" prop="supplyRequirements"> <el-form-item label="供货要求" prop="supplyRequirements">
<el-input v-model="formData.supplyRequirements" placeholder="请输入供货要求" type="textarea" <el-input v-model="formData.supplyRequirements" placeholder="请输入供货要求" type="textarea" :rows="3"></el-input>
:rows="3"></el-input>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>

View File

@ -0,0 +1,256 @@
<template>
<div class="p-2">
<el-card shadow="never">
<template #header>
<el-row :gutter="10" class="mb8">
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
<el-form-item label="查看时间" prop="viewTime">
<el-date-picker clearable v-model="queryParams.viewTime" type="date" value-format="YYYY-MM-DD" placeholder="请选择查看时间" />
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
</template>
<el-table v-loading="loading" :data="noticeList">
<el-table-column type="index" label="序号" width="80" align="center" />
<!-- <el-table-column label="接收通知的用户" align="center" prop="recipientId" />
<el-table-column label="发送通知的用户" align="center" prop="senderId" /> -->
<el-table-column label="通知内容" align="center" prop="msg" />
<el-table-column label="查看状态" align="center" prop="viewStatus">
<template #default="scope">
<el-tag :type="scope.row.viewStatus === 0 ? 'danger' : 'success'">{{ scope.row.viewStatus === 0 ? '未读' : '已读' }}</el-tag>
</template>
</el-table-column>
<!-- <el-table-column label="查看时间" align="center" prop="viewTime" width="180">
<template #default="scope">
<span>{{ parseTime(scope.row.viewTime, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column label="备注" align="center" prop="remark" /> -->
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template #default="scope"> <el-button link type="primary" @click="handleRoute(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>
<!-- 添加或修改消息对话框 -->
<el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
<el-form ref="noticeFormRef" :model="form" :rules="rules" label-width="80px">
<el-form-item label="项目ID" prop="projectId">
<el-input v-model="form.projectId" placeholder="请输入项目ID" />
</el-form-item>
<el-form-item label="接收通知的用户ID" prop="recipientId">
<el-input v-model="form.recipientId" placeholder="请输入接收通知的用户ID" />
</el-form-item>
<el-form-item label="发送通知的用户ID" prop="senderId">
<el-input v-model="form.senderId" placeholder="请输入发送通知的用户ID" />
</el-form-item>
<el-form-item label="配置id" prop="configId">
<el-input v-model="form.configId" placeholder="请输入配置id" />
</el-form-item>
<el-form-item label="详情id" prop="detailId">
<el-input v-model="form.detailId" placeholder="请输入详情id" />
</el-form-item>
<el-form-item label="通知内容">
<editor v-model="form.content" :min-height="192" />
</el-form-item>
<el-form-item label="查看时间" prop="viewTime">
<el-date-picker clearable v-model="form.viewTime" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择查看时间">
</el-date-picker>
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" placeholder="请输入备注" />
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button :loading="buttonLoading" type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</template>
</el-dialog>
</div>
</template>
<script setup name="Notice" lang="ts">
import { listNotice, getNotice, delNotice, addNotice, updateNotice } from '@/api/message/notice';
import { NoticeVO, NoticeQuery, NoticeForm } from '@/api/message/notice/types';
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
import { useUserStoreHook } from '@/store/modules/user';
const noticeList = ref([]);
const buttonLoading = ref(false);
const loading = ref(true);
const showSearch = ref(true);
const ids = ref<Array<string | number>>([]);
const single = ref(true);
const multiple = ref(true);
const total = ref(0);
// 获取用户 store
const userStore = useUserStoreHook();
// 从 store 中获取项目列表和当前选中的项目
const currentProject = computed(() => userStore.selectedProject);
const queryFormRef = ref<ElFormInstance>();
const noticeFormRef = ref<ElFormInstance>();
const dialog = reactive<DialogOption>({
visible: false,
title: ''
});
const initFormData: NoticeForm = {
id: undefined,
projectId: currentProject.value?.id,
recipientId: undefined,
senderId: undefined,
configId: undefined,
detailId: undefined,
content: undefined,
viewStatus: undefined,
viewTime: undefined,
remark: undefined
};
const data = reactive({
form: { ...initFormData },
queryParams: {
pageNum: 1,
pageSize: 10,
projectId: currentProject.value?.id,
userId: userStore.userId,
recipientId: undefined,
senderId: undefined,
configId: undefined,
detailId: undefined,
content: undefined,
viewStatus: undefined,
viewTime: undefined,
params: {}
},
rules: {
id: [{ required: true, message: '主键ID不能为空', trigger: 'blur' }],
projectId: [{ required: true, message: '项目ID不能为空', trigger: 'blur' }],
recipientId: [{ required: true, message: '接收通知的用户ID不能为空', trigger: 'blur' }],
senderId: [{ required: true, message: '发送通知的用户ID不能为空', trigger: 'blur' }],
configId: [{ required: true, message: '配置id不能为空', trigger: 'blur' }],
detailId: [{ required: true, message: '详情id不能为空', trigger: 'blur' }],
content: [{ required: true, message: '通知内容不能为空', trigger: 'blur' }],
viewStatus: [{ required: true, message: '查看状态(0未读 1已读)不能为空', trigger: 'change' }]
}
});
const { queryParams, form, rules } = toRefs(data);
/** 查询消息列表 */
const getList = async () => {
loading.value = true;
const res = await listNotice(queryParams.value);
noticeList.value = res.rows;
if (noticeList.value.length > 0) {
noticeList.value.forEach((item) => {
let obj = JSON.parse(item.content);
item.route = obj.type;
item.msg = obj.content;
});
}
total.value = res.total;
loading.value = false;
};
// 跳转到指定路由
const handleRoute = (row) => {
proxy.$router.push({ path: row.route });
};
/** 取消按钮 */
const cancel = () => {
reset();
dialog.visible = false;
};
/** 表单重置 */
const reset = () => {
form.value = { ...initFormData };
noticeFormRef.value?.resetFields();
};
/** 搜索按钮操作 */
const handleQuery = () => {
queryParams.value.pageNum = 1;
getList();
};
/** 重置按钮操作 */
const resetQuery = () => {
queryFormRef.value?.resetFields();
handleQuery();
};
/** 多选框选中数据 */
const handleSelectionChange = (selection: NoticeVO[]) => {
ids.value = selection.map((item) => item.id);
single.value = selection.length != 1;
multiple.value = !selection.length;
};
/** 新增按钮操作 */
const handleAdd = () => {
reset();
dialog.visible = true;
dialog.title = '添加消息';
};
/** 修改按钮操作 */
const handleUpdate = async (row?: NoticeVO) => {
reset();
const _id = row?.id || ids.value[0];
const res = await getNotice(_id);
Object.assign(form.value, res.data);
dialog.visible = true;
dialog.title = '修改消息';
};
/** 提交按钮 */
const submitForm = () => {
noticeFormRef.value?.validate(async (valid: boolean) => {
if (valid) {
buttonLoading.value = true;
if (form.value.id) {
await updateNotice(form.value).finally(() => (buttonLoading.value = false));
} else {
await addNotice(form.value).finally(() => (buttonLoading.value = false));
}
proxy?.$modal.msgSuccess('操作成功');
dialog.visible = false;
await getList();
}
});
};
/** 删除按钮操作 */
const handleDelete = async (row?: NoticeVO) => {
const _ids = row?.id || ids.value;
await proxy?.$modal.confirm('是否确认删除消息编号为"' + _ids + '"的数据项?').finally(() => (loading.value = false));
await delNotice(_ids);
proxy?.$modal.msgSuccess('删除成功');
await getList();
};
/** 导出按钮操作 */
const handleExport = () => {
proxy?.download(
'message/notice/export',
{
...queryParams.value
},
`notice_${new Date().getTime()}.xlsx`
);
};
onMounted(() => {
getList();
});
</script>

View File

@ -1,120 +1,124 @@
<template> <template>
<div class="p-2"> <div class="p-2">
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
:leave-active-class="proxy?.animate.searchAnimate.leave"> <div v-show="showSearch" class="mb-[10px]">
<div v-show="showSearch" class="mb-[10px]"> <el-card shadow="hover">
<el-card shadow="hover"> <el-form ref="queryFormRef" :model="queryParams" :inline="true">
<el-form ref="queryFormRef" :model="queryParams" :inline="true"> <el-form-item label="上报日期" prop="reportDate">
<el-form-item label="上报日期" prop="reportDate"> <el-date-picker clearable v-model="queryParams.reportDate" type="date" value-format="YYYY-MM-DD" placeholder="请选择上报日期" />
<el-date-picker clearable v-model="queryParams.reportDate" type="date" value-format="YYYY-MM-DD" </el-form-item>
placeholder="请选择上报日期" /> <el-form-item>
</el-form-item> <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
<el-form-item> <el-button icon="Refresh" @click="resetQuery">重置</el-button>
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button> </el-form-item>
<el-button icon="Refresh" @click="resetQuery">重置</el-button> </el-form>
</el-form-item> </el-card>
</el-form> </div>
</el-card> </transition>
</div>
</transition>
<el-card shadow="never"> <el-card shadow="never">
<template #header> <template #header>
<el-row :gutter="10" class="mb8"> <el-row :gutter="10" class="mb8">
<el-col :span="1.5"> <el-col :span="1.5">
<el-button type="primary" plain icon="Plus" @click="handleAdd" <el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['out:constructionValue:add']">新增</el-button>
v-hasPermi="['out:constructionValue:add']">新增</el-button> </el-col>
</el-col> <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
<el-col :span="1.5"> </el-row>
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" </template>
v-hasPermi="['out:constructionValue:remove']">删除</el-button>
</el-col>
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
</template>
<el-table v-loading="loading" :data="constructionValueList" @selection-change="handleSelectionChange"> <el-table v-loading="loading" :data="constructionValueList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" /> <el-table-column type="index" width="55" label="序号" align="center" />
<!-- <el-table-column label="主键ID" align="center" prop="id" v-if="true" /> --> <el-table-column label="上报日期" align="center" prop="reportDate" width="180">
<el-table-column label="上报日期" align="center" prop="reportDate" width="180"> <template #default="scope">
<template #default="scope"> <span>{{ parseTime(scope.row.reportDate, '{y}-{m}-{d}') }}</span>
<span>{{ parseTime(scope.row.reportDate, '{y}-{m}-{d}') }}</span> </template>
</template> </el-table-column>
</el-table-column> <el-table-column label="项目子项" align="center" prop="subProjectName" />
<el-table-column label="项目子项" align="center" prop="subProjectName" /> <el-table-column label="分部工程" align="center" prop="categoryName" />
<el-table-column label="分工程" align="center" prop="categoryName" /> <el-table-column label="分工程" align="center" prop="progressCategoryName" />
<el-table-column label="分项工程" align="center" prop="progressCategoryName" /> <el-table-column label="人工填报数量" align="center" prop="artificialNum" />
<el-table-column label="人工填报数量" align="center" prop="artificialNum" /> <el-table-column label="无人机识别数量" align="center" prop="uavNum" />
<el-table-column label="无人机识别数量" align="center" prop="uavNum" /> <el-table-column label="确认数量" align="center" prop="confirmNum" />
<el-table-column label="确认数量" align="center" prop="confirmNum" /> <el-table-column label="对乙产值" align="center" prop="outValue" />
<el-table-column label="对产值" align="center" prop="outValue" /> <el-table-column label="对产值" align="center" prop="ownerValue" />
<el-table-column label="对甲产值" align="center" prop="ownerValue" /> <el-table-column label="流程状态" align="center" prop="status">
<el-table-column label="流程状态" align="center" prop="status"> <template #default="scope">
<template #default="scope"> <dict-tag :options="wf_business_status" :value="scope.row.auditStatus" />
<dict-tag :options="wf_business_status" :value="scope.row.auditStatus" /> </template>
</template> </el-table-column>
</el-table-column> <el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="210">
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="210"> <template #default="scope">
<template #default="scope"> <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['out:constructionValue:edit']">修改</el-button>
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" <el-button link type="primary" icon="Finished" @click="handleAudit(scope.row)">审核</el-button>
v-hasPermi="['out:constructionValue:edit']">修改</el-button> </template>
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" </el-table-column>
v-hasPermi="['out:constructionValue:remove']">删除</el-button> </el-table>
<el-button link type="primary" icon="Finished" @click="handleAudit(scope.row)" <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
v-hasPermi="['out:constructionValue:remove']">审核</el-button> </el-card>
</template> <!-- 添加或修改施工产值对话框 -->
</el-table-column> <el-dialog draggable :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
</el-table> <el-form ref="constructionValueFormRef" :model="form" :rules="rules" label-width="120px">
<el-form-item label="方阵" prop="matrixId" v-if="!form.id">
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" <el-cascader
v-model:limit="queryParams.pageSize" @pagination="getList" /> :options="matrixOptions"
</el-card> placeholder="请选择"
<!-- 添加或修改施工产值对话框 --> :props="{ value: 'matrixId', label: 'name', emitPath: false }"
<el-dialog draggable :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body> v-model="form.matrixId"
<el-form ref="constructionValueFormRef" :model="form" :rules="rules" label-width="120px"> @clear="resetCascader(1)"
<el-form-item label="方阵" prop="matrixId" v-if="!form.id"> @change="handleChange"
<el-cascader :options="matrixOptions" placeholder="请选择" clearable
:props="{ value: 'matrixId', label: 'name', emitPath: false }" v-model="form.matrixId" />
@clear="resetCascader(1)" @change="handleChange" clearable /> </el-form-item>
</el-form-item> <el-form-item label="分项工程" prop="progressCategoryId" v-if="!form.id">
<el-form-item label="分项工程" prop="progressCategoryId" v-if="!form.id"> <el-cascader
<el-cascader :options="progressCategoryList" v-model="form.progressCategoryId" @clear="resetCascader()" :options="progressCategoryList"
:disabled="!form.matrixId" @change="selectTime" v-model="form.progressCategoryId"
:props="{ expandTrigger: 'hover', value: 'id', label: 'name', emitPath: false }" placeholder="请选择分项工程" @clear="resetCascader()"
clearable> :disabled="!form.matrixId"
</el-cascader> @change="selectTime"
</el-form-item> :props="{ expandTrigger: 'hover', value: 'id', label: 'name', emitPath: false }"
<el-form-item label="计划日期" prop="reportDateId" v-if="!form.id"> placeholder="请选择分项工程"
<el-cascader :options="progressTimeList" v-model="form.reportDateId" :disabled="!form.progressCategoryId" clearable
:props="{ expandTrigger: 'hover', value: 'id', label: 'date', emitPath: false }" placeholder="请选择计划日期" >
@change="submitTime" clearable> </el-cascader>
</el-cascader> </el-form-item>
</el-form-item> <el-form-item label="计划日期" prop="reportDateId" v-if="!form.id">
<el-form-item label="人工填报数量" prop="artificialNum"> <el-cascader
<el-input v-model="form.artificialNum" placeholder="请输入人工填报数量" disabled /> :options="progressTimeList"
</el-form-item> v-model="form.reportDateId"
<el-form-item label="无人机识别数量" prop="uavNum"> :disabled="!form.progressCategoryId"
<el-input v-model="form.uavNum" placeholder="请输入无人机识别数量" disabled /> :props="{ expandTrigger: 'hover', value: 'id', label: 'date', emitPath: false }"
</el-form-item> placeholder="请选择计划日期"
<el-form-item label="上报日期" prop="planDate"> @change="submitTime"
<el-date-picker v-model="form.planDate" type="date" value-format="YYYY-MM-DD" placeholder="请选择上报日期" /> clearable
</el-form-item> >
<el-form-item label="确认数量" prop="confirmNum"> </el-cascader>
<el-input v-model="form.confirmNum" placeholder="请输入确认数量" /> </el-form-item>
</el-form-item> <el-form-item label="人工填报数量" prop="artificialNum">
<!-- <el-form-item label="产值" prop="outValue"> <el-input v-model="form.artificialNum" placeholder="请输入人工填报数量" disabled />
</el-form-item>
<el-form-item label="无人机识别数量" prop="uavNum">
<el-input v-model="form.uavNum" placeholder="请输入无人机识别数量" disabled />
</el-form-item>
<el-form-item label="上报日期" prop="planDate">
<el-date-picker v-model="form.planDate" type="date" value-format="YYYY-MM-DD" placeholder="请选择上报日期" />
</el-form-item>
<el-form-item label="确认数量" prop="confirmNum">
<el-input v-model="form.confirmNum" placeholder="请输入确认数量" />
</el-form-item>
<!-- <el-form-item label="产值" prop="outValue">
<el-input v-model="form.outValue" disabled /> <el-input v-model="form.outValue" disabled />
</el-form-item> --> </el-form-item> -->
</el-form> </el-form>
<template #footer> <template #footer>
<div class="dialog-footer"> <div class="dialog-footer">
<el-button :loading="buttonLoading" type="primary" @click="submitForm"> </el-button> <el-button :loading="buttonLoading" type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button> <el-button @click="cancel"> </el-button>
</div> </div>
</template> </template>
</el-dialog> </el-dialog>
</div> </div>
</template> </template>
<script setup name="ConstructionValue" lang="ts"> <script setup name="ConstructionValue" lang="ts">
import { import {

View File

@ -1,13 +1,11 @@
<template> <template>
<div class="p-2"> <div class="p-2">
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" <el-card shadow="never">
:leave-active-class="proxy?.animate.searchAnimate.leave"> <template #header>
<div v-show="showSearch" class="mb-[10px]"> <el-row :gutter="10" class="mb8">
<el-card shadow="hover">
<el-form ref="queryFormRef" :model="queryParams" :inline="true"> <el-form ref="queryFormRef" :model="queryParams" :inline="true">
<el-form-item label="计划月份" prop="planMonth"> <el-form-item label="计划月份" prop="planMonth">
<el-date-picker v-model="queryParams.planMonth" type="month" value-format="YYYY-MM" <el-date-picker v-model="queryParams.planMonth" type="month" value-format="YYYY-MM" placeholder="请选择计划月份" />
placeholder="请选择计划月份" />
</el-form-item> </el-form-item>
<el-form-item label="类型" prop="type"> <el-form-item label="类型" prop="type">
<el-select v-model="queryParams.type" placeholder="请选择类型"> <el-select v-model="queryParams.type" placeholder="请选择类型">
@ -20,18 +18,11 @@
<el-button icon="Refresh" @click="resetQuery">重置</el-button> <el-button icon="Refresh" @click="resetQuery">重置</el-button>
</el-form-item> </el-form-item>
</el-form> </el-form>
</el-card>
</div>
</transition>
<el-card shadow="never">
<template #header>
<el-row :gutter="10" class="mb8">
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar> <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row> </el-row>
</template> </template>
<el-table v-loading="loading" :data="monthPlanList" @selection-change="handleSelectionChange"> <el-table v-loading="loading" :data="monthPlanList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" /> <el-table-column type="index" label="序号" width="60" align="center" />
<el-table-column label="计划月份" align="center" prop="planMonth" /> <el-table-column label="计划月份" align="center" prop="planMonth" />
<el-table-column label="计划产值" align="center" prop="planValue" /> <el-table-column label="计划产值" align="center" prop="planValue" />
<el-table-column label="完成产值" align="center" prop="completeValue" /> <el-table-column label="完成产值" align="center" prop="completeValue" />
@ -54,16 +45,15 @@
</el-table-column> </el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="210"> <el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="210">
<template #default="scope"> <template #default="scope">
<el-button type="primary" link icon="Edit" @click="handleAdd(scope.row)" <el-button type="primary" link icon="Edit" @click="handleAdd(scope.row)" v-hasPermi="['out:monthPlan:add']">编辑</el-button>
v-hasPermi="['out:monthPlan:add']">编辑</el-button>
<el-button link type="primary" icon="Finished" @click="handleAudit(scope.row)" <el-button link type="primary" icon="Finished" @click="handleAudit(scope.row)" v-hasPermi="['out:constructionValue:remove']"
v-hasPermi="['out:constructionValue:remove']">审核</el-button> >审核</el-button
>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
v-model:limit="queryParams.pageSize" @pagination="getList" />
</el-card> </el-card>
<!-- 添加或修改月度产值计划对话框 --> <!-- 添加或修改月度产值计划对话框 -->
<el-dialog draggable :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body> <el-dialog draggable :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
@ -74,8 +64,14 @@
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="计划月份" prop="planMonth"> <el-form-item label="计划月份" prop="planMonth">
<el-date-picker v-model="form.planMonth" type="month" value-format="YYYY-MM" disabled placeholder="请选择计划月份" <el-date-picker
@change="handlePlanMonthChange" /> v-model="form.planMonth"
type="month"
value-format="YYYY-MM"
disabled
placeholder="请选择计划月份"
@change="handlePlanMonthChange"
/>
</el-form-item> </el-form-item>
<el-form-item label="计划产值" prop="planValue"> <el-form-item label="计划产值" prop="planValue">
<el-input v-model="form.planValue" placeholder="请输入计划产值" disabled /> <el-input v-model="form.planValue" placeholder="请输入计划产值" disabled />

View File

@ -1,13 +1,11 @@
<template> <template>
<div class="p-2"> <div class="p-2">
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
:leave-active-class="proxy?.animate.searchAnimate.leave">
<div v-show="showSearch" class="mb-[10px]"> <div v-show="showSearch" class="mb-[10px]">
<el-card shadow="hover"> <el-card shadow="hover">
<el-form ref="queryFormRef" :model="queryParams" :inline="true"> <el-form ref="queryFormRef" :model="queryParams" :inline="true">
<el-form-item label="计划月份" prop="planMonth"> <el-form-item label="计划月份" prop="planMonth">
<el-date-picker v-model="queryParams.planMonth" type="month" value-format="YYYY-MM" <el-date-picker v-model="queryParams.planMonth" type="month" value-format="YYYY-MM" placeholder="请选择计划月份" />
placeholder="请选择计划月份" />
</el-form-item> </el-form-item>
<el-form-item label="产值类型" prop="valueType"> <el-form-item label="产值类型" prop="valueType">
<el-select v-model="queryParams.valueType" placeholder="请选择产值类型"> <el-select v-model="queryParams.valueType" placeholder="请选择产值类型">
@ -33,19 +31,14 @@
<template #header> <template #header>
<el-row :gutter="10" class="mb8"> <el-row :gutter="10" class="mb8">
<el-col :span="1.5"> <el-col :span="1.5">
<el-button type="primary" plain icon="Plus" @click="handleAdd" <el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['out:monthPlan:add']">新增</el-button>
v-hasPermi="['out:monthPlan:add']">新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()"
v-hasPermi="['out:monthPlan:remove']">删除</el-button>
</el-col> </el-col>
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar> <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row> </el-row>
</template> </template>
<el-table v-loading="loading" :data="monthPlanList" @selection-change="handleSelectionChange"> <el-table v-loading="loading" :data="monthPlanList">
<el-table-column type="selection" width="55" align="center" /> <el-table-column type="index" label="序号" width="55" align="center" />
<el-table-column label="计划月份" align="center" prop="planMonth" /> <el-table-column label="计划月份" align="center" prop="planMonth" />
<el-table-column label="计划产值" align="center" prop="planValue" /> <el-table-column label="计划产值" align="center" prop="planValue" />
<el-table-column label="完成产值" align="center" prop="completeValue" /> <el-table-column label="完成产值" align="center" prop="completeValue" />
@ -67,18 +60,15 @@
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width"> <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template #default="scope"><el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" <template #default="scope"
v-hasPermi="['out:monthPlan:edit']">修改</el-button> ><el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['out:monthPlan:edit']">修改</el-button>
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" <!-- <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['out:monthPlan:remove']">删除</el-button> -->
v-hasPermi="['out:monthPlan:remove']">删除</el-button> <el-button link type="primary" icon="Finished" @click="handleAudit(scope.row)" v-hasPermi="['out:monthPlan:remove']">审核</el-button>
<el-button link type="primary" icon="Finished" @click="handleAudit(scope.row)"
v-hasPermi="['out:monthPlan:remove']">审核</el-button>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
v-model:limit="queryParams.pageSize" @pagination="getList" />
</el-card> </el-card>
<!-- 添加或修改月度产值计划对话框 --> <!-- 添加或修改月度产值计划对话框 -->
<el-dialog draggable :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body> <el-dialog draggable :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>

View File

@ -2,10 +2,10 @@
<div class="p-2"> <div class="p-2">
<el-tabs type="border-card" @tab-change="handleTabChange" v-model="activeTab"> <el-tabs type="border-card" @tab-change="handleTabChange" v-model="activeTab">
<el-tab-pane v-for="(item, index) in tabList" :key="index" :label="item.label" :name="item.value"> <el-tab-pane v-for="(item, index) in tabList" :key="index" :label="item.label" :name="item.value">
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave"> <el-card shadow="never">
<div v-show="showSearch" class="mb-[10px]"> <template #header>
<el-card shadow="hover"> <el-row :gutter="10" class="mb8"
<el-form ref="queryFormRef" :model="queryParams" :inline="true"> ><el-form ref="queryFormRef" :model="queryParams" :inline="true">
<el-form-item label="计划月份" prop="month"> <el-form-item label="计划月份" prop="month">
<el-date-picker v-model="queryParams.month" type="month" value-format="YYYY-MM" placeholder="请选择计划月份" /> <el-date-picker v-model="queryParams.month" type="month" value-format="YYYY-MM" placeholder="请选择计划月份" />
</el-form-item> </el-form-item>
@ -20,12 +20,6 @@
<el-button icon="Refresh" @click="resetQuery">重置</el-button> <el-button icon="Refresh" @click="resetQuery">重置</el-button>
</el-form-item> </el-form-item>
</el-form> </el-form>
</el-card>
</div>
</transition>
<el-card shadow="never">
<template #header>
<el-row :gutter="10" class="mb8">
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar> <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row> </el-row>
</template> </template>

View File

@ -1,43 +1,41 @@
<template> <template>
<div class="p-2"> <div class="p-2">
<el-card shadow="never"> <el-card shadow="never">
<template #header> <template #header>
<el-row :gutter="10" class="mb8"> <el-row :gutter="10" class="mb8">
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar> <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row> </el-row>
</template> </template>
<el-table height="70vh" v-loading="loading" :data="monthPlanList" @selection-change="handleSelectionChange"> <el-table height="70vh" v-loading="loading" :data="monthPlanList" @selection-change="handleSelectionChange">
<el-table-column type="index" width="80" label="序号" align="center" /> <el-table-column type="index" width="80" label="序号" align="center" />
<el-table-column label="名称" align="center" prop="name" /> <el-table-column label="名称" align="center" prop="name" />
<el-table-column label="规格" align="center" prop="specification" /> <el-table-column label="规格" align="center" prop="specification" />
<el-table-column label="单位" align="center" prop="unit" /> <el-table-column label="单位" align="center" prop="unit" />
<el-table-column label="接收数量" align="center" prop="acceptedQuantity" /> <el-table-column label="接收数量" align="center" prop="acceptedQuantity" />
<el-table-column label="价格" align="center" prop="unitPrice"> <el-table-column label="价格" align="center" prop="unitPrice"> </el-table-column>
</el-table-column> <el-table-column label="备注" align="center" prop="remark"> </el-table-column>
<el-table-column label="备注" align="center" prop="remark"> <el-table-column label="操作" align="center" prop="remark" v-if="queryParams.type == '1'">
</el-table-column> <template #default="scope">
<el-table-column label="操作" align="center" prop="remark" v-if="queryParams.type == '1'"> <el-button type="primary" v-hasPermi="['out:monthPlan:purchaseValueAup']" @click="handleUpdate(scope.row)">编辑</el-button>
<template #default="scope"> </template>
<el-button type="primary" @click="handleUpdate(scope.row)">编辑</el-button> </el-table-column>
</template> </el-table>
</el-table-column> </el-card>
</el-table> <!-- 添加或修改月度产值计划对话框 -->
</el-card> <el-dialog draggable :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
<!-- 添加或修改月度产值计划对话框 --> <el-form ref="monthPlanFormRef" :model="form" :rules="rules" label-width="80px">
<el-dialog draggable :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body> <el-form-item label="金额" prop="unitPrice">
<el-form ref="monthPlanFormRef" :model="form" :rules="rules" label-width="80px"> <el-input v-model="form.unitPrice" placeholder="请输入金额" type="number" />
<el-form-item label="金额" prop="unitPrice"> </el-form-item>
<el-input v-model="form.unitPrice" placeholder="请输入金额" type="number" /> </el-form>
</el-form-item> <template #footer>
</el-form> <div class="dialog-footer">
<template #footer> <el-button :loading="buttonLoading" type="primary" @click="submitForm"> </el-button>
<div class="dialog-footer"> <el-button @click="cancel"> </el-button>
<el-button :loading="buttonLoading" type="primary" @click="submitForm"> </el-button> </div>
<el-button @click="cancel"> </el-button> </template>
</div> </el-dialog>
</template> </div>
</el-dialog>
</div>
</template> </template>
<script setup name="MonthPlan" lang="ts"> <script setup name="MonthPlan" lang="ts">
@ -59,123 +57,122 @@ const single = ref(true);
const multiple = ref(true); const multiple = ref(true);
const total = ref(0); const total = ref(0);
const queryFormRef = ref<ElFormInstance>();
const monthPlanFormRef = ref<ElFormInstance>(); const monthPlanFormRef = ref<ElFormInstance>();
const dialog = reactive<DialogOption>({ const dialog = reactive<DialogOption>({
visible: false, visible: false,
title: '' title: ''
}); });
const initFormData = { const initFormData = {
id: undefined, id: undefined,
projectId: currentProject.value?.id,
planValue: undefined,
completeValue: undefined,
differenceValue: undefined,
planMonth: undefined,
isDesign: true,
type: '1',
valueType: undefined,
planAuditStatus: undefined,
completeAuditStatus: undefined,
unitPrice: undefined
};
const data = reactive({
form: { ...initFormData },
queryParams: {
projectId: currentProject.value?.id, projectId: currentProject.value?.id,
planValue: undefined, planValue: undefined,
completeValue: undefined, completeValue: undefined,
differenceValue: undefined, differenceValue: undefined,
planMonth: undefined, planMonth: undefined,
isDesign: true,
type: '1',
valueType: undefined, valueType: undefined,
planAuditStatus: undefined, planAuditStatus: undefined,
completeAuditStatus: undefined, completeAuditStatus: undefined,
unitPrice: undefined, type: '1',
}; params: {}
const data = reactive({ },
form: { ...initFormData }, rules: {
queryParams: { unitPrice: [{ required: true, message: '金额不能为空', trigger: 'change' }]
projectId: currentProject.value?.id, }
planValue: undefined,
completeValue: undefined,
differenceValue: undefined,
planMonth: undefined,
valueType: undefined,
planAuditStatus: undefined,
completeAuditStatus: undefined,
type: '1',
params: {}
},
rules: {
unitPrice: [{ required: true, message: '金额不能为空', trigger: 'change' }]
}
}); });
const { queryParams, form, rules } = toRefs(data); const { queryParams, form, rules } = toRefs(data);
/** 查询月度产值计划列表 */ /** 查询月度产值计划列表 */
const getList = async (type?) => { const getList = async (type?) => {
if (type) { if (type) {
queryParams.value.type = type; queryParams.value.type = type;
} }
loading.value = true; loading.value = true;
const res = await purchaseValueA({ projectId: currentProject.value?.id, type: queryParams.value.type }); const res = await purchaseValueA({ projectId: currentProject.value?.id, type: queryParams.value.type });
monthPlanList.value = res.data; monthPlanList.value = res.data;
console.log(monthPlanList.value); console.log(monthPlanList.value);
total.value = res.total; total.value = res.total;
loading.value = false; loading.value = false;
}; };
/** 取消按钮 */ /** 取消按钮 */
const cancel = () => { const cancel = () => {
reset(); reset();
dialog.visible = false; dialog.visible = false;
}; };
/** 表单重置 */ /** 表单重置 */
const reset = () => { const reset = () => {
form.value = { ...initFormData }; form.value = { ...initFormData };
monthPlanFormRef.value?.resetFields(); monthPlanFormRef.value?.resetFields();
}; };
/** 多选框选中数据 */ /** 多选框选中数据 */
const handleSelectionChange = (selection: MonthPlanVO[]) => { const handleSelectionChange = (selection: MonthPlanVO[]) => {
ids.value = selection.map((item) => item.id); ids.value = selection.map((item) => item.id);
single.value = selection.length != 1; single.value = selection.length != 1;
multiple.value = !selection.length; multiple.value = !selection.length;
}; };
/** 修改按钮操作 */ /** 修改按钮操作 */
const handleUpdate = async (row?: MonthPlanVO) => { const handleUpdate = async (row?: MonthPlanVO) => {
reset(); reset();
Object.assign(form.value, row); Object.assign(form.value, row);
dialog.visible = true; dialog.visible = true;
dialog.title = '修改采购完工产值'; dialog.title = '修改采购完工产值';
}; };
/** 提交按钮 */ /** 提交按钮 */
const submitForm = () => { const submitForm = () => {
form.value.projectId = currentProject.value?.id; form.value.projectId = currentProject.value?.id;
monthPlanFormRef.value?.validate(async (valid: boolean) => { monthPlanFormRef.value?.validate(async (valid: boolean) => {
if (valid) { if (valid) {
buttonLoading.value = true; buttonLoading.value = true;
form.value.isDesign = true; form.value.isDesign = true;
if (form.value.id) { if (form.value.id) {
await purchaseValueAup(form.value).finally(() => (buttonLoading.value = false)); await purchaseValueAup(form.value).finally(() => (buttonLoading.value = false));
} }
proxy?.$modal.msgSuccess('操作成功'); proxy?.$modal.msgSuccess('操作成功');
dialog.visible = false; dialog.visible = false;
await getList(); await getList();
} }
}); });
}; };
onMounted(() => { onMounted(() => {
getList(); getList();
}); });
//监听项目id刷新数据 //监听项目id刷新数据
const listeningProject = watch( const listeningProject = watch(
() => currentProject.value?.id, () => currentProject.value?.id,
(nid, oid) => { (nid, oid) => {
queryParams.value.projectId = nid; queryParams.value.projectId = nid;
form.value.projectId = nid; form.value.projectId = nid;
getList(); getList();
} }
); );
onUnmounted(() => { onUnmounted(() => {
listeningProject(); listeningProject();
}); });
defineExpose({ defineExpose({
getList getList
}); });
</script> </script>

View File

@ -23,7 +23,6 @@ const handleClick = (val) => {
purchPageRef1.value.getList(val.props.name); //子组件方法 purchPageRef1.value.getList(val.props.name); //子组件方法
} else { } else {
purchPageRef2.value.getList(val.props.name); //子组件方法 purchPageRef2.value.getList(val.props.name); //子组件方法
} }
}; };
onMounted(() => { onMounted(() => {

View File

@ -27,17 +27,12 @@
<el-col :span="1.5"> <el-col :span="1.5">
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['out:settlementValueOwner:add']">新增</el-button> <el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['out:settlementValueOwner:add']">新增</el-button>
</el-col> </el-col>
<el-col :span="1.5">
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['out:settlementValueOwner:remove']"
>删除</el-button
>
</el-col>
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar> <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row> </el-row>
</template> </template>
<el-table v-loading="loading" :data="settlementValueOwnerList" @selection-change="handleSelectionChange"> <el-table v-loading="loading" :data="settlementValueOwnerList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" /> <el-table-column type="index" label="序号" width="60" align="center" />
<el-table-column label="填报人" align="center" prop="createByName" /> <el-table-column label="填报人" align="center" prop="createByName" />
<el-table-column label="结算产值" align="center" prop="settlementValue" /> <el-table-column label="结算产值" align="center" prop="settlementValue" />
<el-table-column label="产值类型" align="center" prop="valueType"> <el-table-column label="产值类型" align="center" prop="valueType">
@ -58,18 +53,12 @@
<el-table-column label="说明" align="center" prop="remark" /> <el-table-column label="说明" align="center" prop="remark" />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width"> <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template #default="scope"> <template #default="scope">
<el-tooltip content="修改" placement="top"> <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['out:settlementValueOwner:edit']"
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['out:settlementValueOwner:edit']"></el-button> >修改</el-button
</el-tooltip> >
<el-tooltip content="删除" placement="top"> <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['out:settlementValueOwner:remove']"
<el-button >删除</el-button
link >
type="primary"
icon="Delete"
@click="handleDelete(scope.row)"
v-hasPermi="['out:settlementValueOwner:remove']"
></el-button>
</el-tooltip>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>

View File

@ -28,23 +28,12 @@
<el-col :span="1.5"> <el-col :span="1.5">
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['out:settlementValueSubcontract:add']">新增</el-button> <el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['out:settlementValueSubcontract:add']">新增</el-button>
</el-col> </el-col>
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="Delete"
:disabled="multiple"
@click="handleDelete()"
v-hasPermi="['out:settlementValueSubcontract:remove']"
>删除</el-button
>
</el-col>
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar> <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row> </el-row>
</template> </template>
<el-table v-loading="loading" :data="settlementValueSubcontractList" @selection-change="handleSelectionChange"> <el-table v-loading="loading" :data="settlementValueSubcontractList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" /> <el-table-column type="index" label="序号" width="60" align="center" />
<el-table-column label="分包单位" align="center" prop="contractorName" /> <el-table-column label="分包单位" align="center" prop="contractorName" />
<el-table-column label="单据编码" align="center" prop="documentCode" /> <el-table-column label="单据编码" align="center" prop="documentCode" />
<el-table-column label="结算说明" align="center" prop="settlementDescribe" /> <el-table-column label="结算说明" align="center" prop="settlementDescribe" />
@ -65,24 +54,12 @@
<el-table-column label="合同名称" align="center" prop="contractName" /> <el-table-column label="合同名称" align="center" prop="contractName" />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width"> <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template #default="scope"> <template #default="scope">
<el-tooltip content="修改" placement="top"> <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['out:settlementValueSubcontract:edit']"
<el-button >修改</el-button
link >
type="primary" <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['out:settlementValueSubcontract:remove']"
icon="Edit" >删除</el-button
@click="handleUpdate(scope.row)" >
v-hasPermi="['out:settlementValueSubcontract:edit']"
></el-button>
</el-tooltip>
<el-tooltip content="删除" placement="top">
<el-button
link
type="primary"
icon="Delete"
@click="handleDelete(scope.row)"
v-hasPermi="['out:settlementValueSubcontract:remove']"
></el-button>
</el-tooltip>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>

View File

@ -1,8 +1,7 @@
<template> <template>
<div class="p-2"> <div class="p-2">
<!-- 搜索区域 --> <!-- 搜索区域 -->
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
:leave-active-class="proxy?.animate.searchAnimate.leave">
<div v-show="showSearch" class="mb-[10px]"> <div v-show="showSearch" class="mb-[10px]">
<el-card shadow="hover"> <el-card shadow="hover">
<el-form ref="queryFormRef" :model="queryParams" :inline="true"> <el-form ref="queryFormRef" :model="queryParams" :inline="true">
@ -22,12 +21,10 @@
<template #header> <template #header>
<el-row :gutter="10" class="mb8"> <el-row :gutter="10" class="mb8">
<el-col :span="1.5"> <el-col :span="1.5">
<el-button type="primary" plain icon="Plus" @click="handleAdd" <el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['patch:master:add']">新增</el-button>
v-hasPermi="['patch:patch:add']">新增</el-button>
</el-col> </el-col>
<el-col :span="1.5"> <el-col :span="1.5">
<el-button type="warning" plain icon="Download" @click="handleExport" <el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['patch:master:export']">导出</el-button>
v-hasPermi="['patch:patch:export']">导出</el-button>
</el-col> </el-col>
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar> <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row> </el-row>
@ -59,10 +56,10 @@
<el-table-column label="任务状态" align="center" prop="taskStatus"> <el-table-column label="任务状态" align="center" prop="taskStatus">
<template #default="scope"> <template #default="scope">
<span <span
:class="[Number(scope.row.taskStatus) === 0 ? 'text-warning' : Number(scope.row.taskStatus) === 1 ? 'text-success' : 'text-danger']"> :class="[Number(scope.row.taskStatus) === 0 ? 'text-warning' : Number(scope.row.taskStatus) === 1 ? 'text-success' : 'text-danger']"
>
{{ {{
Number(scope.row.taskStatus) === 0 ? '未完成' : Number(scope.row.taskStatus) === 1 ? '已完成' : Number(scope.row.taskStatus) === 0 ? '未完成' : Number(scope.row.taskStatus) === 1 ? '已完成' : `未知状态(${scope.row.taskStatus})`
`未知状态(${scope.row.taskStatus})`
}} }}
</span> </span>
</template> </template>
@ -70,22 +67,19 @@
<el-table-column label="备注" align="center" prop="remark" /> <el-table-column label="备注" align="center" prop="remark" />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width"> <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template #default="scope"> <template #default="scope">
<!-- <el-tooltip content="修改" placement="top">
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['patch:patch:edit']"></el-button>
</el-tooltip> -->
<el-tooltip content="删除" placement="top"> <el-tooltip content="删除" placement="top">
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['patch:master:remove']"></el-button>
v-hasPermi="['patch:patch:remove']"></el-button>
</el-tooltip> </el-tooltip>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<!-- 进度详情弹窗 --> <!-- 进度详情弹窗 -->
<el-dialog :title="`进度详情(当前总进度:${currentTotalProgress}%`" v-model="progressDialogVisible" width="1000px" <el-dialog :title="`进度详情(当前总进度:${currentTotalProgress}%`" v-model="progressDialogVisible" width="1000px" destroy-on-close>
destroy-on-close>
<div class="mb-4"> <div class="mb-4">
<!-- v-hasPermi="['patch:progress:add']" --> <!-- v-hasPermi="['patch:master:add']" -->
<el-button type="primary" plain icon="Plus" size="small" @click="handleProgressAdd()"> 新增进度 </el-button> <el-button type="primary" plain icon="Plus" size="small" v-hasPermi="['patch:master:progress']" @click="handleProgressAdd()">
新增进度
</el-button>
</div> </div>
<el-table v-loading="progressLoading" :data="progressList" border empty-text="暂无进度数据" style="width: 100%"> <el-table v-loading="progressLoading" :data="progressList" border empty-text="暂无进度数据" style="width: 100%">
<el-table-column prop="slaveName" label="执行人姓名" align="center" width="150" /> <el-table-column prop="slaveName" label="执行人姓名" align="center" width="150" />
@ -99,28 +93,30 @@
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="140"> <el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="140">
<template #default="scope"> <template #default="scope">
<el-tooltip content="修改进度" placement="top"> <el-tooltip content="修改进度" placement="top">
<el-button link type="primary" icon="Edit" size="small" @click="handleProgressUpdate(scope.row)" <el-button link type="primary" icon="Edit" size="small" @click="handleProgressUpdate(scope.row)"></el-button>
v-hasPermi="['patch:progress:edit']"></el-button>
</el-tooltip> </el-tooltip>
<el-tooltip content="删除进度" placement="top"> <el-tooltip content="删除进度" placement="top">
<el-button link type="primary" icon="Delete" size="small" @click="handleProgressDelete(scope.row)" <el-button
v-hasPermi="['patch:progress:remove']"></el-button> link
type="primary"
icon="Delete"
size="small"
@click="handleProgressDelete(scope.row)"
v-hasPermi="['patch:master:removeProgress']"
></el-button>
</el-tooltip> </el-tooltip>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
</el-dialog> </el-dialog>
<!-- 新增/修改进度弹窗 --> <!-- 新增/修改进度弹窗 -->
<el-dialog :title="progressDialog.title" v-model="progressDialog.visible" width="500px" append-to-body <el-dialog :title="progressDialog.title" v-model="progressDialog.visible" width="500px" append-to-body destroy-on-close>
destroy-on-close>
<el-form ref="progressFormRef" :model="progressForm" :rules="progressRules" label-width="120px"> <el-form ref="progressFormRef" :model="progressForm" :rules="progressRules" label-width="120px">
<el-input v-model="progressForm.ordersId" placeholder="关联的任务ID" readonly <el-input v-model="progressForm.ordersId" placeholder="关联的任务ID" readonly style="color: #666; background: #f5f7fa" type="hidden" />
style="color: #666; background: #f5f7fa" type="hidden" />
<el-input v-model="progressForm.projectId" type="hidden" /> <el-input v-model="progressForm.projectId" type="hidden" />
<el-input v-model="progressForm.slaveId" placeholder="请输入执行人ID" v-if="false" /> <el-input v-model="progressForm.slaveId" placeholder="请输入执行人ID" v-if="false" />
<el-form-item label="进度" prop="progress"> <el-form-item label="进度" prop="progress">
<el-input v-model="progressForm.progress" placeholder="请输入进度0-100之间的数字" type="number" <el-input v-model="progressForm.progress" placeholder="请输入进度0-100之间的数字" type="number" @input="handleProgressInput" />
@input="handleProgressInput" />
</el-form-item> </el-form-item>
<el-form-item label="备注" prop="remark"> <el-form-item label="备注" prop="remark">
<el-input v-model="progressForm.remark" type="textarea" placeholder="请输入备注" rows="3" /> <el-input v-model="progressForm.remark" type="textarea" placeholder="请输入备注" rows="3" />
@ -135,15 +131,13 @@
</el-dialog> </el-dialog>
<!-- 分页组件 --> <!-- 分页组件 -->
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
v-model:limit="queryParams.pageSize" @pagination="getList" />
</el-card> </el-card>
<!-- 新增/修改任务弹窗 --> <!-- 新增/修改任务弹窗 -->
<el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body destroy-on-close> <el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body destroy-on-close>
<el-form ref="masterFormRef" :model="form" :rules="rules" label-width="100px"> <el-form ref="masterFormRef" :model="form" :rules="rules" label-width="100px">
<el-input v-model="form.projectId" placeholder="请输入项目ID" :readonly="!!currentProjectId" <el-input v-model="form.projectId" placeholder="请输入项目ID" :readonly="!!currentProjectId" :disabled="!!currentProjectId" v-if="false" />
:disabled="!!currentProjectId" v-if="false" />
<template #help> <template #help>
<span v-if="currentProjectId" class="text-success">已自动关联当前选中项目</span> <span v-if="currentProjectId" class="text-success">已自动关联当前选中项目</span>
</template> </template>
@ -152,17 +146,14 @@
</el-form-item> </el-form-item>
<el-form-item label="执行人姓名" prop="userId"> <el-form-item label="执行人姓名" prop="userId">
<el-select v-model="form.userId" placeholder="请选择执行人姓名" clearable style="width: 100%"> <el-select v-model="form.userId" placeholder="请选择执行人姓名" clearable style="width: 100%">
<el-option v-for="item in slaveOptions" :key="item.id" :label="item.nickName" <el-option v-for="item in slaveOptions" :key="item.id" :label="item.nickName" :value="item.userId"></el-option>
:value="item.userId"></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="计划完成时间" prop="pcd"> <el-form-item label="计划完成时间" prop="pcd">
<el-date-picker clearable v-model="form.pcd" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" <el-date-picker clearable v-model="form.pcd" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择计划完成时间" />
placeholder="请选择计划完成时间" />
</el-form-item> </el-form-item>
<el-form-item label="实际完成时间" prop="act"> <el-form-item label="实际完成时间" prop="act">
<el-date-picker clearable v-model="form.act" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" <el-date-picker clearable v-model="form.act" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择实际完成时间" />
placeholder="请选择实际完成时间" />
</el-form-item> </el-form-item>
<el-form-item label="任务描述" prop="describe"> <el-form-item label="任务描述" prop="describe">
<el-input v-model="form.describe" type="textarea" placeholder="请输入任务描述" /> <el-input v-model="form.describe" type="textarea" placeholder="请输入任务描述" />
@ -244,7 +235,7 @@ interface ProgressDetail {
updateTime?: string; updateTime?: string;
projectId?: string | number; projectId?: string | number;
} }
interface ProgressForm extends Omit<ProgressDetail, 'updateTime'> { } interface ProgressForm extends Omit<ProgressDetail, 'updateTime'> {}
// 4. 获取组件实例 // 4. 获取组件实例
const { proxy } = getCurrentInstance() as ComponentInternalInstance; const { proxy } = getCurrentInstance() as ComponentInternalInstance;
@ -663,7 +654,7 @@ onUnmounted(() => {
width: 120px !important; width: 120px !important;
} }
.el-table-column .el-button--text+.el-button--text { .el-table-column .el-button--text + .el-button--text {
margin-left: 10px; margin-left: 10px;
} }
</style> </style>

View File

@ -4,165 +4,211 @@
<div v-show="showSearch" class="mb-[10px]"> <div v-show="showSearch" class="mb-[10px]">
<el-card shadow="hover"> <el-card shadow="hover">
<el-form ref="queryFormRef" :model="queryParams" :inline="true"> <el-form ref="queryFormRef" :model="queryParams" :inline="true">
<el-form-item label="请选择方阵" prop="pid" label-width="100"> <el-form-item label="请选择项目" prop="pid" label-width="100">
<!-- <el-input v-model="queryParams.pid" placeholder="请选择" clearable /> --> <el-select v-model="queryParams.projectId" placeholder="请选择" @change="handleChange" clearable>
<el-cascader <el-option v-for="item in matrixOptions" :key="item.projectId" :label="item.name" :value="item.projectId" />
:options="matrixOptions" </el-select>
placeholder="请选择" </el-form-item>
@change="handleChange" <el-form-item label="请选择方阵:" prop="pid" label-width="100" v-if="relevancyStructure == '2'">
:props="{ value: 'matrixId', label: 'name' }" <el-select v-model="matrixValue" placeholder="请选择" @change="handleChange" clearable>
v-model="queryParams.matrixId" <el-option v-for="item in matrixList" :key="item.id" :label="item.matrixName" :value="item.id" />
clearable </el-select>
/>
<!-- <el-select v-model="matrixValue" placeholder="请选择" @change="handleChange" clearable>
<el-option v-for="item in matrixOptions" :key="item.id" :label="item.matrixName" :value="item.id" />
</el-select> -->
</el-form-item> </el-form-item>
<!-- <el-form-item>
<el-button type="primary" icon="Download" @click="handleQuery">导出周报</el-button>
</el-form-item> -->
</el-form> </el-form>
</el-card> </el-card>
</div> </div>
</transition> </transition>
<el-tabs type="border-card" v-model="activeTab" @tab-click="handleTabClick">
<el-card shadow="never"> <el-tab-pane :label="item.name" v-for="item in tabList" :key="item.id" :name="item.id"></el-tab-pane>
<!-- <template #header> <el-card shadow="never">
<el-row :gutter="10" class="mb8"> <el-table
<el-col :span="1.5"> ref="progressCategoryTableRef"
<el-button type="primary" plain icon="Plus" @click="handleAdd()" v-hasPermi="['progress:progressCategory:add']">新增</el-button> v-loading="loading"
</el-col> :data="progressCategoryList"
<el-col :span="1.5"> row-key="id"
<el-button type="info" plain icon="Sort" @click="handleToggleExpandAll">展开/折叠</el-button> :default-expand-all="isExpandAll"
</el-col> :tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar> v-if="isExpand"
</el-row> border
</template> --> >
<el-table <el-table-column label="" width="50" type="expand">
ref="progressCategoryTableRef" <template #header>
v-loading="loading" <el-icon
:data="progressCategoryList" class="cursor-pointer text-4! transform-rotate-z--90 transition-all-300"
row-key="id" :class="!isExpandAll ? 'transform-rotate-z--90' : 'transform-rotate-z-90'"
:default-expand-all="isExpandAll" @click="handleToggleExpandAll"
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }" ><Expand
border /></el-icon>
> </template>
<el-table-column label="" width="50" type="expand"> <template #default="scope">
<template #header> <el-card class="pl-25" shadow="hover">
<el-icon <el-table :data="scope.row.children" border>
class="cursor-pointer text-4! transform-rotate-z--90 transition-all-300" <el-table-column label="名称" align="center" prop="name" width="170">
:class="!isExpandAll ? 'transform-rotate-z--90' : 'transform-rotate-z-90'" <template #default="{ row }">
@click="handleToggleExpandAll" <el-tooltip :content="row.remark" placement="top" effect="dark" v-if="row.remark">
><Expand <span class="flex items-center justify-center"
/></el-icon> ><i class="iconfont icon-wenhao mr-0.5 text-3.5! text-#999"></i>{{ row.name }}</span
</template> >
<template #default="scope"> </el-tooltip>
<el-card class="pl-25" shadow="hover"> <span v-else>{{ row.name }}</span>
<el-table :data="scope.row.children" border> </template>
<el-table-column label="名称" align="center" prop="name" width="170"> </el-table-column>
<template #default="{ row }"> <el-table-column label="状态" align="center" prop="status" width="100">
<el-tooltip :content="row.remark" placement="top" effect="dark" v-if="row.remark"> <template #default="{ row }">
<span class="flex items-center justify-center" <dict-tag :options="progress_status" :value="row.status" />
><i class="iconfont icon-wenhao mr-0.5 text-3.5! text-#999"></i>{{ row.name }}</span </template>
</el-table-column>
<el-table-column label="是否延期" align="center" prop="isDelay" width="100">
<template #default="{ row }">
<el-tag :type="row.isDelay == '1' ? 'danger' : 'primary'">{{ row.isDelay == '1' ? '是' : '否' }}</el-tag>
</template>
</el-table-column>
<el-table-column label="计量方式" align="center" prop="unitType" width="100">
<template #default="{ row }">
<dict-tag :options="progress_unit_type" :value="row.unitType" />
</template>
</el-table-column>
<el-table-column label="总量" align="center" prop="total" width="100" />
<el-table-column label="总进度" align="center" prop="projectId">
<template #default="{ row }">
<el-progress :text-inside="true" :stroke-width="20" :percentage="row.completedPercentage" status="success" />
</template>
</el-table-column>
<el-table-column label="计划总量" align="center" prop="planTotal" width="100" />
<el-table-column label="计划中" align="center" prop="projectId">
<template #default="{ row }">
<el-progress :text-inside="true" :stroke-width="20" :percentage="row.planTotalPercentage" />
</template>
</el-table-column>
<el-table-column label="对比" align="center" prop="unitType" width="100">
<template #default="{ row }">
{{ row.completed + '/' + row.total }}
</template>
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="200">
<template #default="scope">
<el-button
type="warning"
icon="Download"
link
size="small"
v-if="scope.row.name === '光伏板'"
@click="openDialog(scope.row, 'importTableStatus', '上传表格')"
v-hasPermi="['progress:progressCategory:add']"
> >
</el-tooltip> 导入表格
<span v-else>{{ row.name }}</span> </el-button>
</template> <el-button
</el-table-column> type="success"
<el-table-column label="状态" align="center" prop="status" width="100"> icon="Plus"
<template #default="{ row }"> link
<dict-tag :options="progress_status" :value="row.status" /> size="small"
</template> @click="planRef.openDialog(scope.row)"
</el-table-column> v-hasPermi="['progress:progressCategory:add']"
<el-table-column label="是否延期" align="center" prop="isDelay" width="100"> >
<template #default="{ row }"> 计划
<el-tag :type="row.isDelay == '1' ? 'danger' : 'primary'">{{ row.isDelay == '1' ? '是' : '否' }}</el-tag> </el-button>
</template> <el-button
</el-table-column> type="primary"
<el-table-column label="计量方式" align="center" prop="unitType" width="100"> icon="Plus"
<template #default="{ row }"> link
<dict-tag :options="progress_unit_type" :value="row.unitType" /> size="small"
</template> @click="handleDayAdd(scope.row)"
</el-table-column> v-hasPermi="['progress:progressCategory:add']"
<el-table-column label="总量" align="center" prop="total" width="100" /> >
<el-table-column label="总进度" align="center" prop="projectId"> 日报
<template #default="{ row }"> </el-button>
<el-progress :text-inside="true" :stroke-width="20" :percentage="row.completedPercentage" status="success" /> </template>
</template> </el-table-column>
</el-table-column> </el-table>
<el-table-column label="计划总量" align="center" prop="planTotal" width="100" /> </el-card>
<el-table-column label="计划中" align="center" prop="projectId"> </template>
<template #default="{ row }"> </el-table-column>
<el-progress :text-inside="true" :stroke-width="20" :percentage="row.planTotalPercentage" /> <el-table-column label="名称" align="center" prop="name" width="150" />
</template> <el-table-column label="状态" align="center" prop="status" width="100">
</el-table-column> <template #default="{ row }">
<el-table-column label="对比" align="center" prop="unitType" width="100"> <dict-tag :options="progress_status" :value="row.status" />
<template #default="{ row }"> </template>
{{ row.completed + '/' + row.total }} </el-table-column>
</template> <el-table-column label="总进度" align="center" prop="projectId">
</el-table-column> <template #default="{ row }">
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="200"> <el-progress :text-inside="true" :stroke-width="20" :percentage="row.completedPercentage" status="success" />
<template #default="scope"> </template>
<!-- <el-button </el-table-column>
type="warning" </el-table>
icon="Download" <el-table ref="progressCategoryTableRef" v-loading="loading" :data="progressCategoryList" v-else border>
link <el-table-column label="名称" align="center" prop="name" width="170">
size="small" <template #default="{ row }">
@click="openDialog(scope.row, 'importDataStatus', '上传数据')" <el-tooltip :content="row.remark" placement="top" effect="dark" v-if="row.remark">
v-hasPermi="['progress:progressCategory:add']" <span class="flex items-center justify-center"><i class="iconfont icon-wenhao mr-0.5 text-3.5! text-#999"></i>{{ row.name }}</span>
> </el-tooltip>
导入数据 <span v-else>{{ row.name }}</span>
</el-button> --> </template>
<el-button </el-table-column>
type="warning" <el-table-column label="状态" align="center" prop="status" width="100">
icon="Download" <template #default="{ row }">
link <dict-tag :options="progress_status" :value="row.status" />
size="small" </template>
v-if="scope.row.name === '光伏板'" </el-table-column>
@click="openDialog(scope.row, 'importTableStatus', '上传表格')" <el-table-column label="是否延期" align="center" prop="isDelay" width="100">
v-hasPermi="['progress:progressCategory:add']" <template #default="{ row }">
> <el-tag :type="row.isDelay == '1' ? 'danger' : 'primary'">{{ row.isDelay == '1' ? '是' : '否' }}</el-tag>
导入表格 </template>
</el-button> </el-table-column>
<el-button <el-table-column label="计量方式" align="center" prop="unitType" width="100">
type="success" <template #default="{ row }">
icon="Plus" <dict-tag :options="progress_unit_type" :value="row.unitType" />
link </template>
size="small" </el-table-column>
@click="planRef.openDialog(scope.row)" <el-table-column label="总量" align="center" prop="total" width="100" />
v-hasPermi="['progress:progressCategory:add']" <el-table-column label="总进度" align="center" prop="projectId">
> <template #default="{ row }">
计划 <el-progress :text-inside="true" :stroke-width="20" :percentage="row.completedPercentage" status="success" />
</el-button> </template>
<el-button </el-table-column>
type="primary" <el-table-column label="计划总量" align="center" prop="planTotal" width="100" />
icon="Plus" <el-table-column label="计划中" align="center" prop="projectId">
link <template #default="{ row }">
size="small" <el-progress :text-inside="true" :stroke-width="20" :percentage="row.planTotalPercentage" />
@click="handleDayAdd(scope.row)" </template>
v-hasPermi="['progress:progressCategory:add']" </el-table-column>
> <el-table-column label="对比" align="center" prop="unitType" width="100">
日报 <template #default="{ row }">
</el-button> {{ row.completed + '/' + row.total }}
</template> </template>
</el-table-column> </el-table-column>
</el-table> <el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="200">
</el-card> <template #default="scope">
</template> <el-button
</el-table-column> type="warning"
<el-table-column label="名称" align="center" prop="name" width="150" /> icon="Download"
<el-table-column label="状态" align="center" prop="status" width="100"> link
<template #default="{ row }"> size="small"
<dict-tag :options="progress_status" :value="row.status" /> v-if="scope.row.name === '光伏板'"
</template> @click="openDialog(scope.row, 'importTableStatus', '上传表格')"
</el-table-column> v-hasPermi="['progress:progressCategory:add']"
<el-table-column label="总进度" align="center" prop="projectId"> >
<template #default="{ row }"> 导入表格
<el-progress :text-inside="true" :stroke-width="20" :percentage="row.completedPercentage" status="success" /> </el-button>
</template> <el-button
</el-table-column> type="success"
</el-table> icon="Plus"
</el-card> link
size="small"
@click="planRef.openDialog(scope.row)"
v-hasPermi="['progress:progressCategory:add']"
>
计划
</el-button>
<el-button type="primary" icon="Plus" link size="small" @click="handleDayAdd(scope.row)" v-hasPermi="['progress:progressCategory:add']">
日报
</el-button>
</template>
</el-table-column>
</el-table>
</el-card>
</el-tabs>
<!-- 导入数据对话框 --> <!-- 导入数据对话框 -->
<el-dialog :title="dialog.title" v-model="dialog.importDataStatus" width="500px" append-to-body> <el-dialog :title="dialog.title" v-model="dialog.importDataStatus" width="500px" append-to-body>
<file-upload class="pl-20 pt" v-model="dialog.file" :limit="20" :file-size="50" :file-type="['shp', 'shx', 'dbf']" /> <file-upload class="pl-20 pt" v-model="dialog.file" :limit="20" :file-size="50" :file-type="['shp', 'shx', 'dbf']" />
@ -191,14 +237,7 @@
</template> </template>
<script setup name="ProgressCategory" lang="ts"> <script setup name="ProgressCategory" lang="ts">
import { import { getProgressCategory, delProgressCategory, addProgressCategory, updateProgressCategory, getProjectSquare } from '@/api/progress/plan/index';
listProgressCategory,
getProgressCategory,
delProgressCategory,
addProgressCategory,
updateProgressCategory,
getProjectSquare
} from '@/api/progress/plan/index';
import { ProgressCategoryVO, ProgressCategoryQuery, ProgressCategoryForm } from '@/api/progress/plan/types'; import { ProgressCategoryVO, ProgressCategoryQuery, ProgressCategoryForm } from '@/api/progress/plan/types';
const { proxy } = getCurrentInstance() as ComponentInternalInstance; const { proxy } = getCurrentInstance() as ComponentInternalInstance;
@ -214,6 +253,7 @@ type ProgressCategoryOption = {
}; };
import { useUserStoreHook } from '@/store/modules/user'; import { useUserStoreHook } from '@/store/modules/user';
import { getCategoryTabList, listProgressCategory } from '@/api/progress/progressCategory';
// 获取用户 store // 获取用户 store
const userStore = useUserStoreHook(); const userStore = useUserStoreHook();
// 从 store 中获取项目列表和当前选中的项目 // 从 store 中获取项目列表和当前选中的项目
@ -239,6 +279,11 @@ const dialog = reactive<any>({
title: '', title: '',
file: '' file: ''
}); });
const isExpand = ref(true);
const activeTab = ref('0');
const relevancyStructure = ref('1');
const matrixList = ref([]);
const tabList = ref<any[]>([]);
const matrixValue = ref<number | undefined>(matrixOptions.value.length > 0 ? matrixOptions.value[0].id : undefined); const matrixValue = ref<number | undefined>(matrixOptions.value.length > 0 ? matrixOptions.value[0].id : undefined);
const initFormData: ProgressCategoryForm = { const initFormData: ProgressCategoryForm = {
id: undefined, id: undefined,
@ -255,7 +300,7 @@ const data = reactive<PageData<ProgressCategoryForm, ProgressCategoryQuery>>({
pid: undefined, pid: undefined,
name: undefined, name: undefined,
unitType: undefined, unitType: undefined,
projectId: currentProject.value?.id, projectId: undefined,
matrixId: undefined, matrixId: undefined,
params: {} params: {}
}, },
@ -272,7 +317,7 @@ const { queryParams, form, rules } = toRefs(data);
/** 查询进度类别列表 */ /** 查询进度类别列表 */
const getList = async () => { const getList = async () => {
if (!queryParams.value.matrixId) { if (!queryParams.value.projectId) {
const res = await getProjectSquare(currentProject.value?.id); const res = await getProjectSquare(currentProject.value?.id);
if (!res.data || res.data.length === 0) { if (!res.data || res.data.length === 0) {
proxy?.$modal.msgWarning('当前项目下没有方阵,请先创建方阵'); proxy?.$modal.msgWarning('当前项目下没有方阵,请先创建方阵');
@ -286,7 +331,13 @@ const getList = async () => {
try { try {
if (!matrixValue.value) matrixValue.value = matrixList[0].id; if (!matrixValue.value) matrixValue.value = matrixList[0].id;
matrixOptions.value = matrixList; matrixOptions.value = matrixList;
queryParams.value.matrixId = matrixList[0].children[0].matrixId; console.log('🚀 ~ getList ~ matrixList:', matrixList);
queryParams.value.projectId = matrixList[0].projectId;
form.value.projectId = matrixList[0].projectId;
await getCategoryTabList(queryParams.value.projectId as string).then((res) => {
tabList.value = res.data;
activeTab.value = res.data[0]?.id;
});
} catch (error) { } catch (error) {
// proxy?.$modal.msgError('获取方阵失败'); // proxy?.$modal.msgError('获取方阵失败');
} }
@ -294,10 +345,20 @@ const getList = async () => {
} }
loading.value = true; loading.value = true;
try { try {
const res = await listProgressCategory(queryParams.value); const id = relevancyStructure.value == '2' ? matrixValue.value : activeTab.value;
const res = await listProgressCategory(id);
const data = proxy?.handleTree<ProgressCategoryVO>(res.data, 'id', 'parentId'); const data = proxy?.handleTree<ProgressCategoryVO>(res.data, 'id', 'parentId');
if (data) { if (data) {
if (data.every((item) => !item.children)) {
isExpand.value = false;
} else {
isExpand.value = true;
}
progressCategoryList.value = data; progressCategoryList.value = data;
progressCategoryOptions.value = [];
const datas: ProgressCategoryOption = { id: 0, name: '顶级节点', children: [...data] };
progressCategoryOptions.value.push(datas);
loading.value = false;
} }
} finally { } finally {
// 不管成功或失败,最后都设置为 false // 不管成功或失败,最后都设置为 false
@ -305,13 +366,19 @@ const getList = async () => {
} }
}; };
/** 查询进度类别下拉树结构 */ const handleTabClick = (tab: any) => {
const getTreeselect = async () => { const id = tab.props.name; // 实际上就是 item.id
const res = await listProgressCategory(); const current = tabList.value.find((item) => item.id === id);
progressCategoryOptions.value = []; if (current.matrixStructureList && current.matrixStructureList.length > 0) {
const data: ProgressCategoryOption = { id: 0, name: '顶级节点', children: [] }; matrixList.value = current.matrixStructureList;
data.children = proxy?.handleTree<ProgressCategoryOption>(res.data, 'id', 'pid'); activeTab.value = current.matrixStructureList[0].id;
progressCategoryOptions.value.push(data); matrixValue.value = current.matrixStructureList[0].id;
} else {
activeTab.value = current.id;
}
relevancyStructure.value = current.relevancyStructure;
getList();
}; };
// 取消按钮 // 取消按钮
@ -383,7 +450,6 @@ const toggleExpandAll = (data: ProgressCategoryVO[], status: boolean) => {
/** 修改按钮操作 */ /** 修改按钮操作 */
const handleUpdate = async (row: ProgressCategoryVO) => { const handleUpdate = async (row: ProgressCategoryVO) => {
reset(); reset();
await getTreeselect();
if (row != null) { if (row != null) {
form.value.pid = row.pid; form.value.pid = row.pid;
} }

View File

@ -4,112 +4,117 @@
<div v-show="showSearch" class="mb-[10px]"> <div v-show="showSearch" class="mb-[10px]">
<el-card shadow="hover"> <el-card shadow="hover">
<el-form ref="queryFormRef" :model="queryParams" :inline="true"> <el-form ref="queryFormRef" :model="queryParams" :inline="true">
<el-form-item label="请选择方阵" prop="pid" label-width="100"> <el-form-item label="请选择项目" prop="pid" label-width="100">
<!-- <el-input v-model="queryParams.pid" placeholder="请选择" clearable /> --> <el-select v-model="queryParams.projectId" placeholder="请选择" @change="handleChange" clearable>
<el-cascader <el-option v-for="item in matrixOptions" :key="item.projectId" :label="item.name" :value="item.projectId" />
:options="matrixOptions" </el-select>
ref="treeRef" </el-form-item>
placeholder="请选择" <el-form-item label="请选择方阵:" prop="pid" label-width="100" v-if="relevancyStructure == '2'">
@change="handleChange" <el-select v-model="matrixValue" placeholder="请选择" @change="handleChange" clearable>
:props="{ value: 'matrixId', label: 'name' }" <el-option v-for="item in matrixList" :key="item.id" :label="item.matrixName" :value="item.id" />
v-model="queryParams.matrixId" </el-select>
clearable
/>
<!-- <el-select v-model="matrixValue" placeholder="请选择" @change="handleChange" clearable>
<el-option v-for="item in matrixOptions" :key="item.id" :label="item.matrixName" :value="item.id" />
</el-select> -->
</el-form-item> </el-form-item>
</el-form> </el-form>
</el-card> </el-card>
</div> </div>
</transition> </transition>
<el-tabs type="border-card" v-model="activeTab" @tab-click="handleTabClick">
<el-tab-pane :label="item.name" v-for="item in tabList" :key="item.id" :name="item.id"></el-tab-pane>
<el-card shadow="never">
<template #header>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button type="primary" plain icon="Plus" @click="handleAdd()">新增</el-button>
</el-col>
<el-col :span="1.5">
<file-upload
upload-url="/progress/progressCategory/import"
v-model="file"
:limit="1"
:file-type="['xls', 'xlsx']"
:on-upload-success="handleSuccess"
>
<el-button type="primary" plain icon="Compass">导入</el-button>
</file-upload>
</el-col>
<el-col :span="1.5">
<el-button type="primary" plain icon="Filter" @click="handleExport">导出</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="info" plain icon="Sort" @click="handleToggleExpandAll">展开/折叠</el-button>
</el-col>
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
</template>
<el-table
ref="progressCategoryTableRef"
v-loading="loading"
:data="progressCategoryList"
row-key="id"
:default-expand-all="isExpandAll"
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
>
<!-- <el-table-column label="父类别id" prop="parentId" /> -->
<el-table-column label="类别名称" prop="name" width="230" />
<el-table-column label="计量方式" align="center" prop="unitType">
<template #default="{ row }">
<dict-tag :options="progress_unit_type" :value="row.unitType" v-if="row.parentId != 0" />
<span v-else></span>
</template>
</el-table-column>
<el-table-column label="计量单位" align="center" prop="unit">
<template #default="{ row }">
{{ row.parentId == 0 ? '' : row.unit }}
</template>
</el-table-column>
<el-table-column label="综合单价(业主)" align="center" prop="ownerPrice">
<template #default="{ row }">
{{ row.parentId == 0 ? '' : row.ownerPrice }}
</template>
</el-table-column>
<el-table-column label="综合单价(分包)" align="center" prop="constructionPrice">
<template #default="{ row }">
{{ row.parentId == 0 ? '' : row.constructionPrice }}
</template>
</el-table-column>
<el-table-column label="产值金额(业主)" align="center" prop="ownerOutputValue">
<template #default="{ row }">
{{ row.parentId == 0 ? '' : row.ownerOutputValue }}
</template>
</el-table-column>
<el-table-column label="产值金额(分包)" align="center" prop="constructionOutputValue">
<template #default="{ row }">
{{ row.parentId == 0 ? '' : row.constructionOutputValue }}
</template>
</el-table-column>
<el-table-column label="总数量" align="center" prop="total">
<template #default="{ row }">
{{ row.parentId == 0 ? '' : row.total }}
</template>
</el-table-column>
<el-table-column label="关联结构" align="center" prop="relevancyStructure" width="100">
<template #default="{ row }">
<el-tag :type="row.relevancyStructure == '1' ? 'primary' : 'success'">
{{ row.relevancyStructure == '1' ? '子项目' : '方阵' }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template #default="scope">
<div>
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['progress:progressCategory:edit']">
修改
</el-button>
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['progress:progressCategory:remove']">
删除
</el-button>
</div>
</template>
</el-table-column>
</el-table>
</el-card>
</el-tabs>
<el-card shadow="never">
<template #header>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button type="primary" plain icon="Plus" @click="handleAdd">新增</el-button>
</el-col>
<el-col :span="1.5">
<file-upload
upload-url="/progress/progressCategory/import"
v-model="file"
:limit="1"
:file-type="['xls', 'xlsx']"
:on-upload-success="handleSuccess"
>
<el-button type="primary" plain icon="Compass">导入</el-button>
</file-upload>
</el-col>
<el-col :span="1.5">
<el-button type="primary" plain icon="Filter" @click="handleExport">导出</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="info" plain icon="Sort" @click="handleToggleExpandAll">展开/折叠</el-button>
</el-col>
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
</template>
<el-table
ref="progressCategoryTableRef"
v-loading="loading"
:data="progressCategoryList"
row-key="id"
:default-expand-all="isExpandAll"
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
>
<!-- <el-table-column label="父类别id" prop="parentId" /> -->
<el-table-column label="类别名称" prop="name" width="230" />
<el-table-column label="计量方式" align="center" prop="unitType">
<template #default="{ row }">
<dict-tag :options="progress_unit_type" :value="row.unitType" v-if="row.parentId != 0" />
<span v-else></span>
</template>
</el-table-column>
<el-table-column label="计量单位" align="center" prop="unit">
<template #default="{ row }">
{{ row.parentId == 0 ? '' : row.unit }}
</template>
</el-table-column>
<el-table-column label="综合单价(业主)" align="center" prop="ownerPrice">
<template #default="{ row }">
{{ row.parentId == 0 ? '' : row.ownerPrice }}
</template>
</el-table-column>
<el-table-column label="综合单价(分包)" align="center" prop="constructionPrice">
<template #default="{ row }">
{{ row.parentId == 0 ? '' : row.constructionPrice }}
</template>
</el-table-column>
<el-table-column label="产值金额(业主)" align="center" prop="ownerOutputValue">
<template #default="{ row }">
{{ row.parentId == 0 ? '' : row.ownerOutputValue }}
</template>
</el-table-column>
<el-table-column label="产值金额(分包)" align="center" prop="constructionOutputValue">
<template #default="{ row }">
{{ row.parentId == 0 ? '' : row.constructionOutputValue }}
</template>
</el-table-column>
<el-table-column label="总数量" align="center" prop="total">
<template #default="{ row }">
{{ row.parentId == 0 ? '' : row.total }}
</template>
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template #default="scope">
<div>
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['progress:progressCategory:edit']">
修改
</el-button>
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['progress:progressCategory:remove']">
删除
</el-button>
</div>
</template>
</el-table-column>
</el-table>
</el-card>
<!-- 添加或修改分项工程单价对话框 --> <!-- 添加或修改分项工程单价对话框 -->
<el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body> <el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
<el-form ref="progressCategoryFormRef" :model="form" :rules="rules" label-width="120px"> <el-form ref="progressCategoryFormRef" :model="form" :rules="rules" label-width="120px">
@ -123,31 +128,37 @@
check-strictly check-strictly
/> />
</el-form-item> </el-form-item>
<el-form-item label="计量方式" prop="unitType" v-if="!form.id"> <el-form-item label="计量方式" prop="unitType" v-if="!form.workType">
<el-select v-model="form.unitType" placeholder="请选择关联数据"> <el-select v-model="form.unitType" placeholder="请选择关联数据">
<el-option v-for="dict in progress_unit_type" :key="dict.value" :label="dict.label" :value="dict.value" /> <el-option v-for="dict in progress_unit_type" :key="dict.value" :label="dict.label" :value="dict.value" />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="类别名称" prop="name"> <el-form-item label="类别名称" prop="name">
<el-input v-model="form.name" placeholder="请输入类别名称" :disabled="form.id != null" /> <el-input v-model="form.name" placeholder="请输入类别名称" />
</el-form-item> </el-form-item>
<el-form-item label="计量单位" prop="unit"> <el-form-item label="计量单位" prop="unit" v-if="form.unitType != '0'">
<el-input v-model="form.unit" placeholder="请输入计量单位" /> <el-input v-model="form.unit" placeholder="请输入计量单位" />
</el-form-item> </el-form-item>
<el-form-item label="综合单价(业主)" prop="ownerPrice"> <el-form-item label="综合单价(业主)" prop="ownerPrice" v-if="form.unitType != '0'">
<el-input v-model="form.ownerPrice" placeholder="请输入综合单价(业主)" /> <el-input v-model="form.ownerPrice" placeholder="请输入综合单价(业主)" />
</el-form-item> </el-form-item>
<el-form-item label="综合单价(分包)" prop="constructionPrice"> <el-form-item label="综合单价(分包)" prop="constructionPrice" v-if="form.unitType != '0'">
<el-input v-model="form.constructionPrice" placeholder="请输入综合单价(分包)" /> <el-input v-model="form.constructionPrice" placeholder="请输入综合单价(分包)" />
</el-form-item> </el-form-item>
<el-form-item label="数量" prop="total" v-if="isDisabled"> <el-form-item label="数量" prop="total" v-if="!form.workType && form.unitType != '0'">
<el-input v-model="form.total" placeholder="请输入数量" /> <el-input v-model="form.total" placeholder="请输入数量" />
</el-form-item> </el-form-item>
<el-form-item label="关联数据" prop="workType" v-if="!form.id"> <el-form-item label="关联数据" prop="workType" v-if="!form.id && form.unitType != '0'">
<el-select v-model="form.workType" placeholder="请选择关联数据"> <el-select v-model="form.workType" placeholder="请选择关联数据">
<el-option v-for="dict in progress_work_type" :key="dict.value" :label="dict.label" :value="dict.value" /> <el-option v-for="dict in progress_work_type" :key="dict.value" :label="dict.label" :value="dict.value" />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="关联结构" prop="relevancyStructure">
<el-select v-model="form.relevancyStructure" value-key="" placeholder="请选择关联结构" clearable filterable @change="">
<el-option label="子项目" value="1"></el-option>
<el-option label="方阵" value="2"></el-option>
</el-select>
</el-form-item>
<el-form-item label="备注" prop="remark" v-if="!form.id"> <el-form-item label="备注" prop="remark" v-if="!form.id">
<el-input v-model="form.remark" placeholder="请输入备注" /> <el-input v-model="form.remark" placeholder="请输入备注" />
</el-form-item> </el-form-item>
@ -173,14 +184,20 @@ import {
delProgressCategory, delProgressCategory,
addProgressCategory, addProgressCategory,
updateProgressCategory, updateProgressCategory,
downloadProgressCategory downloadProgressCategory,
getCategoryTabList,
getCategoryList
} from '@/api/progress/progressCategory'; } from '@/api/progress/progressCategory';
import { ProgressCategoryVO, ProgressCategoryQuery, ProgressCategoryForm } from '@/api/progress/progressCategory/types'; import { ProgressCategoryVO, ProgressCategoryQuery, ProgressCategoryForm } from '@/api/progress/progressCategory/types';
import { getTabList } from '@/api/progress/progressCategoryTemplate';
import { useUserStoreHook } from '@/store/modules/user'; import { useUserStoreHook } from '@/store/modules/user';
const { proxy } = getCurrentInstance() as ComponentInternalInstance; const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const { progress_unit_type, progress_work_type } = toRefs<any>(proxy?.useDict('progress_unit_type', 'progress_work_type')); const { progress_unit_type, progress_work_type } = toRefs<any>(proxy?.useDict('progress_unit_type', 'progress_work_type'));
const activeTab = ref('0');
const relevancyStructure = ref('1');
const matrixList = ref([]);
const tabList = ref<any[]>([]);
// 获取用户 store // 获取用户 store
const userStore = useUserStoreHook(); const userStore = useUserStoreHook();
// 从 store 中获取项目列表和当前选中的项目 // 从 store 中获取项目列表和当前选中的项目
@ -219,6 +236,8 @@ const initFormData: ProgressCategoryForm = {
unitType: undefined, unitType: undefined,
unit: undefined, unit: undefined,
constructionPrice: undefined, constructionPrice: undefined,
relevancyStructure: undefined,
ownerPrice: undefined, ownerPrice: undefined,
unitPrice: undefined, unitPrice: undefined,
outputValue: undefined, outputValue: undefined,
@ -235,7 +254,7 @@ const data = reactive<PageData<ProgressCategoryForm, ProgressCategoryQuery>>({
form: { ...initFormData }, form: { ...initFormData },
queryParams: { queryParams: {
parentId: undefined, parentId: undefined,
projectId: currentProject.value?.id, projectId: undefined,
matrixId: undefined, matrixId: undefined,
matrixName: undefined, matrixName: undefined,
@ -264,7 +283,8 @@ const data = reactive<PageData<ProgressCategoryForm, ProgressCategoryQuery>>({
isDelay: [{ required: true, message: '是否超期不能为空', trigger: 'blur' }], isDelay: [{ required: true, message: '是否超期不能为空', trigger: 'blur' }],
status: [{ required: true, message: '完成状态不能为空', trigger: 'change' }], status: [{ required: true, message: '完成状态不能为空', trigger: 'change' }],
constructionPrice: [{ required: true, message: '综合单价(分包)不能为空', trigger: 'change' }], constructionPrice: [{ required: true, message: '综合单价(分包)不能为空', trigger: 'change' }],
ownerPrice: [{ required: true, message: '综合单价(业主)不能为空', trigger: 'change' }] ownerPrice: [{ required: true, message: '综合单价(业主)不能为空', trigger: 'change' }],
relevancyStructure: [{ required: true, message: '关联结构不能为空', trigger: 'change' }]
} }
}); });
@ -273,7 +293,7 @@ const matrixIdList = ref([]);
/** 查询分项工程单价列表 */ /** 查询分项工程单价列表 */
const getList = async () => { const getList = async () => {
if (!queryParams.value.matrixId) { if (!queryParams.value.projectId) {
const res = await getProjectSquare(currentProject.value?.id); const res = await getProjectSquare(currentProject.value?.id);
if (res.data.length === 0) { if (res.data.length === 0) {
proxy?.$modal.msgWarning('当前项目下没有方阵,请先创建方阵'); proxy?.$modal.msgWarning('当前项目下没有方阵,请先创建方阵');
@ -286,17 +306,26 @@ const getList = async () => {
}); });
if (!matrixValue.value) matrixValue.value = matrixList[0].id; if (!matrixValue.value) matrixValue.value = matrixList[0].id;
matrixOptions.value = matrixList; matrixOptions.value = matrixList;
queryParams.value.matrixId = matrixList[0].children[0].matrixId; queryParams.value.projectId = matrixList[0].projectId;
form.value.projectId = matrixList[0].projectId; form.value.projectId = matrixList[0].projectId;
form.value.matrixId = matrixList[0].children[0].matrixId; // form.value.matrixId = matrixList[0].projectId;
await getCategoryTabList(queryParams.value.projectId as string).then((res) => {
tabList.value = res.data;
activeTab.value = res.data[0]?.id;
});
} }
} }
loading.value = true; loading.value = true;
try { try {
const res = await listProgressCategory(queryParams.value); const id = relevancyStructure.value == '2' ? matrixValue.value : activeTab.value;
const res = await listProgressCategory(id);
const data = proxy?.handleTree<ProgressCategoryVO>(res.data, 'id', 'parentId'); const data = proxy?.handleTree<ProgressCategoryVO>(res.data, 'id', 'parentId');
if (data) { if (data) {
progressCategoryList.value = data; progressCategoryList.value = data;
progressCategoryOptions.value = [];
const datas: ProgressCategoryOption = { id: 0, name: '顶级节点', children: [...data] };
progressCategoryOptions.value.push(datas);
console.log('🚀 ~ getList ~ progressCategoryOptions.value:', progressCategoryOptions.value);
loading.value = false; loading.value = false;
} }
} finally { } finally {
@ -311,11 +340,12 @@ const handleSuccess = () => {
/** 查询分项工程单价下拉树结构 */ /** 查询分项工程单价下拉树结构 */
const getTreeselect = async () => { const getTreeselect = async () => {
const res = await listProgressCategory(queryParams.value); // const id = relevancyStructure.value == '2' ? matrixValue.value : activeTab.value;
progressCategoryOptions.value = []; // const res = await getCategoryList(id);
const data: ProgressCategoryOption = { id: 0, name: '顶级节点', children: [] }; // progressCategoryOptions.value = [];
data.children = proxy?.handleTree<ProgressCategoryOption>(res.data, 'id', 'parentId'); // const data: ProgressCategoryOption = { id: 0, name: '顶级节点', children: [] };
progressCategoryOptions.value.push(data); // data.children = proxy?.handleTree<ProgressCategoryOption>(res.data, 'id', 'parentId');
// progressCategoryOptions.value.push(data);
}; };
// 取消按钮 // 取消按钮
@ -324,21 +354,30 @@ const cancel = () => {
dialog.visible = false; dialog.visible = false;
}; };
const handleTabClick = (tab: any) => {
const id = tab.props.name; // 实际上就是 item.id
const current = tabList.value.find((item) => item.id === id);
if (current.matrixStructureList && current.matrixStructureList.length > 0) {
matrixList.value = current.matrixStructureList;
activeTab.value = current.matrixStructureList[0].id;
matrixValue.value = current.matrixStructureList[0].id;
} else {
activeTab.value = current.id;
}
relevancyStructure.value = current.relevancyStructure;
getList();
};
// 表单重置 // 表单重置
const reset = () => { const reset = () => {
const projectId = form.value.projectId; const projectId = form.value.projectId;
const matrixId = form.value.matrixId; const matrixId = form.value.matrixId;
form.value = { ...initFormData, projectId, matrixId }; form.value = { ...initFormData, projectId, matrixId };
isDisabled.value = false;
progressCategoryFormRef.value?.resetFields(); progressCategoryFormRef.value?.resetFields();
}; };
/** 级联选择器改变事件 */ /** 级联选择器改变事件 */
const handleChange = (value: number) => { const handleChange = (value: string) => {
form.value.matrixId = value[1];
form.value.projectId = value[0];
queryParams.value.matrixId = value[1];
getList(); getList();
}; };
@ -381,12 +420,8 @@ const toggleExpandAll = (data: ProgressCategoryVO[], status: boolean) => {
}; };
/** 修改按钮操作 */ /** 修改按钮操作 */
const isDisabled = ref<boolean>(false);
const handleUpdate = async (row: ProgressCategoryVO) => { const handleUpdate = async (row: ProgressCategoryVO) => {
reset(); reset();
if (!row.unitType) {
isDisabled.value = true;
}
await getTreeselect(); await getTreeselect();
if (row != null) { if (row != null) {
form.value.parentId = row.parentId; form.value.parentId = row.parentId;

View File

@ -20,60 +20,72 @@
</el-card> </el-card>
</div> </div>
</transition> </transition>
<el-tabs type="border-card" v-model="activeTab" @tab-change="getList">
<el-tab-pane :label="item.name" v-for="item in tabList" :key="item.id" :name="item.id"></el-tab-pane>
<el-card shadow="never">
<template #header>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button type="primary" plain icon="Plus" @click="handleAdd()" v-hasPermi="['progress:progressCategoryTemplate:add']">新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="info" plain icon="Sort" @click="handleToggleExpandAll">展开/折叠</el-button>
</el-col>
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
</template>
<el-table
ref="progressCategoryTemplateTableRef"
v-loading="loading"
:data="progressCategoryTemplateList"
row-key="id"
:default-expand-all="isExpandAll"
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
>
<el-table-column label="类别名称" prop="name" />
<el-table-column label="计量方式" align="center" prop="unitType" width="100">
<template #default="{ row }">
<dict-tag :options="progress_unit_type" :value="row.unitType" />
</template>
</el-table-column>
<el-table-column label="关联数据" align="center" prop="workType">
<template #default="{ row }">
<dict-tag :options="progress_work_type" :value="row.workType" />
</template>
</el-table-column>
<el-table-column label="关联结构" align="center" prop="relevancyStructure" width="100">
<template #default="{ row }">
<el-tag :type="row.relevancyStructure == '1' ? 'primary' : 'success'">
{{ row.relevancyStructure == '1' ? '子项目' : '方阵' }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="备注" align="center" prop="remark" />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template #default="scope">
<el-tooltip content="修改" placement="top">
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['progress:progressCategoryTemplate:edit']" />
</el-tooltip>
<el-tooltip content="新增" placement="top">
<el-button link type="primary" icon="Plus" @click="handleAdd(scope.row)" v-hasPermi="['progress:progressCategoryTemplate:add']" />
</el-tooltip>
<el-tooltip content="删除" placement="top">
<el-button
link
type="primary"
icon="Delete"
@click="handleDelete(scope.row)"
v-hasPermi="['progress:progressCategoryTemplate:remove']"
/>
</el-tooltip>
</template>
</el-table-column>
</el-table>
</el-card>
</el-tabs>
<el-card shadow="never">
<template #header>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button type="primary" plain icon="Plus" @click="handleAdd()" v-hasPermi="['progress:progressCategoryTemplate:add']">新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="info" plain icon="Sort" @click="handleToggleExpandAll">展开/折叠</el-button>
</el-col>
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
</template>
<el-table
ref="progressCategoryTemplateTableRef"
v-loading="loading"
:data="progressCategoryTemplateList"
row-key="id"
:default-expand-all="isExpandAll"
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
>
<el-table-column label="类别名称" prop="name" />
<el-table-column label="计量方式" align="center" prop="unitType" width="100">
<template #default="{ row }">
<dict-tag :options="progress_unit_type" :value="row.unitType" />
</template>
</el-table-column>
<el-table-column label="关联数据" align="center" prop="workType">
<template #default="{ row }">
<dict-tag :options="progress_work_type" :value="row.workType" />
</template>
</el-table-column>
<el-table-column label="备注" align="center" prop="remark" />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template #default="scope">
<el-tooltip content="修改" placement="top">
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['progress:progressCategoryTemplate:edit']" />
</el-tooltip>
<el-tooltip content="新增" placement="top">
<el-button link type="primary" icon="Plus" @click="handleAdd(scope.row)" v-hasPermi="['progress:progressCategoryTemplate:add']" />
</el-tooltip>
<el-tooltip content="删除" placement="top">
<el-button
link
type="primary"
icon="Delete"
@click="handleDelete(scope.row)"
v-hasPermi="['progress:progressCategoryTemplate:remove']"
/>
</el-tooltip>
</template>
</el-table-column>
</el-table>
</el-card>
<!-- 添加或修改进度类别模版对话框 --> <!-- 添加或修改进度类别模版对话框 -->
<el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body> <el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
<el-form ref="progressCategoryTemplateFormRef" :model="form" :rules="rules" label-width="80px"> <el-form ref="progressCategoryTemplateFormRef" :model="form" :rules="rules" label-width="80px">
@ -100,6 +112,12 @@
<el-form-item label="类别名称" prop="name"> <el-form-item label="类别名称" prop="name">
<el-input v-model="form.name" placeholder="请输入类别名称" /> <el-input v-model="form.name" placeholder="请输入类别名称" />
</el-form-item> </el-form-item>
<el-form-item label="关联结构" prop="relevancyStructure">
<el-select v-model="form.relevancyStructure" value-key="" placeholder="请选择关联结构" clearable filterable @change="">
<el-option label="子项目" value="1"></el-option>
<el-option label="方阵" value="2"></el-option>
</el-select>
</el-form-item>
<el-form-item label="关联数据" prop="workType"> <el-form-item label="关联数据" prop="workType">
<el-select v-model="form.workType" placeholder="请选择关联数据"> <el-select v-model="form.workType" placeholder="请选择关联数据">
<el-option v-for="dict in progress_work_type" :key="dict.value" :label="dict.label" :value="dict.value" /> <el-option v-for="dict in progress_work_type" :key="dict.value" :label="dict.label" :value="dict.value" />
@ -124,7 +142,9 @@ import {
addProgressCategoryTemplate, addProgressCategoryTemplate,
delProgressCategoryTemplate, delProgressCategoryTemplate,
getProgressCategoryTemplate, getProgressCategoryTemplate,
getTabList,
listProgressCategoryTemplate, listProgressCategoryTemplate,
listProgressCategoryTemplateByParent,
updateProgressCategoryTemplate updateProgressCategoryTemplate
} from '@/api/progress/progressCategoryTemplate'; } from '@/api/progress/progressCategoryTemplate';
import { import {
@ -150,7 +170,7 @@ const buttonLoading = ref(false);
const showSearch = ref(true); const showSearch = ref(true);
const isExpandAll = ref(true); const isExpandAll = ref(true);
const loading = ref(false); const loading = ref(false);
const tabList = ref<any[]>([]);
const queryFormRef = ref<ElFormInstance>(); const queryFormRef = ref<ElFormInstance>();
const progressCategoryTemplateFormRef = ref<ElFormInstance>(); const progressCategoryTemplateFormRef = ref<ElFormInstance>();
const progressCategoryTemplateTableRef = ref<ElTableInstance>(); const progressCategoryTemplateTableRef = ref<ElTableInstance>();
@ -159,6 +179,7 @@ const dialog = reactive<DialogOption>({
visible: false, visible: false,
title: '' title: ''
}); });
const activeTab = ref('0');
const initFormData: ProgressCategoryTemplateForm = { const initFormData: ProgressCategoryTemplateForm = {
id: undefined, id: undefined,
@ -188,7 +209,8 @@ const data = reactive<PageData<ProgressCategoryTemplateForm, ProgressCategoryTem
name: [{ required: true, message: '类别名称不能为空', trigger: 'blur' }], name: [{ required: true, message: '类别名称不能为空', trigger: 'blur' }],
unitType: [{ required: true, message: '计量方式不能为空', trigger: 'change' }], unitType: [{ required: true, message: '计量方式不能为空', trigger: 'change' }],
projectId: [{ required: true, message: '项目id不能为空', trigger: 'blur' }], projectId: [{ required: true, message: '项目id不能为空', trigger: 'blur' }],
constructionType: [{ required: true, message: '施工类型不能为空', trigger: 'change' }] constructionType: [{ required: true, message: '施工类型不能为空', trigger: 'change' }],
relevancyStructure: [{ required: true, message: '关联结构不能为空', trigger: 'change' }]
} }
}); });
@ -197,7 +219,7 @@ const { queryParams, form, rules } = toRefs(data);
/** 查询进度类别模版列表 */ /** 查询进度类别模版列表 */
const getList = async () => { const getList = async () => {
loading.value = true; loading.value = true;
const res = await listProgressCategoryTemplate(queryParams.value); const res = await listProgressCategoryTemplateByParent(activeTab.value);
const data = proxy?.handleTree<ProgressCategoryTemplateVO>(res.data, 'id', 'parentId'); const data = proxy?.handleTree<ProgressCategoryTemplateVO>(res.data, 'id', 'parentId');
if (data) { if (data) {
progressCategoryTemplateList.value = data; progressCategoryTemplateList.value = data;
@ -207,7 +229,7 @@ const getList = async () => {
/** 查询进度类别模版下拉树结构 */ /** 查询进度类别模版下拉树结构 */
const getTreeselect = async () => { const getTreeselect = async () => {
const res = await listProgressCategoryTemplate(); const res = await listProgressCategoryTemplate({ projectId: 0 });
progressCategoryTemplateOptions.value = []; progressCategoryTemplateOptions.value = [];
const data: ProgressCategoryTemplateOption = { id: 0, name: '顶级节点', children: [] }; const data: ProgressCategoryTemplateOption = { id: 0, name: '顶级节点', children: [] };
data.children = proxy?.handleTree<ProgressCategoryTemplateOption>(res.data, 'id', 'parentId'); data.children = proxy?.handleTree<ProgressCategoryTemplateOption>(res.data, 'id', 'parentId');
@ -305,6 +327,10 @@ const handleDelete = async (row: ProgressCategoryTemplateVO) => {
}; };
onMounted(() => { onMounted(() => {
getList(); getTabList('0').then((res) => {
tabList.value = res.data;
activeTab.value = res.data[0]?.id;
getList();
});
}); });
</script> </script>

View File

@ -20,60 +20,70 @@
</el-card> </el-card>
</div> </div>
</transition> </transition>
<el-tabs type="border-card" v-model="activeTab" @tab-change="getList">
<el-tab-pane :label="item.name" v-for="item in tabList" :key="item.id" :name="item.id"></el-tab-pane>
<el-card shadow="never">
<template #header>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button type="primary" plain icon="Plus" @click="handleAdd()" v-hasPermi="['progress:progressCategoryTemplate:add']">新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="info" plain icon="Sort" @click="handleToggleExpandAll">展开/折叠</el-button>
</el-col>
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
</template>
<el-table
ref="progressCategoryTemplateTableRef"
v-loading="loading"
:data="progressCategoryTemplateList"
row-key="id"
:default-expand-all="isExpandAll"
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
>
<el-table-column label="类别名称" prop="name" />
<el-table-column label="计量方式" align="center" prop="unitType" width="100">
<template #default="{ row }">
<dict-tag :options="progress_unit_type" :value="row.unitType" />
</template>
</el-table-column>
<el-table-column label="关联数据" align="center" prop="workType">
<template #default="{ row }">
<dict-tag :options="progress_work_type" :value="row.workType" />
</template>
</el-table-column>
<el-table-column label="关联结构" align="center" prop="relevancyStructure" width="100">
<template #default="{ row }">
<el-tag :type="row.relevancyStructure == '1' ? 'primary' : 'success'">
{{ row.relevancyStructure == '1' ? '子项目' : '方阵' }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="备注" align="center" prop="remark" />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template #default="scope">
<el-tooltip content="修改" placement="top">
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['progress:progressCategoryTemplate:edit']" />
</el-tooltip>
<el-tooltip content="新增" placement="top">
<el-button link type="primary" icon="Plus" @click="handleAdd(scope.row)" v-hasPermi="['progress:progressCategoryTemplate:add']" />
</el-tooltip>
<el-tooltip content="删除" placement="top">
<el-button
link
type="primary"
icon="Delete"
@click="handleDelete(scope.row)"
v-hasPermi="['progress:progressCategoryTemplate:remove']"
/>
</el-tooltip>
</template>
</el-table-column>
</el-table>
</el-card>
</el-tabs>
<el-card shadow="never">
<template #header>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button type="primary" plain icon="Plus" @click="handleAdd()" v-hasPermi="['progress:progressCategoryTemplate:add']">新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="info" plain icon="Sort" @click="handleToggleExpandAll">展开/折叠</el-button>
</el-col>
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
</template>
<el-table
ref="progressCategoryTemplateTableRef"
v-loading="loading"
:data="progressCategoryTemplateList"
row-key="id"
:default-expand-all="isExpandAll"
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
>
<el-table-column label="类别名称" prop="name" />
<el-table-column label="计量方式" align="center" prop="unitType" width="100">
<template #default="{ row }">
<dict-tag :options="progress_unit_type" :value="row.unitType" />
</template>
</el-table-column>
<el-table-column label="关联数据" align="center" prop="workType">
<template #default="{ row }">
<dict-tag :options="progress_work_type" :value="row.workType" />
</template>
</el-table-column>
<el-table-column label="备注" align="center" prop="remark" />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template #default="scope">
<el-tooltip content="修改" placement="top">
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['progress:progressCategoryTemplate:edit']" />
</el-tooltip>
<el-tooltip content="新增" placement="top">
<el-button link type="primary" icon="Plus" @click="handleAdd(scope.row)" v-hasPermi="['progress:progressCategoryTemplate:add']" />
</el-tooltip>
<el-tooltip content="删除" placement="top">
<el-button
link
type="primary"
icon="Delete"
@click="handleDelete(scope.row)"
v-hasPermi="['progress:progressCategoryTemplate:remove']"
/>
</el-tooltip>
</template>
</el-table-column>
</el-table>
</el-card>
<!-- 添加或修改进度类别模版对话框 --> <!-- 添加或修改进度类别模版对话框 -->
<el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body> <el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
<el-form ref="progressCategoryTemplateFormRef" :model="form" :rules="rules" label-width="80px"> <el-form ref="progressCategoryTemplateFormRef" :model="form" :rules="rules" label-width="80px">
@ -100,6 +110,12 @@
<el-option v-for="dict in progress_work_type" :key="dict.value" :label="dict.label" :value="dict.value" /> <el-option v-for="dict in progress_work_type" :key="dict.value" :label="dict.label" :value="dict.value" />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="关联结构" prop="relevancyStructure">
<el-select v-model="form.relevancyStructure" value-key="" placeholder="请选择关联结构" clearable filterable @change="">
<el-option label="子项目" value="1"></el-option>
<el-option label="方阵" value="2"></el-option>
</el-select>
</el-form-item>
<el-form-item label="备注" prop="remark"> <el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容" /> <el-input v-model="form.remark" type="textarea" placeholder="请输入内容" />
</el-form-item> </el-form-item>
@ -119,7 +135,9 @@ import {
addProgressCategoryTemplate, addProgressCategoryTemplate,
delProgressCategoryTemplate, delProgressCategoryTemplate,
getProgressCategoryTemplate, getProgressCategoryTemplate,
getTabList,
listProgressCategoryTemplate, listProgressCategoryTemplate,
listProgressCategoryTemplateByParent,
updateProgressCategoryTemplate updateProgressCategoryTemplate
} from '@/api/progress/progressCategoryTemplate'; } from '@/api/progress/progressCategoryTemplate';
import { import {
@ -135,6 +153,8 @@ type ProgressCategoryTemplateOption = {
name: string; name: string;
children?: ProgressCategoryTemplateOption[]; children?: ProgressCategoryTemplateOption[];
}; };
const activeTab = ref('0');
const tabList = ref<any[]>([]);
const { proxy } = getCurrentInstance() as ComponentInternalInstance; const { proxy } = getCurrentInstance() as ComponentInternalInstance;
@ -186,7 +206,8 @@ const data = reactive<PageData<ProgressCategoryTemplateForm, ProgressCategoryTem
parentId: [{ required: true, message: '父类别id不能为空', trigger: 'blur' }], parentId: [{ required: true, message: '父类别id不能为空', trigger: 'blur' }],
name: [{ required: true, message: '类别名称不能为空', trigger: 'blur' }], name: [{ required: true, message: '类别名称不能为空', trigger: 'blur' }],
unitType: [{ required: true, message: '计量方式不能为空', trigger: 'change' }], unitType: [{ required: true, message: '计量方式不能为空', trigger: 'change' }],
projectId: [{ required: true, message: '项目id不能为空', trigger: 'blur' }] projectId: [{ required: true, message: '项目id不能为空', trigger: 'blur' }],
relevancyStructure: [{ required: true, message: '关联结构不能为空', trigger: 'change' }]
} }
}); });
@ -195,7 +216,7 @@ const { queryParams, form, rules } = toRefs(data);
/** 查询进度类别模版列表 */ /** 查询进度类别模版列表 */
const getList = async () => { const getList = async () => {
loading.value = true; loading.value = true;
const res = await listProgressCategoryTemplate(queryParams.value); const res = await listProgressCategoryTemplateByParent(activeTab.value);
const data = proxy?.handleTree<ProgressCategoryTemplateVO>(res.data, 'id', 'parentId'); const data = proxy?.handleTree<ProgressCategoryTemplateVO>(res.data, 'id', 'parentId');
if (data) { if (data) {
progressCategoryTemplateList.value = data; progressCategoryTemplateList.value = data;
@ -205,7 +226,7 @@ const getList = async () => {
/** 查询进度类别模版下拉树结构 */ /** 查询进度类别模版下拉树结构 */
const getTreeselect = async () => { const getTreeselect = async () => {
const res = await listProgressCategoryTemplate(); const res = await listProgressCategoryTemplate({ projectId: queryParams.value.projectId });
progressCategoryTemplateOptions.value = []; progressCategoryTemplateOptions.value = [];
const data: ProgressCategoryTemplateOption = { id: 0, name: '顶级节点', children: [] }; const data: ProgressCategoryTemplateOption = { id: 0, name: '顶级节点', children: [] };
data.children = proxy?.handleTree<ProgressCategoryTemplateOption>(res.data, 'id', 'parentId'); data.children = proxy?.handleTree<ProgressCategoryTemplateOption>(res.data, 'id', 'parentId');
@ -310,7 +331,11 @@ const getSubProjectList = async () => {
const res = await getChildProject(currentProject.value?.id); const res = await getChildProject(currentProject.value?.id);
projectSon.value = res.data; projectSon.value = res.data;
queryParams.value.projectId = projectSon.value[0]?.id; queryParams.value.projectId = projectSon.value[0]?.id;
getList(); getTabList(queryParams.value.projectId as string).then((res) => {
tabList.value = res.data;
activeTab.value = res.data[0]?.id;
getList();
});
}; };
onMounted(() => { onMounted(() => {

View File

@ -27,6 +27,16 @@
<el-col :span="1.5"> <el-col :span="1.5">
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['land:enterRoad:add']">新增</el-button> <el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['land:enterRoad:add']">新增</el-button>
</el-col> </el-col>
<el-col :span="1.5">
<el-button type="success" plain icon="Plus" @click="downloadTemplate" v-hasPermi="['land:enterRoad:import']">模板下载</el-button>
</el-col>
<el-col :span="1.5">
<el-upload ref="uploadRef" class="upload-demo" :http-request="handleImport" :show-file-list="false">
<template #trigger>
<el-button plain type="primary">导入excel</el-button>
</template>
</el-upload>
</el-col>
<el-col :span="1.5"> <el-col :span="1.5">
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['land:enterRoad:remove']" <el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['land:enterRoad:remove']"
>删除</el-button >删除</el-button
@ -92,7 +102,7 @@
</template> </template>
<script setup name="EnterRoad" lang="ts"> <script setup name="EnterRoad" lang="ts">
import { listEnterRoad, getEnterRoad, delEnterRoad, addEnterRoad, updateEnterRoad } from '@/api/system/landTransfer/enterRoad'; import { listEnterRoad, getEnterRoad, delEnterRoad, addEnterRoad, updateEnterRoad ,importEnterRoad} from '@/api/system/landTransfer/enterRoad';
import { EnterRoadVO, EnterRoadQuery, EnterRoadForm } from '@/api/system/landTransfer/enterRoad/types'; import { EnterRoadVO, EnterRoadQuery, EnterRoadForm } from '@/api/system/landTransfer/enterRoad/types';
import { listLandBlock } from '@/api/system/landTransfer/landBlock'; import { listLandBlock } from '@/api/system/landTransfer/landBlock';
import { useUserStoreHook } from '@/store/modules/user'; import { useUserStoreHook } from '@/store/modules/user';
@ -255,6 +265,43 @@ const listeningProject = watch(
} }
); );
// 导入文件
const handleImport = (options: any) => {
loading.value = true;
let formData = new FormData();
formData.append('file', options.file);
importEnterRoad(currentProject.value?.id,formData).then((res) => {
if (res.code == 200) {
proxy.$modal.msgSuccess(res.msg || '导入成功');
getListLand();
getList();
}
}).catch((err) => {
proxy.$modal.msgError(err.msg || '导入失败');
}).finally(() => {
loading.value = false;
});
};
// 下载模板
const downloadTemplate = () => {
// 导出模版文件
try {
// 创建a标签
const link = document.createElement('a');
// 设置PDF文件路径 - 相对于public目录
link.href = '/enterRoad.xlsx';
// 设置下载后的文件名
link.download = '道路信息导入模板.xlsx';
// 触发点击
document.body.appendChild(link);
link.click();
// 清理
document.body.removeChild(link);
} catch (error) {
alert('下载失败,请重试');
}
};
onUnmounted(() => { onUnmounted(() => {
listeningProject(); listeningProject();
}); });

View File

@ -36,6 +36,16 @@
<el-col :span="1.5"> <el-col :span="1.5">
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['land:landBlock:add']">新增</el-button> <el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['land:landBlock:add']">新增</el-button>
</el-col> </el-col>
<el-col :span="1.5">
<el-button type="success" plain icon="Plus" @click="downloadTemplate" v-hasPermi="['land:enterRoad:import']">模板下载</el-button>
</el-col>
<el-col :span="1.5">
<el-upload ref="uploadRef" class="upload-demo" :http-request="handleImport" :show-file-list="false">
<template #trigger>
<el-button plain type="primary">导入excel</el-button>
</template>
</el-upload>
</el-col>
<el-col :span="1.5"> <el-col :span="1.5">
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['land:landBlock:remove']" <el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['land:landBlock:remove']"
>删除</el-button >删除</el-button
@ -143,7 +153,7 @@
</template> </template>
<script setup name="LandBlock" lang="ts"> <script setup name="LandBlock" lang="ts">
import { listLandBlock, getLandBlock, delLandBlock, LandUnit, addLandBlock, updateLandBlock, subMatrix } from '@/api/system/landTransfer/landBlock'; import { listLandBlock, getLandBlock, delLandBlock, LandUnit, addLandBlock, updateLandBlock, subMatrix,importLandBlock } from '@/api/system/landTransfer/landBlock';
import { LandBlockVO, LandBlockQuery, LandBlockForm } from '@/api/system/landTransfer/landBlock/types'; import { LandBlockVO, LandBlockQuery, LandBlockForm } from '@/api/system/landTransfer/landBlock/types';
import { useUserStoreHook } from '@/store/modules/user'; import { useUserStoreHook } from '@/store/modules/user';
const { proxy } = getCurrentInstance() as ComponentInternalInstance; const { proxy } = getCurrentInstance() as ComponentInternalInstance;
@ -388,6 +398,44 @@ const listeningProject = watch(
} }
); );
// 导入文件
const handleImport = (options:any) => {
loading.value = true;
let formData = new FormData();
formData.append('file', options.file);
importLandBlock(currentProject.value?.id,formData).then((res) => {
if (res.code == 200) {
proxy.$modal.msgSuccess(res.msg || '导入成功');
getList();
getfangzhenList();
}
}).catch((err) => {
proxy.$modal.msgError(err.msg || '导入失败');
}).finally(() => {
loading.value = false;
});
};
// 下载模板
const downloadTemplate = () => {
// 导出模版文件
try {
// 创建a标签
const link = document.createElement('a');
// 设置PDF文件路径 - 相对于public目录
link.href = '/landBlock.xlsx';
// 设置下载后的文件名
link.download = '地块信息导入模板.xlsx';
// 触发点击
document.body.appendChild(link);
link.click();
// 清理
document.body.removeChild(link);
} catch (error) {
alert('下载失败,请重试');
}
};
onUnmounted(() => { onUnmounted(() => {
listeningProject(); listeningProject();
}); });

View File

@ -17,15 +17,6 @@
<el-form-item label="责任人" prop="responsiblePerson"> <el-form-item label="责任人" prop="responsiblePerson">
<el-input v-model="queryParams.responsiblePerson" placeholder="请输入责任人" clearable @keyup.enter="handleQuery" /> <el-input v-model="queryParams.responsiblePerson" placeholder="请输入责任人" clearable @keyup.enter="handleQuery" />
</el-form-item> </el-form-item>
<!-- <el-form-item label="预计完成时间" prop="expectedFinishDate">
<el-date-picker
clearable
v-model="queryParams.expectedFinishDate"
type="date"
value-format="YYYY-MM-DD"
placeholder="请选择预计完成时间"
/>
</el-form-item> -->
<el-form-item> <el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button> <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
<el-button icon="Refresh" @click="resetQuery">重置</el-button> <el-button icon="Refresh" @click="resetQuery">重置</el-button>
@ -41,15 +32,19 @@
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['land:landTransferLedger:add']">新增</el-button> <el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['land:landTransferLedger:add']">新增</el-button>
</el-col> </el-col>
<el-col :span="1.5"> <el-col :span="1.5">
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['land:landTransferLedger:remove']" <el-tag size="large" type="primary">设计面积{{ detailInfo.designArea }}</el-tag>
>删除</el-button </el-col>
> <el-col :span="1.5">
<el-tag size="large" type="success">已流转面积{{ detailInfo.transferAea }}</el-tag>
</el-col>
<el-col :span="1.5">
<el-tag size="large" type="warning">租金{{ detailInfo.landRent / 1000 }}万元</el-tag>
</el-col> </el-col>
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar> <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row> </el-row>
</template> </template>
<el-table v-loading="loading" :data="landTransferLedgerList" @selection-change="handleSelectionChange"> <el-table v-loading="loading" :data="landTransferLedgerList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" /> <el-table-column type="index" label="序号" width="60" align="center" />
<el-table-column label="土地类型" align="center" prop="landTypeName" /> <el-table-column label="土地类型" align="center" prop="landTypeName" />
<el-table-column label="地块" align="center" prop="landName" /> <el-table-column label="地块" align="center" prop="landName" />
<el-table-column label="进场道路" align="center" prop="roadName" /> <el-table-column label="进场道路" align="center" prop="roadName" />
@ -65,7 +60,6 @@
<el-table-column label="状态说明" align="center" prop="statusDescription" /> <el-table-column label="状态说明" align="center" prop="statusDescription" />
<el-table-column label="问题总结" align="center" prop="issueSummary" /> <el-table-column label="问题总结" align="center" prop="issueSummary" />
<el-table-column label="下一步策略" align="center" prop="nextStrategy" width="180" /> <el-table-column label="下一步策略" align="center" prop="nextStrategy" width="180" />
<!-- 固定列 -->
<el-table-column label="操作" align="center" fixed="right" width="200"> <el-table-column label="操作" align="center" fixed="right" width="200">
<template #default="scope"> <template #default="scope">
<el-tooltip content="修改" placement="top"> <el-tooltip content="修改" placement="top">
@ -189,7 +183,8 @@ import {
getLandTransferLedger, getLandTransferLedger,
delLandTransferLedger, delLandTransferLedger,
addLandTransferLedger, addLandTransferLedger,
updateLandTransferLedger updateLandTransferLedger,
landTransferLedgerCount
} from '@/api/system/landTransfer/landTransferLedger'; } from '@/api/system/landTransfer/landTransferLedger';
import { listEnterRoad } from '@/api/system/landTransfer/enterRoad'; import { listEnterRoad } from '@/api/system/landTransfer/enterRoad';
import { LandTransferLedgerVO, LandTransferLedgerQuery, LandTransferLedgerForm } from '@/api/system/landTransfer/landTransferLedger/types'; import { LandTransferLedgerVO, LandTransferLedgerQuery, LandTransferLedgerForm } from '@/api/system/landTransfer/landTransferLedger/types';
@ -272,7 +267,11 @@ const data = reactive<PageData<LandTransferLedgerForm, LandTransferLedgerQuery>>
landType: [{ required: true, message: '土地类型不能为空', trigger: 'change' }] landType: [{ required: true, message: '土地类型不能为空', trigger: 'change' }]
} }
}); });
const detailInfo = ref({
transferAea: 0,
transferRatio: 0,
landRent: 0
});
const { queryParams, form, rules } = toRefs(data); const { queryParams, form, rules } = toRefs(data);
/** 查询项目土地流转台账列表 */ /** 查询项目土地流转台账列表 */
@ -283,7 +282,10 @@ const getList = async () => {
total.value = res.total; total.value = res.total;
loading.value = false; loading.value = false;
}; };
const getLandBlockList = async () => {
let res = await landTransferLedgerCount(currentProject.value?.id);
detailInfo.value = res.data;
};
/** 取消按钮 */ /** 取消按钮 */
const cancel = () => { const cancel = () => {
dialog.visible = false; dialog.visible = false;
@ -385,6 +387,7 @@ const listeningProject = watch(
() => currentProject.value?.id, () => currentProject.value?.id,
(nid, oid) => { (nid, oid) => {
queryParams.value.projectId = nid; queryParams.value.projectId = nid;
getLandBlockList();
getListLand(); getListLand();
getList(); getList();
} }
@ -394,6 +397,7 @@ onUnmounted(() => {
listeningProject(); listeningProject();
}); });
onMounted(() => { onMounted(() => {
getLandBlockList();
getList(); getList();
getListLand(); getListLand();
}); });

View File

@ -94,6 +94,7 @@ const options = reactive<Options>({
previews: {}, previews: {},
visible: false visible: false
}); });
console.log('🚀 ~ userStore.avatar:', userStore.avatar);
/** 编辑头像 */ /** 编辑头像 */
const editCropper = () => { const editCropper = () => {

View File

@ -38,8 +38,17 @@
<el-button type="primary" @click="handleExport()" v-hasPermi="['tender:tenderPlanLimitList:export']">导出excel</el-button> <el-button type="primary" @click="handleExport()" v-hasPermi="['tender:tenderPlanLimitList:export']">导出excel</el-button>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-button type="primary" @click="handleAudit('update')" v-if="versionsData.status == 'draft'">审核</el-button> <el-button
<el-button type="warning" @click="handleAudit('view')" v-else>查看流程</el-button> type="warning"
icon="view"
@click="handleAudit()"
v-if="versionsData.status == 'draft'"
v-hasPermi="['tender:tenderPlanLimitList:getVersionDetail']"
>审核</el-button
>
<el-button type="warning" icon="view" @click="handleAudit()" v-else v-hasPermi="['tender:tenderPlanLimitList:getVersionDetail']"
>查看流程</el-button
>
</el-form-item> </el-form-item>
</el-form> </el-form>
</el-card> </el-card>
@ -65,10 +74,10 @@
</el-table-column> </el-table-column>
<el-table-column prop="price" label="总价" align="center"> <el-table-column prop="price" label="总价" align="center">
<template #default="scope"> <template #default="scope">
{{ scope.row.price }} {{ scope.row.price != 0 ? Number(scope.row.price).toFixed(2) : null }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="price" label="操作" align="center"> <el-table-column prop="operate" label="操作" align="center">
<template #default="scope"> <template #default="scope">
<el-button <el-button
type="primary" type="primary"
@ -76,6 +85,7 @@
@click="handleSave(scope.row)" @click="handleSave(scope.row)"
v-if="scope.row.quantity && scope.row.quantity != 0" v-if="scope.row.quantity && scope.row.quantity != 0"
v-hasPermi="['tender:tenderPlanLimitList:edit']" v-hasPermi="['tender:tenderPlanLimitList:edit']"
:disabled="versionsData.status != 'draft'"
>确定</el-button >确定</el-button
> >
</template> </template>
@ -118,6 +128,7 @@ const tableData = ref([]);
const tableRef = ref(); const tableRef = ref();
const isExpandAll = ref(false); const isExpandAll = ref(false);
const loading = ref(false); const loading = ref(false);
const versionMap = new Map();
// 切换tab // 切换tab
const handleTabChange = (tab: string) => { const handleTabChange = (tab: string) => {
@ -155,9 +166,11 @@ const getVersionNums = async () => {
if (res.code == 200) { if (res.code == 200) {
options.value = res.data; options.value = res.data;
if (res.data.length > 0) { if (res.data.length > 0) {
res.data.forEach((item: any) => {
versionMap.set(item.versions, item);
});
queryForm.value.versions = res.data[0].versions; queryForm.value.versions = res.data[0].versions;
versionsData.value = options.value.find((item) => item.versions == queryForm.value.versions); versionsData.value = options.value.find((item) => item.versions == queryForm.value.versions);
console.log('🚀 ~ changeVersions ~ versionsData.value:', versionsData.value);
getSheetName(); getSheetName();
} else { } else {
queryForm.value.versions = ''; queryForm.value.versions = '';
@ -273,13 +286,21 @@ const handleSave = (row: any) => {
}; };
/** 审核按钮操作 */ /** 审核按钮操作 */
const handleAudit = async (type) => { const handleAudit = async () => {
proxy?.$tab.openPage('/approval/tenderBidd/indexEdit', '审核招标一览', { let id = versionMap.get(queryForm.value.versions).id;
id: queryForm.value.versions, console.log(id);
type, if (activeTab.value == '2') {
activeTab: activeTab.value, proxy?.$tab.openPage('/approval/tenderBidd/indexEdit', '招采工程量清单审核', {
status: versionsData.value.status id: id,
}); type: 'update'
});
}
if (activeTab.value == '3') {
proxy?.$tab.openPage('/approval/tenderBidd/indexEdit2', '物资设备清单审核', {
id: id,
type: 'update'
});
}
}; };
//监听项目id刷新数据 //监听项目id刷新数据

View File

@ -8,7 +8,7 @@
@approvalVerifyOpen="approvalVerifyOpen" @approvalVerifyOpen="approvalVerifyOpen"
@handleApprovalRecord="handleApprovalRecord" @handleApprovalRecord="handleApprovalRecord"
:buttonLoading="buttonLoading" :buttonLoading="buttonLoading"
:id="form.id" :id="form.versions"
:status="form.status" :status="form.status"
:pageType="routeParams.type" :pageType="routeParams.type"
/> />
@ -16,26 +16,20 @@
<!-- 表单区域 --> <!-- 表单区域 -->
<el-card class="rounded-lg shadow-sm bg-white border border-gray-100 transition-all hover:shadow-md overflow-hidden"> <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"> <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> <h3 class="text-lg font-semibold text-gray-800">采工程量清单审核</h3>
</div> </div>
<div class="p-6"> <div class="p-6">
<el-form <el-form ref="leaveFormRef" v-loading="loading" :model="form" :rules="rules" label-width="100px" class="space-y-4">
ref="leaveFormRef"
v-loading="loading"
: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"> <div class="grid grid-cols-1 gap-4">
<el-row> <el-row>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="版本号" prop="formNo"> <el-form-item label="版本号" prop="formNo">
<el-input disabled v-model="form.versions" placeholder="请输入文件名称" /> <el-input :disabled="true" v-model="form.versions" placeholder="请输入文件名称" />
</el-form-item> </el-form-item>
<el-form-item label="表名" prop="formNo"> <el-form-item label="表名" prop="sheet">
<el-input disabled v-model="form.sheet" placeholder="请输入文件名称" /> <el-select v-model="form.sheet" placeholder="选择表名" @change="changeSheet">
<el-option v-for="item in sheets" :key="item" :label="item" :value="item" />
</el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
@ -43,13 +37,14 @@
</el-form> </el-form>
<el-table :data="tableData" style="width: 100%; margin-bottom: 20px; height: calc(100vh - 305px)" row-key="id" default-expand-all border> <el-table :data="tableData" style="width: 100%; margin-bottom: 20px; height: calc(100vh - 305px)" row-key="id" default-expand-all border>
<el-table-column prop="num" label="编号" /> <el-table-column prop="num" label="编号" />
<el-table-column prop="name" label="工程或费用名称" /> <el-table-column prop="name" label="名称" />
<el-table-column prop="specification" label="规格" />
<el-table-column prop="unit" label="单位" /> <el-table-column prop="unit" label="单位" />
<el-table-column prop="quantity" label="数量" /> <el-table-column prop="quantity" label="数量" />
<el-table-column prop="unitPrice" label="单价" align="center" /> <el-table-column prop="unitPrice" label="单价" align="center" />
<el-table-column prop="price" label="总价" align="center"> <el-table-column prop="price" label="总价" align="center">
<template #default="scope"> <template #default="scope">
{{ scope.row.price }} {{ scope.row.price != 0 ? Number(scope.row.price).toFixed(2) : null }}
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
@ -98,11 +93,7 @@ import { StartProcessBo } from '@/api/workflow/workflowCommon/types';
const { proxy } = getCurrentInstance() as any; const { proxy } = getCurrentInstance() as any;
import { useUserStoreHook } from '@/store/modules/user'; import { useUserStoreHook } from '@/store/modules/user';
const { design_change_reason_type } = toRefs<any>(proxy?.useDict('design_change_reason_type')); const { design_change_reason_type } = toRefs<any>(proxy?.useDict('design_change_reason_type'));
import { getKnowledgeDocument } from '@/api/design/technicalStandard'; import { obtainAllVersionNumbers, sheetList, getTableList, updatePrice, importExcelFile, getVersionDetail } from '@/api/tender/index';
import { getConstructionValue } from '@/api/out/constructionValue';
import { workScheduleListDetail } from '@/api/progress/plan';
import { sheetList } from '@/api/contract';
import { getApproval, getTableList } from '@/api/tender';
// 获取用户 store // 获取用户 store
const userStore = useUserStoreHook(); const userStore = useUserStoreHook();
// 从 store 中获取项目列表和当前选中的项目 // 从 store 中获取项目列表和当前选中的项目
@ -126,21 +117,16 @@ const approvalRecordRef = ref<InstanceType<typeof ApprovalRecord>>();
const flowCodeOptions = [ const flowCodeOptions = [
{ {
value: currentProject.value?.id + '_bLimitEquipmentList', value: currentProject.value?.id + '_bLimitEquipmentList',
label: '招标一览审批' label: '招采工程量清单审核'
} }
]; ];
const sheets = ref([]);
const queryForm = ref({
versions: '',
sheet: ''
});
const leaveFormRef = ref<ElFormInstance>(); const leaveFormRef = ref<ElFormInstance>();
const dialog = reactive({ const dialog = reactive({
visible: false, visible: false,
title: '', title: '',
isEdit: false isEdit: false
}); });
const tableData = ref([]);
const submitFormData = ref<StartProcessBo>({ const submitFormData = ref<StartProcessBo>({
businessId: '', businessId: '',
flowCode: '', flowCode: '',
@ -149,15 +135,14 @@ const submitFormData = ref<StartProcessBo>({
const taskVariables = ref<Record<string, any>>({}); const taskVariables = ref<Record<string, any>>({});
const initFormData = { const initFormData = {
id: undefined, versions: '',
projectId: currentProject.value?.id, sheet: '',
versions: undefined, status: '',
sheet: undefined, id: ''
type: undefined,
status: undefined
}; };
const data = reactive({ const data = reactive({
form: { ...initFormData }, form: { ...initFormData },
tableData: [],
rules: {} rules: {}
}); });
@ -166,57 +151,61 @@ const handleClose = () => {
flowCode.value = ''; flowCode.value = '';
buttonLoading.value = false; buttonLoading.value = false;
}; };
const { form, rules } = toRefs(data); const { form, rules, tableData } = toRefs(data);
/** 表单重置 */ /** 表单重置 */
const reset = () => { // const reset = () => {
form.value = { ...initFormData }; // form.value = { ...initFormData };
leaveFormRef.value?.resetFields(); // leaveFormRef.value?.resetFields();
}; // };
/** 获取详情 */ /** 获取详情 */
const getInfo = async () => { const getInfo = () => {
loading.value = true; loading.value = true;
buttonLoading.value = false; buttonLoading.value = false;
nextTick(async () => { nextTick(async () => {
try { const res = await getVersionDetail(routeParams.value.id);
const params = { console.log(res);
projectId: currentProject.value?.id, Object.assign(form.value, res.data);
versions: form.value.versions
};
const res = await sheetList(params);
if (res.code == 200) {
sheets.value = res.data;
if (res.data.length > 0) {
queryForm.value.sheet = res.data[0];
} else {
queryForm.value.sheet = '';
}
try {
const res = await getTableList(form.value);
if (res.code == 200) {
tableData.value = res.data;
}
} catch (error) {
console.log(error);
}
}
} catch (error) {
console.log(error);
}
getApproval(form.value.versions).then((res) => {
form.value.status = res.data.status;
});
if (routeParams.value.type === 'approval') {
form.value.id = routeParams.value.id;
} else {
form.value.id = routeParams.value.id + '_' + routeParams.value.activeTab;
}
loading.value = false; loading.value = false;
buttonLoading.value = false; buttonLoading.value = false;
getSheetName();
}); });
}; };
const sheets = ref([]);
//获取表名
const getSheetName = async () => {
try {
const params = {
projectId: currentProject.value?.id,
versions: form.value.versions
};
const res = await sheetList(params);
if (res.code == 200) {
sheets.value = res.data;
if (res.data.length > 0) {
form.value.sheet = res.data[0];
}
getListTable();
}
} catch (error) {}
};
//选择表名
const changeSheet = () => {
getListTable();
};
//获取列表
const getListTable = async () => {
const res = await getTableList({
projectId: currentProject.value?.id,
versions: form.value.versions,
sheet: form.value.sheet,
type: '2'
});
if (res.code == 200) {
tableData.value = res.data;
}
};
/** 提交按钮 */ /** 提交按钮 */
const submitForm = (status1: string) => { const submitForm = (status1: string) => {
status.value = status1; status.value = status1;
@ -231,7 +220,7 @@ const submitFlow = async () => {
const handleStartWorkFlow = async (data: any) => { const handleStartWorkFlow = async (data: any) => {
try { try {
submitFormData.value.flowCode = flowCode.value; submitFormData.value.flowCode = flowCode.value;
submitFormData.value.businessId = data.versions + '_xianjiayilan'; submitFormData.value.businessId = data.id;
//流程变量 //流程变量
taskVariables.value = { taskVariables.value = {
// leave4/5 使用的流程变量 // leave4/5 使用的流程变量
@ -285,20 +274,11 @@ const submit = async (status, data) => {
onMounted(() => { onMounted(() => {
nextTick(async () => { nextTick(async () => {
routeParams.value = proxy.$route.query; routeParams.value = proxy.$route.query;
console.log('🚀 ~ proxy.$route.query:', proxy.$route.query);
reset();
loading.value = false; loading.value = false;
console.log(routeParams.value); console.log(routeParams.value);
if (routeParams.value.type === 'update' || routeParams.value.type === 'view' || routeParams.value.type === 'approval') { if (routeParams.value.type === 'update' || routeParams.value.type === 'view' || routeParams.value.type === 'approval') {
if (routeParams.value.type === 'approval') {
form.value.versions = routeParams.value.id.split('_')[0];
form.value.type = routeParams.value.id.split('_')[1];
} else {
form.value.versions = routeParams.value.id;
form.value.type = routeParams.value.activeTab;
}
getInfo(); getInfo();
console.log('routeParams.value', routeParams.value);
} }
}); });
}); });

View File

@ -0,0 +1,389 @@
<template>
<div class="p-4 bg-gray-50">
<div class="max-w-4xl mx-auto">
<!-- 顶部按钮区域 -->
<el-card class="mb-4 rounded-lg shadow-sm bg-white border border-gray-100 transition-all hover:shadow-md">
<approvalButton
@submitForm="submitForm"
@approvalVerifyOpen="approvalVerifyOpen"
@handleApprovalRecord="handleApprovalRecord"
:buttonLoading="buttonLoading"
:id="form.versions"
:status="form.status"
:pageType="routeParams.type"
/>
</el-card>
<!-- 表单区域 -->
<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" v-loading="loading" :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 :disabled="true" v-model="form.versions" placeholder="请输入文件名称" />
</el-form-item>
<el-form-item label="表名" prop="sheet">
<el-select v-model="form.sheet" placeholder="选择表名" @change="changeSheet">
<el-option v-for="item in sheets" :key="item" :label="item" :value="item" />
</el-select>
</el-form-item>
</el-col>
</el-row>
</div>
</el-form>
<el-table :data="tableData" style="width: 100%; margin-bottom: 20px; height: calc(100vh - 305px)" row-key="id" default-expand-all border>
<el-table-column prop="num" label="编号" />
<el-table-column prop="name" label="名称" />
<el-table-column prop="specification" label="规格" />
<el-table-column prop="unit" label="单位" />
<el-table-column prop="quantity" label="数量" />
<el-table-column prop="unitPrice" label="单价" align="center" />
<el-table-column prop="price" label="总价" align="center">
<template #default="scope">
{{ scope.row.price != 0 ? Number(scope.row.price).toFixed(2) : null }}
</template>
</el-table-column>
</el-table>
</div>
</el-card>
<!-- 提交组件 -->
<submitVerify ref="submitVerifyRef" :task-variables="taskVariables" @submit-callback="submitCallback" />
<approvalRecord ref="approvalRecordRef"></approvalRecord>
<!-- 流程选择对话框 -->
<el-dialog
draggable
v-model="dialogVisible.visible"
:title="dialogVisible.title"
:before-close="handleClose"
width="500"
class="rounded-lg shadow-lg"
>
<div class="p-4">
<p class="text-gray-600 mb-4">请选择要启动的流程</p>
<el-select v-model="flowCode" placeholder="请选择流程" style="width: 100%">
<el-option v-for="item in flowCodeOptions" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</div>
<template #footer>
<div class="dialog-footer p-4 border-t border-gray-100 flex justify-end space-x-3">
<el-button @click="handleClose" 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" @click="submitFlow()" class="px-4 py-2 bg-primary text-white rounded-md hover:bg-primary/90 transition-colors"
>确认</el-button
>
</div>
</template>
</el-dialog>
</div>
</div>
</template>
<script setup name="Leave" lang="ts">
import { LeaveForm, LeaveQuery, LeaveVO } from '@/api/workflow/leave/types';
import { startWorkFlow } from '@/api/workflow/task';
import SubmitVerify from '@/components/Process/submitVerify.vue';
import ApprovalRecord from '@/components/Process/approvalRecord.vue';
import ApprovalButton from '@/components/Process/approvalButton.vue';
import { StartProcessBo } from '@/api/workflow/workflowCommon/types';
const { proxy } = getCurrentInstance() as any;
import { useUserStoreHook } from '@/store/modules/user';
const { design_change_reason_type } = toRefs<any>(proxy?.useDict('design_change_reason_type'));
import { obtainAllVersionNumbers, sheetList, getTableList, updatePrice, importExcelFile, getVersionDetail } from '@/api/tender/index';
// 获取用户 store
const userStore = useUserStoreHook();
// 从 store 中获取项目列表和当前选中的项目
const currentProject = computed(() => userStore.selectedProject);
const buttonLoading = ref(false);
const loading = ref(true);
//路由参数
const routeParams = ref<Record<string, any>>({});
const flowCode = ref<string>('');
const status = ref<string>('');
const dialogVisible = reactive<DialogOption>({
visible: false,
title: '流程定义'
});
//提交组件
const submitVerifyRef = ref<InstanceType<typeof SubmitVerify>>();
//审批记录组件
const approvalRecordRef = ref<InstanceType<typeof ApprovalRecord>>();
//按钮组件
const flowCodeOptions = [
{
value: currentProject.value?.id + '_wuziyilan',
label: '物资工程量清单审核'
}
];
const leaveFormRef = ref<ElFormInstance>();
const dialog = reactive({
visible: false,
title: '',
isEdit: false
});
const submitFormData = ref<StartProcessBo>({
businessId: '',
flowCode: '',
variables: {}
});
const taskVariables = ref<Record<string, any>>({});
const initFormData = {
versions: '',
sheet: '',
status: '',
id: ''
};
const data = reactive({
form: { ...initFormData },
tableData: [],
rules: {}
});
const handleClose = () => {
dialogVisible.visible = false;
flowCode.value = '';
buttonLoading.value = false;
};
const { form, rules, tableData } = toRefs(data);
/** 表单重置 */
// const reset = () => {
// form.value = { ...initFormData };
// leaveFormRef.value?.resetFields();
// };
/** 获取详情 */
const getInfo = () => {
loading.value = true;
buttonLoading.value = false;
nextTick(async () => {
const res = await getVersionDetail(routeParams.value.id);
console.log(res);
Object.assign(form.value, res.data);
loading.value = false;
buttonLoading.value = false;
getSheetName();
});
};
const sheets = ref([]);
//获取表名
const getSheetName = async () => {
try {
const params = {
projectId: currentProject.value?.id,
versions: form.value.versions
};
const res = await sheetList(params);
if (res.code == 200) {
sheets.value = res.data;
if (res.data.length > 0) {
form.value.sheet = res.data[0];
}
getListTable();
}
} catch (error) {}
};
//选择表名
const changeSheet = () => {
getListTable();
};
//获取列表
const getListTable = async () => {
const res = await getTableList({
projectId: currentProject.value?.id,
versions: form.value.versions,
sheet: form.value.sheet,
type: '3'
});
if (res.code == 200) {
tableData.value = res.data;
}
};
/** 提交按钮 */
const submitForm = (status1: string) => {
status.value = status1;
submit(status.value, form.value);
};
const submitFlow = async () => {
handleStartWorkFlow(form.value);
dialogVisible.visible = false;
};
//提交申请
const handleStartWorkFlow = async (data: any) => {
try {
submitFormData.value.flowCode = flowCode.value;
submitFormData.value.businessId = data.id;
//流程变量
taskVariables.value = {
// leave4/5 使用的流程变量
userList: ['1', '3', '4']
};
submitFormData.value.variables = taskVariables.value;
const resp = await startWorkFlow(submitFormData.value);
if (submitVerifyRef.value) {
buttonLoading.value = false;
submitVerifyRef.value.openDialog(resp.data.taskId);
}
} finally {
buttonLoading.value = false;
}
};
//审批记录
const handleApprovalRecord = () => {
approvalRecordRef.value.init(form.value.id);
};
//提交回调
const submitCallback = async () => {
await proxy.$tab.closePage(proxy.$route);
proxy.$router.go(-1);
};
//审批
const approvalVerifyOpen = async () => {
submitVerifyRef.value.openDialog(routeParams.value.taskId);
};
// 图纸上传成功之后 开始提交
const submit = async (status, data) => {
form.value = data;
if (status === 'draft') {
buttonLoading.value = false;
proxy?.$modal.msgSuccess('暂存成功');
proxy.$tab.closePage(proxy.$route);
proxy.$router.go(-1);
} else {
if ((form.value.status === 'draft' && (flowCode.value === '' || flowCode.value === null)) || routeParams.value.type === 'add') {
flowCode.value = flowCodeOptions[0].value;
dialogVisible.visible = true;
return;
}
//说明启动过先随意穿个参数
if (flowCode.value === '' || flowCode.value === null) {
flowCode.value = 'xx';
}
await handleStartWorkFlow(data);
}
};
onMounted(() => {
nextTick(async () => {
routeParams.value = proxy.$route.query;
loading.value = false;
console.log(routeParams.value);
if (routeParams.value.type === 'update' || routeParams.value.type === 'view' || routeParams.value.type === 'approval') {
getInfo();
console.log('routeParams.value', routeParams.value);
}
});
});
</script>
<style scoped lang="scss">
/* 全局样式 */
: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>

View File

@ -26,18 +26,26 @@
<el-table-column prop="name" label="名称" /> <el-table-column prop="name" label="名称" />
<el-table-column prop="content" label="内容" /> <el-table-column prop="content" label="内容" />
<el-table-column prop="price" label="限价" /> <el-table-column prop="price" label="限价" />
<el-table-column prop="bidd" label="招标文件"> <el-table-column prop="bidd">
<template #header> <span style="color: red">*</span>招标文件 </template>
<template #default="scope"> <template #default="scope">
<el-button type="primary" link v-hasPermi="['tender:biddingPlan:getAnnex']" @click="biddView(scope.row)">查看文件</el-button> <el-button type="primary" link v-hasPermi="['tender:biddingPlan:getAnnex']" @click="biddView(scope.row)">查看文件</el-button>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="winningBidder" label="中标单位" /> <el-table-column prop="winningBidder">
<el-table-column prop="bidFileName" label="中标文件"> <template #header> <span style="color: red">*</span>中标单位 </template>
<template #default="scope">
{{ scope.row.winningBidder }}
</template>
</el-table-column>
<el-table-column prop="bidFileName">
<template #header> <span style="color: red">*</span>中标文件 </template>
<template #default="scope"> <template #default="scope">
<el-button type="primary" link @click="openPdf(scope.row.bidFile)">{{ scope.row.bidFileName }} </el-button> <el-button type="primary" link @click="openPdf(scope.row.bidFile)">{{ scope.row.bidFileName }} </el-button>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="plannedBiddingTime" label="计划招标时间" align="center" width="250"> <el-table-column prop="plannedBiddingTime" align="center" width="250">
<template #header> <span style="color: red">*</span>计划招标时间 </template>
<template #default="scope"> <template #default="scope">
<el-date-picker <el-date-picker
v-model="scope.row.plannedBiddingTime" v-model="scope.row.plannedBiddingTime"
@ -54,7 +62,8 @@
/> />
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="contractPrice" label="合同金额" align="center" width="200"> <el-table-column prop="contractPrice" align="center" width="200">
<template #header> <span style="color: red">*</span>合同金额 </template>
<template #default="scope"> <template #default="scope">
<el-input-number <el-input-number
:model-value="scope.row.contractPrice" :model-value="scope.row.contractPrice"

File diff suppressed because one or more lines are too long