Merge branch 'main' of http://192.168.110.2:3000/taoge/mk_system into fs
This commit is contained in:
@ -5,14 +5,15 @@ VITE_APP_TITLE = 煤科建管平台
|
||||
VITE_APP_ENV = 'development'
|
||||
|
||||
# 开发环境
|
||||
VITE_APP_BASE_API = 'http://192.168.110.180:8899'
|
||||
# 李陈杰 209
|
||||
# VITE_APP_BASE_API = 'http://192.168.110.209:8899'
|
||||
# 曾涛
|
||||
VITE_APP_BASE_API = 'http://192.168.110.180:8899'
|
||||
# VITE_APP_BASE_API = 'http://192.168.110.180:8899'
|
||||
# 罗成
|
||||
# VITE_APP_BASE_API = 'http://192.168.110.188:8899'
|
||||
# 朱银
|
||||
VITE_APP_BASE_API = 'http://192.168.110.180:8899'
|
||||
# VITE_APP_BASE_API = 'http://192.168.110.149:8899'
|
||||
#曾涛
|
||||
# VITE_APP_BASE_API = 'http://192.168.110.171:8899'
|
||||
|
||||
|
1
absolute/path/to/index.vue
Normal file
1
absolute/path/to/index.vue
Normal file
@ -0,0 +1 @@
|
||||
|
@ -101,3 +101,11 @@ export function getProjectId() {
|
||||
method: 'get'
|
||||
});
|
||||
}
|
||||
|
||||
export const getFootNote = (data) => {
|
||||
return request({
|
||||
url: 'gps/equipmentSon/getList',
|
||||
method: 'get',
|
||||
data: data
|
||||
});
|
||||
};
|
||||
|
27
src/api/materials/materialOutbound/index.ts
Normal file
27
src/api/materials/materialOutbound/index.ts
Normal file
@ -0,0 +1,27 @@
|
||||
import request from '@/utils/request';
|
||||
|
||||
//获取出库材料得列表
|
||||
export const outboundMaterials = (query?: any) => {
|
||||
return request({
|
||||
url: '/materials/materials/listRelevancy',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
};
|
||||
//新增出库
|
||||
export const addOutbound = (data?: any) => {
|
||||
return request({
|
||||
url: '/materials/materialsInventory',
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
};
|
||||
|
||||
//获取材料列表
|
||||
export const getMaterialsList = (query?: any) => {
|
||||
return request({
|
||||
url: '/materials/materials/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
};
|
@ -61,3 +61,13 @@ export const delMaterialsInventory = (id: string | number | Array<string | numbe
|
||||
method: 'delete'
|
||||
});
|
||||
};
|
||||
|
||||
//获取新的列表数据
|
||||
export const getLedgerList = (query?: any) => {
|
||||
return request({
|
||||
url: '/materials/materials/listUseDetail',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
};
|
||||
//导出
|
||||
|
@ -33,7 +33,6 @@ export interface MaterialsUseRecordVO {
|
||||
* 备注
|
||||
*/
|
||||
remark: string;
|
||||
|
||||
}
|
||||
|
||||
export interface MaterialsUseRecordForm extends BaseEntity {
|
||||
@ -71,11 +70,9 @@ export interface MaterialsUseRecordForm extends BaseEntity {
|
||||
* 备注
|
||||
*/
|
||||
remark?: string;
|
||||
|
||||
}
|
||||
|
||||
export interface MaterialsUseRecordQuery extends PageQuery {
|
||||
|
||||
/**
|
||||
* 项目ID
|
||||
*/
|
||||
@ -101,11 +98,9 @@ export interface MaterialsUseRecordQuery extends PageQuery {
|
||||
*/
|
||||
residueNumber?: string | number;
|
||||
|
||||
/**
|
||||
* 日期范围参数
|
||||
*/
|
||||
params?: any;
|
||||
/**
|
||||
* 日期范围参数
|
||||
*/
|
||||
params?: any;
|
||||
materialsId?: string | number;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -8,7 +8,7 @@ import { MonthPlanVO, MonthPlanForm, MonthPlanQuery } from '@/api/out/monthPlan/
|
||||
* @returns {*}
|
||||
*/
|
||||
|
||||
export const listMonthPlan = (query?: MonthPlanQuery): AxiosPromise<MonthPlanVO[]> => {
|
||||
export const listMonthPlan = (query?: any) => {
|
||||
return request({
|
||||
url: '/out/monthPlan/list',
|
||||
method: 'get',
|
||||
@ -93,7 +93,7 @@ export const isSubmit = (id): AxiosPromise => {
|
||||
*/
|
||||
export const getMonthInfo = (query): AxiosPromise<MonthPlanVO> => {
|
||||
return request({
|
||||
url: '/out/monthPlan/monthInfo',
|
||||
url: '/out/monthPlan/monthInfo/' + query.id,
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
@ -120,4 +120,4 @@ export const purchaseValueA = (query) => {
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
};
|
||||
};
|
||||
|
@ -8,10 +8,11 @@ import { ProgressCategoryVO, ProgressCategoryForm, ProgressCategoryQuery } from
|
||||
* @returns {*}
|
||||
*/
|
||||
|
||||
export const listProgressCategory = (id?: string | number): AxiosPromise<any[]> => {
|
||||
export const listProgressCategory = (parentId?: string | number,name?:string): AxiosPromise<any[]> => {
|
||||
return request({
|
||||
url: '/progress/progressCategory/listByParent/' + id,
|
||||
method: 'get'
|
||||
url: '/progress/progressCategory/listByParent',
|
||||
method: 'get',
|
||||
params:{parentId,name}
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -78,9 +78,10 @@ export const getTabList = (id: string) => {
|
||||
* @param parentId
|
||||
* @returns {*}
|
||||
*/
|
||||
export const listProgressCategoryTemplateByParent = (parentId: string | number): AxiosPromise<ProgressCategoryTemplateVO[]> => {
|
||||
export const listProgressCategoryTemplateByParent = (parentId: string | number,name:string): AxiosPromise<ProgressCategoryTemplateVO[]> => {
|
||||
return request({
|
||||
url: '/progress/progressCategoryTemplate/listByParent/' + parentId,
|
||||
method: 'get'
|
||||
url: '/progress/progressCategoryTemplate/listByParent' ,
|
||||
method: 'get',
|
||||
params:{parentId,name}
|
||||
});
|
||||
};
|
||||
|
@ -164,7 +164,7 @@ export const updateConstructionUserSalary = (data: ConstructionUserSalaryForm) =
|
||||
*/
|
||||
export const getConstructionUserExit = (query: ConstructionUserExitForm) => {
|
||||
return request({
|
||||
url: '/contractor/constructionUserExit/list',
|
||||
url: '/project/constructionUserExit/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
@ -204,7 +204,6 @@ export const importConstructionUserInfo = (file: string) => {
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
// 获取项目列表
|
||||
export const ProjectList = (query) => {
|
||||
return request({
|
||||
@ -216,7 +215,7 @@ export const ProjectList = (query) => {
|
||||
|
||||
// 获取班组列表
|
||||
export const TeamList = (query) => {
|
||||
return request({
|
||||
return request({
|
||||
url: '/contractor/constructionUser/teamList',
|
||||
method: 'get',
|
||||
params: query
|
||||
@ -230,4 +229,4 @@ export const TeamDistribution = (data) => {
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
};
|
||||
};
|
||||
|
@ -10,7 +10,7 @@ import { ConstructionUserFileVO, ConstructionUserFileForm, ConstructionUserFileQ
|
||||
|
||||
export const listConstructionUserFile = (query?: ConstructionUserFileQuery): AxiosPromise<ConstructionUserFileVO[]> => {
|
||||
return request({
|
||||
url: '/project/constructionUserFile/list',
|
||||
url: '/contractor/constructionUserFile/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
@ -22,7 +22,7 @@ export const listConstructionUserFile = (query?: ConstructionUserFileQuery): Axi
|
||||
*/
|
||||
export const setConstructionUserFile = (data: ConstructionUserFileForm): AxiosPromise<string | number> => {
|
||||
return request({
|
||||
url: '/project/constructionUserFile/save',
|
||||
url: '/contractor/constructionUserFile/save',
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
@ -34,7 +34,7 @@ export const setConstructionUserFile = (data: ConstructionUserFileForm): AxiosPr
|
||||
*/
|
||||
export const delConstructionUserFile = (id: string | number | Array<string | number>) => {
|
||||
return request({
|
||||
url: '/project/constructionUserFile/' + id,
|
||||
url: '/contractor/constructionUserFile/' + id,
|
||||
method: 'delete'
|
||||
});
|
||||
};
|
||||
|
@ -1,6 +1,6 @@
|
||||
import request from '@/utils/request';
|
||||
import { AxiosPromise } from 'axios';
|
||||
import { QuestionBankVO, QuestionBankForm, QuestionBankQuery } from '@/api/safety/questionBank/types';
|
||||
import { QuestionBankVO, QuestionBankForm, QuestionBankQuery } from '@/api/safety/wgzQuestionBank/types';
|
||||
|
||||
/**
|
||||
* 查询题库列表
|
||||
@ -10,7 +10,7 @@ import { QuestionBankVO, QuestionBankForm, QuestionBankQuery } from '@/api/safet
|
||||
|
||||
export const listQuestionBank = (query?: QuestionBankQuery): AxiosPromise<QuestionBankVO[]> => {
|
||||
return request({
|
||||
url: '/safety/questionBank/list',
|
||||
url: '/safety/wgzQuestionBank/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
@ -22,7 +22,7 @@ export const listQuestionBank = (query?: QuestionBankQuery): AxiosPromise<Questi
|
||||
*/
|
||||
export const getQuestionBank = (id: string | number): AxiosPromise<QuestionBankVO> => {
|
||||
return request({
|
||||
url: '/safety/questionBank/' + id,
|
||||
url: '/safety/wgzQuestionBank/' + id,
|
||||
method: 'get'
|
||||
});
|
||||
};
|
||||
@ -33,7 +33,7 @@ export const getQuestionBank = (id: string | number): AxiosPromise<QuestionBankV
|
||||
*/
|
||||
export const addQuestionBank = (data: QuestionBankForm) => {
|
||||
return request({
|
||||
url: '/safety/questionBank',
|
||||
url: '/safety/wgzQuestionBank',
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
@ -45,7 +45,7 @@ export const addQuestionBank = (data: QuestionBankForm) => {
|
||||
*/
|
||||
export const updateQuestionBank = (data: QuestionBankForm) => {
|
||||
return request({
|
||||
url: '/safety/questionBank',
|
||||
url: '/safety/wgzQuestionBank',
|
||||
method: 'put',
|
||||
data: data
|
||||
});
|
||||
@ -57,7 +57,7 @@ export const updateQuestionBank = (data: QuestionBankForm) => {
|
||||
*/
|
||||
export const delQuestionBank = (id: string | number | Array<string | number>) => {
|
||||
return request({
|
||||
url: '/safety/questionBank/' + id,
|
||||
url: '/safety/wgzQuestionBank/' + id,
|
||||
method: 'delete'
|
||||
});
|
||||
};
|
||||
|
@ -1,6 +1,6 @@
|
||||
import request from '@/utils/request';
|
||||
import { AxiosPromise } from 'axios';
|
||||
import { QuestionUserAnswerVO, QuestionUserAnswerForm, QuestionUserAnswerQuery } from '@/api/safety/questionUserAnswer/types';
|
||||
import { QuestionUserAnswerVO, QuestionUserAnswerForm, QuestionUserAnswerQuery } from '@/api/safety/wgzQuestionSave/types';
|
||||
|
||||
/**
|
||||
* 查询用户试卷存储列表
|
||||
@ -10,7 +10,7 @@ import { QuestionUserAnswerVO, QuestionUserAnswerForm, QuestionUserAnswerQuery }
|
||||
|
||||
export const listQuestionUserAnswer = (query?: QuestionUserAnswerQuery): AxiosPromise<QuestionUserAnswerVO[]> => {
|
||||
return request({
|
||||
url: '/safety/questionUserAnswer/list',
|
||||
url: '/safety/wgzQuestionSave/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
@ -22,7 +22,7 @@ export const listQuestionUserAnswer = (query?: QuestionUserAnswerQuery): AxiosPr
|
||||
*/
|
||||
export const getQuestionUserAnswer = (id: string | number): AxiosPromise<QuestionUserAnswerVO> => {
|
||||
return request({
|
||||
url: '/safety/questionUserAnswer/' + id,
|
||||
url: '/safety/wgzQuestionSave/' + id,
|
||||
method: 'get'
|
||||
});
|
||||
};
|
||||
@ -33,7 +33,7 @@ export const getQuestionUserAnswer = (id: string | number): AxiosPromise<Questio
|
||||
*/
|
||||
export const addQuestionUserAnswer = (data: QuestionUserAnswerForm) => {
|
||||
return request({
|
||||
url: '/safety/questionUserAnswer',
|
||||
url: '/safety/wgzQuestionSave',
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
@ -45,7 +45,7 @@ export const addQuestionUserAnswer = (data: QuestionUserAnswerForm) => {
|
||||
*/
|
||||
export const updateQuestionUserAnswer = (data: QuestionUserAnswerForm) => {
|
||||
return request({
|
||||
url: '/safety/questionUserAnswer',
|
||||
url: '/safety/wgzQuestionSave',
|
||||
method: 'put',
|
||||
data: data
|
||||
});
|
||||
@ -57,7 +57,7 @@ export const updateQuestionUserAnswer = (data: QuestionUserAnswerForm) => {
|
||||
*/
|
||||
export const delQuestionUserAnswer = (id: string | number | Array<string | number>) => {
|
||||
return request({
|
||||
url: '/safety/questionUserAnswer/' + id,
|
||||
url: '/safety/wgzQuestionSave/' + id,
|
||||
method: 'delete'
|
||||
});
|
||||
};
|
||||
@ -68,7 +68,7 @@ export const delQuestionUserAnswer = (id: string | number | Array<string | numbe
|
||||
*/
|
||||
export const uploadQuestionUserAnswer = (data: any) => {
|
||||
return request({
|
||||
url: '/safety/questionUserAnswer/upload/zip',
|
||||
url: '/safety/wgzQuestionSave/upload/zip',
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
|
@ -10,7 +10,7 @@ import { QuestionsCategoryVO, QuestionsCategoryForm, QuestionsCategoryQuery } fr
|
||||
|
||||
export const listQuestionsCategory = (query?: QuestionsCategoryQuery): AxiosPromise<QuestionsCategoryVO[]> => {
|
||||
return request({
|
||||
url: '/safety/questionsCategory/list',
|
||||
url: '/safety/wzgQuestionCategory/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
@ -22,7 +22,7 @@ export const listQuestionsCategory = (query?: QuestionsCategoryQuery): AxiosProm
|
||||
*/
|
||||
export const getQuestionsCategory = (id: string | number): AxiosPromise<QuestionsCategoryVO> => {
|
||||
return request({
|
||||
url: '/safety/questionsCategory/' + id,
|
||||
url: '/safety/wzgQuestionCategory' + id,
|
||||
method: 'get'
|
||||
});
|
||||
};
|
||||
@ -33,7 +33,7 @@ export const getQuestionsCategory = (id: string | number): AxiosPromise<Question
|
||||
*/
|
||||
export const addQuestionsCategory = (data: QuestionsCategoryForm) => {
|
||||
return request({
|
||||
url: '/safety/questionsCategory',
|
||||
url: '/safety/wzgQuestionCategory',
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
@ -45,7 +45,7 @@ export const addQuestionsCategory = (data: QuestionsCategoryForm) => {
|
||||
*/
|
||||
export const updateQuestionsCategory = (data: QuestionsCategoryForm) => {
|
||||
return request({
|
||||
url: '/safety/questionsCategory',
|
||||
url: '/safety/wzgQuestionCategory',
|
||||
method: 'put',
|
||||
data: data
|
||||
});
|
||||
@ -57,7 +57,7 @@ export const updateQuestionsCategory = (data: QuestionsCategoryForm) => {
|
||||
*/
|
||||
export const delQuestionsCategory = (id: string | number | Array<string | number>) => {
|
||||
return request({
|
||||
url: '/safety/questionsCategory/' + id,
|
||||
url: '/safety/wzgQuestionCategory' + id,
|
||||
method: 'delete'
|
||||
});
|
||||
};
|
||||
|
@ -22,7 +22,7 @@ export const listQuestionsConfig = (query?: QuestionsConfigQuery): AxiosPromise<
|
||||
*/
|
||||
export const getQuestionsConfig = (id: string | number): AxiosPromise<QuestionsConfigVO> => {
|
||||
return request({
|
||||
url: '/safety/questionsConfig/' + id,
|
||||
url: '/safety/wzgQuestionsConfiguration/' + id,
|
||||
method: 'get'
|
||||
});
|
||||
};
|
||||
@ -45,7 +45,7 @@ export const addQuestionsConfig = (data: QuestionsConfigForm) => {
|
||||
*/
|
||||
export const updateQuestionsConfig = (data: QuestionsConfigForm) => {
|
||||
return request({
|
||||
url: '/safety/questionsConfig',
|
||||
url: '/safety/wzgQuestionsConfiguration',
|
||||
method: 'put',
|
||||
data: data
|
||||
});
|
||||
|
@ -79,3 +79,26 @@ export const landTransferLedgerCount = (id: string | number | Array<string | num
|
||||
method: 'get'
|
||||
});
|
||||
};
|
||||
|
||||
export const addSonLandTransferLedger = (data) => {
|
||||
return request({
|
||||
url: '/land/landTransferLedger/children/add',
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
};
|
||||
|
||||
export const listSonLandTransferLedger = (query) => {
|
||||
return request({
|
||||
url: '/land/landTransferLedger/children/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
};
|
||||
// api/yourApiModule.js
|
||||
export const listallCountValue = (projectId) => {
|
||||
return request({
|
||||
url: '/land/landTransferLedger/allCountValue/' + projectId,
|
||||
method: 'get'
|
||||
});
|
||||
};
|
||||
|
@ -4,6 +4,11 @@ export interface LandTransferLedgerVO {
|
||||
*/
|
||||
id: string | number;
|
||||
|
||||
/**
|
||||
* 父级ID
|
||||
*/
|
||||
parentId: string | number;
|
||||
|
||||
/**
|
||||
* 项目ID
|
||||
*/
|
||||
@ -83,7 +88,6 @@ export interface LandTransferLedgerVO {
|
||||
* 下一步策略
|
||||
*/
|
||||
nextStrategy: string;
|
||||
|
||||
}
|
||||
|
||||
export interface LandTransferLedgerForm extends BaseEntity {
|
||||
@ -92,6 +96,11 @@ export interface LandTransferLedgerForm extends BaseEntity {
|
||||
*/
|
||||
id?: string | number;
|
||||
|
||||
/**
|
||||
* 父级ID
|
||||
*/
|
||||
parentId: string | number;
|
||||
|
||||
/**
|
||||
* 项目ID
|
||||
*/
|
||||
@ -171,11 +180,9 @@ export interface LandTransferLedgerForm extends BaseEntity {
|
||||
* 下一步策略
|
||||
*/
|
||||
nextStrategy?: string;
|
||||
|
||||
}
|
||||
|
||||
export interface LandTransferLedgerQuery extends PageQuery {
|
||||
|
||||
/**
|
||||
* 项目ID
|
||||
*/
|
||||
@ -256,11 +263,8 @@ export interface LandTransferLedgerQuery extends PageQuery {
|
||||
*/
|
||||
nextStrategy?: string;
|
||||
|
||||
/**
|
||||
* 日期范围参数
|
||||
*/
|
||||
params?: any;
|
||||
/**
|
||||
* 日期范围参数
|
||||
*/
|
||||
params?: any;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -203,6 +203,7 @@ watch(
|
||||
});
|
||||
} else {
|
||||
fileList.value = [];
|
||||
|
||||
return [];
|
||||
}
|
||||
},
|
||||
@ -293,7 +294,7 @@ const handleChange = (file: any, filelist: any) => {
|
||||
}
|
||||
}
|
||||
// 记录 status = 'ready' 的文件
|
||||
if (file.status === 'ready') {
|
||||
if (file.status === 'ready' && !props.isConstruction) {
|
||||
pendingFiles.value.push(file);
|
||||
fileList.value = pendingFiles.value;
|
||||
}
|
||||
|
@ -201,6 +201,8 @@ const uploadedSuccessfully = () => {
|
||||
fileList.value = fileList.value.filter((f) => f.url !== undefined).concat(uploadList.value);
|
||||
uploadList.value = [];
|
||||
number.value = 0;
|
||||
console.log(fileList.value);
|
||||
|
||||
emit('update:modelValue', listToString(fileList.value));
|
||||
proxy?.$modal.closeLoading();
|
||||
}
|
||||
|
@ -170,8 +170,6 @@ onMounted(() => {
|
||||
//分页
|
||||
const getWaitingList = () => {
|
||||
pageByTaskWait({ pageNum: 1, pageSize: 10 }).then((resp) => {
|
||||
console.log(resp);
|
||||
|
||||
total.value = resp.total;
|
||||
});
|
||||
};
|
||||
|
@ -7,6 +7,7 @@
|
||||
<template #title>
|
||||
<span class="menu-title" :title="hasTitle(onlyOneChild.meta.title)">{{ onlyOneChild.meta.title }}</span>
|
||||
<span class="bage" v-if="onlyOneChild.meta?.title == '我的待办' && total > 0">{{ total }}</span>
|
||||
<span class="bage" v-if="onlyOneChild.meta?.title == '我的抄送' && totalChao > 0">{{ totalChao }}</span>
|
||||
</template>
|
||||
</el-menu-item>
|
||||
</app-link>
|
||||
@ -16,7 +17,7 @@
|
||||
<template v-if="item.meta" #title>
|
||||
<svg-icon :icon-class="item.meta ? item.meta.icon : ''" />
|
||||
<span class="menu-title" :title="hasTitle(item.meta?.title)">{{ item.meta?.title }}</span>
|
||||
<!-- <span class="bage" v-if="item.meta?.title == '我的任务' && total >= 0">{{ total }}</span> -->
|
||||
<span class="bage" v-if="item.meta?.title == '我的任务' && total > 0">{{ total }}</span>
|
||||
</template>
|
||||
|
||||
<sidebar-item
|
||||
@ -36,7 +37,7 @@ import { isExternal } from '@/utils/validate';
|
||||
import AppLink from './Link.vue';
|
||||
import { getNormalPath } from '@/utils/ruoyi';
|
||||
import { RouteRecordRaw } from 'vue-router';
|
||||
import { pageByTaskWait } from '@/api/workflow/task';
|
||||
import { pageByTaskWait, pageByTaskCopy } from '@/api/workflow/task';
|
||||
import useUserStore from '@/store/modules/user';
|
||||
import useNoticeStore from '@/store/modules/notice';
|
||||
const userStore = useUserStore();
|
||||
@ -56,21 +57,27 @@ const props = defineProps({
|
||||
}
|
||||
});
|
||||
const total = ref(0);
|
||||
const totalChao = ref(0);
|
||||
onMounted(() => {
|
||||
if (onlyOneChild.value.meta?.title == '我的待办' || props.item.meta?.title == '我的任务') {
|
||||
console.log(44444444);
|
||||
getWaitingList();
|
||||
}
|
||||
if (onlyOneChild.value.meta?.title == '我的抄送') {
|
||||
getChaoList();
|
||||
}
|
||||
});
|
||||
// 获取我的待办
|
||||
//分页
|
||||
const getWaitingList = () => {
|
||||
pageByTaskWait({ pageNum: 1, pageSize: 10 }).then((resp) => {
|
||||
console.log(resp);
|
||||
|
||||
total.value = resp.total;
|
||||
});
|
||||
};
|
||||
// 获取我的抄送
|
||||
const getChaoList = () => {
|
||||
pageByTaskCopy({ pageNum: 1, pageSize: 10 }).then((resp) => {
|
||||
totalChao.value = resp.total;
|
||||
});
|
||||
};
|
||||
const onlyOneChild = ref<any>({});
|
||||
|
||||
const hasOneShowingChild = (parent: RouteRecordRaw, children?: RouteRecordRaw[]) => {
|
||||
@ -123,9 +130,7 @@ const hasTitle = (title: string | undefined): string => {
|
||||
watch(
|
||||
() => noticeStore.state.value.notices,
|
||||
(newVal) => {
|
||||
if (onlyOneChild.value.meta?.title == '我的待办') {
|
||||
console.log(121212121);
|
||||
|
||||
if (onlyOneChild.value.meta?.title == '我的待办' || props.item.meta?.title == '我的任务') {
|
||||
let time = setTimeout(() => {
|
||||
getWaitingList();
|
||||
clearTimeout(time);
|
||||
|
@ -14,7 +14,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="detailBox" :class="{'show': newId}">
|
||||
<div class="detailBox" :class="{ 'show': newId }">
|
||||
<!-- <div class="detail_title">{{ newDetail.title }}</div> -->
|
||||
<div class="detail_content" v-html="newDetail.content"></div>
|
||||
</div>
|
||||
@ -62,7 +62,8 @@
|
||||
</div>
|
||||
<div v-for="item in teamAttendanceList" :key="item.id" class="attendance_item">
|
||||
<div class="attendance_item_title">{{ item.teamName }}</div>
|
||||
<div class="attendance_item_number">{{ item.attendanceNumber }} <span class="subfont">人/{{ item.allNumber }}</span></div>
|
||||
<div class="attendance_item_number">{{ item.attendanceNumber }} <span class="subfont">人/{{ item.allNumber
|
||||
}}</span></div>
|
||||
<div class="attendance_item_rate">{{ item.attendanceRate }} %</div>
|
||||
<div class="attendance_item_date subfont">{{ item.attendanceTime }}</div>
|
||||
</div>
|
||||
@ -247,12 +248,13 @@ onUnmounted(() => {
|
||||
margin-top: 15px;
|
||||
|
||||
.tag_item {
|
||||
width: 28%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
border: 1px dashed rgba(29, 214, 255, 0.3);
|
||||
padding: 10px 25px;
|
||||
padding: 10px;
|
||||
|
||||
.tag_info {
|
||||
font-size: 20px;
|
||||
|
@ -173,19 +173,20 @@ onUnmounted(() => {
|
||||
.chart_container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 5px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.echart {
|
||||
height: 50%;
|
||||
height: 48%;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
max-height: 100px;
|
||||
height: 100px;
|
||||
margin: 0 15px;
|
||||
padding: 0 10px;
|
||||
margin-top: 15px;
|
||||
|
@ -57,10 +57,10 @@
|
||||
</transition>
|
||||
<el-card shadow="never" class="mb8">
|
||||
<el-table ref="tableRef" v-loading="loading" :data="tableData" row-key="id" border lazy default-expand-all>
|
||||
<el-table-column prop="num" label="编号" />
|
||||
<el-table-column prop="name" label="工程或费用名称" />
|
||||
<el-table-column prop="num" label="编号" align="center" />
|
||||
<el-table-column prop="name" label="工程或费用名称" align="center" />
|
||||
<el-table-column prop="unit" label="单位" align="center" />
|
||||
<el-table-column prop="specification" label="规格" align="center"/>
|
||||
<el-table-column prop="specification" label="规格" align="center" />
|
||||
<el-table-column prop="quantity" label="数量" align="center">
|
||||
<template #default="scope">
|
||||
{{ scope.row.children.length > 0 ? '' : scope.row.quantity }}
|
||||
@ -262,7 +262,7 @@ const importExcel = (options: any): any => {
|
||||
let formData = new FormData();
|
||||
formData.append('file', options.file);
|
||||
loading.value = true;
|
||||
BiddingImportExcelFile({ projectId: currentProject.value?.id }, formData)
|
||||
BiddingImportExcelFile({ projectId: currentProject.value?.id, versions: queryForm.value.versions }, formData)
|
||||
.then((res) => {
|
||||
const { code } = res;
|
||||
if (code == 200) {
|
||||
|
@ -23,13 +23,19 @@
|
||||
{{ (queryParams.pageNum - 1) * queryParams.pageSize + scope.$index + 1 }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="name" label="名称" />
|
||||
<el-table-column prop="content" label="内容" />
|
||||
<el-table-column prop="price" label="限价" />
|
||||
<el-table-column prop="name" label="名称" align="center" />
|
||||
<el-table-column prop="content" label="内容" align="center" />
|
||||
<el-table-column prop="price" label="限价" align="center" />
|
||||
<el-table-column prop="plannedBiddingTime" align="center">
|
||||
<template #header> <span style="color: red">*</span>计划招标时间 </template>
|
||||
<template #default="scope">
|
||||
<el-date-picker v-model="scope.row.plannedBiddingTime" type="date" value-format="YYYY-MM-DD" placeholder="选择时间" />
|
||||
<el-date-picker
|
||||
v-model="scope.row.plannedBiddingTime"
|
||||
type="date"
|
||||
value-format="YYYY-MM-DD"
|
||||
placeholder="选择时间"
|
||||
:disabled="scope.row.status == 0"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="price" label="操作" align="center">
|
||||
@ -143,9 +149,11 @@
|
||||
(scope.row.selectNum ? Number(scope.row.selectNum) : 0) ==
|
||||
0
|
||||
? ''
|
||||
: (scope.row.quantity ? Number(scope.row.quantity) : 0) -
|
||||
(scope.row.selectNum ? Number(scope.row.selectNum) : 0) -
|
||||
(scope.row.useQuantity ? Number(scope.row.useQuantity) : 0)
|
||||
: (
|
||||
(scope.row.quantity ? Number(scope.row.quantity) : 0) -
|
||||
(scope.row.selectNum ? Number(scope.row.selectNum) : 0) -
|
||||
(scope.row.useQuantity ? Number(scope.row.useQuantity) : 0)
|
||||
).toFixed(2)
|
||||
}}
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
@ -24,7 +24,8 @@
|
||||
</el-form-item>
|
||||
<el-form-item label="合同类型" prop="contractType">
|
||||
<el-select v-model="form.contractType" placeholder="请选择合同类型">
|
||||
<el-option v-for="item in income_contract_type" :key="item.value" :label="item.label" :value="item.value" />
|
||||
<el-option v-for="item in income_contract_type" :key="item.value" :label="item.label"
|
||||
:value="item.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="业主单位" prop="contractOwner">
|
||||
@ -37,17 +38,15 @@
|
||||
<editor v-model="form.contractedContent" :min-height="192" />
|
||||
</el-form-item>
|
||||
<el-form-item label="合同金额" prop="amount">
|
||||
<el-input
|
||||
v-model="form.amount"
|
||||
placeholder="请输入合同金额"
|
||||
oninput="value=value.replace(/[^0-9.]/g,'').replace(/\.{2,}/g,'.').replace(/^(\-)*(\d+)\.(\d\d).*$/,'$1$2.$3')"
|
||||
/>
|
||||
<el-input v-model="form.amount" placeholder="请输入合同金额"
|
||||
oninput="value=value.replace(/[^0-9.]/g,'').replace(/\.{2,}/g,'.').replace(/^(\-)*(\d+)\.(\d\d).*$/,'$1$2.$3')" />
|
||||
</el-form-item>
|
||||
<el-form-item label="备注" prop="remark">
|
||||
<el-input v-model="form.remark" placeholder="请输入备注" />
|
||||
</el-form-item>
|
||||
<el-form-item label="附件">
|
||||
<FileUpload :multiple="true" :fileType="['pdf']" :onUploadSuccess="onUploadSuccess" :ref="fileRef" :defaultFileList="tempFileList" />
|
||||
<FileUpload :multiple="true" :fileType="['pdf']" :onUploadSuccess="onUploadSuccess" :ref="fileRef"
|
||||
:defaultFileList="tempFileList" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</template>
|
||||
@ -61,35 +60,36 @@
|
||||
</el-form-item>
|
||||
<el-form-item label="合同类型" prop="contractType">
|
||||
<el-select v-model="form.contractType" placeholder="请选择合同类型">
|
||||
<el-option v-for="item in expenses_contract_type" :key="item.value" :label="item.label" :value="item.value" />
|
||||
<el-option v-for="item in expenses_contract_type" :key="item.value" :label="item.label"
|
||||
:value="item.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="招标计划" prop="tenderId">
|
||||
<!-- <el-input v-model="form.tenderId" placeholder="请输入招标Id" /> -->
|
||||
<el-input v-model="form.name" placeholder="请选择招标计划" disabled />
|
||||
<el-button type="primary" @click="handleChoose" v-hasPermi="['ctr:expensesContract:tenderList']">选择招标</el-button>
|
||||
<el-button type="primary" @click="handleChoose"
|
||||
v-hasPermi="['ctr:expensesContract:tenderList']">选择招标</el-button>
|
||||
</el-form-item>
|
||||
<el-form-item label="供应商" prop="contractSupplier">
|
||||
<el-input v-model="form.contractSupplier" placeholder="请输入供应商" disabled />
|
||||
</el-form-item>
|
||||
<el-form-item label="分包内容">
|
||||
<!-- <editor v-model="form.contractedContent" :min-height="192" disabled /> -->
|
||||
<el-input v-model="form.contractedContent" style="width: 300px" :autosize="{ minRows: 2, maxRows: 4 }" type="textarea" disabled />
|
||||
<el-input v-model="form.contractedContent" style="width: 300px" :autosize="{ minRows: 2, maxRows: 4 }"
|
||||
type="textarea" disabled />
|
||||
</el-form-item>
|
||||
<el-form-item label="合同金额" prop="amount">
|
||||
<el-input
|
||||
oninput="value=value.replace(/[^0-9.]/g,'').replace(/\.{2,}/g,'.').replace(/^(\-)*(\d+)\.(\d\d).*$/,'$1$2.$3')"
|
||||
v-model="form.amount"
|
||||
placeholder="请输入合同金额"
|
||||
disabled
|
||||
/>
|
||||
v-model="form.amount" placeholder="请输入合同金额" disabled />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="备注" prop="remark">
|
||||
<el-input v-model="form.remark" placeholder="请输入备注" />
|
||||
</el-form-item>
|
||||
<el-form-item label="合同附件">
|
||||
<FileUpload :multiple="true" :fileType="['pdf']" :onUploadSuccess="onUploadSuccess" :ref="fileRef" :defaultFileList="tempFileList" />
|
||||
<FileUpload :multiple="true" :fileType="['pdf']" :onUploadSuccess="onUploadSuccess" :ref="fileRef"
|
||||
:defaultFileList="tempFileList" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</template>
|
||||
@ -208,7 +208,7 @@ const payRatioComputed = computed({
|
||||
return total;
|
||||
},
|
||||
// 只读
|
||||
set: () => {}
|
||||
set: () => { }
|
||||
});
|
||||
const checkContractType = (type) => {
|
||||
contract_type.value = type;
|
||||
@ -280,7 +280,6 @@ const resetForm = () => {
|
||||
};
|
||||
fileList.value = [];
|
||||
tempFileList.value = [];
|
||||
contract_type.value = '';
|
||||
setTimeout(() => {
|
||||
localStorage.removeItem('tempContractForm');
|
||||
}, 0);
|
||||
@ -399,6 +398,7 @@ const getInfoByProjectIdList = async () => {
|
||||
form.value.contractOwner = res.data.planDuration;
|
||||
};
|
||||
onMounted(() => {
|
||||
contract_type.value = '';
|
||||
getInfoByProjectIdList();
|
||||
|
||||
const tempForm = localStorage.getItem('tempContractForm');
|
||||
|
@ -47,9 +47,9 @@
|
||||
<el-row :gutter="8" class="mb-3 font-medium text-gray-700 whitespace-nowrap">
|
||||
<el-col :span="4">专业</el-col>
|
||||
<el-col :span="5">设计人员(可多选)</el-col>
|
||||
<el-col :span="5">校审人员</el-col>
|
||||
<el-col :span="5">校审人员</el-col> <el-col :span="4">审核人员</el-col>
|
||||
<el-col :span="5">审定人员</el-col>
|
||||
<el-col :span="4">审核人员</el-col>
|
||||
|
||||
<el-col :span="3"></el-col>
|
||||
</el-row>
|
||||
|
||||
@ -209,61 +209,7 @@
|
||||
</el-col>
|
||||
|
||||
<!-- 4. 审定人员 -->
|
||||
<el-col :span="5" class="mb-4 sm:mb-0">
|
||||
<div class="pl-2 border-l-2 border-orange-200 py-2">
|
||||
<div class="space-y-3">
|
||||
<div
|
||||
v-for="(person, personIndex) in majorConfig.approvedPersons"
|
||||
:key="`approved-${configIndex}-${personIndex}`"
|
||||
class="flex items-center"
|
||||
>
|
||||
<el-form-item
|
||||
:prop="`approved.${configIndex}.persons.${personIndex}.userId`"
|
||||
:rules="{ required: true, message: '请选择审定人员', trigger: 'change' }"
|
||||
class="flex-1 mr-2 mb-0"
|
||||
label="审定"
|
||||
label-width="50px"
|
||||
>
|
||||
<el-select
|
||||
filterable
|
||||
v-model="person.userId"
|
||||
placeholder="选择人员"
|
||||
class="w-full transition-all duration-300 border-gray-300"
|
||||
@change="() => checkDuplicate(person, 'approved', configIndex, personIndex)"
|
||||
>
|
||||
<el-option v-for="item in userList" :key="`user-${item.userId}`" :label="item.nickName" :value="item.userId" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<!-- <div class="flex gap-1">
|
||||
<el-button
|
||||
type="danger"
|
||||
size="small"
|
||||
@click="removePerson('approved', configIndex, personIndex)"
|
||||
class="transition-all duration-300 hover:bg-red-600"
|
||||
:disabled="majorConfig.approvedPersons.length <= 1 || disabledForm"
|
||||
>
|
||||
<el-icon :size="14"><Delete /></el-icon>
|
||||
</el-button>
|
||||
<el-button
|
||||
type="success"
|
||||
size="small"
|
||||
@click="addPerson('approved', configIndex)"
|
||||
class="transition-all duration-300 transform hover:scale-105"
|
||||
:disabled="!form.designers[configIndex].userMajor || disabledForm"
|
||||
>
|
||||
<el-icon :size="14"><Plus /></el-icon>
|
||||
</el-button>
|
||||
</div> -->
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-if="majorConfig.approvedPersons.length == 0"
|
||||
class="text-gray-500 text-xs py-2 bg-gray-100 rounded border border-dashed border-gray-200"
|
||||
>
|
||||
点击"添加"
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
|
||||
|
||||
<!-- 5. 审核人员 -->
|
||||
<el-col :span="5" class="mb-4 sm:mb-0">
|
||||
@ -321,6 +267,61 @@
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="5" class="mb-4 sm:mb-0">
|
||||
<div class="pl-2 border-l-2 border-orange-200 py-2">
|
||||
<div class="space-y-3">
|
||||
<div
|
||||
v-for="(person, personIndex) in majorConfig.approvedPersons"
|
||||
:key="`approved-${configIndex}-${personIndex}`"
|
||||
class="flex items-center"
|
||||
>
|
||||
<el-form-item
|
||||
:prop="`approved.${configIndex}.persons.${personIndex}.userId`"
|
||||
:rules="{ required: true, message: '请选择审定人员', trigger: 'change' }"
|
||||
class="flex-1 mr-2 mb-0"
|
||||
label="审定"
|
||||
label-width="50px"
|
||||
>
|
||||
<el-select
|
||||
filterable
|
||||
v-model="person.userId"
|
||||
placeholder="选择人员"
|
||||
class="w-full transition-all duration-300 border-gray-300"
|
||||
@change="() => checkDuplicate(person, 'approved', configIndex, personIndex)"
|
||||
>
|
||||
<el-option v-for="item in userList" :key="`user-${item.userId}`" :label="item.nickName" :value="item.userId" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<!-- <div class="flex gap-1">
|
||||
<el-button
|
||||
type="danger"
|
||||
size="small"
|
||||
@click="removePerson('approved', configIndex, personIndex)"
|
||||
class="transition-all duration-300 hover:bg-red-600"
|
||||
:disabled="majorConfig.approvedPersons.length <= 1 || disabledForm"
|
||||
>
|
||||
<el-icon :size="14"><Delete /></el-icon>
|
||||
</el-button>
|
||||
<el-button
|
||||
type="success"
|
||||
size="small"
|
||||
@click="addPerson('approved', configIndex)"
|
||||
class="transition-all duration-300 transform hover:scale-105"
|
||||
:disabled="!form.designers[configIndex].userMajor || disabledForm"
|
||||
>
|
||||
<el-icon :size="14"><Plus /></el-icon>
|
||||
</el-button>
|
||||
</div> -->
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-if="majorConfig.approvedPersons.length == 0"
|
||||
class="text-gray-500 text-xs py-2 bg-gray-100 rounded border border-dashed border-gray-200"
|
||||
>
|
||||
点击"添加"
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
|
||||
<!-- 操作列 -->
|
||||
<el-col :span="2" class="pr-4 mt-2 text-right">
|
||||
@ -343,13 +344,17 @@
|
||||
type="primary"
|
||||
size="large"
|
||||
v-hasPermi="['design:user:batch']"
|
||||
icon="Check"
|
||||
@click="submitForm"
|
||||
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"
|
||||
>
|
||||
<i class="el-icon-check mr-2"></i>确认提交
|
||||
>确认提交
|
||||
</el-button>
|
||||
<el-button size="large" @click="resetForm" class="px-8 py-2.5 transition-all duration-300 border-gray-300 hover:bg-gray-100 font-medium">
|
||||
<i class="el-icon-refresh mr-2"></i>重置
|
||||
<el-button
|
||||
size="large"
|
||||
icon="Refresh"
|
||||
@click="resetForm"
|
||||
class="px-8 py-2.5 transition-all duration-300 border-gray-300 hover:bg-gray-100 font-medium"
|
||||
>重置
|
||||
</el-button>
|
||||
</div>
|
||||
</el-form>
|
||||
|
@ -93,11 +93,10 @@
|
||||
>审核通知单</el-button
|
||||
>
|
||||
<el-button
|
||||
v-if="scope.row.status != 'draft'"
|
||||
v-if="scope.row.status != 'draft' || scope.row.auditStatus != 'draft'"
|
||||
type="success"
|
||||
link
|
||||
icon="View"
|
||||
v-hasPermi="['design:designChange:query']"
|
||||
@click="handleViewDetail(scope.row)"
|
||||
>查看通知单</el-button
|
||||
>
|
||||
@ -113,8 +112,7 @@
|
||||
type="warning"
|
||||
link
|
||||
icon="View"
|
||||
v-hasPermi="['design:drawingreviewReceipts:list']"
|
||||
v-if="scope.row.status != 'draft'"
|
||||
v-if="scope.row.status != 'draft' || scope.row.auditStatus != 'draft'"
|
||||
@click="handleViewHistory(scope.row)"
|
||||
>查看单据</el-button
|
||||
>
|
||||
|
@ -62,13 +62,13 @@
|
||||
:accept="'.xlsx,.xls'"
|
||||
:limit="1"
|
||||
>
|
||||
<el-button type="primary" icon="Upload">导入文件</el-button>
|
||||
<el-button type="primary" icon="Download">导入文件</el-button>
|
||||
</el-upload>
|
||||
<el-button
|
||||
v-if="!form.id || form.status == 'draft'"
|
||||
type="primary"
|
||||
style="margin-left: 20px"
|
||||
icon="Download"
|
||||
icon="Upload"
|
||||
@click="exportTemplate"
|
||||
class="transition-all hover:bg-blue-600"
|
||||
>
|
||||
|
@ -121,10 +121,10 @@
|
||||
</div> -->
|
||||
|
||||
<div class="info-item">
|
||||
<span class="info-label">更新时间</span>
|
||||
<span class="info-label">上传时间</span>
|
||||
<div class="info-value mt-0.5 flex items-center">
|
||||
<i class="fa fa-calendar-o text-gray-400 dark:text-gray-500 mr-1.5"></i>
|
||||
{{ info.updateTime || '未更新' }}
|
||||
{{ info.createTime || '暂无' }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -68,6 +68,7 @@
|
||||
<el-button link type="primary" icon="View" @click="handleView(scope.row)" v-hasPermi="['design:volumeCatalog:listFile']"
|
||||
>查看文件</el-button
|
||||
>
|
||||
<el-badge v-if="scope.row.fileCount" :value="scope.row.fileCount" class="item" type="danger"> </el-badge>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="外部意见" align="center">
|
||||
@ -153,8 +154,8 @@
|
||||
<el-form-item v-if="uploadForm.type == '3'" label="蓝图" prop="fileIds">
|
||||
<file-upload :fileType="['pdf']" :isShowTip="false" :fileSize="100" v-model="uploadForm.fileIds"></file-upload>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="uploadForm.type == '3'" label="抄送人">
|
||||
<el-select multiple filterable clearable v-model="form.userIds" placeholder="请选择抄送人">
|
||||
<el-form-item v-if="uploadForm.type == '3'" label="通知人">
|
||||
<el-select multiple filterable clearable v-model="form.userIds" placeholder="请选择通知人">
|
||||
<el-option :value="item.userId" v-for="item in userCoryList" :key="item.userId" :label="item.nickName + '-' + item.phonenumber" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
@ -171,8 +172,8 @@
|
||||
<!-- 查看文件列表 -->
|
||||
<el-dialog draggable title="图纸列表" v-model="viewVisible" width="1000px">
|
||||
<el-tabs type="border-card" v-model="activeName" class="demo-tabs" @tab-click="handleClick">
|
||||
<el-tab-pane label="蓝图" name="3"
|
||||
><TableContent :data="fileList" :wf-business-status="wf_business_status">
|
||||
<el-tab-pane label="蓝图" name="3">
|
||||
<TableContent :data="fileList" :wf-business-status="wf_business_status">
|
||||
<template #operation="{ row }">
|
||||
<el-button
|
||||
link
|
||||
@ -195,10 +196,10 @@
|
||||
>查看单据</el-button
|
||||
>
|
||||
</template>
|
||||
</TableContent></el-tab-pane
|
||||
>
|
||||
<el-tab-pane label="过程图纸 " name="1"
|
||||
><TableContent :data="fileList" :wf-business-status="wf_business_status">
|
||||
</TableContent>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="过程图纸 " name="1">
|
||||
<TableContent :data="fileList" :wf-business-status="wf_business_status">
|
||||
<template #operation="{ row }">
|
||||
<el-button link type="primary" icon="edit" @click="handleAudit(row)" v-if="row.auditStatus == 'draft' || row.auditStatus == 'back'"
|
||||
>审核</el-button
|
||||
@ -216,15 +217,15 @@
|
||||
>查看单据</el-button
|
||||
>
|
||||
</template>
|
||||
</TableContent></el-tab-pane
|
||||
>
|
||||
<el-tab-pane label="作废 " name="4"
|
||||
><TableContent :data="fileList" :wf-business-status="wf_business_status">
|
||||
</TableContent>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="作废 " name="4">
|
||||
<TableContent :data="fileList" :wf-business-status="wf_business_status">
|
||||
<template #operation="{ row }">
|
||||
<el-button type="danger" link icon="Download" @click="handleDownload(row)"> 下载 </el-button>
|
||||
</template>
|
||||
</TableContent></el-tab-pane
|
||||
>
|
||||
</TableContent>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
<template #footer>
|
||||
<span>
|
||||
@ -644,22 +645,29 @@ const getVolumeFileList = async (type) => {
|
||||
}
|
||||
};
|
||||
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('下载失败,请重试');
|
||||
}
|
||||
proxy?.download(
|
||||
'/design/volumeCatalog/exportExcel',
|
||||
{
|
||||
projectId: currentProject.value?.id
|
||||
},
|
||||
`设计出图计划导入模版.xlsx`
|
||||
);
|
||||
// // 导出模版文件
|
||||
// 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) => {
|
||||
@ -699,6 +707,7 @@ onUnmounted(() => {
|
||||
border-collapse: collapse; //合并为一个单一的边框
|
||||
border-color: rgba(199, 199, 199, 1); //边框颜色按实际自定义即可
|
||||
}
|
||||
|
||||
thead {
|
||||
tr {
|
||||
th {
|
||||
@ -708,16 +717,19 @@ onUnmounted(() => {
|
||||
letter-spacing: 5px;
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
td {
|
||||
text-align: left;
|
||||
height: 35px; //设置单元格最小高度
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
.th-bg {
|
||||
background-color: rgba(247, 247, 247, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tbody {
|
||||
tr {
|
||||
td {
|
||||
@ -725,6 +737,7 @@ onUnmounted(() => {
|
||||
height: 40px; //设置单元格最小高度
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
th {
|
||||
height: 35px; //设置单元格最小高度
|
||||
text-align: center;
|
||||
@ -733,6 +746,7 @@ onUnmounted(() => {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.table-content {
|
||||
box-shadow: 0px 0px 10px #ddd;
|
||||
padding: 20px;
|
||||
|
@ -1,187 +1,102 @@
|
||||
<template>
|
||||
<div class="p5" style="width: 100%;height: calc(100vh - 84px);" v-loading="loading">
|
||||
<div id="TrajectoryEarth" style="width: 100%;height: 100%;"></div>
|
||||
<div class="p5" style="width: 100%; height: calc(100vh - 84px)" v-loading="loading">
|
||||
<!-- 返回按钮区域 -->
|
||||
<div style="position: absolute; top: 20px; left: 20px; z-index: 100; display: flex; gap: 10px">
|
||||
<el-button type="primary" icon="ArrowLeft" @click="handleBack">返回</el-button>
|
||||
<el-button type="success" icon="Play" @click="handleStart">开始</el-button>
|
||||
<el-button type="warning" icon="Pause" @click="handleStop">停止</el-button>
|
||||
</div>
|
||||
<div id="TrajectoryEarth" style="width: 100%; height: 100%"></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="equipmentGPS">
|
||||
import { ref, onMounted, onUnmounted } from 'vue';
|
||||
import { ElButton } from 'element-plus';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import { useRoute, useRouter } from 'vue-router'; // 补充导入useRouter
|
||||
import { getFootNote } from '@/api/equipment/index';
|
||||
import { ModelPathMover } from './index.js';
|
||||
|
||||
const route = useRoute();
|
||||
const router = useRouter(); // 初始化router
|
||||
const loading = ref(true);
|
||||
let modelMover = null;
|
||||
|
||||
// 返回上一页
|
||||
const handleBack = () => {
|
||||
router.back();
|
||||
};
|
||||
|
||||
// 开始轨迹运动
|
||||
const handleStart = () => {
|
||||
if (modelMover && typeof modelMover.start === 'function') {
|
||||
try {
|
||||
modelMover.start();
|
||||
ElMessage.success('轨迹已开始播放');
|
||||
} catch (error) {
|
||||
console.error('启动轨迹失败:', error);
|
||||
ElMessage.error('启动轨迹失败');
|
||||
}
|
||||
} else {
|
||||
ElMessage.warning('轨迹未初始化,请稍后再试');
|
||||
}
|
||||
};
|
||||
|
||||
// 停止轨迹运动
|
||||
const handleStop = () => {
|
||||
if (modelMover && typeof modelMover.stop === 'function') {
|
||||
try {
|
||||
modelMover.stop();
|
||||
ElMessage.success('轨迹已停止');
|
||||
} catch (error) {
|
||||
console.error('停止轨迹失败:', error);
|
||||
ElMessage.error('停止轨迹失败');
|
||||
}
|
||||
} else {
|
||||
ElMessage.warning('轨迹未初始化,请稍后再试');
|
||||
}
|
||||
};
|
||||
|
||||
let earthInstance = null;
|
||||
let data = [
|
||||
{
|
||||
"lng": 106.45637808828741,
|
||||
"lat": 29.5597535878972,
|
||||
"alt": 0
|
||||
},
|
||||
{
|
||||
"lng": 106.45971817314378,
|
||||
"lat": 29.54708008996366,
|
||||
"alt": 0
|
||||
},
|
||||
{
|
||||
"lng": 106.4594902314301,
|
||||
"lat": 29.53682043192008,
|
||||
"alt": 0
|
||||
},
|
||||
{
|
||||
"lng": 106.47398277208025,
|
||||
"lat": 29.5448688679258,
|
||||
"alt": 0
|
||||
},
|
||||
{
|
||||
"lng": 106.4793889453858,
|
||||
"lat": 29.549294608101395,
|
||||
"alt": 0.0016450895529057888
|
||||
},
|
||||
{
|
||||
"lng": 106.49100748408087,
|
||||
"lat": 29.551808876409023,
|
||||
"alt": 0
|
||||
},
|
||||
{
|
||||
"lng": 106.5040076285079,
|
||||
"lat": 29.55321574288158,
|
||||
"alt": 0
|
||||
},
|
||||
{
|
||||
"lng": 106.51355510567937,
|
||||
"lat": 29.546776414794298,
|
||||
"alt": 0
|
||||
},
|
||||
{
|
||||
"lng": 106.51838453732344,
|
||||
"lat": 29.537721996213506,
|
||||
"alt": 0
|
||||
},
|
||||
{
|
||||
"lng": 106.51457768703192,
|
||||
"lat": 29.524855377287736,
|
||||
"alt": 0.0009144105438296915
|
||||
},
|
||||
{
|
||||
"lng": 106.52872030672225,
|
||||
"lat": 29.53289655789934,
|
||||
"alt": 0.0005979679117487334
|
||||
},
|
||||
{
|
||||
"lng": 106.53493249730421,
|
||||
"lat": 29.541341118458874,
|
||||
"alt": 0
|
||||
},
|
||||
{
|
||||
"lng": 106.53390022310705,
|
||||
"lat": 29.54848036964581,
|
||||
"alt": 0
|
||||
},
|
||||
{
|
||||
"lng": 106.53471751083796,
|
||||
"lat": 29.55380771856629,
|
||||
"alt": 0
|
||||
},
|
||||
{
|
||||
"lng": 106.53518023558718,
|
||||
"lat": 29.560247052020156,
|
||||
"alt": 0
|
||||
},
|
||||
{
|
||||
"lng": 106.52470634506619,
|
||||
"lat": 29.560148336926677,
|
||||
"alt": 0
|
||||
},
|
||||
{
|
||||
"lng": 106.52527983360243,
|
||||
"lat": 29.55240114606003,
|
||||
"alt": 0
|
||||
},
|
||||
{
|
||||
"lng": 106.51837614087053,
|
||||
"lat": 29.557734494325807,
|
||||
"alt": 0.0021893863172707047
|
||||
},
|
||||
{
|
||||
"lng": 106.51573052195917,
|
||||
"lat": 29.564878142363643,
|
||||
"alt": 0
|
||||
},
|
||||
{
|
||||
"lng": 106.50951515081469,
|
||||
"lat": 29.556427329943944,
|
||||
"alt": 0
|
||||
},
|
||||
{
|
||||
"lng": 106.5076746620389,
|
||||
"lat": 29.565884717127823,
|
||||
"alt": 0
|
||||
},
|
||||
{
|
||||
"lng": 106.50341642164544,
|
||||
"lat": 29.558842113740727,
|
||||
"alt": 0
|
||||
},
|
||||
{
|
||||
"lng": 106.50065453145776,
|
||||
"lat": 29.567897073636868,
|
||||
"alt": 0
|
||||
},
|
||||
{
|
||||
"lng": 106.49328990493458,
|
||||
"lat": 29.558741275828908,
|
||||
"alt": 0
|
||||
},
|
||||
{
|
||||
"lng": 106.49363360765534,
|
||||
"lat": 29.57333026493932,
|
||||
"alt": 0
|
||||
},
|
||||
{
|
||||
"lng": 106.51905977395505,
|
||||
"lat": 29.57828423907017,
|
||||
"alt": 0
|
||||
},
|
||||
{
|
||||
"lng": 106.51145952743101,
|
||||
"lat": 29.584527208426245,
|
||||
"alt": 0
|
||||
},
|
||||
{
|
||||
"lng": 106.49372239119027,
|
||||
"lat": 29.58774998459616,
|
||||
"alt": 0
|
||||
},
|
||||
{
|
||||
"lng": 106.48214171543982,
|
||||
"lat": 29.580866974898736,
|
||||
"alt": 0.006089177027688381
|
||||
},
|
||||
{
|
||||
"lng": 106.48801515807557,
|
||||
"lat": 29.57049465877845,
|
||||
"alt": 0
|
||||
},
|
||||
{
|
||||
"lng": 106.47638485150803,
|
||||
"lat": 29.571501851940585,
|
||||
"alt": 0.0011061005102942808
|
||||
},
|
||||
{
|
||||
"lng": 106.47903303165843,
|
||||
"lat": 29.562542838689904,
|
||||
"alt": 0.0011137835517156711
|
||||
},
|
||||
{
|
||||
"lng": 106.4645244823306,
|
||||
"lat": 29.56868284644567,
|
||||
"alt": 0.00008251706068442191
|
||||
},
|
||||
{
|
||||
"lng": 106.47108853087332,
|
||||
"lat": 29.555194220499004,
|
||||
"alt": 0
|
||||
},
|
||||
]
|
||||
'locLongitude': 106.45637808828741,
|
||||
'locLatitude': 29.5597535878972,
|
||||
'locAltitude': 0
|
||||
}
|
||||
];
|
||||
|
||||
// 获取轨迹数据
|
||||
const getTrajectoryData = async () => {
|
||||
try {
|
||||
// 从URL参数中获取clientId、projectId和userId
|
||||
const { clientId, projectId, userId } = route.query;
|
||||
|
||||
if (!clientId || !projectId || !userId) {
|
||||
ElMessage.warning('缺少必要参数,请检查传入的参数');
|
||||
return;
|
||||
}
|
||||
|
||||
loading.value = true;
|
||||
const res = await getFootNote({ clientId, projectId, userId });
|
||||
|
||||
if (res && res.code === 200 && res.data && res.data.length > 0) {
|
||||
data = res.data;
|
||||
// 渲染轨迹
|
||||
if (earthInstance && earthInstance.viewer) {
|
||||
renderRange(data);
|
||||
}
|
||||
} else {
|
||||
ElMessage.warning('暂无轨迹数据');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取轨迹数据失败:', error);
|
||||
ElMessage.error('获取轨迹数据失败,请稍后重试');
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 创建地球
|
||||
const createEarth = () => {
|
||||
@ -191,48 +106,51 @@ const createEarth = () => {
|
||||
}
|
||||
|
||||
window.YJ.on({
|
||||
ws: true,
|
||||
ws: true
|
||||
// host: getIP(), // 资源所在服务器地址
|
||||
// username: this.loginForm.username, // 用户名
|
||||
// password: md5pass, // 密码
|
||||
}).then((res) => {
|
||||
loading.value = false;
|
||||
// 创建地球实例
|
||||
earthInstance = new YJ.YJEarth('TrajectoryEarth');
|
||||
window.Earth3 = earthInstance;
|
||||
})
|
||||
.then((res) => {
|
||||
// 创建地球实例
|
||||
earthInstance = new YJ.YJEarth('TrajectoryEarth');
|
||||
window.Earth3 = earthInstance;
|
||||
|
||||
// 开启右键和左键点击事件
|
||||
YJ.Global.openRightClick(window.Earth3);
|
||||
YJ.Global.openLeftClick(window.Earth3);
|
||||
// 开启右键和左键点击事件
|
||||
YJ.Global.openRightClick(window.Earth3);
|
||||
YJ.Global.openLeftClick(window.Earth3);
|
||||
|
||||
// 设置初始视角
|
||||
const view = {
|
||||
position: {
|
||||
lng: 102.03643298211526,
|
||||
lat: 34.393586474501,
|
||||
alt: 11298179.51993155
|
||||
},
|
||||
orientation: {
|
||||
heading: 360,
|
||||
pitch: -89.94481747201486,
|
||||
roll: 0
|
||||
}
|
||||
};
|
||||
// 设置初始视角
|
||||
const view = {
|
||||
position: {
|
||||
lng: 102.03643298211526,
|
||||
lat: 34.393586474501,
|
||||
alt: 11298179.51993155
|
||||
},
|
||||
orientation: {
|
||||
heading: 360,
|
||||
pitch: -89.94481747201486,
|
||||
roll: 0
|
||||
}
|
||||
};
|
||||
|
||||
YJ.Global.CesiumContainer(window.Earth3, {
|
||||
compass: false, //罗盘
|
||||
YJ.Global.CesiumContainer(window.Earth3, {
|
||||
compass: false //罗盘
|
||||
});
|
||||
// 加载底图
|
||||
loadBaseMap(earthInstance.viewer);
|
||||
|
||||
// 可以取消注释以下代码来设置初始视角
|
||||
// YJ.Global.flyTo(earthInstance, view);
|
||||
// YJ.Global.setDefaultView(earthInstance.viewer, view)
|
||||
|
||||
// 地球创建完成后获取并渲染轨迹数据
|
||||
getTrajectoryData();
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error('初始化地球失败:', err);
|
||||
ElMessage.error('初始化地球失败,请稍后重试');
|
||||
});
|
||||
// 加载底图
|
||||
loadBaseMap(earthInstance.viewer);
|
||||
|
||||
// 可以取消注释以下代码来设置初始视角
|
||||
// YJ.Global.flyTo(earthInstance, view);
|
||||
// YJ.Global.setDefaultView(earthInstance.viewer, view)
|
||||
renderRange(data);
|
||||
}).catch((err) => {
|
||||
console.error('初始化地球失败:', err);
|
||||
ElMessage.error('初始化地球失败,请稍后重试');
|
||||
});
|
||||
};
|
||||
|
||||
// 加载底图
|
||||
@ -274,35 +192,39 @@ const renderRange = (data) => {
|
||||
}
|
||||
|
||||
try {
|
||||
const positions = data.map((point) => {
|
||||
return Cesium.Cartesian3.fromDegrees(point.lng, point.lat, point.alt || 0);
|
||||
const positions = data.map((item) => {
|
||||
return {
|
||||
lon: item.locLongitude,
|
||||
lat: item.locLatitude,
|
||||
height: item.locAltitude || 0,
|
||||
name: item.name || ''
|
||||
};
|
||||
});
|
||||
|
||||
const entity = earthInstance.viewer.entities.add({
|
||||
polyline: {
|
||||
positions: positions,
|
||||
width: 5,
|
||||
material: Cesium.Color.RED,
|
||||
clampToGround: true
|
||||
}
|
||||
modelMover = new ModelPathMover(window.Earth3.viewer, {
|
||||
// modelUrl: './air.glb', // 模型URL
|
||||
positions: positions,
|
||||
speed: 50, // 移动速度
|
||||
loop: true, // 循环运动
|
||||
iconUrl: '/image/Foot.png', // 模型上方图标
|
||||
baseHeight: 10 // 外部传入的统一高度(米)
|
||||
});
|
||||
|
||||
// 调整视角以适应轨迹
|
||||
earthInstance.viewer.flyTo(entity);
|
||||
window.modelMover = modelMover;
|
||||
} catch (err) {
|
||||
console.error('渲染轨迹失败:', err);
|
||||
ElMessage.error('渲染轨迹失败');
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
onMounted(() => {
|
||||
createEarth();
|
||||
});
|
||||
|
||||
//
|
||||
onUnmounted(() => {
|
||||
if (modelMover) {
|
||||
modelMover.stop(); // 组件卸载时停止轨迹
|
||||
modelMover = null;
|
||||
}
|
||||
if (earthInstance) {
|
||||
earthInstance.destroy();
|
||||
earthInstance = null;
|
||||
|
392
src/views/equipment/index.js
Normal file
392
src/views/equipment/index.js
Normal file
@ -0,0 +1,392 @@
|
||||
export class ModelPathMover {
|
||||
/**
|
||||
* 构造函数
|
||||
* @param {Cesium.Viewer} viewer - Cesium viewer实例
|
||||
* @param {Object} options - 配置选项
|
||||
* @param {Number} [options.baseHeight=0] - 外部传入的统一高度(米),将叠加到所有位置点上
|
||||
*/
|
||||
constructor(viewer, options) {
|
||||
this.viewer = viewer;
|
||||
this.modelUrl = options.modelUrl;
|
||||
this.positions = options.positions || [];
|
||||
this.speed = options.speed || 10; // 米/秒
|
||||
this.loop = options.loop !== undefined ? options.loop : true;
|
||||
this.pathStyle = options.pathStyle || {
|
||||
color: Cesium.Color.YELLOW,
|
||||
width: 3
|
||||
};
|
||||
this.markerStyle = options.markerStyle || {
|
||||
color: Cesium.Color.RED,
|
||||
pixelSize: 10,
|
||||
outlineColor: Cesium.Color.WHITE,
|
||||
outlineWidth: 2
|
||||
};
|
||||
this.iconUrl = options.iconUrl;
|
||||
this.iconSize = options.iconSize || 32;
|
||||
this.iconOffset = options.iconOffset || 0;
|
||||
this.headingOffset = options.headingOffset || 0;
|
||||
// 新增:接收外部传入的统一高度(默认0米)
|
||||
this.baseHeight = options.baseHeight || 0;
|
||||
|
||||
// 内部状态(保持不变)
|
||||
this.modelEntity = null;
|
||||
this.pathEntity = null;
|
||||
this.markerEntities = [];
|
||||
this.iconEntity = null;
|
||||
this.currentIndex = 0;
|
||||
this.isMoving = false;
|
||||
this.lastTime = 0;
|
||||
this.animationFrameId = null;
|
||||
this.currentPosition = null;
|
||||
this.progress = 0;
|
||||
this.modelHeight = 0;
|
||||
|
||||
// 初始化
|
||||
this.init();
|
||||
|
||||
// 调试信息(增加baseHeight打印)
|
||||
console.log('ModelPathMover初始化完成', {
|
||||
positionCount: this.positions.length,
|
||||
speed: this.speed,
|
||||
loop: this.loop,
|
||||
baseHeight: this.baseHeight // 打印传入的统一高度
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化(保持不变)
|
||||
*/
|
||||
init() {
|
||||
if (this.positions.length < 2) {
|
||||
console.warn('至少需要2个位置点才能进行移动');
|
||||
}
|
||||
this.createPath();
|
||||
this.createMarkers();
|
||||
this.createModel();
|
||||
if (this.iconUrl) {
|
||||
this.createIcon();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建模型(修改:叠加baseHeight)
|
||||
*/
|
||||
createModel() {
|
||||
if (this.positions.length === 0) return;
|
||||
|
||||
const firstPos = this.positions[0];
|
||||
// 关键修改:在原始高度基础上叠加baseHeight
|
||||
const finalHeight = (firstPos.height || 0) + this.baseHeight;
|
||||
this.currentPosition = Cesium.Cartesian3.fromDegrees(
|
||||
firstPos.lon,
|
||||
firstPos.lat,
|
||||
finalHeight // 使用叠加后的高度
|
||||
);
|
||||
|
||||
// 初始朝向计算(保持不变)
|
||||
let initialOrientation = Cesium.Transforms.headingPitchRollQuaternion(this.currentPosition, new Cesium.HeadingPitchRoll(0, 0, 0));
|
||||
|
||||
if (this.positions.length > 1) {
|
||||
const nextPos = this.positions[1];
|
||||
// 计算下一个点时同样叠加baseHeight
|
||||
const nextFinalHeight = (nextPos.height || 0) + this.baseHeight;
|
||||
const nextCartesian = Cesium.Cartesian3.fromDegrees(nextPos.lon, nextPos.lat, nextFinalHeight);
|
||||
const heading = this.calculateHeading(this.currentPosition, nextCartesian);
|
||||
initialOrientation = Cesium.Transforms.headingPitchRollQuaternion(this.currentPosition, new Cesium.HeadingPitchRoll(heading, 0, 0));
|
||||
}
|
||||
|
||||
this.modelEntity = this.viewer.entities.add({
|
||||
name: 'Moving Model',
|
||||
position: this.currentPosition,
|
||||
orientation: initialOrientation,
|
||||
model: {
|
||||
uri: this.modelUrl,
|
||||
minimumPixelSize: 64,
|
||||
readyPromise: (model) => {
|
||||
const boundingSphere = model.boundingSphere;
|
||||
if (boundingSphere) {
|
||||
this.modelHeight = boundingSphere.radius * 2;
|
||||
console.log('模型高度检测完成:', this.modelHeight, '米');
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建路径(修改:叠加baseHeight)
|
||||
*/
|
||||
createPath() {
|
||||
if (this.positions.length < 2) return;
|
||||
|
||||
// 关键修改:遍历所有点时,给每个点的高度叠加baseHeight
|
||||
const pathPositions = this.positions.map((pos) => {
|
||||
const finalHeight = (pos.height || 0) + this.baseHeight;
|
||||
return Cesium.Cartesian3.fromDegrees(pos.lon, pos.lat, finalHeight);
|
||||
});
|
||||
|
||||
this.pathEntity = this.viewer.entities.add({
|
||||
name: 'Model Path',
|
||||
polyline: {
|
||||
positions: pathPositions,
|
||||
width: this.pathStyle.width,
|
||||
material: this.pathStyle.color,
|
||||
clampToGround: false
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建位置标记(修改:叠加baseHeight)
|
||||
*/
|
||||
createMarkers() {
|
||||
this.markerEntities = this.positions.map((pos, index) => {
|
||||
// 关键修改:标记点高度同样叠加baseHeight
|
||||
const finalHeight = (pos.height || 0) + this.baseHeight;
|
||||
const position = Cesium.Cartesian3.fromDegrees(pos.lon, pos.lat, finalHeight);
|
||||
|
||||
const marker = this.viewer.entities.add({
|
||||
name: `Position Marker ${index}`,
|
||||
position: position,
|
||||
point: {
|
||||
color: this.markerStyle.color,
|
||||
pixelSize: this.markerStyle.pixelSize,
|
||||
outlineColor: this.markerStyle.outlineColor,
|
||||
outlineWidth: this.markerStyle.outlineWidth
|
||||
},
|
||||
label: {
|
||||
text: pos.name || `Point ${index + 1}`,
|
||||
font: '14px sans-serif',
|
||||
pixelOffset: new Cesium.Cartesian2(0, -20),
|
||||
fillColor: Cesium.Color.WHITE
|
||||
}
|
||||
});
|
||||
|
||||
return marker;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建模型上方的图标(保持不变)
|
||||
*/
|
||||
createIcon() {
|
||||
this.iconEntity = this.viewer.entities.add({
|
||||
name: 'Model Icon',
|
||||
position: new Cesium.CallbackProperty(() => {
|
||||
return this.adjustCartesianHeight(this.currentPosition, 0.3);
|
||||
}, false),
|
||||
billboard: {
|
||||
image: this.iconUrl,
|
||||
width: this.iconSize,
|
||||
height: this.iconSize,
|
||||
verticalOrigin: Cesium.VerticalOrigin.BOTTOM
|
||||
},
|
||||
label: {
|
||||
text: 'Model Icon',
|
||||
font: '14px sans-serif',
|
||||
pixelOffset: new Cesium.Cartesian2(0, -40),
|
||||
fillColor: Cesium.Color.WHITE
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 调整笛卡尔坐标的高度(在原有高度基础上叠加指定值)
|
||||
* @param {Cesium.Cartesian3} cartesian - 原始笛卡尔坐标
|
||||
* @param {Number} heightOffset - 要增加的高度值(米,可为负数)
|
||||
* @param {Cesium.Ellipsoid} [ellipsoid=Cesium.Ellipsoid.WGS84] - 参考椭球体
|
||||
* @returns {Cesium.Cartesian3|null} 调整高度后的笛卡尔坐标(失败返回null)
|
||||
*/
|
||||
adjustCartesianHeight(cartesian, heightOffset, ellipsoid = Cesium.Ellipsoid.WGS84) {
|
||||
// 1. 校验输入的笛卡尔坐标是否有效
|
||||
// if (!Cesium.Cartesian3.isValid(cartesian)) {
|
||||
// console.error("无效的笛卡尔坐标,无法调整高度");
|
||||
// return null;
|
||||
// }
|
||||
|
||||
// 2. 笛卡尔坐标 → Cartographic(地理坐标,含弧度经纬度和高度)
|
||||
const cartographic = Cesium.Cartographic.fromCartesian(cartesian, ellipsoid);
|
||||
if (!cartographic) {
|
||||
console.error('笛卡尔坐标转换为Cartographic失败');
|
||||
return null;
|
||||
}
|
||||
|
||||
// 3. 调整高度(在原有高度上叠加offset,可为负数)
|
||||
cartographic.height += heightOffset;
|
||||
// 可选:确保高度不低于0(根据需求决定是否保留)
|
||||
// cartographic.height = Math.max(cartographic.height, 0);
|
||||
|
||||
// 4. Cartographic → 笛卡尔坐标(使用弧度经纬度转换)
|
||||
const adjustedCartesian = Cesium.Cartesian3.fromRadians(
|
||||
cartographic.longitude, // 经度(弧度)
|
||||
cartographic.latitude, // 纬度(弧度)
|
||||
cartographic.height, // 调整后的高度(米)
|
||||
ellipsoid
|
||||
);
|
||||
|
||||
return adjustedCartesian;
|
||||
}
|
||||
/**
|
||||
* 开始移动(保持不变)
|
||||
*/
|
||||
start() {
|
||||
if (this.isMoving) {
|
||||
console.log('模型已经在移动中');
|
||||
return;
|
||||
}
|
||||
if (this.positions.length < 2) {
|
||||
console.error('无法移动:位置点数量不足(至少需要2个)');
|
||||
return;
|
||||
}
|
||||
this.isMoving = true;
|
||||
this.lastTime = performance.now();
|
||||
this.progress = 0;
|
||||
console.log('开始移动,速度:', this.speed, '米/秒');
|
||||
this.animate();
|
||||
}
|
||||
|
||||
/**
|
||||
* 动画循环函数(保持不变)
|
||||
*/
|
||||
animate() {
|
||||
if (!this.isMoving) return;
|
||||
const currentTime = performance.now();
|
||||
const timeDeltaMs = currentTime - this.lastTime;
|
||||
this.lastTime = currentTime;
|
||||
const timeDelta = timeDeltaMs / 1000;
|
||||
this.updatePosition(timeDelta);
|
||||
this.animationFrameId = requestAnimationFrame(() => this.animate());
|
||||
}
|
||||
|
||||
/**
|
||||
* 停止移动(保持不变)
|
||||
*/
|
||||
stop() {
|
||||
if (!this.isMoving) return;
|
||||
this.isMoving = false;
|
||||
console.log('停止移动');
|
||||
if (this.animationFrameId) {
|
||||
cancelAnimationFrame(this.animationFrameId);
|
||||
this.animationFrameId = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新模型位置(修改:叠加baseHeight)
|
||||
*/
|
||||
updatePosition(timeDelta) {
|
||||
if (!this.isMoving) return;
|
||||
const distanceToMove = this.speed * timeDelta;
|
||||
const currentPos = this.positions[this.currentIndex];
|
||||
const nextIndex = (this.currentIndex + 1) % this.positions.length;
|
||||
const nextPos = this.positions[nextIndex];
|
||||
|
||||
// 关键修改:计算当前点和下一点时,均叠加baseHeight
|
||||
const currentFinalHeight = (currentPos.height || 0) + this.baseHeight;
|
||||
const nextFinalHeight = (nextPos.height || 0) + this.baseHeight;
|
||||
|
||||
const currentCartesian = Cesium.Cartesian3.fromDegrees(currentPos.lon, currentPos.lat, currentFinalHeight);
|
||||
const nextCartesian = Cesium.Cartesian3.fromDegrees(nextPos.lon, nextPos.lat, nextFinalHeight);
|
||||
|
||||
// 后续逻辑保持不变
|
||||
const totalDistance = Cesium.Cartesian3.distance(currentCartesian, nextCartesian);
|
||||
if (totalDistance < 0.001) {
|
||||
this.currentIndex = nextIndex;
|
||||
this.progress = 0;
|
||||
this.setModelPosition(nextCartesian, this.getNextPositionCartesian(nextIndex));
|
||||
return;
|
||||
}
|
||||
this.progress += distanceToMove / totalDistance;
|
||||
if (this.progress >= 1.0) {
|
||||
const remainingDistance = (this.progress - 1.0) * totalDistance;
|
||||
this.currentIndex = nextIndex;
|
||||
if (!this.loop && this.currentIndex === this.positions.length - 1) {
|
||||
this.setModelPosition(nextCartesian, null);
|
||||
this.stop();
|
||||
console.log('已到达终点,停止移动');
|
||||
return;
|
||||
}
|
||||
const newTotalDistance = Cesium.Cartesian3.distance(nextCartesian, this.getNextPositionCartesian(this.currentIndex));
|
||||
this.progress = newTotalDistance > 0.001 ? remainingDistance / newTotalDistance : 0;
|
||||
this.setModelPosition(nextCartesian, this.getNextPositionCartesian(this.currentIndex));
|
||||
} else {
|
||||
const newPosition = Cesium.Cartesian3.lerp(currentCartesian, nextCartesian, this.progress, new Cesium.Cartesian3());
|
||||
this.setModelPosition(newPosition, nextCartesian);
|
||||
}
|
||||
this.viewer.scene.requestRender();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取下一个位置的笛卡尔坐标(修改:叠加baseHeight)
|
||||
*/
|
||||
getNextPositionCartesian(currentIndex) {
|
||||
const nextIndex = (currentIndex + 1) % this.positions.length;
|
||||
const nextPos = this.positions[nextIndex];
|
||||
// 关键修改:返回下一点时叠加baseHeight
|
||||
const finalHeight = (nextPos.height || 0) + this.baseHeight;
|
||||
return Cesium.Cartesian3.fromDegrees(nextPos.lon, nextPos.lat, finalHeight);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置模型位置和方向(保持不变)
|
||||
*/
|
||||
setModelPosition(position, targetPosition) {
|
||||
if (!this.modelEntity) return;
|
||||
this.currentPosition = position;
|
||||
this.modelEntity.position.setValue(position);
|
||||
if (targetPosition) {
|
||||
const heading = this.calculateHeading(position, targetPosition);
|
||||
this.modelEntity.orientation.setValue(Cesium.Transforms.headingPitchRollQuaternion(position, new Cesium.HeadingPitchRoll(heading, 0, 0)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算两点之间的朝向(保持不变)
|
||||
*/
|
||||
calculateHeading(from, to) {
|
||||
const fromCartographic = Cesium.Cartographic.fromCartesian(from);
|
||||
const toCartographic = Cesium.Cartographic.fromCartesian(to);
|
||||
const startLat = fromCartographic.latitude;
|
||||
const startLon = fromCartographic.longitude;
|
||||
const endLat = toCartographic.latitude;
|
||||
const endLon = toCartographic.longitude;
|
||||
const dLon = endLon - startLon;
|
||||
const y = Math.sin(dLon) * Math.cos(endLat);
|
||||
const x = Math.cos(startLat) * Math.sin(endLat) - Math.sin(startLat) * Math.cos(endLat) * Math.cos(dLon);
|
||||
let heading = Math.atan2(y, x);
|
||||
heading = (heading + Cesium.Math.TWO_PI) % Cesium.Math.TWO_PI;
|
||||
heading = (heading + this.headingOffset) % Cesium.Math.TWO_PI;
|
||||
return heading;
|
||||
}
|
||||
|
||||
/**
|
||||
* 手动设置模型高度(保持不变)
|
||||
*/
|
||||
setModelHeight(height) {
|
||||
this.modelHeight = height;
|
||||
console.log('手动设置模型高度:', height, '米');
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置航向角偏移(保持不变)
|
||||
*/
|
||||
setHeadingOffset(offsetDegrees) {
|
||||
this.headingOffset = Cesium.Math.toRadians(offsetDegrees);
|
||||
console.log('设置航向角偏移:', offsetDegrees, '度');
|
||||
}
|
||||
|
||||
/**
|
||||
* 销毁所有资源(保持不变)
|
||||
*/
|
||||
destroy() {
|
||||
this.stop();
|
||||
if (this.modelEntity) this.viewer.entities.remove(this.modelEntity);
|
||||
if (this.pathEntity) this.viewer.entities.remove(this.pathEntity);
|
||||
this.markerEntities.forEach((marker) => this.viewer.entities.remove(marker));
|
||||
if (this.iconEntity) this.viewer.entities.remove(this.iconEntity);
|
||||
this.modelEntity = null;
|
||||
this.pathEntity = null;
|
||||
this.markerEntities = [];
|
||||
this.iconEntity = null;
|
||||
}
|
||||
}
|
@ -24,27 +24,22 @@
|
||||
<template #header>
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['system:equipment:edit']"
|
||||
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['gps:equipment:edit']"
|
||||
>修改</el-button
|
||||
>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['system:equipment:remove']"
|
||||
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['gps:equipment:remove']"
|
||||
>删除</el-button
|
||||
>
|
||||
</el-col>
|
||||
<el-col :span="1.8">
|
||||
<el-button type="primary" plain icon="User" :disabled="single" @click="handleBindUser()" v-hasPermi="['system:equipment:bindUser']"
|
||||
<el-button type="primary" plain icon="User" :disabled="single" @click="handleBindUser()" v-hasPermi="['gps:equipment:bindManmachine']"
|
||||
>绑定用户</el-button
|
||||
>
|
||||
</el-col>
|
||||
<el-col :span="2">
|
||||
<el-button type="primary" plain @click="handleViewAll" v-hasPermi="['system:equipment:view']">{{ viewAllButtonText }}</el-button>
|
||||
</el-col>
|
||||
|
||||
<!-- 新增:跳转空页面按钮 -->
|
||||
<el-col :span="2">
|
||||
<el-button type="primary" plain icon="international" @click="handleGoToEmptyPage"> GPS定位 </el-button>
|
||||
<el-button type="primary" plain @click="handleViewAll">{{ viewAllButtonText }}</el-button>
|
||||
</el-col>
|
||||
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||
@ -68,17 +63,7 @@
|
||||
</el-table-column>
|
||||
|
||||
<!-- 设备名称列 -->
|
||||
<el-table-column label="设备名称" align="center">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
type="text"
|
||||
@click="handleOpenHistoryUser(scope.row.clientId, scope.row.userId)"
|
||||
style="padding: 0; color: #409eff; cursor: pointer"
|
||||
>
|
||||
{{ scope.row.deviceName || '-' }}
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="设备名称" align="center" prop="deviceName" />
|
||||
|
||||
<el-table-column label="远程连接地址" align="center" prop="remoteAddressStr" />
|
||||
<el-table-column label="连接创建时间" align="center">
|
||||
@ -106,7 +91,28 @@
|
||||
type="primary"
|
||||
icon="User"
|
||||
@click="scope.row.type === 1 ? handleUnbindUser(scope.row) : handleBindUser(scope.row)"
|
||||
v-hasPermi="['gps:equipment:bindUser']"
|
||||
v-hasPermi="scope.row.type === 1 ? ['gps:equipment:unbindManmachine'] : ['gps:equipment:bindManmachine']"
|
||||
>
|
||||
</el-button>
|
||||
</el-tooltip>
|
||||
|
||||
<el-tooltip content="足迹" placement="top">
|
||||
<el-button
|
||||
link
|
||||
type="primary"
|
||||
icon="Location"
|
||||
v-hasPermi="['gps:equipmentSon:getList']"
|
||||
@click="handleGoToEmptyPage(scope.row.userId, scope.row.projectId, scope.row.clientId)"
|
||||
:disabled="!scope.row.userId || !scope.row.projectId"
|
||||
></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="历史记录" placement="top">
|
||||
<el-button
|
||||
link
|
||||
type="primary"
|
||||
icon="Clock"
|
||||
@click="handleOpenHistoryUser(scope.row.clientId, scope.row.userId)"
|
||||
v-hasPermi="['gps:equipment:getUserList']"
|
||||
>
|
||||
</el-button>
|
||||
</el-tooltip>
|
||||
@ -141,9 +147,6 @@
|
||||
<el-option v-for="project in projectList" :key="project.projectId" :label="project.projectName" :value="project.projectId" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="设备名称" prop="deviceName">
|
||||
<el-input v-model="bindForm.deviceName" disabled placeholder="设备名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="选择用户" prop="userId" required>
|
||||
<el-select v-model="bindForm.userId" placeholder="请选择用户" clearable>
|
||||
<el-option v-for="user in userList" :key="user.sysUserId" :label="user.userName" :value="user.sysUserId" />
|
||||
@ -170,6 +173,7 @@
|
||||
>
|
||||
<el-table-column label="序号" type="index" width="60" align="center" />
|
||||
<el-table-column label="用户名" align="center" prop="userName" />
|
||||
<el-table-column label="项目名称" align="center" prop="projectName" />
|
||||
<el-table-column label="状态" align="center" width="120">
|
||||
<template #default="scope">
|
||||
<el-tag :type="scope.row.type === 0 ? 'success' : 'info'" size="small">
|
||||
@ -177,6 +181,19 @@
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" width="80">
|
||||
<template #default="scope">
|
||||
<el-tooltip content="足迹" placement="top">
|
||||
<el-button
|
||||
link
|
||||
type="primary"
|
||||
icon="Location"
|
||||
v-hasPermi="['gps:equipmentSon:getList']"
|
||||
@click="handleGoToEmptyPage(scope.row.userId, scope.row.projectId, currentHistoryClientId)"
|
||||
></el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<div v-if="!historyUserLoading && historyUserList.length === 0" style="text-align: center; padding: 50px 0">
|
||||
@ -240,7 +257,7 @@ const projectList = ref<any[]>([]);
|
||||
const projectLoading = ref(false);
|
||||
const userLoading = ref(false);
|
||||
const viewAllButtonText = computed(() => {
|
||||
return queryParams.value.type === 1 ? '查看未绑定设备' : '查看已绑定设备';
|
||||
return queryParams.value.type === 1 ? '查看未绑定项目设备' : '查看已绑定项目设备';
|
||||
});
|
||||
|
||||
// 对话框相关
|
||||
@ -473,9 +490,16 @@ const handleViewAll = () => {
|
||||
getList();
|
||||
};
|
||||
|
||||
const handleGoToEmptyPage = () => {
|
||||
const handleGoToEmptyPage = (userId: any, projectId: any, clientId: any) => {
|
||||
console.log('userId:', userId, 'projectId:', projectId, 'clientId:', clientId);
|
||||
|
||||
router.push({
|
||||
path: './equipmentGPS'
|
||||
path: './equipmentGPS',
|
||||
query: {
|
||||
userId: userId,
|
||||
projectId: projectId,
|
||||
clientId: clientId
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
@ -568,41 +592,53 @@ const handleDelete = async (row?: ExtendedEquipmentVO) => {
|
||||
};
|
||||
|
||||
/** 绑定用户按钮操作 */
|
||||
const handleBindUser = async (row?: EquipmentVO) => {
|
||||
Object.assign(bindForm, {
|
||||
id: undefined,
|
||||
projectId: undefined,
|
||||
userId: undefined,
|
||||
clientId: row?.clientId,
|
||||
deviceName: undefined
|
||||
});
|
||||
bindUserFormRef.value?.resetFields();
|
||||
userList.value = [];
|
||||
|
||||
const _id = row?.id || ids.value[0];
|
||||
const handleBindUser = async (row: ExtendedEquipmentVO) => {
|
||||
try {
|
||||
const res = await getEquipment(_id);
|
||||
const equipmentData = res.data;
|
||||
bindForm.id = equipmentData.id;
|
||||
bindForm.deviceName = equipmentData.deviceName;
|
||||
bindForm.clientId = row?.clientId || equipmentData.clientId;
|
||||
if (!row) {
|
||||
proxy?.$modal.msgWarning('未获取到设备信息');
|
||||
return;
|
||||
}
|
||||
|
||||
if (row.id === undefined || row.id === null || row.id === '') {
|
||||
proxy?.$modal.msgWarning('设备ID不能为空');
|
||||
return;
|
||||
}
|
||||
const deviceId = Number(row.id);
|
||||
if (isNaN(deviceId) || deviceId <= 0) {
|
||||
proxy?.$modal.msgWarning(`设备ID格式错误,必须是正整数,当前值: ${row.id}`);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!row.clientId || typeof row.clientId !== 'string' || row.clientId.trim() === '') {
|
||||
proxy?.$modal.msgWarning(`设备标识clientId格式错误,必须是非空字符串,当前值: ${row.clientId}`);
|
||||
return;
|
||||
}
|
||||
|
||||
// 初始化表单
|
||||
Object.assign(bindForm, {
|
||||
id: deviceId,
|
||||
projectId: undefined,
|
||||
userId: undefined,
|
||||
clientId: row.clientId,
|
||||
deviceName: row.deviceName || '未知设备'
|
||||
});
|
||||
bindUserFormRef.value?.resetFields();
|
||||
userList.value = [];
|
||||
|
||||
// 加载项目和用户数据
|
||||
if (projectList.value.length === 0) {
|
||||
await getProjects();
|
||||
}
|
||||
|
||||
if (equipmentData.projectId) {
|
||||
bindForm.projectId = equipmentData.projectId;
|
||||
await getUsersByProjectId(equipmentData.projectId);
|
||||
} else if (currentProject.value?.id) {
|
||||
if (currentProject.value?.id) {
|
||||
bindForm.projectId = currentProject.value.id;
|
||||
await getUsersByProjectId(currentProject.value.id);
|
||||
}
|
||||
|
||||
bindDialogVisible.value = true;
|
||||
} catch (error) {
|
||||
console.error('获取绑定用户信息失败:', error);
|
||||
proxy?.$modal.msgError('获取数据失败,请重试');
|
||||
console.error('打开绑定用户对话框失败:', error);
|
||||
proxy?.$modal.msgError('操作失败,请重试');
|
||||
}
|
||||
};
|
||||
|
||||
@ -618,17 +654,9 @@ const submitBindUser = () => {
|
||||
|
||||
bindButtonLoading.value = true;
|
||||
try {
|
||||
const bindData = {
|
||||
id: bindForm.id,
|
||||
projectId: bindForm.projectId,
|
||||
userId: bindForm.userId,
|
||||
clientId: bindForm.clientId,
|
||||
deviceName: bindForm.deviceName
|
||||
};
|
||||
|
||||
console.log('提交绑定用户参数:', bindData);
|
||||
|
||||
await bindUser(bindData);
|
||||
// 直接使用bindForm数据调用bindUser接口
|
||||
console.log('提交绑定用户参数:', bindForm);
|
||||
await bindUser(bindForm);
|
||||
proxy?.$modal.msgSuccess('用户绑定成功');
|
||||
bindDialogVisible.value = false;
|
||||
await getList();
|
||||
@ -708,6 +736,8 @@ const handleOpenHistoryUser = async (clientId: string | number | undefined, curr
|
||||
historyUserDialogVisible.value = true;
|
||||
historyUserLoading.value = true;
|
||||
historyUserList.value = [];
|
||||
// 保存当前clientId用于足迹操作
|
||||
currentHistoryClientId.value = clientId;
|
||||
|
||||
try {
|
||||
const res = await gethistroyUser({
|
||||
@ -732,6 +762,27 @@ const handleOpenHistoryUser = async (clientId: string | number | undefined, curr
|
||||
}
|
||||
};
|
||||
|
||||
/** 历史弹窗中的足迹操作 */
|
||||
const handleFootprintOperation = () => {
|
||||
if (!historyUserList.value || historyUserList.value.length === 0) {
|
||||
proxy?.$modal.msgWarning('暂无用户数据,无法查看足迹');
|
||||
return;
|
||||
}
|
||||
|
||||
// 获取第一个用户的数据(通常是当前绑定用户)
|
||||
const firstUser = historyUserList.value[0];
|
||||
if (!firstUser.sysUserId) {
|
||||
proxy?.$modal.msgWarning('用户ID不存在,无法查看足迹');
|
||||
return;
|
||||
}
|
||||
|
||||
// 跳转到足迹页面
|
||||
handleGoToEmptyPage(firstUser.sysUserId, firstUser.projectId || currentProject.value?.id, currentHistoryClientId.value);
|
||||
};
|
||||
|
||||
// 当前历史弹窗的clientId
|
||||
const currentHistoryClientId = ref('');
|
||||
|
||||
/** 页面挂载时初始化 */
|
||||
onMounted(() => {
|
||||
getList();
|
||||
|
@ -1,6 +1,7 @@
|
||||
<template>
|
||||
<div class="p-2">
|
||||
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
|
||||
<transition :enter-active-class="proxy?.animate.searchAnimate.enter"
|
||||
:leave-active-class="proxy?.animate.searchAnimate.leave">
|
||||
<div v-show="showSearch" class="mb-[10px]">
|
||||
<el-card shadow="hover">
|
||||
<el-form ref="queryFormRef" :model="queryParams" :inline="true" label-width="100px">
|
||||
@ -11,25 +12,15 @@
|
||||
<el-input v-model="queryParams.formalitiesId" placeholder="请输入手续办理清单模板id" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item> -->
|
||||
<el-form-item label="计划开始时间" prop="planTheStartTime">
|
||||
<el-date-picker
|
||||
clearable
|
||||
v-model="queryParams.planTheStartTime"
|
||||
type="date"
|
||||
value-format="YYYY-MM-DD"
|
||||
placeholder="请选择计划开始时间"
|
||||
/>
|
||||
<el-date-picker clearable v-model="queryParams.planTheStartTime" type="date" value-format="YYYY-MM-DD"
|
||||
placeholder="请选择计划开始时间" />
|
||||
</el-form-item>
|
||||
<el-form-item label="负责人" prop="head">
|
||||
<el-input v-model="queryParams.head" placeholder="请输入负责人" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="实际完成时间" prop="actualCompletionTime">
|
||||
<el-date-picker
|
||||
clearable
|
||||
v-model="queryParams.actualCompletionTime"
|
||||
type="date"
|
||||
value-format="YYYY-MM-DD"
|
||||
placeholder="请选择实际完成时间"
|
||||
/>
|
||||
<el-date-picker clearable v-model="queryParams.actualCompletionTime" type="date" value-format="YYYY-MM-DD"
|
||||
placeholder="请选择实际完成时间" />
|
||||
</el-form-item>
|
||||
<!-- <el-form-item label="手续材料" prop="formalitiesUrl">
|
||||
<el-input v-model="queryParams.formalitiesUrl" placeholder="请输入手续材料" clearable @keyup.enter="handleQuery" />
|
||||
@ -47,19 +38,21 @@
|
||||
<template #header>
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="Plus" @click="handleAdd()" v-hasPermi="['formalities:formalitiesAreConsolidated:getTree']"
|
||||
>新增</el-button
|
||||
>
|
||||
<span style="margin-left: 10px"
|
||||
><el-tooltip class="box-item" effect="dark" content="从原有模板列表选择新增" placement="top">
|
||||
<el-icon color="#409efc"><WarningFilled /></el-icon> </el-tooltip
|
||||
></span>
|
||||
<el-button type="primary" plain icon="Plus" @click="handleAdd()"
|
||||
v-hasPermi="['formalities:formalitiesAreConsolidated:getTree']">新增</el-button>
|
||||
<span style="margin-left: 10px"><el-tooltip class="box-item" effect="dark" content="从原有模板列表选择新增"
|
||||
placement="top">
|
||||
<el-icon color="#409efc">
|
||||
<WarningFilled />
|
||||
</el-icon> </el-tooltip></span>
|
||||
</el-col>
|
||||
<el-col :span="1.5" v-hasPermi="['formalities:listOfFormalities:list']">
|
||||
<el-button type="primary" plain icon="Plus" @click="addTemplate()">新增数据</el-button>
|
||||
<span style="margin-left: 10px">
|
||||
<el-tooltip class="box-item" effect="dark" content="创建新模板并添加数据" placement="top">
|
||||
<el-icon color="#409efc"><WarningFilled /></el-icon>
|
||||
<el-icon color="#409efc">
|
||||
<WarningFilled />
|
||||
</el-icon>
|
||||
</el-tooltip>
|
||||
</span>
|
||||
</el-col>
|
||||
@ -78,7 +71,8 @@
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<el-table v-loading="loading" :data="formalitiesAreConsolidatedList" @selection-change="handleSelectionChange" row-key="id" default-expand-all>
|
||||
<el-table v-loading="loading" :data="formalitiesAreConsolidatedList" @selection-change="handleSelectionChange"
|
||||
row-key="id" default-expand-all>
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<!-- <el-table-column label="手续办理清单模板父级" align="center" prop="formalitiesPname" /> -->
|
||||
<el-table-column label="手续办理清单" align="left" prop="formalitiesName" />
|
||||
@ -101,51 +95,52 @@
|
||||
<el-table-column label="办理状态" align="center" prop="processingStatus" />
|
||||
<el-table-column label="手续材料" align="center" prop="formalitiesUrl" width="180">
|
||||
<template #default="scope">
|
||||
<el-link type="primary" :underline="false" @click="handlePreview(scope.row)" target="_blank" v-if="scope.row.formalitiesPid"
|
||||
>查看</el-link
|
||||
>
|
||||
<div style="display: flex; justify-content: center; align-items: center;">
|
||||
|
||||
|
||||
<div>
|
||||
<el-link type="primary" :underline="false" @click="handlePreview(scope.row)" target="_blank"
|
||||
v-if="scope.row.formalitiesPid">查看</el-link>
|
||||
</div>
|
||||
<div>
|
||||
<el-badge v-if="scope.row.fileCount" :value="scope.row.fileCount" class="item" type="danger">
|
||||
</el-badge>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</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">
|
||||
<div v-if="scope.row.formalitiesPid">
|
||||
<el-button
|
||||
link
|
||||
type="primary"
|
||||
icon="Edit"
|
||||
v-if="scope.row.processingStatus != '已完成'"
|
||||
<el-button link type="primary" icon="Edit" v-if="scope.row.processingStatus != '已完成'"
|
||||
@click="handleUpdate(scope.row)"
|
||||
v-hasPermi="['formalities:formalitiesAreConsolidated:edit']"
|
||||
>修改</el-button
|
||||
>
|
||||
<el-button link type="primary" icon="Upload" v-if="scope.row.processingStatus != '已完成'" @click="handleUpload(scope.row)"
|
||||
>上传</el-button
|
||||
>
|
||||
<el-button
|
||||
link
|
||||
type="primary"
|
||||
icon="EditPen"
|
||||
@click="handleUpdateStatus(scope.row)"
|
||||
v-hasPermi="['formalities:formalitiesAreConsolidated:edit']"
|
||||
>修改状态</el-button
|
||||
>
|
||||
v-hasPermi="['formalities:formalitiesAreConsolidated:edit']">修改</el-button>
|
||||
<el-button link type="primary" icon="Upload" v-if="scope.row.processingStatus != '已完成'"
|
||||
@click="handleUpload(scope.row)">上传</el-button>
|
||||
<el-button link type="primary" icon="EditPen" @click="handleUpdateStatus(scope.row)"
|
||||
v-hasPermi="['formalities:formalitiesAreConsolidated:edit']">修改状态</el-button>
|
||||
</div>
|
||||
</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" />
|
||||
<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="formalitiesAreConsolidatedFormRef" :model="form" :rules="rules" label-width="160px">
|
||||
<el-form-item label="计划开始时间" prop="planTheStartTime">
|
||||
<el-date-picker clearable v-model="form.planTheStartTime" type="date" value-format="YYYY-MM-DD" placeholder="请选择计划开始时间">
|
||||
<el-date-picker clearable v-model="form.planTheStartTime" type="date" value-format="YYYY-MM-DD"
|
||||
placeholder="请选择计划开始时间">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="计划完成时间" prop="planTheStartTime">
|
||||
<el-date-picker clearable v-model="form.planTheEndTime" type="date" value-format="YYYY-MM-DD" placeholder="请选择计划完成时间">
|
||||
<el-date-picker clearable v-model="form.planTheEndTime" type="date" value-format="YYYY-MM-DD"
|
||||
placeholder="请选择计划完成时间">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="负责人" prop="head">
|
||||
@ -167,24 +162,20 @@
|
||||
<el-table :data="fileList" style="width: 100%" border v-loading="fileLoading">
|
||||
<el-table-column prop="fileName" label="文件" align="center">
|
||||
<template #default="scope">
|
||||
<el-link :key="scope.row.annexUrl" :href="scope.row.annexUrl" target="_blank" type="primary" :underline="false">
|
||||
<el-link :key="scope.row.annexUrl" :href="scope.row.annexUrl" target="_blank" type="primary"
|
||||
:underline="false">
|
||||
{{ scope.row.fileName || '查看文件' }}
|
||||
</el-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="90" align="center" v-if="fileStatus != '1'">
|
||||
<el-table-column label="操作" align="center" v-if="fileStatus != '1'">
|
||||
<template #default="scope">
|
||||
<el-button type="danger" link icon="Delete" @click="handleDeleteFile(scope.row)"> 删除 </el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<pagination
|
||||
v-show="fileTotal > 0"
|
||||
:total="fileTotal"
|
||||
v-model:page="fileParams.pageNum"
|
||||
v-model:limit="fileParams.pageSize"
|
||||
@pagination="getFileList"
|
||||
/>
|
||||
<pagination v-show="fileTotal > 0" :total="fileTotal" v-model:page="fileParams.pageNum"
|
||||
v-model:limit="fileParams.pageSize" @pagination="getFileList" />
|
||||
<template #footer>
|
||||
<span>
|
||||
<el-button type="primary" @click="viewVisible = false">关闭</el-button>
|
||||
@ -194,18 +185,9 @@
|
||||
<!-- 上传文件对话框 -->
|
||||
<el-dialog draggable title="上传文件" v-model="fileVisible" width="450">
|
||||
<el-form-item label="上传文件" prop="processingStatus">
|
||||
<file-upload
|
||||
v-model="file"
|
||||
ref="uploadRef"
|
||||
uploadUrl="/formalities/formalitiesAnnex"
|
||||
v-hasPermi="['formalities:formalitiesAnnex:add']"
|
||||
:data="{ formalitiesId: form.id }"
|
||||
:fileType="['pdf']"
|
||||
:auto-upload="false"
|
||||
showFileList
|
||||
method="put"
|
||||
:onUploadSuccess="handleUploadSuccess"
|
||||
/>
|
||||
<file-upload v-model="file" ref="uploadRef" uploadUrl="/formalities/formalitiesAnnex"
|
||||
v-hasPermi="['formalities:formalitiesAnnex:add']" :data="{ formalitiesId: form.id }" :fileType="['pdf']"
|
||||
:auto-upload="false" showFileList method="put" :onUploadSuccess="handleUploadSuccess" />
|
||||
</el-form-item>
|
||||
<template #footer>
|
||||
<span>
|
||||
@ -233,21 +215,19 @@
|
||||
</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-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 的是一级,禁用一级
|
||||
}
|
||||
}" />
|
||||
<div style="margin-left: 10px; display: flex; justify-content: center; align-items: center">
|
||||
<el-tooltip class="box-item" effect="dark" content="列表上已选择得模版不可再选" placement="top">
|
||||
<el-icon><WarningFilled /></el-icon>
|
||||
<el-icon>
|
||||
<WarningFilled />
|
||||
</el-icon>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</el-form-item>
|
||||
@ -268,7 +248,8 @@
|
||||
<el-option v-for="item in listOfFormalitiesList" :label="item.name" :value="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="名称" prop="formalitiesName" :rules="[{ required: true, message: '请输入名称', trigger: 'blur' }]">
|
||||
<el-form-item label="名称" prop="formalitiesName"
|
||||
:rules="[{ required: true, message: '请输入名称', trigger: 'blur' }]">
|
||||
<el-input v-model="formTemplate.formalitiesName" placeholder="请输入名称" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
@ -31,13 +31,20 @@
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<el-table v-loading="loading" :data="listOfFormalitiesList" @selection-change="handleSelectionChange" row-key="id" default-expand-all>
|
||||
<el-table
|
||||
v-loading="loading"
|
||||
:data="listOfFormalitiesList"
|
||||
@selection-change="handleSelectionChange"
|
||||
row-key="id"
|
||||
default-expand-all
|
||||
style="height: calc(100vh - 300px); overflow-y: auto"
|
||||
>
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="名称" prop="name" />
|
||||
</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="listOfFormalitiesFormRef" :model="form" :rules="rules" label-width="80px">
|
||||
|
90
src/views/materials/materialOutbound/component/outbound.vue
Normal file
90
src/views/materials/materialOutbound/component/outbound.vue
Normal file
@ -0,0 +1,90 @@
|
||||
<template>
|
||||
<div class="p-2">
|
||||
<el-table size="small" v-if="props.row.length !== 0" :data="props.row">
|
||||
<el-table-column label="材料名称" align="center" prop="materialsName" />
|
||||
<!-- <el-table-column label="材料数量" align="center" prop="quantityCount" /> -->
|
||||
<el-table-column label="剩余量" align="center" prop="residue">
|
||||
<template #default="scope">
|
||||
<span>{{ scope.row.residue }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="出库数量" align="center" prop="number">
|
||||
<template #default="scope">
|
||||
<el-input-number v-if="scope.row.type" v-model="scope.row.number" :controls="false" :min="0" :max="scope.row.residue" :precision="0" />
|
||||
<span v-else>{{ scope.row.number }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="交接单位" align="center" prop="recipient">
|
||||
<template #default="scope">
|
||||
<el-input v-if="scope.row.type" style="width: 150px" v-model="scope.row.recipient" />
|
||||
<span v-else>{{ scope.row.recipient }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="领用人" align="center" prop=" shipper">
|
||||
<template #default="scope">
|
||||
<el-input v-if="scope.row.type" style="width: 150px" v-model="scope.row.shipper" />
|
||||
<span v-else>{{ scope.row.shipper }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作人" align="center" prop="operator">
|
||||
<template #default="scope">
|
||||
<el-input v-if="scope.row.type" style="width: 150px" v-model="scope.row.operator" />
|
||||
<span v-else>{{ scope.row.operator }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="出库时间" align="center" prop="outPutTime" width="180" />
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-button link type="primary" @click="handleConfirm(scope.row)" v-if="scope.row.type"> 确认 </el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useUserStoreHook } from '@/store/modules/user';
|
||||
import { addOutbound } from '@/api/materials/materialOutbound';
|
||||
|
||||
// 获取用户 store
|
||||
const userStore = useUserStoreHook();
|
||||
|
||||
// 从 store 中获取项目列表和当前选中的项目
|
||||
const currentProject = computed(() => userStore.selectedProject);
|
||||
const emit = defineEmits(['success']);
|
||||
const props = defineProps({
|
||||
row: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
}
|
||||
});
|
||||
|
||||
const handleConfirm = async (row: any) => {
|
||||
if (row.number == 0 || !row.number) {
|
||||
ElMessage.error('请输入出库数量');
|
||||
return;
|
||||
}
|
||||
if (!row.shipper) {
|
||||
ElMessage.error('请输入领用人');
|
||||
return;
|
||||
}
|
||||
if (!row.operator) {
|
||||
ElMessage.error('请输入操作人');
|
||||
return;
|
||||
}
|
||||
console.log(row);
|
||||
|
||||
const params = {
|
||||
...row,
|
||||
materialsId: row.id,
|
||||
projectId: currentProject.value?.id,
|
||||
outPut: '1'
|
||||
};
|
||||
console.log(params);
|
||||
const data = await addOutbound(params);
|
||||
if (data.code === 200) {
|
||||
ElMessage.success('出库成功');
|
||||
emit('success');
|
||||
}
|
||||
};
|
||||
</script>
|
148
src/views/materials/materialOutbound/index.vue
Normal file
148
src/views/materials/materialOutbound/index.vue
Normal file
@ -0,0 +1,148 @@
|
||||
<template>
|
||||
<div class="p-2">
|
||||
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
|
||||
<div class="mb-[10px]">
|
||||
<el-card shadow="hover">
|
||||
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
|
||||
<el-form-item label="材料名称" prop="materialName">
|
||||
<el-input v-model="queryParams.materialName" placeholder="请输入材料名称" clearable @keyup.enter="handleQuery" />
|
||||
</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>
|
||||
</el-card>
|
||||
</div>
|
||||
</transition>
|
||||
|
||||
<el-card shadow="never">
|
||||
<el-table
|
||||
v-loading="loading"
|
||||
:data="tableList"
|
||||
:row-key="
|
||||
(row) => {
|
||||
return row.id;
|
||||
}
|
||||
"
|
||||
@row-click="
|
||||
(row, column, event) => {
|
||||
// 阻止点击行时自动展开
|
||||
if (column.property) event.stopPropagation();
|
||||
}
|
||||
"
|
||||
:preserve-expanded-content="true"
|
||||
>
|
||||
<el-table-column type="expand">
|
||||
<template #default="{ row }">
|
||||
<outbound :row="row.children ?? []" @success="getTableList" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="序号" type="index" width="60" align="center" />
|
||||
<el-table-column label="材料名称" align="center" prop="materialsName" />
|
||||
<el-table-column label="规格" align="center" prop="typeSpecificationName" />
|
||||
<el-table-column label="计量单位" align="center" prop="weightId" />
|
||||
<el-table-column label="材料数量" align="center" prop="quantityCount" />
|
||||
<el-table-column label="剩余量" align="center" prop="residue" />
|
||||
<el-table-column label="操作人" align="center" prop="operator"> </el-table-column>
|
||||
<el-table-column label="创建时间" align="center" prop="createTime" width="180" />
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-button link type="primary" icon="Plus" @click="handleoutbound(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="getTableList"
|
||||
/>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { outboundMaterials } from '@/api/materials/materialOutbound';
|
||||
import { useUserStoreHook } from '@/store/modules/user';
|
||||
import outbound from './component/outbound.vue';
|
||||
import { number } from 'vue-types';
|
||||
const { proxy } = getCurrentInstance() as any;
|
||||
const queryFormRef = ref();
|
||||
const queryParams = ref({
|
||||
materialName: '',
|
||||
pageNum: 1,
|
||||
pageSize: 10
|
||||
});
|
||||
const total = ref(0);
|
||||
const loading = ref(false);
|
||||
const tableList = ref([]);
|
||||
// 获取用户 store
|
||||
const userStore = useUserStoreHook();
|
||||
|
||||
// 从 store 中获取项目列表和当前选中的项目
|
||||
const currentProject = computed(() => userStore.selectedProject);
|
||||
//获取列表数据
|
||||
const getTableList = async () => {
|
||||
try {
|
||||
loading.value = true;
|
||||
const res = await outboundMaterials({ ...queryParams.value, projectId: currentProject.value?.id });
|
||||
if (res.code === 200) {
|
||||
loading.value = false;
|
||||
tableList.value = res.rows;
|
||||
total.value = res.data.total;
|
||||
}
|
||||
} catch (error) {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
getTableList();
|
||||
// 出入库
|
||||
const handleoutbound = (row: any) => {
|
||||
console.log(row);
|
||||
if (row.children == null) {
|
||||
row.children = [];
|
||||
}
|
||||
if (row.children.some((child) => child.type === 'add')) {
|
||||
ElMessage.warning('已经存在出库记录,不能重复添加');
|
||||
return;
|
||||
}
|
||||
row.children.push({
|
||||
type: 'add',
|
||||
id: row.id,
|
||||
number: 0,
|
||||
operator: '',
|
||||
shipper: '',
|
||||
recipient: '',
|
||||
residue: row.residue,
|
||||
materialsName: row.materialsName
|
||||
});
|
||||
// 手动触发展开行
|
||||
const table = document.querySelector('.el-table__body-wrapper');
|
||||
const rows = table?.querySelectorAll('.el-table__row');
|
||||
const rowEl = rows?.[Array.from(tableList.value).indexOf(row)];
|
||||
const expandBtn: any = rowEl?.querySelector('.el-table__expand-icon');
|
||||
// 如果行未展开,则点击展开按钮
|
||||
if (expandBtn && !expandBtn.classList.contains('el-table__expand-icon--expanded')) {
|
||||
expandBtn.click();
|
||||
}
|
||||
};
|
||||
//搜索
|
||||
const handleQuery = () => {
|
||||
queryParams.value.pageNum = 1;
|
||||
getTableList();
|
||||
};
|
||||
|
||||
//重置
|
||||
const resetQuery = () => {
|
||||
console.log(111111111);
|
||||
|
||||
queryFormRef.value?.resetFields();
|
||||
handleQuery();
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
@ -1,22 +1,20 @@
|
||||
<template>
|
||||
<div class="p-2">
|
||||
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
|
||||
<div v-show="showSearch" class="mb-[10px]">
|
||||
<div class="mb-[10px]">
|
||||
<el-card shadow="hover">
|
||||
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
|
||||
<el-form-item label="材料名称" prop="materialsName">
|
||||
<el-input v-model="queryParams.materialsName" placeholder="请输入材料名称" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" v-hasPermi="['materials:materialsInventory:list']" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
|
||||
<el-button icon="Refresh" v-hasPermi="['materials:materialsInventory:list']" @click="resetQuery">重置</el-button>
|
||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
</div>
|
||||
</transition>
|
||||
|
||||
<el-card shadow="never">
|
||||
<template #header>
|
||||
<el-row :gutter="10" class="mb8">
|
||||
@ -25,275 +23,179 @@
|
||||
导出
|
||||
</el-button>
|
||||
</el-col>
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getTableList"></right-toolbar>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<el-table v-loading="loading" :data="materialsInventoryList" @expand-change="handleExpandChange">
|
||||
<el-table-column type="expand">
|
||||
<template #default="props">
|
||||
<div style="margin-left: 60px">
|
||||
<el-table :data="materialsUseRecordList" border v-loading="loadingChild">
|
||||
<el-table-column label="序号" align="center" type="index" width="60" />
|
||||
<el-table-column label="使用数量" align="center" prop="useNumber" />
|
||||
<el-table-column label="剩余量" align="center" prop="residueNumber" />
|
||||
<el-table-column label="使用部位" align="center" prop="usePart" />
|
||||
<el-table-column label="备注" align="center" prop="remark" />
|
||||
</el-table>
|
||||
<pagination
|
||||
v-show="totalChild > 0"
|
||||
:total="totalChild"
|
||||
v-model:page="queryParamsChild.pageNum"
|
||||
v-model:limit="queryParamsChild.pageSize"
|
||||
@pagination="getListChild"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<el-table :data="tableData" row-key="id" border default-expand-all class="custom-table">
|
||||
<el-table-column prop="materialsName" label="物资名称" align="left" class-name="inventory-register" />
|
||||
<el-table-column prop="quantityCount" label="计划数量" align="center" class-name="inventory-register" />
|
||||
<el-table-column label="入库登记" align="center" class-name="inventory-register">
|
||||
<el-table-column prop="supplier" label="供货单位" align="center" class-name="inventory-register" />
|
||||
<el-table-column prop="number" label="数量" align="center" class-name="inventory-register" />
|
||||
<el-table-column prop="operator" label="签收人" align="center" class-name="inventory-register" />
|
||||
<el-table-column prop="enterTime" label="日期" align="center" class-name="inventory-register" />
|
||||
</el-table-column>
|
||||
<!-- <el-table-column type="selection" width="55" align="center" /> -->
|
||||
<el-table-column label="序号" type="index" width="60" align="center" />
|
||||
<el-table-column label="物资名称" align="center" prop="materialsName" />
|
||||
<el-table-column label="计划数量" align="center" prop="quantityCount" />
|
||||
<el-table-column label="入库登记" align="center">
|
||||
<el-table-column label="数量" align="center" prop="number">
|
||||
<template #default="scope">
|
||||
<span v-if="scope.row.outPut === '0'">{{ scope.row.number }}</span>
|
||||
<span v-else></span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="签收人" align="center" prop="operator">
|
||||
<template #default="scope">
|
||||
<span v-if="scope.row.outPut === '0'">{{ scope.row.operator }}</span>
|
||||
<span v-else></span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="日期" align="center" prop="outPutTime" width="160">
|
||||
<template #default="scope">
|
||||
<span v-if="scope.row.outPut === '0'">{{ parseTime(scope.row.outPutTime, '{y}年{m}月{d}日') }}</span>
|
||||
<span v-else></span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="出库登记" align="center" class-name="out-register">
|
||||
<el-table-column prop="recipient" label="接受单位" align="center" class-name="out-register" />
|
||||
<el-table-column prop="outNumber" label="数量" align="center" class-name="out-register" />
|
||||
<el-table-column prop="outOperator" label="出库人" align="center" class-name="out-register" />
|
||||
<el-table-column prop="shipper" label="领用人" align="center" class-name="out-register" />
|
||||
<el-table-column prop="createTime" label="领用日期" align="center" class-name="out-register" />
|
||||
</el-table-column>
|
||||
<el-table-column label="出库登记" align="center">
|
||||
<el-table-column label="交接单位" align="center" prop="recipient" />
|
||||
<el-table-column label="使用部位" align="center" prop="usePart" />
|
||||
<el-table-column label="数量" align="center" prop="number">
|
||||
<template #default="scope">
|
||||
<span v-if="scope.row.outPut === '1'">{{ scope.row.number }}</span>
|
||||
<span v-else></span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="出库人" align="center" prop="operator">
|
||||
<template #default="scope">
|
||||
<span v-if="scope.row.outPut === '1'">{{ scope.row.operator }}</span>
|
||||
<span v-else></span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="领用人" align="center" prop="shipper" />
|
||||
<el-table-column label="日期" align="center" prop="outPutTime" width="160">
|
||||
<template #default="scope">
|
||||
<span v-if="scope.row.outPut === '1'">{{ parseTime(scope.row.outPutTime, '{y}年{m}月{d}日') }}</span>
|
||||
<span v-else></span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="到货剩余登记" align="center" class-name="out-register">
|
||||
<el-table-column prop="residue" label="剩余量" align="center" class-name="out-register" />
|
||||
<el-table-column prop="disposition" label="处理方式" align="center" class-name="out-register" />
|
||||
</el-table-column>
|
||||
<el-table-column label="剩余处理" align="center">
|
||||
<el-table-column label="剩余量" align="center" prop="residue" />
|
||||
<el-table-column label="处理方式" align="center" prop="disposition" />
|
||||
<el-table-column label="使用登记" align="center" class-name="use-register">
|
||||
<el-table-column prop="usePart" label="使用部位" align="center" class-name="use-register" />
|
||||
<el-table-column prop="useNumber" label="使用数量" align="center" class-name="use-register" />
|
||||
<el-table-column prop="useTime" label="使用日期" align="center" class-name="use-register" />
|
||||
<el-table-column prop="residueNumber" label="剩余量" align="center" class-name="use-register" />
|
||||
</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-space wrap>
|
||||
<el-button link type="success" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['materials:materialsInventory:edit']">
|
||||
修改
|
||||
</el-button>
|
||||
<el-button link type="danger" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['materials:materialsInventory:remove']">
|
||||
删除
|
||||
</el-button>
|
||||
</el-space>
|
||||
</template>
|
||||
</el-table-column> -->
|
||||
<el-table-column label="备注" align="center" prop="remark" class-name="use-register" />
|
||||
</el-table>
|
||||
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
|
||||
<pagination
|
||||
v-show="total > 0"
|
||||
:total="total"
|
||||
v-model:page="queryParams.pageNum"
|
||||
v-model:limit="queryParams.pageSize"
|
||||
@pagination="getTableList"
|
||||
/>
|
||||
</el-card>
|
||||
<!-- 添加或修改材料出/入库对话框 -->
|
||||
<el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
|
||||
<el-form ref="materialsInventoryFormRef" :model="form" :rules="rules" label-width="120px">
|
||||
<el-form-item label="出入库状态" prop="outPut">
|
||||
<el-select v-model="form.outPut" clearable placeholder="请输入出入库状态">
|
||||
<el-option v-for="item in out_put_type" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="出/入库的数量" prop="number">
|
||||
<el-input v-model="form.number" placeholder="请输入出/入库的数量" />
|
||||
</el-form-item>
|
||||
<el-form-item label="出/入库操作时间" prop="outPutTime">
|
||||
<el-date-picker clearable v-model="form.outPutTime" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择出/入库操作时间">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="剩余库存数量" prop="residue">
|
||||
<el-input v-model="form.residue" placeholder="请输入剩余库存数量" />
|
||||
</el-form-item>
|
||||
<el-form-item label="操作人" prop="operator">
|
||||
<el-input v-model="form.operator" placeholder="请输入操作人" />
|
||||
</el-form-item>
|
||||
<el-form-item label="材料出入证明" prop="path">
|
||||
<el-input v-model="form.path" type="textarea" placeholder="请输入内容" />
|
||||
</el-form-item>
|
||||
<el-form-item label="处理方式" prop="disposition">
|
||||
<el-input v-model="form.disposition" placeholder="请输入处理方式" />
|
||||
</el-form-item>
|
||||
<el-form-item label="交接单位" prop="recipient">
|
||||
<el-input v-model="form.recipient" placeholder="请输入交接单位" />
|
||||
</el-form-item>
|
||||
<el-form-item label="领用人" prop="shipper">
|
||||
<el-input v-model="form.shipper" placeholder="请输入领用人" />
|
||||
</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="MaterialsInventory" lang="ts">
|
||||
import {
|
||||
addMaterialsInventory,
|
||||
delMaterialsInventory,
|
||||
getMaterialsInventory,
|
||||
listMaterialsInventory,
|
||||
updateMaterialsInventory
|
||||
} from '@/api/materials/materialsInventory';
|
||||
import { MaterialsInventoryForm, MaterialsInventoryQuery, MaterialsInventoryVO } from '@/api/materials/materialsInventory/types';
|
||||
import { useUserStoreHook } from '@/store/modules/user';
|
||||
import { listMaterialsUseRecord } from '@/api/materials/materialsUseRecord';
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
const { out_put_type } = toRefs<any>(proxy?.useDict('out_put_type'));
|
||||
<script setup lang="ts">
|
||||
import useUserStore from '@/store/modules/user';
|
||||
import { getLedgerList } from '@/api/materials/materialsInventory';
|
||||
|
||||
// 获取用户 store
|
||||
const userStore = useUserStoreHook();
|
||||
// 从 store 中获取项目列表和当前选中的项目
|
||||
const { proxy } = getCurrentInstance() as any;
|
||||
const userStore = useUserStore();
|
||||
const currentProject = computed(() => userStore.selectedProject);
|
||||
const materialsInventoryList = ref<MaterialsInventoryVO[]>([]);
|
||||
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 queryFormRef = ref();
|
||||
const queryParams = ref({
|
||||
materialsName: '',
|
||||
pageNum: 1,
|
||||
pageSize: 10
|
||||
});
|
||||
const total = ref(0);
|
||||
const loadingChild = ref(true);
|
||||
const totalChild = ref(0);
|
||||
const materialsUseRecordList = ref<any[]>([]);
|
||||
const queryFormRef = ref<ElFormInstance>();
|
||||
const materialsInventoryFormRef = ref<ElFormInstance>();
|
||||
|
||||
const dialog = reactive<DialogOption>({
|
||||
visible: false,
|
||||
title: ''
|
||||
});
|
||||
|
||||
const initFormData: MaterialsInventoryForm = {
|
||||
id: undefined,
|
||||
materialsId: undefined,
|
||||
projectId: currentProject.value?.id,
|
||||
outPut: undefined,
|
||||
number: undefined,
|
||||
outPutTime: undefined,
|
||||
residue: undefined,
|
||||
operator: undefined,
|
||||
path: undefined,
|
||||
disposition: undefined,
|
||||
recipient: undefined,
|
||||
shipper: undefined,
|
||||
remark: undefined
|
||||
};
|
||||
const data = reactive({
|
||||
form: { ...initFormData },
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
materialsId: undefined,
|
||||
projectId: currentProject.value?.id,
|
||||
outPut: undefined,
|
||||
number: undefined,
|
||||
outPutTime: undefined,
|
||||
residue: undefined,
|
||||
operator: undefined,
|
||||
path: undefined,
|
||||
disposition: undefined,
|
||||
recipient: undefined,
|
||||
shipper: undefined,
|
||||
params: {}
|
||||
},
|
||||
queryParamsChild: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
inventoryId: undefined,
|
||||
usePart: undefined,
|
||||
useNumber: undefined,
|
||||
residueNumber: undefined
|
||||
},
|
||||
rules: {
|
||||
id: [{ required: true, message: '主键id不能为空', trigger: 'blur' }],
|
||||
materialsId: [{ required: true, message: '材料id不能为空', trigger: 'blur' }]
|
||||
}
|
||||
});
|
||||
|
||||
const { queryParams, form, rules, queryParamsChild } = toRefs(data);
|
||||
const materialsOptions = ref([]);
|
||||
/** 处理外层表格展开/折叠:记录当前展开行的inventoryId */
|
||||
const handleExpandChange = (row: any) => {
|
||||
queryParamsChild.value.inventoryId = row.id;
|
||||
getListChild();
|
||||
};
|
||||
/** 查询材料子级登记列表(内层列表) */
|
||||
const getListChild = async () => {
|
||||
loadingChild.value = true;
|
||||
try {
|
||||
const res = await listMaterialsUseRecord(queryParamsChild.value);
|
||||
materialsUseRecordList.value = res.rows;
|
||||
totalChild.value = res.total;
|
||||
} finally {
|
||||
loadingChild.value = false;
|
||||
const tableRef = ref();
|
||||
const showSearch = ref(true);
|
||||
const loading = ref(false);
|
||||
const tableData = ref([]);
|
||||
//获取列表
|
||||
const getTableList = async () => {
|
||||
const parmas = {
|
||||
...queryParams.value,
|
||||
projectId: currentProject.value.id
|
||||
};
|
||||
const res = await getLedgerList(parmas);
|
||||
if (res.code === 200) {
|
||||
const data = restructureData(res.rows);
|
||||
tableData.value = data;
|
||||
total.value = res.total;
|
||||
}
|
||||
};
|
||||
|
||||
/** 查询材料出/入库列表 */
|
||||
const getList = async () => {
|
||||
loading.value = true;
|
||||
const res = await listMaterialsInventory(queryParams.value);
|
||||
materialsInventoryList.value = res.rows;
|
||||
total.value = res.total;
|
||||
const materialsMap = new Map();
|
||||
materialsOptions.value = Array.from(materialsMap.values());
|
||||
loading.value = false;
|
||||
};
|
||||
// 重组数据结构的函数
|
||||
const restructureData = (data) => {
|
||||
return data.map((item) => {
|
||||
const newItem: any = {
|
||||
id: item.id,
|
||||
materialsName: item.materialsName,
|
||||
quantityCount: item.quantityCount,
|
||||
supplier: item.supplier,
|
||||
number: item.number,
|
||||
operator: item.operator,
|
||||
enterTime: item.enterTime,
|
||||
children: []
|
||||
};
|
||||
|
||||
/** 取消按钮 */
|
||||
const cancel = () => {
|
||||
reset();
|
||||
dialog.visible = false;
|
||||
};
|
||||
if (item.outList && item.outList.length > 0) {
|
||||
// 处理第一个outList项目
|
||||
const firstOut = item.outList[0];
|
||||
newItem.recipient = firstOut.recipient;
|
||||
newItem.outNumber = firstOut.number;
|
||||
newItem.outOperator = firstOut.operator;
|
||||
newItem.shipper = firstOut.shipper;
|
||||
newItem.createTime = firstOut.createTime;
|
||||
newItem.residue = firstOut.residue;
|
||||
newItem.disposition = firstOut.disposition;
|
||||
|
||||
/** 表单重置 */
|
||||
const reset = () => {
|
||||
form.value = { ...initFormData };
|
||||
materialsInventoryFormRef.value?.resetFields();
|
||||
};
|
||||
// 处理第一个outList中的useList
|
||||
if (firstOut.useList && firstOut.useList.length > 0) {
|
||||
const firstUse = firstOut.useList[0];
|
||||
newItem.usePart = firstUse.usePart;
|
||||
newItem.useNumber = firstUse.useNumber;
|
||||
newItem.useTime = firstUse.createTime;
|
||||
newItem.residueNumber = firstUse.residueNumber;
|
||||
newItem.remark = firstUse.remark;
|
||||
|
||||
// 将剩余的useList项目添加到children
|
||||
for (let i = 1; i < firstOut.useList.length; i++) {
|
||||
const useItem = firstOut.useList[i];
|
||||
newItem.children.push({
|
||||
id: useItem.id,
|
||||
usePart: useItem.usePart,
|
||||
useNumber: useItem.useNumber,
|
||||
useTime: useItem.createTime,
|
||||
residueNumber: useItem.residueNumber,
|
||||
remark: useItem.remark,
|
||||
type: 'use'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 处理剩余的outList项目
|
||||
for (let i = 1; i < item.outList.length; i++) {
|
||||
const outItem = item.outList[i];
|
||||
const outNode: any = {
|
||||
id: outItem.id,
|
||||
recipient: outItem.recipient,
|
||||
outNumber: outItem.number,
|
||||
outOperator: outItem.operator,
|
||||
shipper: outItem.shipper,
|
||||
createTime: outItem.createTime,
|
||||
residue: outItem.residue,
|
||||
disposition: outItem.disposition,
|
||||
type: 'out',
|
||||
children: []
|
||||
};
|
||||
|
||||
// 处理当前outList项目中的useList
|
||||
if (outItem.useList && outItem.useList.length > 0) {
|
||||
const firstUse = outItem.useList[0];
|
||||
outNode.usePart = firstUse.usePart;
|
||||
outNode.useNumber = firstUse.useNumber;
|
||||
outNode.useTime = firstUse.createTime;
|
||||
outNode.residueNumber = firstUse.residueNumber;
|
||||
outNode.remark = firstUse.remark;
|
||||
|
||||
// 将剩余的useList项目添加到children
|
||||
for (let j = 1; j < outItem.useList.length; j++) {
|
||||
const useItem = outItem.useList[j];
|
||||
outNode.children.push({
|
||||
id: useItem.id,
|
||||
usePart: useItem.usePart,
|
||||
useNumber: useItem.useNumber,
|
||||
useTime: useItem.createTime,
|
||||
residueNumber: useItem.residueNumber,
|
||||
remark: useItem.remark,
|
||||
type: 'use'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
newItem.children.push(outNode);
|
||||
}
|
||||
}
|
||||
return newItem;
|
||||
});
|
||||
};
|
||||
/** 搜索按钮操作 */
|
||||
const handleQuery = () => {
|
||||
queryParams.value.pageNum = 1;
|
||||
getList();
|
||||
getTableList();
|
||||
};
|
||||
|
||||
/** 重置按钮操作 */
|
||||
@ -302,75 +204,46 @@ const resetQuery = () => {
|
||||
handleQuery();
|
||||
};
|
||||
|
||||
/** 多选框选中数据 */
|
||||
const handleSelectionChange = (selection: MaterialsInventoryVO[]) => {
|
||||
ids.value = selection.map((item) => item.id);
|
||||
single.value = selection.length != 1;
|
||||
multiple.value = !selection.length;
|
||||
};
|
||||
|
||||
/** 修改按钮操作 */
|
||||
const handleUpdate = async (row?: MaterialsInventoryVO) => {
|
||||
reset();
|
||||
const _id = row?.id || ids.value[0];
|
||||
const res = await getMaterialsInventory(_id);
|
||||
Object.assign(form.value, res.data);
|
||||
dialog.visible = true;
|
||||
dialog.title = '修改材料出/入库';
|
||||
};
|
||||
|
||||
/** 提交按钮 */
|
||||
const submitForm = () => {
|
||||
materialsInventoryFormRef.value?.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
buttonLoading.value = true;
|
||||
form.value.projectId = currentProject.value?.id;
|
||||
if (form.value.id) {
|
||||
await updateMaterialsInventory(form.value).finally(() => (buttonLoading.value = false));
|
||||
} else {
|
||||
await addMaterialsInventory(form.value).finally(() => (buttonLoading.value = false));
|
||||
}
|
||||
proxy?.$modal.msgSuccess('操作成功');
|
||||
dialog.visible = false;
|
||||
await getList();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/** 删除按钮操作 */
|
||||
const handleDelete = async (row?: MaterialsInventoryVO) => {
|
||||
const _ids = row?.id || ids.value;
|
||||
await proxy?.$modal.confirm('是否确认删除材料出/入库编号为"' + _ids + '"的数据项?').finally(() => (loading.value = false));
|
||||
await delMaterialsInventory(_ids);
|
||||
proxy?.$modal.msgSuccess('删除成功');
|
||||
await getList();
|
||||
};
|
||||
|
||||
/** 导出按钮操作 */
|
||||
//导出
|
||||
const handleExport = () => {
|
||||
proxy?.download(
|
||||
'materials/materialsInventory/export',
|
||||
'/materials/materials/export',
|
||||
{
|
||||
...queryParams.value
|
||||
projectId: currentProject.value?.id
|
||||
},
|
||||
`materialsInventory_${new Date().getTime()}.xlsx`
|
||||
`物资跟踪管理台账.xlsx`
|
||||
);
|
||||
};
|
||||
|
||||
//监听项目id刷新数据
|
||||
const listeningProject = watch(
|
||||
() => currentProject.value?.id,
|
||||
(nid, oid) => {
|
||||
queryParams.value.projectId = nid;
|
||||
form.value.projectId = nid;
|
||||
getList();
|
||||
}
|
||||
);
|
||||
|
||||
onUnmounted(() => {
|
||||
listeningProject();
|
||||
});
|
||||
onMounted(() => {
|
||||
getList();
|
||||
getTableList();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
/* 关键样式 - 确保选择器有足够优先级 */
|
||||
.custom-table .el-table__body .inventory-register,
|
||||
.custom-table .el-table__header .inventory-register {
|
||||
background-color: #f0f9ff !important;
|
||||
}
|
||||
|
||||
.custom-table .el-table__body .out-register,
|
||||
.custom-table .el-table__header .out-register {
|
||||
background-color: #f0fff3 !important;
|
||||
}
|
||||
|
||||
.custom-table .el-table__body .use-register,
|
||||
.custom-table .el-table__header .use-register {
|
||||
background-color: #fffaf0 !important;
|
||||
}
|
||||
|
||||
/* 表头样式增强 */
|
||||
.el-table__header th {
|
||||
background-color: #eef1f6;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/* 操作按钮样式 */
|
||||
.operation-buttons {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
</style>
|
||||
|
@ -1,84 +1,101 @@
|
||||
<template>
|
||||
<div class="p-2">
|
||||
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave"> </transition>
|
||||
<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="materialsName">
|
||||
<el-input v-model="queryParams.materialsName" placeholder="请输入物资名称" clearable @keyup.enter="handleQuery" />
|
||||
</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>
|
||||
<!-- 外层表格:使用expandedRowKeys控制展开状态 -->
|
||||
<el-table
|
||||
ref="outerTableRef"
|
||||
v-loading="loading"
|
||||
:data="materialsUseInventoryList"
|
||||
@expand-change="handleExpandChange"
|
||||
border
|
||||
:expanded-row-keys="expandedRowKeys"
|
||||
>
|
||||
<el-table-column type="expand">
|
||||
<template #default="props">
|
||||
<div style="margin-left: 60px">
|
||||
<!-- 子表格:使用当前行的独立数据 -->
|
||||
<el-table :data="getChildData(props.row.id)" border v-loading="getChildLoading(props.row.id)">
|
||||
<el-table-column label="序号" align="center" type="index" width="60" />
|
||||
<el-table-column label="使用数量" align="center" prop="useNumber" />
|
||||
<el-table-column label="剩余量" align="center" prop="residueNumber" />
|
||||
<el-table-column label="使用部位" align="center" prop="usePart" />
|
||||
<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"
|
||||
icon="delete"
|
||||
v-if="scope.row.ishow"
|
||||
@click="handleDelete(scope.row, props.row.id)"
|
||||
v-hasPermi="['materials:materialsUseRecord:remove']"
|
||||
>删除</el-button
|
||||
>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- 子分页:使用当前行的独立分页参数 -->
|
||||
<pagination
|
||||
v-show="getChildTotal(props.row.id) > 0"
|
||||
:total="getChildTotal(props.row.id)"
|
||||
v-model:page="getChildQueryParams(props.row.id).pageNum"
|
||||
v-model:limit="getChildQueryParams(props.row.id).pageSize"
|
||||
@pagination="(page, limit) => handleChildPagination(props.row.id, page, limit)"
|
||||
/>
|
||||
</div>
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="5">
|
||||
<el-card shadow="never">
|
||||
<el-tree style="max-width: 600px" :data="TreeData" :props="defaultProps" @node-click="handleNodeClick" />
|
||||
</el-card>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="19">
|
||||
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave"> </transition>
|
||||
<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="materialsName">
|
||||
<el-input v-model="queryParams.materialsName" placeholder="请输入物资名称" clearable @keyup.enter="handleQuery" />
|
||||
</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-column>
|
||||
<el-table-column label="序号" align="center" type="index" width="60" />
|
||||
<el-table-column label="物资名称" align="center" prop="materialsName" />
|
||||
<el-table-column label="交接单位" align="center" prop="recipient" />
|
||||
<el-table-column label="计划数量" align="center" prop="quantityCount" />
|
||||
<el-table-column label="数量" align="center" prop="number" />
|
||||
<el-table-column label="出库人" align="center" prop="operator" />
|
||||
<el-table-column label="领用人" align="center" prop="shipper" />
|
||||
<el-table-column label="剩余量" align="center" prop="residue" />
|
||||
<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" icon="Plus" @click="handleAdd(scope.row)" v-hasPermi="['materials:materialsUseRecord:add']"
|
||||
>添加登记</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>
|
||||
<!-- 外层表格:使用expandedRowKeys控制展开状态 -->
|
||||
<el-table
|
||||
ref="outerTableRef"
|
||||
v-loading="loading"
|
||||
:data="materialsUseInventoryList"
|
||||
@expand-change="handleExpandChange"
|
||||
border
|
||||
:expanded-row-keys="expandedRowKeys"
|
||||
>
|
||||
<el-table-column type="expand">
|
||||
<template #default="props">
|
||||
<div style="margin-left: 60px">
|
||||
<!-- 子表格:使用当前行的独立数据 -->
|
||||
<el-table :data="getChildData(props.row.id)" border v-loading="getChildLoading(props.row.id)">
|
||||
<el-table-column label="序号" align="center" type="index" width="60" />
|
||||
<el-table-column label="使用数量" align="center" prop="useNumber" />
|
||||
<el-table-column label="剩余量" align="center" prop="residueNumber" />
|
||||
<el-table-column label="使用部位" align="center" prop="usePart" />
|
||||
<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"
|
||||
icon="delete"
|
||||
v-if="scope.row.ishow"
|
||||
@click="handleDelete(scope.row, props.row.id)"
|
||||
v-hasPermi="['materials:materialsUseRecord:remove']"
|
||||
>删除</el-button
|
||||
>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- 子分页:使用当前行的独立分页参数 -->
|
||||
<pagination
|
||||
v-show="getChildTotal(props.row.id) > 0"
|
||||
:total="getChildTotal(props.row.id)"
|
||||
v-model:page="getChildQueryParams(props.row.id).pageNum"
|
||||
v-model:limit="getChildQueryParams(props.row.id).pageSize"
|
||||
@pagination="(page, limit) => handleChildPagination(props.row.id, page, limit)"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="序号" align="center" type="index" width="60" />
|
||||
<el-table-column label="物资名称" align="center" prop="materialsName" />
|
||||
<el-table-column label="交接单位" align="center" prop="recipient" />
|
||||
<el-table-column label="计划数量" align="center" prop="quantityCount" />
|
||||
<el-table-column label="数量" align="center" prop="number" />
|
||||
<el-table-column label="出库人" align="center" prop="operator" />
|
||||
<el-table-column label="领用人" align="center" prop="shipper" />
|
||||
<el-table-column label="剩余量" align="center" prop="residue" />
|
||||
<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" icon="Plus" @click="handleAdd(scope.row)" v-hasPermi="['materials:materialsUseRecord:add']"
|
||||
>添加登记</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-col>
|
||||
</el-row>
|
||||
|
||||
<!-- 添加或修改材料使用登记对话框 -->
|
||||
<el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
|
||||
<el-form ref="materialsUseRecordFormRef" :model="form" :rules="rules" label-width="80px">
|
||||
@ -115,7 +132,7 @@ import { MaterialsUseRecordVO, MaterialsUseRecordQuery, MaterialsUseRecordForm }
|
||||
import { getCurrentInstance, ComponentInternalInstance, onMounted, ref, reactive, toRefs, computed, watch, WatchStopHandle } from 'vue';
|
||||
import { ElFormInstance, ElTable } from 'element-plus';
|
||||
import useUserStore from '@/store/modules/user';
|
||||
import { get } from 'lodash';
|
||||
import { getMaterialsList } from '@/api/materials/materialOutbound';
|
||||
|
||||
// 类型定义补充
|
||||
interface DialogOption {
|
||||
@ -183,7 +200,8 @@ const data = reactive({
|
||||
projectId: currentProject.value?.id,
|
||||
outPut: 1,
|
||||
materialsName: undefined,
|
||||
usePart: undefined
|
||||
usePart: undefined,
|
||||
materialsId: ''
|
||||
} as MaterialsUseRecordQuery & {
|
||||
outPut?: number;
|
||||
materialsName?: string;
|
||||
@ -199,6 +217,32 @@ const data = reactive({
|
||||
|
||||
const { form, rules } = toRefs(data);
|
||||
const queryParams = ref<typeof data.queryParams>({ ...data.queryParams });
|
||||
const TreeData: any = ref([]);
|
||||
//获取材料列表
|
||||
const getMaterialsListData = async () => {
|
||||
const res = await getMaterialsList({ projectId: currentProject.value?.id, pageNum: 1, pageSize: 999 });
|
||||
if (res.code === 200) {
|
||||
// 将数据转换为树形结构
|
||||
TreeData.value = res.rows.map((item) => ({
|
||||
...item,
|
||||
label: item.materialsName + '_' + item.createTime,
|
||||
children: []
|
||||
}));
|
||||
queryParams.value.materialsId = TreeData.value[0].id;
|
||||
getList();
|
||||
}
|
||||
};
|
||||
|
||||
const handleNodeClick = (data: any) => {
|
||||
console.log(data);
|
||||
queryParams.value.materialsId = data.id;
|
||||
getList();
|
||||
};
|
||||
|
||||
const defaultProps = {
|
||||
children: 'children',
|
||||
label: 'label'
|
||||
};
|
||||
|
||||
// ------------------------------ 子列表状态工具函数 ------------------------------
|
||||
/** 获取或初始化指定父行的子列表状态 */
|
||||
@ -420,6 +464,7 @@ onUnmounted(() => {
|
||||
|
||||
// 页面挂载时加载数据
|
||||
onMounted(() => {
|
||||
getList();
|
||||
// getList();
|
||||
getMaterialsListData();
|
||||
});
|
||||
</script>
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -133,7 +133,7 @@
|
||||
></el-col>
|
||||
<el-col :span="12" :offset="0"
|
||||
><el-form-item label="供应商" prop="supplier">
|
||||
<el-select v-model="form.supplierId" value-key="id" placeholder="请选择供应商" clearable filterable @change="">
|
||||
<el-select v-model="form.supplierId" value-key="id" placeholder="请选择供应商" clearable filterable @change="getPlanList">
|
||||
<el-option v-for="item in supplierOptions" :key="item.id" :label="item.supplierName" :value="item.id"> </el-option>
|
||||
</el-select> </el-form-item
|
||||
></el-col>
|
||||
@ -145,7 +145,14 @@
|
||||
></el-col>
|
||||
<el-col :span="12" :offset="0">
|
||||
<el-form-item label="需求计划" prop="planId">
|
||||
<el-select v-model="form.planId" value-key="id" placeholder="请选择需求计划" multiple filterable :disabled="!form.mrpBaseId">
|
||||
<el-select
|
||||
v-model="form.planId"
|
||||
value-key="id"
|
||||
placeholder="请选择需求计划"
|
||||
multiple
|
||||
filterable
|
||||
:disabled="!form.mrpBaseId && !form.supplierId"
|
||||
>
|
||||
<el-option v-for="item in planList" :key="item.id" :label="item.name" :value="item.id"> </el-option>
|
||||
</el-select> </el-form-item
|
||||
></el-col>
|
||||
@ -190,18 +197,17 @@
|
||||
></el-col> -->
|
||||
</el-row>
|
||||
</el-form>
|
||||
<el-table v-loading="loading" :data="selectPlanList" v-if="form.id">
|
||||
<el-table v-loading="loading" :data="selectPlanList">
|
||||
<el-table-column label="物资名称" align="center" prop="name" />
|
||||
|
||||
<el-table-column label="质量标准" align="center" prop="qs" />
|
||||
<el-table-column label="规格型号" align="center" prop="specification" />
|
||||
<el-table-column label="计量单位" align="center" prop="unit" width="80" />
|
||||
<el-table-column label="需求数量" align="center" prop="demandQuantity" v-if="form.docType == 2">
|
||||
<el-table-column label="需求数量" align="center" prop="demandQuantity">
|
||||
<template #default="scope">
|
||||
<el-input v-model="scope.row.demandQuantity" placeholder="请输入" type="number" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="需求数量" align="center" prop="demandQuantity" v-else />
|
||||
<!-- <el-table-column label="需求数量" align="center" prop="demandQuantity" v-else /> -->
|
||||
<!-- <el-table-column label="需求到货时间" align="center" prop="arrivalTime" width="250" /> -->
|
||||
<el-table-column label="备注" align="center" prop="remark" />
|
||||
</el-table>
|
||||
@ -357,6 +363,7 @@ const data = reactive({
|
||||
docCode: [{ required: true, message: '采购单编号不能为空', trigger: 'blur' }],
|
||||
planId: [{ required: true, message: '需求计划不能为空', trigger: 'blur' }],
|
||||
mrpBaseId: [{ required: true, message: '需求批次号不能为空', trigger: 'blur' }],
|
||||
supplierId: [{ required: true, message: '供应商不能为空', trigger: 'blur' }],
|
||||
// 电话号码验证
|
||||
technicalDirectorTel: [
|
||||
{ required: true, message: '请输入电话', trigger: 'blur' },
|
||||
@ -461,9 +468,16 @@ const handleUpdate = async (row?: PurchaseDocVO) => {
|
||||
const _id = row?.id || ids.value[0];
|
||||
const res = await getPurchaseDoc(_id);
|
||||
Object.assign(form.value, res.data);
|
||||
getPlanList();
|
||||
form.value.planId = form.value.associationList?.map((item: any) => item.planId);
|
||||
await getPlanList();
|
||||
|
||||
form.value.planId = form.value.associationList?.map((item: any) => item.planId);
|
||||
planList.value.forEach((item) => {
|
||||
form.value.associationList.forEach((items: any) => {
|
||||
if (item.id == items.planId) {
|
||||
item.demandQuantity = items.demandQuantity;
|
||||
}
|
||||
});
|
||||
});
|
||||
dialog.visible = true;
|
||||
dialog.title = '修改物资-采购联系单';
|
||||
};
|
||||
@ -471,6 +485,7 @@ const handleUpdate = async (row?: PurchaseDocVO) => {
|
||||
const selectPlanList = computed(() => {
|
||||
if (!form.value.planId) return [];
|
||||
const result = planList.value.filter((item) => form.value.planId.includes(item.id));
|
||||
|
||||
return result;
|
||||
});
|
||||
|
||||
@ -479,11 +494,12 @@ const submitForm = () => {
|
||||
purchaseDocFormRef.value?.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
buttonLoading.value = true;
|
||||
form.value.associationList = form.value.planId?.map((item: any) => ({
|
||||
planId: item
|
||||
}));
|
||||
form.value.associationList = selectPlanList.value;
|
||||
form.value.associationList.forEach((item: any) => {
|
||||
item.planId = item.id;
|
||||
delete item.id;
|
||||
});
|
||||
form.value.supplier = supplierOptions.value.find((item) => item.id == form.value.supplierId)?.supplierName;
|
||||
|
||||
if (form.value.id) {
|
||||
await updatePurchaseDoc(form.value).finally(() => (buttonLoading.value = false));
|
||||
} else {
|
||||
@ -498,13 +514,16 @@ const submitForm = () => {
|
||||
|
||||
const getPlanList = async () => {
|
||||
form.value.planId = '';
|
||||
const res = await getBatch({
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
projectId: currentProject.value?.id,
|
||||
mrpBaseId: form.value.mrpBaseId
|
||||
});
|
||||
planList.value = res.rows;
|
||||
if (form.value.mrpBaseId && form.value.supplierId) {
|
||||
const res = await getBatch({
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
projectId: currentProject.value?.id,
|
||||
mrpBaseId: form.value.mrpBaseId,
|
||||
supplierId: form.value.supplierId
|
||||
});
|
||||
planList.value = res.rows;
|
||||
}
|
||||
};
|
||||
|
||||
const getBatchList = async () => {
|
||||
|
@ -14,6 +14,7 @@
|
||||
</el-form-item>
|
||||
<el-form-item label="类型" prop="type">
|
||||
<el-select v-model="queryParams.type" placeholder="请选择类型">
|
||||
<el-option label="全部" value="0" />
|
||||
<el-option label="对甲" value="1" />
|
||||
<el-option label="对乙" value="2" />
|
||||
</el-select>
|
||||
@ -102,7 +103,7 @@
|
||||
|
||||
<script setup name="MonthPlan" lang="ts">
|
||||
import { listMonthPlan, getMonthPlan, delMonthPlan, addMonthPlan, updateMonthPlan } from '@/api/out/monthPlan';
|
||||
import { MonthPlanVO, MonthPlanQuery, MonthPlanForm } from '@/api/out/monthPlan/types';
|
||||
import { MonthPlanVO } from '@/api/out/monthPlan/types';
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
const { out_value_type } = toRefs<any>(proxy?.useDict('out_value_type'));
|
||||
const { wf_business_status } = toRefs<any>(proxy?.useDict('wf_business_status'));
|
||||
@ -112,13 +113,7 @@ import { useUserStoreHook } from '@/store/modules/user';
|
||||
const userStore = useUserStoreHook();
|
||||
// 从 store 中获取项目列表和当前选中的项目
|
||||
const currentProject = computed(() => userStore.selectedProject);
|
||||
const month = computed(() => {
|
||||
const now = new Date();
|
||||
const year = now.getFullYear();
|
||||
const month = String(now.getMonth() + 1).padStart(2, '0'); // getMonth() 从0开始
|
||||
const currentMonth = `${year}-${month}`;
|
||||
return currentMonth;
|
||||
});
|
||||
const month = '';
|
||||
const monthPlanList = ref<MonthPlanVO[]>([]);
|
||||
const buttonLoading = ref(false);
|
||||
const loading = ref(true);
|
||||
@ -163,7 +158,7 @@ const data = reactive({
|
||||
valueType: undefined,
|
||||
planAuditStatus: undefined,
|
||||
completeAuditStatus: undefined,
|
||||
type: '1',
|
||||
type: '0',
|
||||
params: {}
|
||||
},
|
||||
rules: {
|
||||
@ -180,7 +175,11 @@ const { queryParams, form, rules } = toRefs(data);
|
||||
/** 查询月度产值计划列表 */
|
||||
const getList = async () => {
|
||||
loading.value = true;
|
||||
const res = await listMonthPlan(queryParams.value);
|
||||
let type = queryParams.value.type;
|
||||
if (type == '0') {
|
||||
type = '';
|
||||
}
|
||||
const res = await listMonthPlan({ ...queryParams.value, type: type });
|
||||
monthPlanList.value = res.rows;
|
||||
total.value = res.total;
|
||||
loading.value = false;
|
||||
@ -241,7 +240,6 @@ const submitForm = () => {
|
||||
if (valid) {
|
||||
buttonLoading.value = true;
|
||||
form.value.isDesign = true;
|
||||
|
||||
if (form.value.id) {
|
||||
await updateMonthPlan(form.value).finally(() => (buttonLoading.value = false));
|
||||
} else {
|
||||
@ -265,8 +263,10 @@ const handleDelete = async (row?: MonthPlanVO) => {
|
||||
|
||||
/** 审核按钮操作 */
|
||||
const handleAudit = async (row?: MonthPlanVO) => {
|
||||
proxy.$tab.closePage(proxy.$route);
|
||||
proxy?.$tab.openPage('/approval/monthPlan/indexEdit', '审核月度产值计划', {
|
||||
planMonth: row?.planMonth,
|
||||
id: row?.id,
|
||||
type: 'update'
|
||||
});
|
||||
};
|
||||
|
@ -104,6 +104,7 @@ import { StartProcessBo } from '@/api/workflow/workflowCommon/types';
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
import { useUserStoreHook } from '@/store/modules/user';
|
||||
import { getMonthInfo, isSubmit } from '@/api/out/monthPlan';
|
||||
import { id } from 'element-plus/es/locale/index.mjs';
|
||||
// 获取用户 store
|
||||
const userStore = useUserStoreHook();
|
||||
// 从 store 中获取项目列表和当前选中的项目
|
||||
@ -169,14 +170,12 @@ const getInfo = () => {
|
||||
loading.value = true;
|
||||
buttonLoading.value = false;
|
||||
nextTick(async () => {
|
||||
console.log('🚀 ~ routeParams.value:', routeParams.value.businessId);
|
||||
const projectId = routeParams.value.businessId ? routeParams.value.businessId.split('_')[0] : currentProject.value?.id;
|
||||
const res = await getMonthInfo({ projectId: projectId, planMonth: routeParams.value.planMonth });
|
||||
console.log(routeParams.value);
|
||||
// routeParams.value.businessId ? routeParams.value.businessId.split('_')[0] : routeParams.value.id;
|
||||
const res = await getMonthInfo({ id: routeParams.value.id.split('_')[0] });
|
||||
form.value = res.data as any;
|
||||
|
||||
console.log('🚀 ~ getInfo ~ form.value:', form.value[0].projectId);
|
||||
form.value[0].mid = form.value[0].id;
|
||||
form.value[0].id = form.value[0].projectId + '_' + form.value[0].planMonth;
|
||||
form.value[0].id = form.value[0].id + '_plan';
|
||||
loading.value = false;
|
||||
buttonLoading.value = false;
|
||||
});
|
||||
@ -196,7 +195,7 @@ const submitFlow = async () => {
|
||||
const handleStartWorkFlow = async (data: LeaveForm) => {
|
||||
try {
|
||||
submitFormData.value.flowCode = flowCode.value;
|
||||
submitFormData.value.businessId = currentProject.value?.id + '_' + form.value[0]?.planMonth;
|
||||
submitFormData.value.businessId = routeParams.value.id + '_plan';
|
||||
|
||||
//流程变量
|
||||
taskVariables.value = {
|
||||
@ -215,8 +214,6 @@ const handleStartWorkFlow = async (data: LeaveForm) => {
|
||||
};
|
||||
//审批记录
|
||||
const handleApprovalRecord = () => {
|
||||
console.log(form.value[0]?.id);
|
||||
|
||||
approvalRecordRef.value.init(form.value[0]?.id);
|
||||
};
|
||||
//提交回调
|
||||
@ -231,20 +228,12 @@ const approvalVerifyOpen = async () => {
|
||||
// 图纸上传成功之后 开始提交
|
||||
const submit = async (status, data) => {
|
||||
form.value = data;
|
||||
console.log(form.value);
|
||||
|
||||
if (status === 'draft') {
|
||||
buttonLoading.value = false;
|
||||
proxy?.$modal.msgSuccess('暂存成功');
|
||||
proxy.$tab.closePage(proxy.$route);
|
||||
proxy.$router.go(-1);
|
||||
} else {
|
||||
const res = await isSubmit(data[0]?.mid);
|
||||
|
||||
if (!res.data) {
|
||||
proxy?.$modal.msgError('三种计划产值必须填写');
|
||||
return;
|
||||
}
|
||||
if ((form.value[0]?.planAuditStatus === 'draft' && (flowCode.value === '' || flowCode.value === null)) || routeParams.value.type === 'add') {
|
||||
flowCode.value = flowCodeOptions[0].value;
|
||||
dialogVisible.visible = true;
|
||||
@ -261,12 +250,9 @@ const submit = async (status, data) => {
|
||||
onMounted(() => {
|
||||
nextTick(async () => {
|
||||
routeParams.value = proxy.$route.query;
|
||||
console.log('🚀 ~ proxy.$route.query:', proxy.$route.query);
|
||||
reset();
|
||||
loading.value = false;
|
||||
if (routeParams.value.type === 'update' || routeParams.value.type === 'view' || routeParams.value.type === 'approval') {
|
||||
console.log('🚀 ~ routeParams.value:', routeParams.value);
|
||||
|
||||
getInfo();
|
||||
}
|
||||
});
|
||||
|
@ -85,7 +85,7 @@ const handleQuery = () => {
|
||||
|
||||
/** 重置按钮操作 */
|
||||
const resetQuery = () => {
|
||||
queryParams.value.month = '';
|
||||
resetMonth();
|
||||
handleQuery();
|
||||
};
|
||||
// 获取列表
|
||||
@ -102,14 +102,17 @@ const getList = async () => {
|
||||
total.value = res.total;
|
||||
}
|
||||
};
|
||||
onMounted(() => {
|
||||
const currentDate = new Date();
|
||||
const resetMonth=()=>{
|
||||
const currentDate = new Date();
|
||||
const year = currentDate.getFullYear();
|
||||
const month = currentDate.getMonth() + 1; // 月份从0开始,所以需要加1
|
||||
|
||||
// 形成"YYYY-M"格式
|
||||
const formattedDate = `${year}-${String(month).padStart(2, '0')}`;
|
||||
queryParams.value.month = formattedDate;
|
||||
}
|
||||
onMounted(() => {
|
||||
resetMonth();
|
||||
|
||||
getList();
|
||||
});
|
||||
|
@ -120,17 +120,17 @@
|
||||
<!-- <el-input v-model="form.projectStructure" placeholder="请输入对应项目结构" /> -->
|
||||
</el-form-item>
|
||||
<el-form-item label="预计开始时间" prop="planStartDate">
|
||||
<el-date-picker clearable v-model="form.planStartDate" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" placeholder="选择预计开始时间" />
|
||||
<el-date-picker clearable v-model="form.planStartDate" type="date" value-format="YYYY-MM-DD" placeholder="选择预计开始时间" />
|
||||
</el-form-item>
|
||||
<el-form-item label="预计结束时间" prop="planEndDate">
|
||||
<el-date-picker clearable v-model="form.planEndDate" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" placeholder="选择预计结束时间" />
|
||||
<el-date-picker clearable v-model="form.planEndDate" type="date" value-format="YYYY-MM-DD" placeholder="选择预计结束时间" />
|
||||
</el-form-item>
|
||||
<el-form-item label="实际开始时间" prop="practicalStartDate">
|
||||
<el-date-picker
|
||||
clearable
|
||||
v-model="form.practicalStartDate"
|
||||
type="datetime"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
type="date"
|
||||
value-format="YYYY-MM-DD"
|
||||
placeholder="选择实际开始时间"
|
||||
/>
|
||||
</el-form-item>
|
||||
@ -138,8 +138,8 @@
|
||||
<el-date-picker
|
||||
clearable
|
||||
v-model="form.practicalEndDate"
|
||||
type="datetime"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
type="date"
|
||||
value-format="YYYY-MM-DD"
|
||||
placeholder="选择实际结束时间"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
@ -216,7 +216,7 @@ const { queryParams, form, rules } = toRefs(data);
|
||||
/** 查询进度类别模版列表 */
|
||||
const getList = async () => {
|
||||
loading.value = true;
|
||||
const res = await listProgressCategoryTemplateByParent(activeTab.value);
|
||||
const res = await listProgressCategoryTemplateByParent(activeTab.value,queryParams.value.name);
|
||||
const data = proxy?.handleTree<ProgressCategoryTemplateVO>(res.data, 'id', 'parentId');
|
||||
if (data) {
|
||||
progressCategoryTemplateList.value = data;
|
||||
|
@ -44,11 +44,11 @@
|
||||
{{ userDetail?.sfzNumber }}
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<!-- <el-col :span="12">
|
||||
<el-form-item label="身份证号码">
|
||||
{{ userDetail?.sfzNumber }}
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-col> -->
|
||||
<el-col :span="12">
|
||||
<el-form-item label="身份证有效开始期">
|
||||
{{ dayjs(userDetail?.sfzStart).format('YYYY 年 MM 月 DD 日') }}
|
||||
@ -59,7 +59,7 @@
|
||||
{{ dayjs(userDetail?.sfzEnd).format('YYYY 年 MM 月 DD 日') }}
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-col :span="24">
|
||||
<el-form-item label="身份证地址">
|
||||
{{ userDetail?.sfzSite }}
|
||||
</el-form-item>
|
||||
|
@ -10,7 +10,7 @@
|
||||
<el-form-item label="地块名称" prop="landName">
|
||||
<el-input v-model="queryParams.landName" placeholder="请输入地块名称" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="所属村委会" prop="villageCommittee">
|
||||
<!-- <el-form-item label="所属村委会" prop="villageCommittee">
|
||||
<el-input v-model="queryParams.villageCommittee" placeholder="请输入所属村委会" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="设计面积(亩)" prop="designArea">
|
||||
@ -21,7 +21,7 @@
|
||||
</el-form-item>
|
||||
<el-form-item label="农户数(户)" prop="farmerCount">
|
||||
<el-input v-model="queryParams.farmerCount" type="number" 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 icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -44,14 +44,14 @@
|
||||
{{ userDetail?.sfzNumber }}
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<!-- <el-col :span="12">
|
||||
<el-form-item label="身份证号码">
|
||||
{{ userDetail?.sfzNumber }}
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-col> -->
|
||||
<el-col :span="12">
|
||||
<el-form-item label="身份证有效开始期">
|
||||
{{ dayjs(userDetail?.sfzStart).format('YYYY 年 MM 月 DD 日') }}
|
||||
{{ dayjs(userDetail?.sfzStart).format('YYYY年 MM 月 DD 日') }}
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
|
@ -1,7 +1,6 @@
|
||||
<template>
|
||||
<div class="p-2">
|
||||
<transition :enter-active-class="proxy?.animate.searchAnimate.enter"
|
||||
:leave-active-class="proxy?.animate.searchAnimate.leave">
|
||||
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
|
||||
<div v-show="showSearch" class="mb-[10px]">
|
||||
<el-card shadow="hover">
|
||||
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
|
||||
@ -46,43 +45,59 @@
|
||||
<template #header>
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="Plus" @click="handleAdd"
|
||||
v-hasPermi="['contractor:constructionUser:add']">新增 </el-button>
|
||||
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['contractor:constructionUser:add']">新增 </el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()"
|
||||
v-hasPermi="['contractor:constructionUser:remove']">
|
||||
<el-button
|
||||
type="danger"
|
||||
plain
|
||||
icon="Delete"
|
||||
:disabled="multiple"
|
||||
@click="handleDelete()"
|
||||
v-hasPermi="['contractor:constructionUser:remove']"
|
||||
>
|
||||
删除
|
||||
</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="warning" plain icon="Download" @click="handleExport"
|
||||
v-hasPermi="['contractor:constructionUser:export']">导出
|
||||
<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['contractor:constructionUser:export']"
|
||||
>导出
|
||||
</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="warning" plain icon="Edit" :disabled="multiple" @click="statusDialog = true">用户状态编辑
|
||||
</el-button>
|
||||
<el-button type="warning" plain icon="Edit" :disabled="multiple" @click="statusDialog = true">用户状态编辑 </el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-switch v-model="playCardStatus" class="ml-2" inline-prompt
|
||||
style="--el-switch-on-color: #13ce66; --el-switch-off-color: #ff4949" :loading="playCardLoding"
|
||||
@change="handlePlayCardStatus" inactive-text="一键关闭打卡" active-text="一键开启打卡" />
|
||||
<el-switch
|
||||
v-model="playCardStatus"
|
||||
class="ml-2"
|
||||
inline-prompt
|
||||
style="--el-switch-on-color: #13ce66; --el-switch-off-color: #ff4949"
|
||||
:loading="playCardLoding"
|
||||
@change="handlePlayCardStatus"
|
||||
inactive-text="一键关闭打卡"
|
||||
active-text="一键开启打卡"
|
||||
/>
|
||||
</el-col>
|
||||
<el-row @mouseover="informationStatus = true" :gutter="10" @mouseout="informationStatus = false">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="success" plain>员工资料 </el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5" v-show="informationStatus">
|
||||
<el-button type="primary" plain icon="Edit" @click="downloadTemplate"
|
||||
v-hasPermi="['contractor:constructionUserFile:download']">下载资料模板
|
||||
<el-button type="primary" plain icon="Edit" @click="downloadTemplate" v-hasPermi="['contractor:constructionUserFile:download']"
|
||||
>下载资料模板
|
||||
</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5" v-show="informationStatus">
|
||||
<file-upload v-model="filePath" isImportInfo :isShowTip="false"
|
||||
uploadUrl="/project/constructionUserFile/upload/zip" :limit="1" :file-size="50">
|
||||
<el-button type="warning" plain icon="Edit"
|
||||
v-hasPermi="['contractor:constructionUserFile:upload']">导入员工资料 </el-button>
|
||||
<file-upload
|
||||
v-model="filePath"
|
||||
isImportInfo
|
||||
:isShowTip="false"
|
||||
uploadUrl="/project/constructionUserFile/upload/zip"
|
||||
:limit="1"
|
||||
:file-size="50"
|
||||
>
|
||||
<el-button type="warning" plain icon="Edit" v-hasPermi="['contractor:constructionUserFile:upload']">导入员工资料 </el-button>
|
||||
</file-upload>
|
||||
</el-col>
|
||||
</el-row>
|
||||
@ -120,9 +135,18 @@
|
||||
</el-table-column>
|
||||
<el-table-column label="打卡状态" align="center" prop="clock">
|
||||
<template #default="scope">
|
||||
<el-switch v-model="scope.row.clock" class="ml-2" inline-prompt
|
||||
style="--el-switch-on-color: #13ce66; --el-switch-off-color: #ff4949" active-text="开启" inactive-text="禁用"
|
||||
:loading="playCardLoding" active-value="0" inactive-value="1" @change="handleClockStatus(scope.row)" />
|
||||
<el-switch
|
||||
v-model="scope.row.clock"
|
||||
class="ml-2"
|
||||
inline-prompt
|
||||
style="--el-switch-on-color: #13ce66; --el-switch-off-color: #ff4949"
|
||||
active-text="开启"
|
||||
inactive-text="禁用"
|
||||
:loading="playCardLoding"
|
||||
active-value="0"
|
||||
inactive-value="1"
|
||||
@change="handleClockStatus(scope.row)"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="薪水" align="center" min-width="180">
|
||||
@ -131,8 +155,7 @@
|
||||
{{ scope.row.salary ? scope.row.salary : scope.row.standardSalary }}
|
||||
(<dict-tag :options="wage_measure_unit_type" :value="scope.row.wageMeasureUnit"></dict-tag>)
|
||||
</span>
|
||||
<div class="text-blue text-sm cursor-pointer" @click="openSalaryDialog(scope.row)">{{ scope.row.salary ?
|
||||
'取消变更' : '变更' }}</div>
|
||||
<div class="text-blue text-sm cursor-pointer" @click="openSalaryDialog(scope.row)">{{ scope.row.salary ? '取消变更' : '变更' }}</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="入场时间" align="center" prop="entryDate" min-width="180" />
|
||||
@ -146,30 +169,31 @@
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" fixed="right" min-width="300">
|
||||
<template #default="scope">
|
||||
<el-space wrap>
|
||||
<el-button link type="primary" icon="View" @click="handleShowDrawer(scope.row)"
|
||||
v-hasPermi="['contractor:constructionUser:query']">
|
||||
<el-button link type="primary" icon="View" @click="handleShowDrawer(scope.row)" v-hasPermi="['contractor:constructionUser:query']">
|
||||
详情
|
||||
</el-button>
|
||||
<el-button link type="success" icon="Edit" @click="handleUpdate(scope.row)"
|
||||
v-hasPermi="['contractor:constructionUser:edit']">
|
||||
<el-button link type="success" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['contractor:constructionUser:edit']">
|
||||
修改
|
||||
</el-button>
|
||||
<el-button link type="warning" icon="Female" @click="handlePlayCard(scope.row)"> 打卡 </el-button>
|
||||
<el-button link type="danger" icon="Avatar" @click="handleJoinBlacklist(scope.row)"
|
||||
v-hasPermi="['contractor:constructionBlacklist:add']">
|
||||
<el-button
|
||||
link
|
||||
type="danger"
|
||||
icon="Avatar"
|
||||
@click="handleJoinBlacklist(scope.row)"
|
||||
v-hasPermi="['contractor:constructionBlacklist:add']"
|
||||
>
|
||||
黑名单
|
||||
</el-button>
|
||||
<!-- <el-button link type="primary" icon="Switch" @click="handleToggle(scope.row)"> 切换人脸 </el-button> -->
|
||||
<el-button link type="primary" icon="Switch" @click="handleChange(scope.row)"> 人员迁移 </el-button>
|
||||
<el-button link type="primary" icon="Switch" @click="handleAssign(scope.row)"> 分配班组 </el-button>
|
||||
<el-button link type="primary" icon="ChatLineSquare" @click="handleExit(scope.row)"> 入退场记录 </el-button>
|
||||
<el-button link type="danger" icon="Delete" @click="handleDelete(scope.row)"
|
||||
v-hasPermi="['contractor:constructionUser:remove']">
|
||||
<el-button link type="danger" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['contractor:constructionUser:remove']">
|
||||
删除
|
||||
</el-button>
|
||||
<el-tooltip content="红点:部分上传,绿点:已上传,无点:未上传" placement="right" effect="dark">
|
||||
<el-badge :is-dot="scope.row.fileUploadStatus != '1'"
|
||||
:type="uploadStatusColor(scope.row.fileUploadStatus)">
|
||||
<el-badge :is-dot="scope.row.fileUploadStatus != '1'" :type="uploadStatusColor(scope.row.fileUploadStatus)">
|
||||
<el-button link type="primary" icon="FolderAdd" @click="handleUpload(scope.row)">文件上传 </el-button>
|
||||
</el-badge>
|
||||
</el-tooltip>
|
||||
@ -178,8 +202,7 @@
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum"
|
||||
v-model:limit="queryParams.pageSize" @pagination="getList" />
|
||||
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
|
||||
</el-card>
|
||||
<!-- 添加或修改施工人员对话框 -->
|
||||
<el-dialog draggable :title="dialog.title" v-model="dialog.visible" width="930px" append-to-body>
|
||||
@ -231,14 +254,12 @@
|
||||
</div>
|
||||
<div class="el-col el-col-12">
|
||||
<el-form-item label="身份证有效开始期" prop="sfzStart">
|
||||
<el-date-picker clearable v-model="form.sfzStart" type="date" value-format="YYYY-MM-DD"
|
||||
placeholder="请输入身份证有效开始期" />
|
||||
<el-date-picker clearable v-model="form.sfzStart" type="date" value-format="YYYY-MM-DD" placeholder="请输入身份证有效开始期" />
|
||||
</el-form-item>
|
||||
</div>
|
||||
<div class="el-col el-col-12">
|
||||
<el-form-item label="身份证有效结束期" prop="sfzEnd">
|
||||
<el-date-picker clearable v-model="form.sfzEnd" type="date" value-format="YYYY-MM-DD"
|
||||
placeholder="请输入身份证有效结束期" />
|
||||
<el-date-picker clearable v-model="form.sfzEnd" type="date" value-format="YYYY-MM-DD" placeholder="请输入身份证有效结束期" />
|
||||
</el-form-item>
|
||||
</div>
|
||||
<div class="el-col el-col-12">
|
||||
@ -248,8 +269,7 @@
|
||||
</div>
|
||||
<div class="el-col el-col-12">
|
||||
<el-form-item label="身份证出生日期" prop="sfzBirth">
|
||||
<el-date-picker clearable v-model="form.sfzBirth" type="date" value-format="YYYY-MM-DD"
|
||||
placeholder="请输入身份证出生日期" />
|
||||
<el-date-picker clearable v-model="form.sfzBirth" type="date" value-format="YYYY-MM-DD" placeholder="请输入身份证出生日期" />
|
||||
</el-form-item>
|
||||
</div>
|
||||
<div class="el-col el-col-12">
|
||||
@ -302,16 +322,14 @@
|
||||
<div class="el-col el-col-12">
|
||||
<el-form-item label="打卡" prop="clock">
|
||||
<el-select v-model="form.clock" clearable placeholder="请选择打卡状态">
|
||||
<el-option v-for="item in user_clock_type" :key="item.value" :label="item.label"
|
||||
:value="item.value" />
|
||||
<el-option v-for="item in user_clock_type" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</div>
|
||||
<div class="el-col el-col-12">
|
||||
<el-form-item label="结算方式" prop="wageMeasureUnit">
|
||||
<el-select v-model="form.wageMeasureUnit" clearable placeholder="请选择结算方式">
|
||||
<el-option v-for="item in wage_measure_unit_type" :key="item.value" :label="item.label"
|
||||
:value="item.value" />
|
||||
<el-option v-for="item in wage_measure_unit_type" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</div>
|
||||
@ -340,8 +358,7 @@
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="分包单位" label-width="130px">
|
||||
<el-select v-model="skipObject.contractorId" :disabled="!skipObject.projectId" placeholder="请选择分包单位"
|
||||
style="width: 240px">
|
||||
<el-select v-model="skipObject.contractorId" :disabled="!skipObject.projectId" placeholder="请选择分包单位" style="width: 240px">
|
||||
<el-option v-for="item in contractorList" :key="item.id" :label="item.name" :value="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
@ -356,8 +373,7 @@
|
||||
<div class="image_upload" v-for="(item, index) in uploadPath" :key="item.value">
|
||||
<div class="title">{{ item.label }}</div>
|
||||
<div class="file_upload_all" v-if="item.value != 7">
|
||||
<file-upload v-model="item.path" isConstruction :isShowTip="false" :limit="10" :file-type="['pdf']"
|
||||
:file-size="50" />
|
||||
<file-upload v-model="item.path" isConstruction show-file-list :isShowTip="false" :limit="10" :file-type="['pdf']" :file-size="50" />
|
||||
</div>
|
||||
</div>
|
||||
<template #footer>
|
||||
@ -376,7 +392,8 @@
|
||||
</el-form>
|
||||
</div>
|
||||
<template #footer>
|
||||
<span><el-button type="primary" @click="submitForm">保存</el-button>
|
||||
<span
|
||||
><el-button type="primary" @click="submitForm">保存</el-button>
|
||||
<el-button @click="showFaceDrawer = false">取消</el-button>
|
||||
</span>
|
||||
</template>
|
||||
@ -388,7 +405,8 @@
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<template #footer>
|
||||
<span><el-button type="primary" @click="handleEdit">保存</el-button>
|
||||
<span
|
||||
><el-button type="primary" @click="handleEdit">保存</el-button>
|
||||
<el-button @click="statusDialog = false">取消</el-button>
|
||||
</span>
|
||||
</template>
|
||||
@ -412,8 +430,8 @@
|
||||
<el-timeline-item color="rgb(255, 73, 73)">
|
||||
<div class="mb">{{ '退场时间:' + item.entryDate }}</div>
|
||||
<div class="pl-xl">
|
||||
<span class="text-coolgray font-bold">退场文件:<image-preview v-for="itm in item.pathUrl" :src="itm"
|
||||
width="100px" class="mr" /></span><br />
|
||||
<span class="text-coolgray font-bold">退场文件:<image-preview v-for="itm in item.pathUrl" :src="itm" width="100px" class="mr" /></span
|
||||
><br />
|
||||
<p class="mt text-coolgray">
|
||||
备注:<span class="text-blue">{{ item.remark }}</span>
|
||||
</p>
|
||||
@ -441,8 +459,11 @@
|
||||
<el-date-picker v-model="monthValue" type="month" placeholder="请选择月份" @change="handleMonth" />
|
||||
</template>
|
||||
<template #date-cell="{ data }">
|
||||
<div class="w100% h100% position-relative m-0 monthDay" :class="data.isSelected ? 'is-selected' : ''"
|
||||
@click="handleViewPlayCard(playCardIdx(data), data)">
|
||||
<div
|
||||
class="w100% h100% position-relative m-0 monthDay"
|
||||
:class="data.isSelected ? 'is-selected' : ''"
|
||||
@click="handleViewPlayCard(playCardIdx(data), data)"
|
||||
>
|
||||
{{ data.day.split('-').slice(1).join('-') }}
|
||||
<div :style="{ background: playCardColor(data) }" v-if="playCardIdx(data) != -1"></div>
|
||||
</div>
|
||||
@ -461,8 +482,12 @@
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="班组" label-width="130px">
|
||||
<el-select v-model="personnelAllocationObject.teamId" :disabled="!personnelAllocationObject.projectId" placeholder="请选择分包单位"
|
||||
style="width: 240px">
|
||||
<el-select
|
||||
v-model="personnelAllocationObject.teamId"
|
||||
:disabled="!personnelAllocationObject.projectId"
|
||||
placeholder="请选择班组"
|
||||
style="width: 240px"
|
||||
>
|
||||
<el-option v-for="item in teamList" :key="item.id" :label="item.teamName" :value="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
@ -527,8 +552,8 @@ import { parseTime } from '@/utils/ruoyi';
|
||||
|
||||
const calendar = ref<CalendarInstance>();
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
const { type_of_work, user_sex_type, user_clock_type, user_file_type, user_status_type, wage_measure_unit_type,user_post_type } = toRefs<any>(
|
||||
proxy?.useDict('type_of_work', 'user_sex_type', 'user_clock_type', 'user_file_type', 'user_status_type', 'wage_measure_unit_type','user_post_type')
|
||||
const { type_of_work, user_sex_type, user_clock_type, user_file_type, user_status_type, wage_measure_unit_type, user_post_type } = toRefs<any>(
|
||||
proxy?.useDict('type_of_work', 'user_sex_type', 'user_clock_type', 'user_file_type', 'user_status_type', 'wage_measure_unit_type', 'user_post_type')
|
||||
);
|
||||
// 获取用户 store
|
||||
const userStore = useUserStoreHook();
|
||||
@ -586,7 +611,7 @@ const personnelAllocationObject = reactive({
|
||||
memberId: null,
|
||||
projectId: '',
|
||||
teamId: '',
|
||||
postId: '',
|
||||
postId: ''
|
||||
});
|
||||
|
||||
const contractorList = ref<Array<skipTeamType>>([]);
|
||||
@ -942,7 +967,7 @@ const downloadTemplate = async () => {
|
||||
};
|
||||
|
||||
//导入资料
|
||||
const importInformation = async () => { };
|
||||
const importInformation = async () => {};
|
||||
|
||||
/** 人员迁移 */
|
||||
const handleChange = async (row: ConstructionUserVO) => {
|
||||
@ -974,7 +999,7 @@ const handleExit = async (row: ConstructionUserVO) => {
|
||||
|
||||
//上传按钮
|
||||
const handleUpload = async (row: ConstructionUserVO) => {
|
||||
const _id = row?.id || ids.value[0];
|
||||
const _id = row?.sysUserId;
|
||||
currentUserId.value = _id;
|
||||
const res = await listConstructionUserFile({ userId: _id });
|
||||
fileList.value = res.data;
|
||||
@ -1110,14 +1135,17 @@ const listeningProject = watch(
|
||||
const handleAssign = async (row: ConstructionUserVO) => {
|
||||
const _id = row?.id || ids.value[0];
|
||||
currentUserId.value = _id;
|
||||
personnelAllocationObject.projectId = '';
|
||||
personnelAllocationObject.postId = '';
|
||||
personnelAllocationObject.teamId = '';
|
||||
personnelAllocationObject.memberId = row?.sysUserId;
|
||||
skipName.value = row?.userName;
|
||||
personnelAllocation.value = true;
|
||||
};
|
||||
// 选择项目1
|
||||
const selectProject1 = (e: any) => {
|
||||
// 请求班组
|
||||
getTeamList(personnelAllocationObject.projectId);
|
||||
|
||||
};
|
||||
const getTeamList = async (projectId) => {
|
||||
const res = await TeamList({
|
||||
@ -1152,7 +1180,7 @@ onMounted(() => {
|
||||
position: relative;
|
||||
font-size: 12px;
|
||||
|
||||
>div {
|
||||
> div {
|
||||
margin: 0 15px;
|
||||
position: relative;
|
||||
font-size: 12px;
|
||||
@ -1197,7 +1225,7 @@ onMounted(() => {
|
||||
.monthDay {
|
||||
padding: 8px;
|
||||
|
||||
>div {
|
||||
> div {
|
||||
position: absolute;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
|
@ -14,15 +14,6 @@
|
||||
<el-option v-for="dict in safety_question_type" :key="dict.value" :label="dict.label" :value="dict.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="题目内容" prop="questionContent">
|
||||
<el-input v-model="queryParams.questionContent" placeholder="请输入题目内容" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="选项" prop="options">
|
||||
<el-input v-model="queryParams.options" placeholder="请输入选项" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="正确答案" prop="correctAnswer">
|
||||
<el-input v-model="queryParams.correctAnswer" placeholder="请输入正确答案" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
@ -38,32 +29,18 @@
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['safety:questionBank:add']"> 新增 </el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['safety:questionBank:edit']"
|
||||
>修改
|
||||
</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['safety:questionBank:remove']"
|
||||
>删除
|
||||
</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['safety:questionBank:export']">导出 </el-button>
|
||||
</el-col>
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<el-table v-loading="loading" :data="questionBankList" @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 label="题目类别" align="center" prop="categoryType">
|
||||
<el-table v-loading="loading" :data="questionBankList">
|
||||
<el-table-column label="序号" align="center" type="index" width="80" />
|
||||
<el-table-column label="题目类别" align="center" width="100" prop="categoryType">
|
||||
<template #default="scope">
|
||||
<dict-tag :options="safety_question_category_type" :value="scope.row.categoryType" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="题目类型" align="center" prop="questionType">
|
||||
<el-table-column label="题目类型" align="center" width="100" prop="questionType">
|
||||
<template #default="scope">
|
||||
<dict-tag :options="safety_question_type" :value="scope.row.questionType" />
|
||||
</template>
|
||||
@ -73,16 +50,11 @@
|
||||
<el-table-column label="正确答案" align="center" prop="correctAnswer" />
|
||||
<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="['safety:questionBank:edit']"></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="删除" placement="top">
|
||||
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['safety:questionBank:remove']"></el-button>
|
||||
</el-tooltip>
|
||||
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['safety:questionBank:edit']">修改</el-button>
|
||||
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['safety:questionBank:remove']">删除</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>
|
||||
<!-- 添加或修改题库对话框 -->
|
||||
|
@ -1,7 +1,6 @@
|
||||
<template>
|
||||
<div class="p-2">
|
||||
<transition :enter-active-class="proxy?.animate.searchAnimate.enter"
|
||||
:leave-active-class="proxy?.animate.searchAnimate.leave">
|
||||
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
|
||||
<div v-show="showSearch" class="mb-[10px]">
|
||||
<el-card shadow="hover">
|
||||
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
|
||||
@ -31,23 +30,27 @@
|
||||
注:上传压缩包内的文件夹名称需设置为【姓名-身份证-满分-得分-及格分】, <br />
|
||||
例如:小明-5130112333654X-100-59-60
|
||||
</template>
|
||||
<file-upload :limit="1" v-model:model-value="filePath" isImportInfo :fileType="['zip']"
|
||||
uploadUrl="/safety/questionUserAnswer/upload/zip" :file-size="5000"
|
||||
:data="{ projectId: currentProject.id }"><el-button type="success" plain
|
||||
icon="Upload">上传线下安全考试</el-button></file-upload>
|
||||
<file-upload
|
||||
:limit="1"
|
||||
v-model:model-value="filePath"
|
||||
isImportInfo
|
||||
:fileType="['zip']"
|
||||
uploadUrl="/safety/wgzQuestionSave/upload/zip"
|
||||
:file-size="5000"
|
||||
:data="{ projectId: currentProject.id }"
|
||||
><el-button type="success" plain icon="Upload">上传线下安全考试</el-button></file-upload
|
||||
>
|
||||
</el-tooltip>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="Download" :disabled="single"
|
||||
@click="handleDownload()">批量下载试卷</el-button>
|
||||
<el-button type="primary" plain icon="Download" :disabled="single" @click="handleDownload()">批量下载试卷</el-button>
|
||||
</el-col>
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<el-table v-loading="loading" :data="questionUserAnswerList" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="主键id" align="center" prop="id" v-if="false" />
|
||||
<el-table-column type="index" label="序号" width="80" align="center" />
|
||||
<el-table-column label="姓名" align="center" prop="userName" />
|
||||
<el-table-column label="及格线/总分" align="center" prop="pass" />
|
||||
<el-table-column label="得分" align="center" prop="score" />
|
||||
@ -59,21 +62,19 @@
|
||||
<dict-tag :options="user_exam_type" :value="scope.row.examType" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-link type="primary" :underline="false" :href="scope.row.fileUrl[0]" target="_blank">
|
||||
<!-- <el-link type="primary" :underline="false" :href="scope.row.path[0]" target="_blank">
|
||||
<el-button link type="primary" icon="View">预览试卷</el-button>
|
||||
</el-link>
|
||||
|
||||
<el-button link type="primary" icon="Download" @click="downloadOssOne(scope.row)"
|
||||
v-hasPermi="['system:oss:download']">下载试卷</el-button>
|
||||
</el-link> -->
|
||||
<el-button link type="primary" icon="Download" @click="downloadOssOne(scope.row)" v-hasPermi="['system:oss:download']"
|
||||
>下载试卷</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" />
|
||||
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
@ -196,35 +197,15 @@ const handleSelectionChange = (selection: QuestionUserAnswerVO[]) => {
|
||||
multiple.value = !selection.length;
|
||||
};
|
||||
|
||||
/** 修改按钮操作 */
|
||||
// const handleUpdate = async (row?: QuestionUserAnswerVO) => {
|
||||
// reset();
|
||||
// const _id = row?.id || ids.value[0];
|
||||
// const res = await getQuestionUserAnswer(_id);
|
||||
// Object.assign(form.value, res.data);
|
||||
// dialog.visible = true;
|
||||
// dialog.title = '修改用户试卷存储';
|
||||
// };
|
||||
|
||||
/** 批量下载按钮操作 */
|
||||
const handleDownload = async () => {
|
||||
const _ids = ids.value;
|
||||
await downLoadOss({ idList: _ids }, '/safety/questionUserAnswer/exportFile', '安全考试.zip');
|
||||
await downLoadOss({ idList: _ids }, '/safety/wgzQuestionSave/exportFile', '安全考试.zip');
|
||||
};
|
||||
/** 下载单个按钮操作 */
|
||||
const downloadOssOne = async (row?: QuestionUserAnswerVO) => {
|
||||
await download.oss(row?.file);
|
||||
};
|
||||
|
||||
// const fileWatch = watch(
|
||||
// () => filePath.value,
|
||||
// (nid, oid) => {
|
||||
// uploadQuestionUserAnswer({ file: filePath.value, projectId: currentProject.value?.id }).then((res) => {
|
||||
// console.log(res);
|
||||
// });
|
||||
// }
|
||||
// );
|
||||
|
||||
//监听项目id刷新数据
|
||||
const listeningProject = watch(
|
||||
() => currentProject.value?.id,
|
||||
|
@ -22,38 +22,21 @@
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['safety:questionsCategory:add']">新增</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['safety:questionsCategory:edit']"
|
||||
>修改</el-button
|
||||
>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['safety:questionsCategory:remove']"
|
||||
>删除</el-button
|
||||
>
|
||||
</el-col>
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<el-table v-loading="loading" :data="questionsCategoryList" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table v-loading="loading" :data="questionsCategoryList">
|
||||
<el-table-column label="序号" align="center" type="index" width="100" />
|
||||
<el-table-column label="题库类别" align="center" prop="categoryName" />
|
||||
<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="['safety:questionsCategory:edit']"></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="删除" placement="top">
|
||||
<el-button
|
||||
link
|
||||
type="primary"
|
||||
icon="Delete"
|
||||
@click="handleDelete(scope.row)"
|
||||
v-hasPermi="['safety:questionsCategory:remove']"
|
||||
></el-button>
|
||||
</el-tooltip>
|
||||
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['safety:questionsCategory:edit']"
|
||||
>修改</el-button
|
||||
>
|
||||
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['safety:questionsCategory:remove']"
|
||||
>删除</el-button
|
||||
>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
@ -1,309 +1,220 @@
|
||||
<template>
|
||||
<div class="p-2">
|
||||
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
|
||||
<div v-show="showSearch" class="mb-[10px]">
|
||||
<el-card shadow="hover">
|
||||
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
|
||||
<el-form-item label="单选题" prop="singleChoice">
|
||||
<el-input v-model="queryParams.singleChoice" placeholder="请输入单选题" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="单选分数" prop="singleScore">
|
||||
<el-input v-model="queryParams.singleScore" placeholder="请输入单选分数" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="多选题" prop="multipleChoice">
|
||||
<el-input v-model="queryParams.multipleChoice" placeholder="请输入多选题" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="多选分数" prop="multipleScore">
|
||||
<el-input v-model="queryParams.multipleScore" placeholder="请输入多选分数" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="判断题" prop="estimate">
|
||||
<el-input v-model="queryParams.estimate" placeholder="请输入判断题" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="判断分数" prop="estimateScore">
|
||||
<el-input v-model="queryParams.estimateScore" placeholder="请输入判断分数" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="满分" prop="fullMark">
|
||||
<el-input v-model="queryParams.fullMark" placeholder="请输入满分" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="及格线" prop="passScore">
|
||||
<el-input v-model="queryParams.passScore" placeholder="请输入及格线" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="答题最大时间" prop="answerTime">
|
||||
<el-input v-model="queryParams.answerTime" placeholder="请输入答题最大时间" clearable @keyup.enter="handleQuery" />
|
||||
</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>
|
||||
</el-card>
|
||||
<div class="container p-4 md:p-6">
|
||||
<el-card shadow="hover" class="config-card transition-all duration-300 hover:shadow-lg">
|
||||
<div class="card-header mb-4">
|
||||
<h2 class="text-xl font-semibold text-gray-800">题库配置</h2>
|
||||
<p class="text-gray-500 text-sm">设置各类题型数量、分值及考试参数</p>
|
||||
</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="['safety:questionsConfig:add']"> 新增 </el-button>
|
||||
<el-form :model="form" label-width="120px" ref="formRef" class="config-form">
|
||||
<el-row :gutter="20">
|
||||
<!-- 单选题设置 -->
|
||||
<el-col :span="12" class="form-item-col">
|
||||
<el-form-item label="单选题(道)" :rules="[{ required: true, message: '单选题数量不能为空', trigger: 'blur' }]">
|
||||
<el-input type="number" v-model="form.singleChoice" min="0" class="transition-all" placeholder="请输入数量" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['safety:questionsConfig:edit']"
|
||||
>修改
|
||||
</el-button>
|
||||
|
||||
<el-col :span="12" class="form-item-col">
|
||||
<el-form-item label="单选分数" :rules="[{ required: true, message: '单选分数不能为空', trigger: 'blur' }]">
|
||||
<el-input type="number" v-model="form.singleScore" min="0" class="transition-all" placeholder="每题分数" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['safety:questionsConfig:remove']"
|
||||
>删除
|
||||
</el-button>
|
||||
|
||||
<!-- 多选题设置 -->
|
||||
<el-col :span="12" class="form-item-col">
|
||||
<el-form-item label="多选题(道)" :rules="[{ required: true, message: '多选题数量不能为空', trigger: 'blur' }]">
|
||||
<el-input type="number" v-model="form.multipleChoice" min="0" class="transition-all" placeholder="请输入数量" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['safety:questionsConfig:export']">导出 </el-button>
|
||||
|
||||
<el-col :span="12" class="form-item-col">
|
||||
<el-form-item label="多选分数" :rules="[{ required: true, message: '多选分数不能为空', trigger: 'blur' }]">
|
||||
<el-input type="number" v-model="form.multipleScore" min="0" class="transition-all" placeholder="每题分数" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<!-- 判断题设置 -->
|
||||
<el-col :span="12" class="form-item-col">
|
||||
<el-form-item label="判断题(道)" :rules="[{ required: true, message: '判断题数量不能为空', trigger: 'blur' }]">
|
||||
<el-input type="number" v-model="form.estimate" min="0" class="transition-all" placeholder="请输入数量" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="12" class="form-item-col">
|
||||
<el-form-item label="判断分数" :rules="[{ required: true, message: '判断分数不能为空', trigger: 'blur' }]">
|
||||
<el-input type="number" v-model="form.estimateScore" min="0" class="transition-all" placeholder="每题分数" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<!-- 分数设置 -->
|
||||
<el-col :span="12" class="form-item-col">
|
||||
<el-form-item label="及格分数" :rules="[{ required: true, message: '及格分数不能为空', trigger: 'blur' }]">
|
||||
<el-input
|
||||
type="number"
|
||||
v-model="form.passingScore"
|
||||
min="0"
|
||||
:max="form.fullMark"
|
||||
@change="handlePassingScoreChange"
|
||||
class="transition-all"
|
||||
placeholder="请输入及格分数"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="12" class="form-item-col">
|
||||
<el-form-item label="满分">
|
||||
<el-input type="number" v-model="form.fullMark" disabled class="bg-gray-50" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<!-- 时间设置 -->
|
||||
<el-col :span="12" class="form-item-col">
|
||||
<el-form-item label="答题时间(分钟)" :rules="[{ required: true, message: '答题时间不能为空', trigger: 'blur' }]">
|
||||
<el-input type="number" v-model="form.answerTime" min="0" class="transition-all" placeholder="请输入时间" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<el-table v-loading="loading" :data="questionsConfigList" @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 label="单选题" align="center" prop="singleChoice" />
|
||||
<el-table-column label="单选分数" align="center" prop="singleScore" />
|
||||
<el-table-column label="多选题" align="center" prop="multipleChoice" />
|
||||
<el-table-column label="多选分数" align="center" prop="multipleScore" />
|
||||
<el-table-column label="判断题" align="center" prop="estimate" />
|
||||
<el-table-column label="判断分数" align="center" prop="estimateScore" />
|
||||
<el-table-column label="满分" align="center" prop="fullMark" />
|
||||
<el-table-column label="及格线" align="center" prop="passScore" />
|
||||
<el-table-column label="答题最大时间" align="center" prop="answerTime" />
|
||||
<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="['safety:questionsConfig:edit']"></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="删除" placement="top">
|
||||
<el-button
|
||||
link
|
||||
type="primary"
|
||||
icon="Delete"
|
||||
@click="handleDelete(scope.row)"
|
||||
v-hasPermi="['safety:questionsConfig:remove']"
|
||||
></el-button>
|
||||
</el-tooltip>
|
||||
</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="questionsConfigFormRef" :model="form" :rules="rules" label-width="80px">
|
||||
<el-form-item label="单选题" prop="singleChoice">
|
||||
<el-input v-model="form.singleChoice" placeholder="请输入单选题" />
|
||||
</el-form-item>
|
||||
<el-form-item label="单选分数" prop="singleScore">
|
||||
<el-input v-model="form.singleScore" placeholder="请输入单选分数" />
|
||||
</el-form-item>
|
||||
<el-form-item label="多选题" prop="multipleChoice">
|
||||
<el-input v-model="form.multipleChoice" placeholder="请输入多选题" />
|
||||
</el-form-item>
|
||||
<el-form-item label="多选分数" prop="multipleScore">
|
||||
<el-input v-model="form.multipleScore" placeholder="请输入多选分数" />
|
||||
</el-form-item>
|
||||
<el-form-item label="判断题" prop="estimate">
|
||||
<el-input v-model="form.estimate" placeholder="请输入判断题" />
|
||||
</el-form-item>
|
||||
<el-form-item label="判断分数" prop="estimateScore">
|
||||
<el-input v-model="form.estimateScore" placeholder="请输入判断分数" />
|
||||
</el-form-item>
|
||||
<el-form-item label="满分" prop="fullMark">
|
||||
<el-input v-model="form.fullMark" placeholder="请输入满分" />
|
||||
</el-form-item>
|
||||
<el-form-item label="及格线" prop="passScore">
|
||||
<el-input v-model="form.passScore" placeholder="请输入及格线" />
|
||||
</el-form-item>
|
||||
<el-form-item label="答题最大时间" prop="answerTime">
|
||||
<el-input v-model="form.answerTime" 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 class="form-actions flex justify-center mt-6">
|
||||
<el-button type="primary" @click="onSubmit" :loading="buttonLoading" class="px-8 transition-all hover:scale-105"> 保存配置 </el-button>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="QuestionsConfig" lang="ts">
|
||||
import { addQuestionsConfig, delQuestionsConfig, getQuestionsConfig, listQuestionsConfig, updateQuestionsConfig } from '@/api/safety/questionsConfig';
|
||||
import { QuestionsConfigForm, QuestionsConfigQuery, QuestionsConfigVO } from '@/api/safety/questionsConfig/types';
|
||||
import { ref, reactive, computed, onMounted, getCurrentInstance } from 'vue';
|
||||
import { ElFormInstance, ComponentInternalInstance } from 'element-plus';
|
||||
import { getQuestionsConfig, updateQuestionsConfig } from '@/api/safety/questionsConfig';
|
||||
import { QuestionsConfigForm} from '@/api/safety/questionsConfig/types';
|
||||
import { useUserStoreHook } from '@/store/modules/user';
|
||||
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
// 获取用户 store
|
||||
// 获取用户信息
|
||||
const userStore = useUserStoreHook();
|
||||
// 从 store 中获取项目列表和当前选中的项目
|
||||
const currentProject = computed(() => userStore.selectedProject);
|
||||
const questionsConfigList = ref<QuestionsConfigVO[]>([]);
|
||||
|
||||
// 表单相关
|
||||
const formRef = ref<ElFormInstance>();
|
||||
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);
|
||||
|
||||
const queryFormRef = ref<ElFormInstance>();
|
||||
const questionsConfigFormRef = ref<ElFormInstance>();
|
||||
|
||||
const dialog = reactive<DialogOption>({
|
||||
visible: false,
|
||||
title: ''
|
||||
});
|
||||
|
||||
const initFormData: QuestionsConfigForm = {
|
||||
const form = reactive<QuestionsConfigForm>({
|
||||
id: undefined,
|
||||
projectId: currentProject.value?.id,
|
||||
singleChoice: undefined,
|
||||
singleScore: undefined,
|
||||
multipleChoice: undefined,
|
||||
multipleScore: undefined,
|
||||
estimate: undefined,
|
||||
estimateScore: undefined,
|
||||
fullMark: undefined,
|
||||
passScore: undefined,
|
||||
answerTime: undefined
|
||||
};
|
||||
const data = reactive<PageData<QuestionsConfigForm, QuestionsConfigQuery>>({
|
||||
form: { ...initFormData },
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
projectId: currentProject.value?.id,
|
||||
singleChoice: undefined,
|
||||
singleScore: undefined,
|
||||
multipleChoice: undefined,
|
||||
multipleScore: undefined,
|
||||
estimate: undefined,
|
||||
estimateScore: undefined,
|
||||
fullMark: undefined,
|
||||
passScore: undefined,
|
||||
answerTime: undefined,
|
||||
params: {}
|
||||
},
|
||||
rules: {
|
||||
id: [{ required: true, message: '主键id不能为空', trigger: 'blur' }],
|
||||
singleChoice: [{ required: true, message: '单选题不能为空', trigger: 'blur' }],
|
||||
singleScore: [{ required: true, message: '单选分数不能为空', trigger: 'blur' }],
|
||||
multipleChoice: [{ required: true, message: '多选题不能为空', trigger: 'blur' }],
|
||||
multipleScore: [{ required: true, message: '多选分数不能为空', trigger: 'blur' }],
|
||||
estimate: [{ required: true, message: '判断题不能为空', trigger: 'blur' }],
|
||||
estimateScore: [{ required: true, message: '判断分数不能为空', trigger: 'blur' }],
|
||||
fullMark: [{ required: true, message: '满分不能为空', trigger: 'blur' }],
|
||||
passScore: [{ required: true, message: '及格线不能为空', trigger: 'blur' }],
|
||||
answerTime: [{ required: true, message: '答题最大时间不能为空', trigger: 'blur' }]
|
||||
}
|
||||
singleChoice: 0,
|
||||
singleScore: 0,
|
||||
multipleChoice: 0,
|
||||
multipleScore: 0,
|
||||
estimate: 0,
|
||||
estimateScore: 0,
|
||||
fullMark: 0,
|
||||
passScore: 0,
|
||||
answerTime: 0,
|
||||
passingScore: 0
|
||||
});
|
||||
|
||||
const { queryParams, form, rules } = toRefs(data);
|
||||
// 计算满分
|
||||
const calculateFullMark = () => {
|
||||
form.fullMark =
|
||||
(form.singleChoice || 0) * (form.singleScore || 0) +
|
||||
(form.multipleChoice || 0) * (form.multipleScore || 0) +
|
||||
(form.estimate || 0) * (form.estimateScore || 0);
|
||||
|
||||
/** 查询题库配置列表 */
|
||||
const getList = async () => {
|
||||
loading.value = true;
|
||||
const res = await listQuestionsConfig(queryParams.value);
|
||||
questionsConfigList.value = res.rows;
|
||||
total.value = res.total;
|
||||
loading.value = false;
|
||||
// 确保及格分不超过满分
|
||||
if (form.passingScore > form.fullMark) {
|
||||
form.passingScore = form.fullMark;
|
||||
}
|
||||
};
|
||||
|
||||
/** 取消按钮 */
|
||||
const cancel = () => {
|
||||
reset();
|
||||
dialog.visible = false;
|
||||
// 监听分数变化,自动计算满分
|
||||
['singleChoice', 'singleScore', 'multipleChoice', 'multipleScore', 'estimate', 'estimateScore'].forEach((field) => {
|
||||
watch(() => form[field], calculateFullMark);
|
||||
});
|
||||
|
||||
// 处理及格分变化
|
||||
const handlePassingScoreChange = (val: number) => {
|
||||
if (val >= form.fullMark) {
|
||||
form.passingScore = form.fullMark;
|
||||
}
|
||||
};
|
||||
|
||||
/** 表单重置 */
|
||||
const reset = () => {
|
||||
form.value = { ...initFormData };
|
||||
questionsConfigFormRef.value?.resetFields();
|
||||
};
|
||||
|
||||
/** 搜索按钮操作 */
|
||||
const handleQuery = () => {
|
||||
queryParams.value.pageNum = 1;
|
||||
getList();
|
||||
};
|
||||
|
||||
/** 重置按钮操作 */
|
||||
const resetQuery = () => {
|
||||
queryFormRef.value?.resetFields();
|
||||
handleQuery();
|
||||
};
|
||||
|
||||
/** 多选框选中数据 */
|
||||
const handleSelectionChange = (selection: QuestionsConfigVO[]) => {
|
||||
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?: QuestionsConfigVO) => {
|
||||
reset();
|
||||
const _id = row?.id || ids.value[0];
|
||||
const res = await getQuestionsConfig(_id);
|
||||
Object.assign(form.value, res.data);
|
||||
dialog.visible = true;
|
||||
dialog.title = '修改题库配置';
|
||||
};
|
||||
|
||||
/** 提交按钮 */
|
||||
const submitForm = () => {
|
||||
questionsConfigFormRef.value?.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
buttonLoading.value = true;
|
||||
if (form.value.id) {
|
||||
await updateQuestionsConfig(form.value).finally(() => (buttonLoading.value = false));
|
||||
} else {
|
||||
await addQuestionsConfig(form.value).finally(() => (buttonLoading.value = false));
|
||||
}
|
||||
proxy?.$modal.msgSuccess('操作成功');
|
||||
dialog.visible = false;
|
||||
await getList();
|
||||
// 获取配置详情
|
||||
const getDetail = () => {
|
||||
getQuestionsConfig(1).then((res: any) => {
|
||||
if (res.code == 200 && res.data) {
|
||||
Object.assign(form, res.data);
|
||||
calculateFullMark(); // 确保满分计算正确
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/** 删除按钮操作 */
|
||||
const handleDelete = async (row?: QuestionsConfigVO) => {
|
||||
const _ids = row?.id || ids.value;
|
||||
await proxy?.$modal.confirm('是否确认删除题库配置编号为"' + _ids + '"的数据项?').finally(() => (loading.value = false));
|
||||
await delQuestionsConfig(_ids);
|
||||
proxy?.$modal.msgSuccess('删除成功');
|
||||
await getList();
|
||||
};
|
||||
|
||||
/** 导出按钮操作 */
|
||||
const handleExport = () => {
|
||||
proxy?.download(
|
||||
'safety/questionsConfig/export',
|
||||
{
|
||||
...queryParams.value
|
||||
},
|
||||
`questionsConfig_${new Date().getTime()}.xlsx`
|
||||
);
|
||||
// 提交表单
|
||||
const onSubmit = () => {
|
||||
formRef.value?.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
buttonLoading.value = true;
|
||||
try {
|
||||
await updateQuestionsConfig(form);
|
||||
// 显示成功消息(假设使用element-plus的message组件)
|
||||
ElMessage.success('配置保存成功');
|
||||
getDetail(); // 重新获取最新配置
|
||||
} catch (error) {
|
||||
ElMessage.error('保存失败,请重试');
|
||||
} finally {
|
||||
buttonLoading.value = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// 页面加载时获取数据
|
||||
onMounted(() => {
|
||||
getList();
|
||||
getDetail();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.container {
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
padding-top: 20px;
|
||||
}
|
||||
|
||||
.config-card {
|
||||
border-radius: 12px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.card-header {
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
padding-bottom: 12px;
|
||||
}
|
||||
|
||||
.form-item-col {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.form-actions {
|
||||
padding: 16px;
|
||||
border-top: 1px solid #f0f0f0;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
// 输入框聚焦效果
|
||||
::v-deep .el-input__wrapper:focus-within {
|
||||
box-shadow: 0 0 0 2px rgba(48, 163, 255, 0.2);
|
||||
}
|
||||
|
||||
// 响应式调整
|
||||
@media (max-width: 768px) {
|
||||
.el-col {
|
||||
&:span-12 {
|
||||
width: 100% !important;
|
||||
}
|
||||
}
|
||||
|
||||
.card-header {
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="p-2 editInfo">
|
||||
<el-form label-position="top" ref="userFormRef" :model="form" :rules="rules" label-width="80px">
|
||||
<el-form label-position="top" ref="userFormRef" :model="form" :rules="rules" label-width="80px" size="large">
|
||||
<el-row>
|
||||
<el-col :span="10">
|
||||
<el-form-item label="用户昵称" prop="nickName">
|
||||
@ -70,15 +70,15 @@
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="备注">
|
||||
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容"></el-input>
|
||||
<el-input v-model="form.remark" type="textarea" :autosize="{ minRows: 3, maxRows: 3 }" placeholder="请输入内容"></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<!-- <div class="box_submit">
|
||||
<el-button type="primary" @click="submitForm">确 定</el-button>
|
||||
<el-button @click="cancel()">取 消</el-button>
|
||||
</div> -->
|
||||
<div class="box_submit">
|
||||
<el-button size="large" @click="cancel()">取 消</el-button>
|
||||
<!-- <el-button size="large" type="primary" @click="submitForm">确 定</el-button> -->
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -192,12 +192,12 @@ async function handleDeptChange(value: number | string) {
|
||||
];
|
||||
}
|
||||
|
||||
const submitForm = () => {
|
||||
const submitForm = (cb) => {
|
||||
userFormRef.value?.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
form.value.userId ? await api.updateUser(form.value) : await api.addUser(form.value);
|
||||
proxy?.$modal.msgSuccess('操作成功');
|
||||
proxy?.$emit('submit', false);
|
||||
// form.value.userId ? await api.updateUser(form.value) : await api.addUser(form.value);
|
||||
// proxy?.$modal.msgSuccess('操作成功');
|
||||
cb();
|
||||
}
|
||||
});
|
||||
};
|
||||
@ -243,16 +243,16 @@ const getInfoForm = () => {
|
||||
onMounted(() => {
|
||||
getDeptTree();
|
||||
});
|
||||
defineExpose({ open, getInfoForm });
|
||||
defineExpose({ open, getInfoForm, submitForm });
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.editInfo {
|
||||
position: relative;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
.box_submit {
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
bottom: 10px;
|
||||
align-self: flex-end;
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -11,7 +11,7 @@
|
||||
</el-table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="title_detail" style="margin-top: 20px">
|
||||
<div class="title_detail" style="margin-top: 10px">
|
||||
<span>选择或修改当前角色信息</span>
|
||||
<div style="margin-top: 10px" class="box_detail">
|
||||
<!-- 项目列表选择区 -->
|
||||
@ -34,7 +34,7 @@
|
||||
</div>
|
||||
<!-- 角色分配区 -->
|
||||
<div class="post_list">
|
||||
<span>关联项目角色分配</span>
|
||||
<div class="list_title">关联项目角色分配</div>
|
||||
<div v-if="selectedProjects.length === 0" class="no-selection">请从左侧选择项目进行角色分配</div>
|
||||
<div v-for="(project, index) in selectedProjects" :key="project.id" class="project-role-container">
|
||||
<div class="project-header">
|
||||
@ -64,8 +64,8 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="box_submit">
|
||||
<el-button type="primary" @click="submitForm">确 定</el-button>
|
||||
<el-button @click="cancel()">取 消</el-button>
|
||||
<el-button size="large" @click="cancel()">取 消</el-button>
|
||||
<el-button size="large" type="primary" @click="submitForm">保存角色信息</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@ -219,7 +219,19 @@ const removeProject = (projectId: number | string) => {
|
||||
// 提交表单
|
||||
const submitForm = async () => {
|
||||
// 整理项目角色数据
|
||||
if (form.value.projectRoles.length == 0) {
|
||||
console.log(selectedProjects.value);
|
||||
|
||||
if (selectedProjects.value.length == 0) {
|
||||
proxy?.$modal.msgWarning('请选择项目角色');
|
||||
return;
|
||||
}
|
||||
let flag = false;
|
||||
selectedProjects.value.forEach((project) => {
|
||||
if (project.appRoles.length > 0 || project.webRoles.length > 0) {
|
||||
flag = true;
|
||||
}
|
||||
});
|
||||
if (!flag) {
|
||||
proxy?.$modal.msgWarning('请选择项目角色');
|
||||
return;
|
||||
}
|
||||
@ -328,10 +340,12 @@ defineExpose({ open });
|
||||
|
||||
<style lang="scss">
|
||||
.roleInfo {
|
||||
position: relative;
|
||||
height: 100%;
|
||||
padding-bottom: 60px;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
|
||||
.title_detail {
|
||||
> span {
|
||||
@ -359,7 +373,7 @@ defineExpose({ open });
|
||||
|
||||
.project_list {
|
||||
width: 320px;
|
||||
background-color: #fff;
|
||||
border: 1px solid #eee;
|
||||
|
||||
.project-items {
|
||||
margin-top: 10px;
|
||||
@ -374,8 +388,7 @@ defineExpose({ open });
|
||||
border: 1px solid #eee;
|
||||
|
||||
&:hover {
|
||||
background-color: #f5f7fa;
|
||||
border-color: #e4e7ed;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.project-item-content {
|
||||
@ -403,7 +416,11 @@ defineExpose({ open });
|
||||
|
||||
.post_list {
|
||||
flex: 1;
|
||||
background-color: #fff;
|
||||
border: 1px solid #eee;
|
||||
|
||||
.list_title {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.no-selection {
|
||||
height: 100%;
|
||||
@ -417,9 +434,9 @@ defineExpose({ open });
|
||||
.project-role-container {
|
||||
padding: 15px;
|
||||
margin-bottom: 15px;
|
||||
background-color: #f9f9f9;
|
||||
// background-color: #f9f9f9;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #f0f0f0;
|
||||
border: 1px solid rgb(229 231 235);
|
||||
|
||||
.project-header {
|
||||
display: flex;
|
||||
@ -445,7 +462,9 @@ defineExpose({ open });
|
||||
|
||||
.role-assignment {
|
||||
.role-group {
|
||||
margin-bottom: 15px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-bottom: 10px;
|
||||
|
||||
.role-label {
|
||||
display: inline-block;
|
||||
@ -471,9 +490,7 @@ defineExpose({ open });
|
||||
}
|
||||
|
||||
.box_submit {
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
bottom: 0px;
|
||||
align-self: flex-end;
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
}
|
||||
|
@ -154,11 +154,26 @@
|
||||
</el-row>
|
||||
|
||||
<!-- 添加或修改用户配置对话框 -->
|
||||
<el-dialog draggable ref="formDialogRef" v-model="dialog.visible" :title="dialog.title" width="1300px" append-to-body @close="closeDialog">
|
||||
<el-dialog
|
||||
draggable
|
||||
ref="formDialogRef"
|
||||
style="background: rgb(249, 250, 251)"
|
||||
v-model="dialog.visible"
|
||||
:title="dialog.title"
|
||||
width="1300px"
|
||||
append-to-body
|
||||
@close="closeDialog"
|
||||
>
|
||||
<div class="boxDetial">
|
||||
<div class="tab_info">
|
||||
<span @click="onTab(1)" :class="{ active: type == 1 }">基本资料</span>
|
||||
<span @click="onTab(2)" :class="{ active: type == 2 }">角色信息</span>
|
||||
<div class="tab_item" @click="onTab(1)" :class="{ active: type == 1 }">
|
||||
<Avatar style="width: 1em; height: 1em; margin-right: 8px" :style="{ color: type == 1 ? '#1890ff' : '#000' }" />
|
||||
<span>基本资料</span>
|
||||
</div>
|
||||
<div class="tab_item" @click="onTab(2)" :class="{ active: type == 2 }">
|
||||
<Key style="width: 1em; height: 1em; margin-right: 8px" :style="{ color: type == 2 ? '#1890ff' : '#000' }" />
|
||||
<span>角色信息</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tab_content" v-show="type == 1">
|
||||
<editInfo ref="editInfoRef" @close="dialog.visible = false" @submit="getList" @setDeptId="setDeptId"></editInfo>
|
||||
@ -232,6 +247,7 @@ import ShuttleFrame from '../../project/projectRelevancy/component/ShuttleFrame.
|
||||
import { listProject } from '@/api/project/project';
|
||||
import editInfo from './comm/editInfo.vue';
|
||||
import roleInfo from './comm/roleInfo.vue';
|
||||
import { color } from 'echarts';
|
||||
const router = useRouter();
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
const { sys_normal_disable, sys_user_sex } = toRefs<any>(proxy?.useDict('sys_normal_disable', 'sys_user_sex'));
|
||||
@ -690,14 +706,21 @@ const uploadCert = async () => {
|
||||
certDialog.value = false;
|
||||
proxy?.$modal.msgSuccess('上传证书目录成功');
|
||||
};
|
||||
const onTab = (val) => {
|
||||
type.value = val;
|
||||
const onTab = (val: number) => {
|
||||
if (val == 2) {
|
||||
let obj = editInfoRef.value?.getInfoForm();
|
||||
form.value = obj;
|
||||
nextTick(() => {
|
||||
roleInfoRef.value?.open(form.value, deptIdRole.value);
|
||||
// 查看基本信息
|
||||
editInfoRef.value?.submitForm((res) => {
|
||||
type.value = val;
|
||||
let obj = editInfoRef.value?.getInfoForm();
|
||||
form.value = obj;
|
||||
console.log(obj);
|
||||
|
||||
nextTick(() => {
|
||||
roleInfoRef.value?.open(form.value, deptIdRole.value);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
type.value = val;
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@ -706,21 +729,32 @@ const onTab = (val) => {
|
||||
.boxDetial {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
align-items: start;
|
||||
height: 680px;
|
||||
gap: 20px;
|
||||
|
||||
.tab_info {
|
||||
height: 100%;
|
||||
height: 40%;
|
||||
width: 200px;
|
||||
background: #f0f2f5;
|
||||
padding: 10px;
|
||||
background: #fff;
|
||||
padding: 30px 10px;
|
||||
text-align: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
border-radius: 0.5rem;
|
||||
font-size: 18px;
|
||||
> span {
|
||||
.tab_item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 5px;
|
||||
margin-bottom: 10px;
|
||||
padding: 5px 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
.tab_item:hover {
|
||||
background-color: rgb(249, 250, 251);
|
||||
}
|
||||
.active {
|
||||
color: #1890ff;
|
||||
}
|
||||
@ -729,7 +763,8 @@ const onTab = (val) => {
|
||||
height: 100%;
|
||||
width: calc(100% - 200px);
|
||||
padding: 20px 10px;
|
||||
background: #ccc;
|
||||
background: #fff;
|
||||
border-radius: 0.5rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -59,10 +59,12 @@
|
||||
</transition>
|
||||
<el-card shadow="never" class="mb8">
|
||||
<el-table ref="tableAllRef" v-loading="loading" :data="tableData" row-key="id" border lazy :expand-row-keys="expandRowKeys">
|
||||
<el-table-column prop="num" label="编号" />
|
||||
<el-table-column prop="name" label="工程或费用名称" />
|
||||
<el-table-column prop="num" label="编号" align="center" />
|
||||
<el-table-column prop="name" label="工程或费用名称" align="center" />
|
||||
<el-table-column prop="unit" label="单位" align="center" />
|
||||
|
||||
<el-table-column prop="supplier" label="供货单位" align="center" v-if="activeTab == '3'" />
|
||||
<el-table-column prop="contractNumber" label="合同编号" align="center" v-if="activeTab == '3'" />
|
||||
<el-table-column prop="specification" label="规格" align="center" />
|
||||
<el-table-column prop="quantity" label="数量" align="center">
|
||||
<template #default="scope">
|
||||
|
@ -23,22 +23,24 @@
|
||||
{{ (queryParams.pageNum - 1) * queryParams.pageSize + scope.$index + 1 }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="name" label="名称" />
|
||||
<el-table-column prop="content" label="内容" />
|
||||
<el-table-column prop="price" label="限价" />
|
||||
<el-table-column prop="bidd">
|
||||
<el-table-column prop="name" label="名称" align="center" />
|
||||
<el-table-column prop="content" label="内容" align="center" />
|
||||
<el-table-column prop="price" label="限价" align="center" />
|
||||
<el-table-column prop="bidd" align="center">
|
||||
<template #header> <span style="color: red">*</span>招标文件 </template>
|
||||
<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)" v-if="scope.row.annexCount > 0"
|
||||
>查看文件({{ scope.row.annexCount }})</el-button
|
||||
>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="winningBidder">
|
||||
<el-table-column prop="winningBidder" align="center">
|
||||
<template #header> <span style="color: red">*</span>中标单位 </template>
|
||||
<template #default="scope">
|
||||
{{ scope.row.winningBidder }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="bidFileName">
|
||||
<el-table-column prop="bidFileName" align="center">
|
||||
<template #header> <span style="color: red">*</span>中标文件 </template>
|
||||
<template #default="scope">
|
||||
<el-button type="primary" link @click="openPdf(scope.row.bidFile)">{{ scope.row.bidFileName }} </el-button>
|
||||
@ -198,9 +200,11 @@
|
||||
? activeTab == 2
|
||||
? 0
|
||||
: ''
|
||||
: (scope.row.quantity ? Number(scope.row.quantity) : 0) -
|
||||
(scope.row.selectNum ? Number(scope.row.selectNum) : 0) -
|
||||
(scope.row.useQuantity ? Number(scope.row.useQuantity) : 0)
|
||||
: (
|
||||
(scope.row.quantity ? Number(scope.row.quantity) : 0) -
|
||||
(scope.row.selectNum ? Number(scope.row.selectNum) : 0) -
|
||||
(scope.row.useQuantity ? Number(scope.row.useQuantity) : 0)
|
||||
).toFixed(2)
|
||||
}}
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
@ -34,15 +34,13 @@
|
||||
<el-table-column :show-overflow-tooltip="true" prop="flowName" align="center" label="流程定义名称"></el-table-column>
|
||||
<el-table-column align="center" prop="flowCode" label="流程定义编码"></el-table-column>
|
||||
<el-table-column align="center" prop="categoryName" label="流程分类"></el-table-column>
|
||||
<el-table-column align="center" prop="version" label="版本号" width="90">
|
||||
<template #default="scope"> v{{ scope.row.version }}.0</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" prop="nodeName" label="任务名称"></el-table-column>
|
||||
<el-table-column align="center" label="流程状态" min-width="70">
|
||||
<template #default="scope">
|
||||
<dict-tag :options="wf_business_status" :value="scope.row.flowStatus"></dict-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" prop="updateTime" label="更新时间" width="150"></el-table-column>
|
||||
<el-table-column label="操作" align="center" width="200">
|
||||
<template #default="scope">
|
||||
<el-button type="primary" size="small" icon="View" @click="handleView(scope.row)">查看</el-button>
|
||||
|
Reference in New Issue
Block a user