This commit is contained in:
shi
2025-09-05 16:03:39 +08:00
235 changed files with 21706 additions and 5622 deletions

View File

@ -5,7 +5,16 @@ VITE_APP_TITLE = 煤科建管平台
VITE_APP_ENV = 'development' VITE_APP_ENV = 'development'
# 开发环境 # 开发环境
VITE_APP_BASE_API = 'http://192.168.110.209: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.188:8899'
# 朱银
VITE_APP_BASE_API = 'http://192.168.110.180:8899'
#曾涛
# VITE_APP_BASE_API = 'http://192.168.110.171:8899'
# 无人机接口地址 # 无人机接口地址

View File

@ -31,6 +31,7 @@
"await-to-js": "3.0.0", "await-to-js": "3.0.0",
"axios": "1.7.8", "axios": "1.7.8",
"crypto-js": "4.2.0", "crypto-js": "4.2.0",
"date-fns": "^4.1.0",
"diagram-js": "12.3.0", "diagram-js": "12.3.0",
"didi": "9.0.2", "didi": "9.0.2",
"echarts": "5.5.0", "echarts": "5.5.0",
@ -68,7 +69,8 @@
"vue-types": "5.1.3", "vue-types": "5.1.3",
"vue3-print-nb": "^0.1.4", "vue3-print-nb": "^0.1.4",
"vue3-scroll-seamless": "^1.0.6", "vue3-scroll-seamless": "^1.0.6",
"vxe-table": "4.5.22" "vxe-table": "4.5.22",
"xlsx": "^0.18.5"
}, },
"devDependencies": { "devDependencies": {
"@eslint/js": "9.15.0", "@eslint/js": "9.15.0",

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

BIN
public/assets/demo/back.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 419 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 344 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 428 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
public/assets/demo/rain.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1014 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 993 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
public/assets/demo/sb1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

BIN
public/assets/demo/sb2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

BIN
public/assets/demo/sb3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

BIN
public/assets/demo/sb4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
public/assets/demo/sbi1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

BIN
public/assets/demo/sbi2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 107 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

BIN
public/assets/demo/wcl.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
public/assets/demo/ycl.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

BIN
public/assets/demo/yin.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
public/assets/demo/zzcl.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

BIN
public/catalog.xlsx Normal file

Binary file not shown.

BIN
public/daolu.xlsx Normal file

Binary file not shown.

BIN
public/dikuai.xlsx Normal file

Binary file not shown.

BIN
public/enterRoad.xlsx Normal file

Binary file not shown.

BIN
public/landBlock.xlsx Normal file

Binary file not shown.

Binary file not shown.

View File

@ -8,14 +8,20 @@
import useSettingsStore from '@/store/modules/settings'; import useSettingsStore from '@/store/modules/settings';
import { handleThemeStyle } from '@/utils/theme'; import { handleThemeStyle } from '@/utils/theme';
import useAppStore from '@/store/modules/app'; import useAppStore from '@/store/modules/app';
import { getProjectTeam } from './utils/projectTeam';
const appStore = useAppStore(); const appStore = useAppStore();
onMounted(() => { onMounted(() => {
nextTick(() => { nextTick(() => {
// 初始化主题样式 // 初始化主题样式
handleThemeStyle(useSettingsStore().theme); handleThemeStyle(useSettingsStore().theme);
getProjectTeam();
}); });
}); });
</script> </script>
<style>
* {
-webkit-user-select: none; /* Safari */
-moz-user-select: none; /* Firefox */
-ms-user-select: none; /* IE10+/Edge */
user-select: none; /* Standard syntax */
}
</style>

View File

@ -21,7 +21,7 @@ export const AddbiddingUser = (data) => {
data data
}); });
}; };
// 新增招投标人员 // 查询招投标人员
export const biddingUserList = (projectId) => { export const biddingUserList = (projectId) => {
return request({ return request({
url: '/bidding/biddingUser/list', url: '/bidding/biddingUser/list',

View File

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

View File

@ -72,3 +72,15 @@ export const getFileList = (data) => {
params: data params: data
}) })
} }
/**
* 查看收入合同附件列表
* @param id
*/
export const getInfoByProjectId = (data) => {
return request({
url: '/bidding/listOfWinningBids/getInfoByProjectId',
method: 'get',
params: data
})
}

View File

@ -27,3 +27,11 @@ export const systemUserList = (query) => {
params: query params: query
}); });
}; };
// 查询
export const desUserList = (query) => {
return request({
url: '/design/drawingreviewReceipts/desUser/list',
method: 'get',
params: query
});
};

View File

@ -56,7 +56,7 @@ export const fillOutTheDesignVerificationForm = (data) => {
export const drawingreviewReceipts = (data) => { export const drawingreviewReceipts = (data) => {
return request({ return request({
url: '/design/drawingreviewReceipts', url: '/design/drawingreviewReceipts',
method: 'post', method: 'put',
data data
}); });
}; };
@ -96,3 +96,10 @@ export const drawingreview = (id) => {
method: 'get' method: 'get'
}); });
}; };
// 获取单据
export const getDrawingreviewReceipts = (id) => {
return request({
url: '/design/drawingreviewReceipts/review/' + id,
method: 'get'
});
};

View File

@ -24,3 +24,11 @@ export const exportWord = (params) => {
method: 'post' method: 'post'
}); });
}; };
// 导出模版
export const exportExcel = (params) => {
return request({
url: '/design/collect/exportExcel',
method: 'post',
params: params
});
};

View File

@ -116,6 +116,28 @@ export const getileDetail = (id) => {
method: 'get' method: 'get'
}); });
}; };
/**
* 获取专业列表
* @param query
*/
export const majorList = (params) => {
return request({
url: '/design/volumeCatalog/majorList',
method: 'get',
params: params
});
};
/**
* 获取人员列表
* @param query
*/
export const copyUserList = (params) => {
return request({
url: '/design/volumeCatalog/copyUserList',
method: 'get',
params: params
});
};
/** /**
* 获取二维码信息 * 获取二维码信息
* @param query * @param query

View File

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

View File

@ -75,3 +75,12 @@ export const getWhetherItExists = (id: string | number): AxiosPromise<ListOfForm
} }
}); });
}; };
//模版新增
export const addFormalities = (data: any): AxiosPromise<ListOfFormalitiesVO> => {
return request({
url: '/formalities/formalitiesAreConsolidated/addFormalities',
method: 'post',
data
});
};

View File

@ -0,0 +1,100 @@
import request from '@/utils/request';
import { AxiosPromise } from 'axios';
import { MasterVO, MasterForm, MasterQuery } from '@/api/patch/types';
/**
* 合同金额
*
*/
export const totalAmount = () => {
return request({
url: '/money/big/screen/totalAmount',
method: 'get'
});
};
/**
* 查询项目位置列表
*
*/ export const projectGis = (clientid?: any) => {
return request({
url: '/money/big/screen/project/gis',
method: 'get',
params: clientid
});
};
/**
* 应收实收
*
*/ export const incomePay = (clientid) => {
return request({
url: '/money/big/screen/income/pay',
method: 'get',
params: clientid
});
};
/**
* 收入合同分析
*
*/ export const incomeAnalyze = (clientid) => {
return request({
url: '/money/big/screen/income/analyze',
method: 'get',
params: clientid
});
};
/**
* 应付实付
*
*/ export const expensesPay = (clientid) => {
return request({
url: '/money/big/screen/expenses/pay',
method: 'get',
params: clientid
});
};
/**
* 支出合同分析
*
*/
export const expensesAnalyze = (clientid) => {
return request({
url: '/money/big/screen/expenses/analyze',
method: 'get',
params: clientid
});
};
/**
* 成本
*
*/ export const cost = (clientid) => {
return request({
url: '/money/big/screen/cost',
method: 'get',
params: clientid
});
};
// 资金KPI
export const monthMoney = () => {
return request({
url: '/money/big/screen/monthMoney',
method: 'get'
});
};
// 现金流
export const monthCash = () => {
return request({
url: '/money/big/screen/monthCash',
method: 'get'
});
};
// 现金流总和
export const cashTotal = () => {
return request({
url: '/money/big/screen/cashTotal',
method: 'get'
});
};

View File

@ -143,3 +143,30 @@ export const getDictList = (query: any): AxiosPromise<any[]> => {
params: query params: query
}); });
}; };
export const coryEngineeringList = (query: any): AxiosPromise<any[]> => {
return request({
url: '/cailiaoshebei/mrpBase/coryEngineeringList',
method: 'get',
params: query
});
};
/**
* 获取到物资状态为已完成的版本
*/
export const obtainTheVersion = (query: any) => {
return request({
url: '/cailiaoshebei/mrpBase/obtainTheVersion',
method: 'get',
params: query
});
};
/**
* 获取到物资剩余量
*/
export const mrpBaseRemaining = (query: any) => {
return request({
url: '/cailiaoshebei/mrpBase/remaining',
method: 'get',
params: query
});
};

View File

@ -14,6 +14,18 @@ export const listCompany = (query?: CompanyQuery): AxiosPromise<CompanyVO[]> =>
method: 'get', method: 'get',
params: query params: query
}); });
}; /**
* 查询材料提供商
* @param query
* @returns {*}
*/
export const supplierInputGet = (query?) => {
return request({
url: '/supplierInput/supplierInput/getList',
method: 'get',
params: query
});
}; };
/** /**

View File

@ -61,3 +61,25 @@ export const delMaterialIssue = (id: string | number | Array<string | number>) =
method: 'delete' method: 'delete'
}); });
}; };
//获取一起名称
export const getMaterialName = (id: any) => {
return request({
url: '/materials/materials/inventoryNumber/' + id,
method: 'get'
});
};
//获取出库记录
export const inventoryList = (id: any) => {
return request({
url: '/materials/materialIssue/inventory/list/' + id,
method: 'get'
});
};
//获取材料表信息
export const getMaterialInfo = (id: any) => {
return request({
url: '/materials/materials/listByFormCode/' + id,
method: 'get'
});
};

View File

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

View File

@ -0,0 +1,70 @@
import request from '@/utils/request';
import { AxiosPromise } from 'axios';
import { MaterialsUseRecordVO, MaterialsUseRecordForm, MaterialsUseRecordQuery } from '@/api/materials/materialsUseRecord/types';
/**
* 查询材料使用登记列表
* @param query
* @returns {*}
*/
export const listMaterialsUseInventory = (query?: MaterialsUseRecordQuery): AxiosPromise<MaterialsUseRecordVO[]> => {
return request({
url: '/materials/materialsInventory/list',
method: 'get',
params: query
});
};
export const listMaterialsUseRecord = (query?: MaterialsUseRecordQuery): AxiosPromise<MaterialsUseRecordVO[]> => {
return request({
url: '/materials/materialsUseRecord/list',
method: 'get',
params: query
});
};
/**
* 查询材料使用登记详细
* @param id
*/
export const getMaterialsUseRecord = (id: string | number): AxiosPromise<MaterialsUseRecordVO> => {
return request({
url: '/materials/materialsUseRecord/' + id,
method: 'get'
});
};
/**
* 新增材料使用登记
* @param data
*/
export const addMaterialsUseRecord = (data: MaterialsUseRecordForm) => {
return request({
url: '/materials/materialsUseRecord',
method: 'post',
data: data
});
};
/**
* 修改材料使用登记
* @param data
*/
export const updateMaterialsUseRecord = (data: MaterialsUseRecordForm) => {
return request({
url: '/materials/materialsUseRecord',
method: 'put',
data: data
});
};
/**
* 删除材料使用登记
* @param id
*/
export const delMaterialsUseRecord = (id: string | number | Array<string | number>) => {
return request({
url: '/materials/materialsUseRecord/' + id,
method: 'delete'
});
};

View File

@ -0,0 +1,111 @@
export interface MaterialsUseRecordVO {
/**
* 主键ID
*/
id: string | number;
/**
* 项目ID
*/
projectId: string | number;
/**
* 库存ID
*/
inventoryId: string | number;
/**
* 使用部位
*/
usePart: string;
/**
* 使用数量
*/
useNumber: number;
/**
* 剩余量
*/
residueNumber: string | number;
/**
* 备注
*/
remark: string;
}
export interface MaterialsUseRecordForm extends BaseEntity {
/**
* 主键ID
*/
id?: string | number;
/**
* 项目ID
*/
projectId?: string | number;
/**
* 库存ID
*/
inventoryId?: string | number;
/**
* 使用部位
*/
usePart?: string;
/**
* 使用数量
*/
useNumber?: number;
/**
* 剩余量
*/
residueNumber?: string | number;
/**
* 备注
*/
remark?: string;
}
export interface MaterialsUseRecordQuery extends PageQuery {
/**
* 项目ID
*/
projectId?: string | number;
/**
* 库存ID
*/
inventoryId?: string | number;
/**
* 使用部位
*/
usePart?: string;
/**
* 使用数量
*/
useNumber?: number;
/**
* 剩余量
*/
residueNumber?: string | number;
/**
* 日期范围参数
*/
params?: any;
}

View File

@ -21,7 +21,7 @@ export const totalsupplyplan = (params: any): AxiosPromise => {
export const totalSupplyplanDetails = (id: any): AxiosPromise => { export const totalSupplyplanDetails = (id: any): AxiosPromise => {
return request({ return request({
url: '/design/totalsupplyplan/' + id, url: '/design/totalsupplyplan/' + id,
method: 'get', method: 'get'
}); });
}; };
// 修改物资-总供应计划 // 修改物资-总供应计划
@ -33,4 +33,11 @@ export const materialChangeSupplyplan = (data: any): AxiosPromise => {
}); });
}; };
// 总供应计划-批量编辑
export const totalSupplyplanBatchEdit = (data: any): AxiosPromise => {
return request({
url: '/design/totalsupplyplan/batchEdit',
method: 'put',
data
});
};

View File

@ -3,9 +3,9 @@ import { AxiosPromise } from 'axios';
import { RouteRecordRaw } from 'vue-router'; import { RouteRecordRaw } from 'vue-router';
// 获取路由 // 获取路由
export function getRouters(): AxiosPromise<RouteRecordRaw[]> { export function getRouters(id: string): AxiosPromise<RouteRecordRaw[]> {
return request({ return request({
url: '/system/menu/getRouters', url: '/system/menu/getRouters/' + id,
method: 'get' method: 'get'
}); });
} }

View File

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

View File

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

View File

@ -98,3 +98,26 @@ export const getMonthInfo = (query): AxiosPromise<MonthPlanVO> => {
params: query params: query
}); });
}; };
/**
* 修改采购完工产值对甲
* @param id
*/
export const purchaseValueAup = (query) => {
return request({
url: '/out/monthPlan/purchaseValueAup',
method: 'get',
params: query
});
};
/**
* 采购完工产值对甲
* @param id
*/
export const purchaseValueA = (query) => {
return request({
url: '/out/monthPlan/purchaseValueA',
method: 'get',
params: query
});
};

View File

@ -7,3 +7,19 @@ export function listOutTable(query: any) {
params: query params: query
}); });
} }
// 对甲产值和对乙产值
export function comparisonOfOutputValue(query: any) {
return request({
url: '/out/table/outCompare',
method: 'get',
params: query
});
}
// 对甲结算和对乙结算
export function comparisonOfSettlementValue(query: any) {
return request({
url: '/out/table/comparisonOfOwnerAndSub',
method: 'get',
params: query
});
}

View File

@ -0,0 +1,24 @@
import request from '@/utils/request';
/**
* 修改采购完工产值对甲
* @param id
*/
export const purchaseValueAup = (query) => {
return request({
url: '/out/monthPlan/purchaseValueAup',
method: 'get',
params: query
});
};
/**
* 采购完工产值对甲
* @param id
*/
export const purchaseValueA = (query) => {
return request({
url: '/out/monthPlan/purchaseValueA',
method: 'get',
params: query
});
};

View File

@ -61,3 +61,13 @@ export const delConstructionSchedulePlan = (id: string | number | Array<string |
method: 'delete' method: 'delete'
}); });
}; };
/**
* 获取项目结构
* @param id
*/
export const getProjectStructure = (id: string | number | Array<string | number>) => {
return request({
url: '/project/project/projectStructure/' + id,
method: 'get'
});
};

View File

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

View File

@ -84,10 +84,10 @@ export interface ProgressCategoryVO {
*/ */
remark: string; remark: string;
/** /**
* 子对象 * 子对象
*/ */
children: ProgressCategoryVO[]; children: ProgressCategoryVO[];
} }
export interface ProgressCategoryForm extends BaseEntity { export interface ProgressCategoryForm extends BaseEntity {
@ -95,6 +95,9 @@ export interface ProgressCategoryForm extends BaseEntity {
* 主键id * 主键id
*/ */
id?: string | number; id?: string | number;
constructionPrice?: string | number;
ownerPrice?: string | number;
relevancyStructure?: string;
/** /**
* 父类别id * 父类别id
@ -175,11 +178,9 @@ export interface ProgressCategoryForm extends BaseEntity {
* 备注 * 备注
*/ */
remark?: string; remark?: string;
} }
export interface ProgressCategoryQuery { export interface ProgressCategoryQuery {
/** /**
* 父类别id * 父类别id
*/ */
@ -255,11 +256,8 @@ export interface ProgressCategoryQuery {
*/ */
status?: string; status?: string;
/** /**
* 日期范围参数 * 日期范围参数
*/ */
params?: any; params?: any;
} }

View File

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

View File

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

View File

@ -28,10 +28,10 @@ export interface ContractorVO {
* 管理人联系电话 * 管理人联系电话
*/ */
custodianPhone: string; custodianPhone: string;
/** /**
* 分包类型 * 分包类型
*/ */
contractorType?: string; contractorType?: string;
/** /**
* 公司相关文件 * 公司相关文件
@ -54,6 +54,14 @@ export interface ContractorForm extends BaseEntity {
* 主键id * 主键id
*/ */
id?: string | number; id?: string | number;
/**
* 供应商id
*/
supplierId?: string | number;
/**
* 供应商
*/
supplier?: string;
/** /**
* 主键id * 主键id
@ -127,10 +135,10 @@ export interface ContractorQuery extends PageQuery {
* 管理人联系电话 * 管理人联系电话
*/ */
custodianPhone?: string; custodianPhone?: string;
/** /**
* 分包类型 * 分包类型
*/ */
contractorType?: string; contractorType?: string;
/** /**
* 日期范围参数 * 日期范围参数

View File

@ -96,8 +96,6 @@ export const addProjectFacilities = (data: any) => {
* @param data * @param data
*/ */
export const addProjectPilePoint = (data: any) => { export const addProjectPilePoint = (data: any) => {
console.log('🚀 ~ addProjectPilePoint ~ data:', data);
return request({ return request({
url: '/facility/photovoltaicPanelPoint/parts/geoJson', url: '/facility/photovoltaicPanelPoint/parts/geoJson',
method: 'post', method: 'post',
@ -186,3 +184,82 @@ export const uploadProjectFile = (data: any) => {
data: data data: data
}); });
}; };
/**
* 切换项目
* @param id
*/
export const changeProject = (id: string | number) => {
return request({
url: '/project/project/changeProject/' + id,
method: 'get'
});
};
/**
* 打卡规则
* @param id
*/
export const attendanceRuleEdit = (data) => {
return request({
url: '/project/attendanceRule',
method: 'put',
data
});
};
/**
* 打卡规则
* @param id
*/
export const attendanceRuleAdd = (data) => {
return request({
url: '/project/attendanceRule',
method: 'post',
data
});
};
/**
* 获取规则
* @param id
*/
export const byProjectIdDetail = (id) => {
return request({
url: '/project/attendanceRule/byProjectId/' + id,
method: 'get'
});
};
// 新增项目打卡范围
export const addAttendanceRange = (data) => {
return request({
url: '/project/projectPunchrange',
method: 'post',
data
});
};
// 删除项目打卡范围
export const delAttendanceRange = (id) => {
return request({
url: '/project/projectPunchrange/' + id,
method: 'delete'
});
};
// 修改项目打卡范围
export const updateAttendanceRange = (data) => {
return request({
url: '/project/projectPunchrange',
method: 'put',
data
});
};
// 查询项目打卡范围列表
export const getAttendanceRangeList = (data) => {
return request({
url: '/project/projectPunchrange/list',
method: 'get',
params: data
});
};

View File

@ -8,7 +8,7 @@ import { SupplierInputVO, SupplierInputForm, SupplierInputQuery } from '@/api/su
* @returns {*} * @returns {*}
*/ */
export const listSupplierInput = (query?: SupplierInputQuery): AxiosPromise<SupplierInputVO[]> => { export const listSupplierInput = (query?: any): AxiosPromise<SupplierInputVO[]> => {
return request({ return request({
url: '/supplierInput/supplierInput/list', url: '/supplierInput/supplierInput/list',
method: 'get', method: 'get',

View File

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

View File

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

View File

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

View File

@ -20,18 +20,20 @@ export const getMenu = (menuId: string | number): AxiosPromise<MenuVO> => {
}; };
// 查询菜单下拉树结构 // 查询菜单下拉树结构
export const treeselect = (): AxiosPromise<MenuTreeOption[]> => { export const treeselect = (params?: any): AxiosPromise<MenuTreeOption[]> => {
return request({ return request({
url: '/system/menu/treeselect', url: '/system/menu/treeselect',
method: 'get' method: 'get',
params
}); });
}; };
// 根据角色ID查询菜单下拉树结构 // 根据角色ID查询菜单下拉树结构
export const roleMenuTreeselect = (roleId: string | number): AxiosPromise<RoleMenuTree> => { export const roleMenuTreeselect = (roleId: string | number, params?: any): AxiosPromise<RoleMenuTree> => {
return request({ return request({
url: '/system/menu/roleMenuTreeselect/' + roleId, url: '/system/menu/roleMenuTreeselect/' + roleId,
method: 'get' method: 'get',
params
}); });
}; };
@ -68,3 +70,11 @@ export const delMenu = (menuId: string | number) => {
method: 'delete' method: 'delete'
}); });
}; };
// 获取所有路由
export const getAllRouters = () => {
return request({
url: '/system/menu/getAllRouters',
method: 'get'
});
};

View File

@ -12,9 +12,9 @@ export function listPost(query: { pageNum: number; pageSize: number }): AxiosPro
} }
// 查询岗位列表 // 查询岗位列表
export function listTreeByProject(projectId: string): AxiosPromise<PostVO[]> { export function listTreeByProject(): AxiosPromise<PostVO[]> {
return request({ return request({
url: '/system/dept/list/treeByProjectId/' + projectId, url: '/system/dept/list/tree',
method: 'get' method: 'get'
}); });
} }
@ -75,3 +75,11 @@ export function getRoleList(deptId?: number | string): AxiosPromise<any[]> {
} }
}); });
} }
// 获取部门下的项目列表
export function getProjectByDeptId(deptId?: number | string): AxiosPromise<any[]> {
return request({
url: '/system/dept/projectIdList/' + deptId,
method: 'get'
});
}

View File

@ -147,10 +147,11 @@ export const authUserSelectAll = (data: any) => {
}); });
}; };
// 根据角色ID查询部门树结构 // 根据角色ID查询部门树结构
export const deptTreeSelect = (roleId: string | number): AxiosPromise<RoleDeptTree> => { export const deptTreeSelect = (roleId: string | number, params?) => {
return request({ return request({
url: '/system/role/deptTree/' + roleId, url: '/system/role/deptTree/' + roleId,
method: 'get' method: 'get',
params
}); });
}; };

View File

@ -60,19 +60,20 @@ export interface UserForm {
nickName?: string; nickName?: string;
password: string; password: string;
phonenumber?: string; phonenumber?: string;
projectRoles?: any[];
email?: string; email?: string;
sex?: string; sex?: string;
status: string; status: string;
remark?: string; remark?: string;
postIds: string[]; postIds: string[];
roleIds: string[];
filePath?: string; filePath?: string;
} }
export interface UserInfoVO { export interface UserInfoVO {
user: UserVO; user: UserVO;
roles: RoleVO[]; roles: RoleVO[];
roleIds: string[];
projectRoles: any[];
posts: PostVO[]; posts: PostVO[];
postIds: string[]; postIds: string[];
roleGroup: string; roleGroup: string;

View File

@ -91,3 +91,41 @@ export const getTenderPlanDetail = (query: any): AxiosPromise<any> => {
params: query params: query
}); });
}; };
//查看招标文件
export const biddViewLook = (query: any): AxiosPromise<any> => {
return request({
url: '/tender/biddingPlan/getAnnex',
method: 'get',
params: query
});
};
//删除招标文件
export const delBiddView = (query: any): AxiosPromise<any> => {
return request({
url: '/tender/biddingPlanAnnex/' + query.ids,
method: 'delete'
});
};
//获取招标单位
export const getUnitList = (query: any): AxiosPromise<any> => {
return request({
url: '/supplierInput/supplierInput/getList',
method: 'get',
params: query
});
};
//修改状态
export const editStatus = (query: any): AxiosPromise<any> => {
return request({
url: '/tender/biddingPlan/editStatus',
method: 'put',
data: query
});
};
//获取版本详情
export const getVersionDetail = (id: any) => {
return request({
url: '/tender/tenderPlanLimitList/getVersionDetail/' + id,
method: 'get'
});
};

BIN
src/assets/demo/avatar.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

BIN
src/assets/demo/back.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

BIN
src/assets/demo/gaojing.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
src/assets/demo/rain.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

BIN
src/assets/demo/wcl.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
src/assets/demo/yichuli.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

BIN
src/assets/demo/zzcl.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -288,3 +288,14 @@ h6 {
.top-right-btn { .top-right-btn {
margin-left: auto; margin-left: auto;
} }
.text-two-lines {
display: -webkit-box; /* 触发弹性盒模型 */
-webkit-box-orient: vertical; /* 垂直排列文本行 */
-webkit-line-clamp: 2; /* 限制显示2行 */
/* 3. 超出部分处理 */
overflow: hidden; /* 隐藏超出容器的内容 */
text-overflow: ellipsis; /* 超出部分显示省略号 */
/* 可选:优化文本间距 */
line-height: 1.5; /* 行高,控制两行的垂直间距 */
}

View File

@ -1,28 +1,14 @@
<template> <template>
<div> <div>
<el-upload <el-upload v-if="type === 'url'" :action="upload.url" :before-upload="handleBeforeUpload"
v-if="type === 'url'" :on-success="handleUploadSuccess" :on-error="handleUploadError" class="editor-img-uploader" name="file"
:action="upload.url" :show-file-list="false" :headers="upload.headers">
:before-upload="handleBeforeUpload"
:on-success="handleUploadSuccess"
:on-error="handleUploadError"
class="editor-img-uploader"
name="file"
:show-file-list="false"
:headers="upload.headers"
>
<i ref="uploadRef"></i> <i ref="uploadRef"></i>
</el-upload> </el-upload>
</div> </div>
<div class="editor"> <div class="editor">
<quill-editor <quill-editor ref="quillEditorRef" v-model:content="content" content-type="html" :options="options" :style="styles"
ref="quillEditorRef" @text-change="(e: any) => $emit('update:modelValue', content)" />
v-model:content="content"
content-type="html"
:options="options"
:style="styles"
@text-change="(e: any) => $emit('update:modelValue', content)"
/>
</div> </div>
</template> </template>
@ -47,7 +33,9 @@ const props = defineProps({
/* 上传文件大小限制(MB) */ /* 上传文件大小限制(MB) */
fileSize: propTypes.number.def(5), fileSize: propTypes.number.def(5),
/* 类型base64格式、url格式 */ /* 类型base64格式、url格式 */
type: propTypes.string.def('url') type: propTypes.string.def('url'),
/* 占位符 */
placeholder: propTypes.string.def('请输入内容'),
}); });
const { proxy } = getCurrentInstance() as ComponentInternalInstance; const { proxy } = getCurrentInstance() as ComponentInternalInstance;
@ -90,7 +78,7 @@ const options = ref<any>({
} }
} }
}, },
placeholder: '请输入内容', placeholder: props.placeholder,
readOnly: props.readOnly readOnly: props.readOnly
}); });
@ -166,77 +154,96 @@ const handleUploadError = (err: any) => {
.editor-img-uploader { .editor-img-uploader {
display: none; display: none;
} }
.editor, .editor,
.ql-toolbar { .ql-toolbar {
white-space: pre-wrap !important; white-space: pre-wrap !important;
line-height: normal !important; line-height: normal !important;
} }
.quill-img { .quill-img {
display: none; display: none;
} }
.ql-snow .ql-tooltip[data-mode='link']::before { .ql-snow .ql-tooltip[data-mode='link']::before {
content: '请输入链接地址:'; content: '请输入链接地址:';
} }
.ql-snow .ql-tooltip.ql-editing a.ql-action::after { .ql-snow .ql-tooltip.ql-editing a.ql-action::after {
border-right: 0; border-right: 0;
content: '保存'; content: '保存';
padding-right: 0; padding-right: 0;
} }
.ql-snow .ql-tooltip[data-mode='video']::before { .ql-snow .ql-tooltip[data-mode='video']::before {
content: '请输入视频地址:'; content: '请输入视频地址:';
} }
.ql-snow .ql-picker.ql-size .ql-picker-label::before, .ql-snow .ql-picker.ql-size .ql-picker-label::before,
.ql-snow .ql-picker.ql-size .ql-picker-item::before { .ql-snow .ql-picker.ql-size .ql-picker-item::before {
content: '14px'; content: '14px';
} }
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value='small']::before, .ql-snow .ql-picker.ql-size .ql-picker-label[data-value='small']::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value='small']::before { .ql-snow .ql-picker.ql-size .ql-picker-item[data-value='small']::before {
content: '10px'; content: '10px';
} }
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value='large']::before, .ql-snow .ql-picker.ql-size .ql-picker-label[data-value='large']::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value='large']::before { .ql-snow .ql-picker.ql-size .ql-picker-item[data-value='large']::before {
content: '18px'; content: '18px';
} }
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value='huge']::before, .ql-snow .ql-picker.ql-size .ql-picker-label[data-value='huge']::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value='huge']::before { .ql-snow .ql-picker.ql-size .ql-picker-item[data-value='huge']::before {
content: '32px'; content: '32px';
} }
.ql-snow .ql-picker.ql-header .ql-picker-label::before, .ql-snow .ql-picker.ql-header .ql-picker-label::before,
.ql-snow .ql-picker.ql-header .ql-picker-item::before { .ql-snow .ql-picker.ql-header .ql-picker-item::before {
content: '文本'; content: '文本';
} }
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value='1']::before, .ql-snow .ql-picker.ql-header .ql-picker-label[data-value='1']::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value='1']::before { .ql-snow .ql-picker.ql-header .ql-picker-item[data-value='1']::before {
content: '标题1'; content: '标题1';
} }
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value='2']::before, .ql-snow .ql-picker.ql-header .ql-picker-label[data-value='2']::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value='2']::before { .ql-snow .ql-picker.ql-header .ql-picker-item[data-value='2']::before {
content: '标题2'; content: '标题2';
} }
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value='3']::before, .ql-snow .ql-picker.ql-header .ql-picker-label[data-value='3']::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value='3']::before { .ql-snow .ql-picker.ql-header .ql-picker-item[data-value='3']::before {
content: '标题3'; content: '标题3';
} }
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value='4']::before, .ql-snow .ql-picker.ql-header .ql-picker-label[data-value='4']::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value='4']::before { .ql-snow .ql-picker.ql-header .ql-picker-item[data-value='4']::before {
content: '标题4'; content: '标题4';
} }
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value='5']::before, .ql-snow .ql-picker.ql-header .ql-picker-label[data-value='5']::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value='5']::before { .ql-snow .ql-picker.ql-header .ql-picker-item[data-value='5']::before {
content: '标题5'; content: '标题5';
} }
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value='6']::before, .ql-snow .ql-picker.ql-header .ql-picker-label[data-value='6']::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value='6']::before { .ql-snow .ql-picker.ql-header .ql-picker-item[data-value='6']::before {
content: '标题6'; content: '标题6';
} }
.ql-snow .ql-picker.ql-font .ql-picker-label::before, .ql-snow .ql-picker.ql-font .ql-picker-label::before,
.ql-snow .ql-picker.ql-font .ql-picker-item::before { .ql-snow .ql-picker.ql-font .ql-picker-item::before {
content: '标准字体'; content: '标准字体';
} }
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value='serif']::before, .ql-snow .ql-picker.ql-font .ql-picker-label[data-value='serif']::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value='serif']::before { .ql-snow .ql-picker.ql-font .ql-picker-item[data-value='serif']::before {
content: '衬线字体'; content: '衬线字体';
} }
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value='monospace']::before, .ql-snow .ql-picker.ql-font .ql-picker-label[data-value='monospace']::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value='monospace']::before { .ql-snow .ql-picker.ql-font .ql-picker-item[data-value='monospace']::before {
content: '等宽字体'; content: '等宽字体';

View File

@ -1,11 +1,29 @@
<template> <template>
<div class="upload-file"> <div class="upload-file">
<el-upload ref="fileUploadRef" multiple :action="realUploadUrl" :before-upload="handleBeforeUpload" <el-upload
:file-list="fileList" :limit="limit" :on-error="handleUploadError" :on-exceed="handleExceed" ref="fileUploadRef"
:on-success="handleUploadSuccess" :show-file-list="showFileList" :headers="headers" class="upload-file-uploader" multiple
:list-type="isConstruction ? 'picture-card' : 'text'" :accept="accept" :drag="isDarg" :data="data" :action="realUploadUrl"
:auto-upload="autoUpload" :on-change="handleChange" :on-remove="handleRemove" :method="method" :before-upload="handleBeforeUpload"
:http-request="customUpload"> :file-list="fileList"
:limit="limit"
:on-error="handleUploadError"
:on-exceed="handleExceed"
:on-success="handleUploadSuccess"
:show-file-list="showFileList"
:on-preview="handlePreview"
:headers="headers"
class="upload-file-uploader"
:list-type="isConstruction ? 'picture-card' : 'text'"
:accept="accept"
:drag="isDarg"
:data="data"
:auto-upload="autoUpload"
:on-change="handleChange"
:on-remove="handleRemove"
:method="method"
:http-request="customUpload"
>
<slot> <slot>
<div> <div>
<!-- 上传按钮 --> <!-- 上传按钮 -->
@ -24,10 +42,20 @@
的文件 的文件
</div> </div>
<!-- 文件列表 --> <!-- 文件列表 -->
<transition-group v-if="!isConstruction && !isImportInfo" <transition-group
class="upload-file-list el-upload-list el-upload-list--text" name="el-fade-in-linear" tag="ul" @click.stop> v-if="!isConstruction && !isImportInfo"
<li style="margin-top: 10px" v-for="(file, index) in fileList" :key="file.uid" class="upload-file-list el-upload-list el-upload-list--text"
class="el-upload-list__item ele-upload-list__item-content"> name="el-fade-in-linear"
tag="ul"
@click.stop
>
<li
style="margin-top: 10px"
v-for="(file, index) in fileList"
:key="file.uid"
class="el-upload-list__item ele-upload-list__item-content"
v-if="autoUpload"
>
<el-link :href="`${file.url}`" :underline="false" target="_blank"> <el-link :href="`${file.url}`" :underline="false" target="_blank">
<span class="el-icon-document"> {{ getFileName(file.name) }} </span> <span class="el-icon-document"> {{ getFileName(file.name) }} </span>
</el-link> </el-link>
@ -180,40 +208,39 @@ watch(
}, },
{ deep: true, immediate: true } { deep: true, immediate: true }
); );
watch(() => props.defaultFileList, () => { watch(
if (props.defaultFileList.length === 0) return; () => props.defaultFileList,
props.defaultFileList.forEach((item: any) => { () => {
fileList.value.push(item); if (props.defaultFileList.length === 0) return;
}); props.defaultFileList.forEach((item: any) => {
fileList.value.push(item);
}, { deep: true, immediate: true }); });
},
{ deep: true, immediate: true }
);
// 上传前校检格式和大小 // 上传前校检格式和大小
const handleBeforeUpload = (file: any) => { const handleBeforeUpload = (file: any) => {
// 校检文件类型 if (!validateFile(file)) return false;
if (props.fileType.length) { proxy?.$modal.loading('正在上传文件,请稍候...');
const fileName = file.name.split('.'); number.value++;
const fileExt = fileName[fileName.length - 1]; return true;
const isTypeOk = props.fileType.indexOf(fileExt) >= 0; };
if (!isTypeOk) {
proxy?.$modal.msgError(`文件格式不正确, 请上传${props.fileType.join('/')}格式文件!`); //校检格式和大小
return false; const validateFile = (file: File) => {
} const ext = file.name.split('.').pop()?.toLowerCase();
if (props.fileType.length && !props.fileType.includes(ext!)) {
proxy?.$modal.msgError(`文件格式不正确,请上传 ${props.fileType.join('/')} 格式文件!`);
return false;
} }
// 校检文件名是否包含特殊字符
if (file.name.includes(',')) { if (file.name.includes(',')) {
proxy?.$modal.msgError('文件名不正确,不能包含英文逗号!'); proxy?.$modal.msgError('文件名不正确,不能包含英文逗号!');
return false; return false;
} }
// 校检文件大小 if (props.fileSize && file.size / 1024 / 1024 > props.fileSize) {
if (props.fileSize) { proxy?.$modal.msgError(`上传文件大小不能超过 ${props.fileSize} MB!`);
const isLt = file.size / 1024 / 1024 < props.fileSize; return false;
if (!isLt) {
proxy?.$modal.msgError(`上传文件大小不能超过 ${props.fileSize} MB!`);
return false;
}
} }
proxy?.$modal.loading('正在上传文件,请稍候...');
number.value++;
return true; return true;
}; };
@ -254,13 +281,25 @@ const handleUploadSuccess = (res: any, file: UploadFileWithOssId) => {
uploadedSuccessfully(res); uploadedSuccessfully(res);
}; };
const handleChange = (file: any, fileList: any) => { const handleChange = (file: any, filelist: any) => {
if (!props.autoUpload) {
// 手动上传模式:在选中文件时拦截非法文件
const isValid = validateFile(file.raw || file);
if (!isValid) {
fileUploadRef.value?.handleRemove(file); // 直接移除非法文件
console.log(file, filelist, fileList.value);
fileList.value = [...fileList.value]; // 触发列表更新
return;
}
}
// 记录 status = 'ready' 的文件 // 记录 status = 'ready' 的文件
if (file.status === 'ready') { if (file.status === 'ready') {
pendingFiles.value.push(file); pendingFiles.value.push(file);
fileList.value = pendingFiles.value;
} }
console.log(fileList.value);
emit('handleChange', file, fileList); emit('handleChange', file, filelist);
}; };
// 删除文件 // 删除文件
@ -270,6 +309,12 @@ const handleRemove = (file: any, fileList: any) => {
emit('handleRemove', file, fileList); emit('handleRemove', file, fileList);
}; };
const handlePreview = (file: any) => {
if (file.url) {
window.open(file.url);
}
};
// 删除文件 // 删除文件
const handleDelete = async (index: string | number, type?: string) => { const handleDelete = async (index: string | number, type?: string) => {
await proxy?.$modal.confirm('是否确认删除此文件?').finally(); await proxy?.$modal.confirm('是否确认删除此文件?').finally();
@ -308,11 +353,6 @@ const uploadedSuccessfully = (res: any) => {
emit('update:modelValue', listToString(fileList.value)); emit('update:modelValue', listToString(fileList.value));
proxy?.$modal.closeLoading(); proxy?.$modal.closeLoading();
} }
// if (props.autoUpload && props.limit === fileList.value.length) {
// fileUploadRef.value?.clearFiles();
// fileList.value = [];
// emit('update:modelValue', ''); // 同步到外部 v-model
// }
props.onUploadSuccess?.(fileList.value, res); props.onUploadSuccess?.(fileList.value, res);
}; };
@ -376,6 +416,11 @@ const submitUpload = async () => {
if (!pendingFiles.value.length) { if (!pendingFiles.value.length) {
return 'noFile'; return 'noFile';
} }
const validFiles = pendingFiles.value.filter((f: any) => validateFile(f.raw || f));
if (!validFiles.length) {
proxy?.$modal.msgError('没有符合条件的文件可上传');
return;
}
try { try {
proxy?.$modal.loading('正在上传文件,请稍候...'); proxy?.$modal.loading('正在上传文件,请稍候...');
const formData = new FormData(); const formData = new FormData();
@ -424,7 +469,7 @@ defineExpose({ submitUpload });
} }
} }
>span { > span {
width: 100%; width: 100%;
} }
} }

View File

@ -185,6 +185,10 @@ const props = defineProps({
taskVariables: { taskVariables: {
type: Object as () => Record<string, any>, type: Object as () => Record<string, any>,
default: () => {} default: () => {}
},
businessId1: {
type: String,
default: ''
} }
}); });
//遮罩层 //遮罩层
@ -336,6 +340,9 @@ const handleCompleteTask = async () => {
} }
if (isDrawing.value) { if (isDrawing.value) {
isShowSubmit.value = true; isShowSubmit.value = true;
nextTick(() => {
detailFormTeRef.value.getInfo(props.businessId1);
});
return; return;
} }
await proxy?.$modal.confirm('是否确认提交?'); await proxy?.$modal.confirm('是否确认提交?');
@ -538,6 +545,9 @@ const handleTermination = async () => {
const handleTerminationTask = async () => { const handleTerminationTask = async () => {
if (isDrawing.value) { if (isDrawing.value) {
isShowTermination.value = true; isShowTermination.value = true;
nextTick(() => {
detailFormTeRef.value.getInfo(props.businessId1);
});
return; return;
} }
const params = { const params = {

View File

@ -1,5 +1,5 @@
<template> <template>
<div class="select-container"> <div class="select-container" v-loading.fullscreen.lock="fullscreenLoading">
<label for="projectSelect" class="select-label">项目列表:</label> <label for="projectSelect" class="select-label">项目列表:</label>
<el-select <el-select
id="projectSelect" id="projectSelect"
@ -19,12 +19,18 @@
import { ref, computed, watch } from 'vue'; import { ref, computed, watch } from 'vue';
import { useUserStore } from '@/store/modules/user'; import { useUserStore } from '@/store/modules/user';
import { getProjectTeam } from '@/utils/projectTeam'; import { getProjectTeam } from '@/utils/projectTeam';
import router, { resetRouter } from '@/router';
import usePermissionStore from '@/store/modules/permission';
import { isHttp } from '@/utils/validate';
import { changeProject } from '@/api/project/project';
const fullscreenLoading = ref(false);
const route = useRoute();
const userStore = useUserStore(); const userStore = useUserStore();
const projects = computed(() => [ const projects = computed(() => [
// { id: '', name: '全部工程项目' }, // 添加空选项 // { id: '', name: '全部工程项目' }, // 添加空选项
...userStore.projects ...userStore.projects
]); ]);
const proxy = getCurrentInstance()?.proxy as any;
const selectedProjectId = ref(userStore.selectedProject?.id || ''); const selectedProjectId = ref(userStore.selectedProject?.id || '');
@ -37,13 +43,66 @@ watch(
{ deep: true } { deep: true }
); );
const handleSelect = (projectId: string) => { /** 切换项目逻辑 */
const handleSelect = async (projectId: string) => {
proxy.$cache.local.setJSON('isCheckRole', 'true');
const userStore = useUserStore();
const permissionStore = usePermissionStore();
const selectedProject = projects.value.find((p) => p.id === projectId); const selectedProject = projects.value.find((p) => p.id === projectId);
if (selectedProject) { if (!selectedProject) return;
userStore.setSelectedProject(selectedProject); const loadingInstance = ElLoading.service({
console.log(userStore.selectedProject); // 打印选中的项目 lock: true,
} text: '项目切换中...',
background: 'rgba(0, 0, 0, 0.7)'
});
setTimeout(() => {
if (loadingInstance && loadingInstance.visible) {
loadingInstance.close();
}
}, 3000);
await changeProject(projectId);
console.log('切换项目', selectedProject);
// 更新项目 & 权限
userStore.setSelectedProject(selectedProject);
await userStore.setInfo();
await userStore.setRoles(); // 这里会刷新 permissions/roles
// 重新生成路由
permissionStore.generateRoutes().then((routeList) => {
const currentPath = router.currentRoute.value.fullPath;
const exist = currentPath == '/' || currentPath == '/index' ? true : routeExists(currentPath, routeList);
if (exist) return loadingInstance.close();
proxy?.$tab.closeAllPage();
router.push('/index');
loadingInstance.close();
// 刷新当前路由
});
}; };
function routeExists(fullPath: string, routes: any[], parentPath = ''): boolean {
for (const route of routes) {
// 拼接完整 path
let currentPath = route.path.startsWith('/') ? route.path : `${parentPath}/${route.path}`;
// 处理多余的 "//"
currentPath = currentPath.replace(/\/+/g, '/');
// 判断
if (currentPath === fullPath) {
return true;
}
// 递归子路由
if (route.children && route.children.length > 0) {
if (routeExists(fullPath, route.children, currentPath)) {
return true;
}
}
}
return false;
}
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>

View File

@ -4,6 +4,7 @@
<el-menu-item v-if="index < visibleNumber" :key="index" :style="{ '--theme': theme }" :index="item.path"> <el-menu-item v-if="index < visibleNumber" :key="index" :style="{ '--theme': theme }" :index="item.path">
<svg-icon v-if="item.meta && item.meta.icon && item.meta.icon !== '#'" :icon-class="item.meta ? item.meta.icon : ''" /> <svg-icon v-if="item.meta && item.meta.icon && item.meta.icon !== '#'" :icon-class="item.meta ? item.meta.icon : ''" />
{{ item.meta?.title }} {{ item.meta?.title }}
<!-- <span class="bage" v-if="item.meta?.title == '我的任务' && total > 0">{{ total }}</span> -->
</el-menu-item> </el-menu-item>
</template> </template>
@ -26,20 +27,27 @@ import useAppStore from '@/store/modules/app';
import useSettingsStore from '@/store/modules/settings'; import useSettingsStore from '@/store/modules/settings';
import usePermissionStore from '@/store/modules/permission'; import usePermissionStore from '@/store/modules/permission';
import { RouteRecordRaw } from 'vue-router'; import { RouteRecordRaw } from 'vue-router';
import useUserStore from '@/store/modules/user';
import useNoticeStore from '@/store/modules/notice';
import { pageByTaskWait } from '@/api/workflow/task';
const userStore = useUserStore();
const noticeStore = storeToRefs(useNoticeStore());
// 顶部栏初始数 // 顶部栏初始数
const visibleNumber = ref<number>(-1); const visibleNumber = ref<number>(-1);
// 当前激活菜单的 index // 当前激活菜单的 index
const currentIndex = ref<string>(); const currentIndex = ref<string>();
// 隐藏侧边栏路由 // 隐藏侧边栏路由
const hideList = ['/index', '/user/profile']; const hideList = ['/index', '/user/profile'];
const total = ref(1);
const appStore = useAppStore(); const appStore = useAppStore();
const settingsStore = useSettingsStore(); const settingsStore = useSettingsStore();
const permissionStore = usePermissionStore(); const permissionStore = usePermissionStore();
const route = useRoute(); const route = useRoute();
const router = useRouter(); const router = useRouter();
onMounted(() => {
console.log(33333);
getWaitingList();
});
// 主题颜色 // 主题颜色
const theme = computed(() => settingsStore.theme); const theme = computed(() => settingsStore.theme);
// 所有的路由信息 // 所有的路由信息
@ -158,6 +166,26 @@ onBeforeUnmount(() => {
onMounted(() => { onMounted(() => {
setVisibleNumber(); setVisibleNumber();
}); });
// 获取我的待办
//分页
const getWaitingList = () => {
pageByTaskWait({ pageNum: 1, pageSize: 10 }).then((resp) => {
console.log(resp);
total.value = resp.total;
});
};
//用深度监听 消息
watch(
() => noticeStore.state.value.notices,
(newVal) => {
let time = setTimeout(() => {
getWaitingList();
clearTimeout(time);
}, 500);
},
{ deep: true }
);
</script> </script>
<style lang="scss"> <style lang="scss">
@ -197,4 +225,31 @@ onMounted(() => {
.topmenu-container .svg-icon { .topmenu-container .svg-icon {
margin-right: 4px; margin-right: 4px;
} }
.bage {
position: absolute;
top: 6px;
right: -12px;
padding: 0 6px;
height: 16px;
line-height: 16px;
background: #ff7a7a;
border-radius: 8px;
font-size: 12px;
color: #fff;
white-space: nowrap;
box-sizing: border-box;
}
.el-menu-item .el-menu-item__content {
position: relative;
padding-right: 24px;
}
.menu-title {
display: inline-block;
max-width: calc(100% - 24px);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
</style> </style>

View File

@ -23,14 +23,14 @@
<!-- <header-search id="header-search" class="right-menu-item" /> --> <!-- <header-search id="header-search" class="right-menu-item" /> -->
<search-menu ref="searchMenuRef" /> <search-menu ref="searchMenuRef" />
<el-tooltip effect="dark" placement="bottom"> <el-tooltip effect="dark" placement="bottom">
<ProjectSelector /> <ProjectSelector />
</el-tooltip> </el-tooltip>
<!-- <el-tooltip content="搜索" effect="dark" placement="bottom"> <el-tooltip content="搜索" effect="dark" placement="bottom">
<div class="right-menu-item hover-effect" @click="openSearchMenu"> <div class="right-menu-item hover-effect" @click="openSearchMenu">
<svg-icon class-name="search-icon" icon-class="search" /> <svg-icon class-name="search-icon" icon-class="search" />
</div> </div>
</el-tooltip> --> </el-tooltip>
<!-- 消息 --> <!-- 消息 -->
<el-tooltip :content="proxy.$t('navbar.message')" effect="dark" placement="bottom"> <el-tooltip :content="proxy.$t('navbar.message')" effect="dark" placement="bottom">
<div> <div>

View File

@ -6,6 +6,7 @@
<svg-icon :icon-class="onlyOneChild.meta.icon || (item.meta && item.meta.icon)" /> <svg-icon :icon-class="onlyOneChild.meta.icon || (item.meta && item.meta.icon)" />
<template #title> <template #title>
<span class="menu-title" :title="hasTitle(onlyOneChild.meta.title)">{{ onlyOneChild.meta.title }}</span> <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>
</template> </template>
</el-menu-item> </el-menu-item>
</app-link> </app-link>
@ -15,6 +16,7 @@
<template v-if="item.meta" #title> <template v-if="item.meta" #title>
<svg-icon :icon-class="item.meta ? item.meta.icon : ''" /> <svg-icon :icon-class="item.meta ? item.meta.icon : ''" />
<span class="menu-title" :title="hasTitle(item.meta?.title)">{{ item.meta?.title }}</span> <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> -->
</template> </template>
<sidebar-item <sidebar-item
@ -34,7 +36,11 @@ import { isExternal } from '@/utils/validate';
import AppLink from './Link.vue'; import AppLink from './Link.vue';
import { getNormalPath } from '@/utils/ruoyi'; import { getNormalPath } from '@/utils/ruoyi';
import { RouteRecordRaw } from 'vue-router'; import { RouteRecordRaw } from 'vue-router';
import { pageByTaskWait } from '@/api/workflow/task';
import useUserStore from '@/store/modules/user';
import useNoticeStore from '@/store/modules/notice';
const userStore = useUserStore();
const noticeStore = storeToRefs(useNoticeStore());
const props = defineProps({ const props = defineProps({
item: { item: {
type: Object as PropType<RouteRecordRaw>, type: Object as PropType<RouteRecordRaw>,
@ -49,7 +55,22 @@ const props = defineProps({
default: '' default: ''
} }
}); });
const total = ref(0);
onMounted(() => {
if (onlyOneChild.value.meta?.title == '我的待办' || props.item.meta?.title == '我的任务') {
console.log(44444444);
getWaitingList();
}
});
// 获取我的待办
//分页
const getWaitingList = () => {
pageByTaskWait({ pageNum: 1, pageSize: 10 }).then((resp) => {
console.log(resp);
total.value = resp.total;
});
};
const onlyOneChild = ref<any>({}); const onlyOneChild = ref<any>({});
const hasOneShowingChild = (parent: RouteRecordRaw, children?: RouteRecordRaw[]) => { const hasOneShowingChild = (parent: RouteRecordRaw, children?: RouteRecordRaw[]) => {
@ -64,12 +85,12 @@ const hasOneShowingChild = (parent: RouteRecordRaw, children?: RouteRecordRaw[])
return true; return true;
}); });
// When there is only one child router, the child router is displayed by default // 只有一个子路由时默认显示子路由
if (showingChildren.length === 1) { if (showingChildren.length === 1) {
return true; return true;
} }
// Show parent if there are no child router to display // 没有子路由可显示时显示父路由
if (showingChildren.length === 0) { if (showingChildren.length === 0) {
onlyOneChild.value = { ...parent, path: '', noShowingChildren: true }; onlyOneChild.value = { ...parent, path: '', noShowingChildren: true };
return true; return true;
@ -98,4 +119,49 @@ const hasTitle = (title: string | undefined): string => {
} }
return title; return title;
}; };
//用深度监听 消息
watch(
() => noticeStore.state.value.notices,
(newVal) => {
if (onlyOneChild.value.meta?.title == '我的待办') {
console.log(121212121);
let time = setTimeout(() => {
getWaitingList();
clearTimeout(time);
}, 500);
}
},
{ deep: true }
);
</script> </script>
<style lang="scss" scoped>
.bage {
position: absolute;
top: 6px;
right: 36px;
padding: 0 6px;
height: 16px;
line-height: 16px;
background: #ff7a7a;
border-radius: 8px;
font-size: 12px;
color: #fff;
white-space: nowrap;
box-sizing: border-box;
}
.el-menu-item .el-menu-item__content {
position: relative;
padding-right: 24px;
}
.menu-title {
display: inline-block;
max-width: calc(100% - 24px);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
</style>

View File

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

View File

@ -1,3 +1,4 @@
import $cache from '@/plugins/cache';
import { to as tos } from 'await-to-js'; import { to as tos } from 'await-to-js';
import router from './router'; import router from './router';
import NProgress from 'nprogress'; import NProgress from 'nprogress';
@ -9,6 +10,8 @@ import useUserStore from '@/store/modules/user';
import useSettingsStore from '@/store/modules/settings'; import useSettingsStore from '@/store/modules/settings';
import usePermissionStore from '@/store/modules/permission'; import usePermissionStore from '@/store/modules/permission';
let isFirst = false;
NProgress.configure({ showSpinner: false }); NProgress.configure({ showSpinner: false });
const whiteList = ['/login', '/register', '/social-callback', '/register*', '/register/*', '/materials/purchaseDoc/uploadCode']; const whiteList = ['/login', '/register', '/social-callback', '/register*', '/register/*', '/materials/purchaseDoc/uploadCode'];
@ -16,54 +19,64 @@ const isWhiteList = (path: string) => {
return whiteList.some((pattern) => isPathMatch(pattern, path)); return whiteList.some((pattern) => isPathMatch(pattern, path));
}; };
router.beforeEach(async (to, from, next) => { router.beforeEach(async (to, from) => {
NProgress.start(); NProgress.start();
if (to.path == '/indexEquipment' || to.path == '/materials/purchaseDoc/uploadCode' || to.path == '/codeDetail') {
next(); // 特殊页面放行
} else if (getToken()) { if (['/indexEquipment', '/materials/purchaseDoc/uploadCode', '/codeDetail'].includes(to.path)) {
to.meta.title && useSettingsStore().setTitle(to.meta.title); return true;
/* has token*/
if (to.path === '/login') {
next({ path: '/' });
NProgress.done();
} else if (isWhiteList(to.path)) {
next();
} else {
if (useUserStore().roles.length === 0) {
isRelogin.show = true;
// 判断当前用户是否已拉取完user_info信息
const [err] = await tos(useUserStore().getInfo());
if (err) {
await useUserStore().logout();
ElMessage.error(err);
next({ path: '/' });
} else {
isRelogin.show = false;
const accessRoutes = await usePermissionStore().generateRoutes();
// 根据roles权限生成可访问的路由表
accessRoutes.forEach((route) => {
if (!isHttp(route.path)) {
router.addRoute(route); // 动态添加可访问路由表
}
});
// @ts-expect-error hack方法 确保addRoutes已完成
next({ path: to.path, replace: true, params: to.params, query: to.query, hash: to.hash, name: to.name as string }); // hack方法 确保addRoutes已完成
}
} else {
next();
}
}
} else {
// 没有token
if (isWhiteList(to.path)) {
// 在免登录白名单,直接进入
next();
} else {
const redirect = encodeURIComponent(to.fullPath || '/');
next(`/login?redirect=${redirect}`); // 否则全部重定向到登录页
NProgress.done();
}
} }
// 已登录
if (getToken()) {
if (to.meta.title) useSettingsStore().setTitle(to.meta.title);
if (to.path === '/login') {
NProgress.done();
return { path: '/' };
}
if (isWhiteList(to.path)) {
return true;
}
if ((!isFirst && useUserStore().roles.length === 0) || $cache.local.getJSON('isCheckRole') === 'true') {
isFirst = true;
isRelogin.show = true;
const [err] = await tos(useUserStore().getInfo());
if (err) {
await useUserStore().logout();
ElMessage.error(err);
NProgress.done();
return { path: '/' };
}
isRelogin.show = false;
const accessRoutes = await usePermissionStore().generateRoutes();
accessRoutes.forEach((route) => {
if (!isHttp(route.path)) router.addRoute(route);
});
$cache.local.remove('isCheckRole');
// 确保路由已添加后再跳转
return { ...to, replace: true };
}
return true;
} else {
isFirst = false;
}
// 未登录
if (isWhiteList(to.path)) {
return true;
}
const redirect = encodeURIComponent(to.fullPath || '/');
NProgress.done();
return { path: `/login?redirect=${redirect}` };
}); });
router.afterEach(() => { router.afterEach(() => {

View File

@ -1,6 +1,7 @@
import { createWebHistory, createRouter, RouteRecordRaw } from 'vue-router'; import { createWebHistory, createRouter, RouteRecordRaw } from 'vue-router';
/* Layout */ /* Layout */
import Layout from '@/layout/index.vue'; import Layout from '@/layout/index.vue';
import usePermissionStore from '@/store/modules/permission';
/** /**
* Note: 路由配置项 * Note: 路由配置项
@ -65,11 +66,7 @@ export const constantRoutes: RouteRecordRaw[] = [
component: () => import('@/views/register.vue'), component: () => import('@/views/register.vue'),
hidden: true hidden: true
}, },
{
path: '/:pathMatch(.*)*',
component: () => import('@/views/error/404.vue'),
hidden: true
},
{ {
path: '/401', path: '/401',
component: () => import('@/views/error/401.vue'), component: () => import('@/views/error/401.vue'),
@ -134,10 +131,16 @@ export const constantRoutes: RouteRecordRaw[] = [
component: () => import('@/views/gis2D/index.vue'), component: () => import('@/views/gis2D/index.vue'),
hidden: true hidden: true
}, },
{ {
path: '/materials/purchaseDoc/uploadCode', path: '/materials/purchaseDoc/uploadCode',
component: () => import('@/views/materials/purchaseDoc/uploadCode.vue'), component: () => import('@/views/materials/purchaseDoc/uploadCode.vue'),
hidden: true hidden: true
},
{
path: '/:pathMatch(.*)*',
component: () => import('@/views/error/404.vue'),
hidden: true
} }
]; ];
@ -231,3 +234,11 @@ const router = createRouter({
}); });
export default router; export default router;
export function resetRouter() {
router.getRoutes().forEach((route) => {
if (route.name && !constantRoutes.find((r) => r.name === route.name)) {
router.hasRoute(route.name) && router.removeRoute(route.name);
}
});
}

View File

@ -10,6 +10,7 @@ import ParentView from '@/components/ParentView/index.vue';
import InnerLink from '@/layout/components/InnerLink/index.vue'; import InnerLink from '@/layout/components/InnerLink/index.vue';
import { createCustomNameComponent } from '@/utils/createCustomNameComponent'; import { createCustomNameComponent } from '@/utils/createCustomNameComponent';
import { useUserStoreHook } from './user';
// 匹配views里面所有的.vue文件 // 匹配views里面所有的.vue文件
const modules = import.meta.glob('./../../views/**/*.vue'); const modules = import.meta.glob('./../../views/**/*.vue');
@ -44,7 +45,7 @@ export const usePermissionStore = defineStore('permission', () => {
sidebarRouters.value = routes; sidebarRouters.value = routes;
}; };
const generateRoutes = async (): Promise<RouteRecordRaw[]> => { const generateRoutes = async (): Promise<RouteRecordRaw[]> => {
const res = await getRouters(); const res = await getRouters(useUserStoreHook().selectedProject?.id || '0');
const { data } = res; const { data } = res;
const sdata = JSON.parse(JSON.stringify(data)); const sdata = JSON.parse(JSON.stringify(data));
const rdata = JSON.parse(JSON.stringify(data)); const rdata = JSON.parse(JSON.stringify(data));

View File

@ -28,7 +28,6 @@ const getSelectedProjectFromStorage = () => {
const getProjectTeamListFromStorage = () => { const getProjectTeamListFromStorage = () => {
const stored = $cache.local.getJSON('ProjectTeamList'); const stored = $cache.local.getJSON('ProjectTeamList');
console.log('获取缓存的项目班组列表:', stored); console.log('获取缓存的项目班组列表:', stored);
return stored ? stored : null; return stored ? stored : null;
}; };
@ -41,7 +40,9 @@ export const useUserStore = defineStore('user', () => {
const deptId = ref<string | number>(''); const deptId = ref<string | number>('');
const avatar = ref(''); const avatar = ref('');
const roles = ref<Array<string>>([]); // 用户角色编码集合 → 判断路由权限 const roles = ref<Array<string>>([]); // 用户角色编码集合 → 判断路由权限
const permissions = ref<Array<string>>([]); // 用户权限编码集合 → 判断按钮权限 const permissions = ref<Array<any>>([]); // 用户权限编码集合 → 判断按钮权限
const permissionList = ref<Array<any>>([]); // 用户所有权限列表
const roleList = ref<Array<any>>([]); // 用户所有角色列表
const projects = ref<Array<{ id: string; name: string }>>([]); const projects = ref<Array<{ id: string; name: string }>>([]);
// 从localStorage获取缓存的项目如果没有则默认为null // 从localStorage获取缓存的项目如果没有则默认为null
@ -66,15 +67,32 @@ export const useUserStore = defineStore('user', () => {
// 获取用户信息 // 获取用户信息
const getInfo = async (): Promise<void> => { const getInfo = async (): Promise<void> => {
// **新增项目数据获取**
const [projectErr, projectRes] = await to(getUserProject());
if (projectRes?.data) {
const projectList = projectRes.data.map((p) => ({
id: p.projectId,
name: p.projectName || '未知项目'
}));
setProjects(projectList);
// 如果有缓存的选中项目,且该项目在当前项目列表中存在,则使用缓存的项目
const storedProject = getSelectedProjectFromStorage();
if (storedProject && projectList.some((p) => p.id === storedProject.id)) {
setSelectedProject(storedProject);
} else if (projectList.length > 0) {
// 否则默认选择第一个项目
setSelectedProject(projectList[0]);
}
}
const [err, res] = await to(getUserInfo()); const [err, res] = await to(getUserInfo());
if (res) { if (res) {
const data = res.data; const data = res.data;
const user = data.user; const user = data.user;
const profile = user.avatar == '' || user.avatar == null ? defAva : user.avatar; const profile = user.avatar == '' || user.avatar == null ? defAva : user.avatar;
if (data.roles && data.roles.length > 0) { if (data.roles && data.roles.length > 0) {
roles.value = data.roles; permissionList.value = data.permissions;
permissions.value = data.permissions; roleList.value = data.roles;
setRoles();
} else { } else {
roles.value = ['ROLE_DEFAULT']; roles.value = ['ROLE_DEFAULT'];
} }
@ -85,30 +103,39 @@ export const useUserStore = defineStore('user', () => {
tenantId.value = user.tenantId; tenantId.value = user.tenantId;
deptId.value = user.deptId; deptId.value = user.deptId;
// **新增项目数据获取**
const [projectErr, projectRes] = await to(getUserProject());
if (projectRes?.data) {
const projectList = projectRes.data.map((p) => ({
id: p.projectId,
name: p.projectName || '未知项目'
}));
setProjects(projectList);
// 如果有缓存的选中项目,且该项目在当前项目列表中存在,则使用缓存的项目
const storedProject = getSelectedProjectFromStorage();
if (storedProject && projectList.some((p) => p.id === storedProject.id)) {
setSelectedProject(storedProject);
} else if (projectList.length > 0) {
// 否则默认选择第一个项目
setSelectedProject(projectList[0]);
}
}
return Promise.resolve(); return Promise.resolve();
} }
return Promise.reject(err); return Promise.reject(err);
}; };
const setInfo = async () => {
const [err, res] = await to(getUserInfo());
if (res) {
const data = res.data;
const user = data.user;
const profile = user.avatar == '' || user.avatar == null ? defAva : user.avatar;
if (data.roles && data.roles.length > 0) {
permissionList.value = data.permissions;
roleList.value = data.roles;
setRoles();
} else {
roles.value = ['ROLE_DEFAULT'];
}
name.value = user.userName;
nickname.value = user.nickName;
avatar.value = profile;
userId.value = user.userId;
tenantId.value = user.tenantId;
deptId.value = user.deptId;
}
};
const setRoles = () => {
const projectRole = roleList.value.find((item) => item.projectId == selectedProject.value?.id)?.projectRoles || [];
roles.value = projectRole;
const projectPermissions = permissionList.value.find((item) => item.projectId == selectedProject.value?.id)?.projectPermissions || [];
permissions.value = projectPermissions;
getProjectTeam();
};
// 注销 // 注销
const logout = async (): Promise<void> => { const logout = async (): Promise<void> => {
@ -158,7 +185,9 @@ export const useUserStore = defineStore('user', () => {
setProjectTeamList, setProjectTeamList,
projects, projects,
selectedProject, selectedProject,
ProjectTeamList ProjectTeamList,
setInfo,
setRoles
}; };
}); });

View File

@ -2,7 +2,11 @@ import $cache from '@/plugins/cache';
//获取班组列表 //获取班组列表
import { listProjectTeam } from '@/api/project/projectTeam'; import { listProjectTeam } from '@/api/project/projectTeam';
import { ProjectTeamVO } from '@/api/project/projectTeam/types'; import { ProjectTeamVO } from '@/api/project/projectTeam/types';
import useUserStore from '@/store/modules/user';
export const getProjectTeam = async () => { export const getProjectTeam = async () => {
const isPermission = useUserStore().permissions.some((item) => item == 'project:team:list');
if (!isPermission && useUserStore().permissions[0] != '*:*:*') return;
const { id } = $cache.local.getJSON('selectedProject'); const { id } = $cache.local.getJSON('selectedProject');
const res = await listProjectTeam({ const res = await listProjectTeam({
pageNum: 1, pageNum: 1,

View File

@ -176,22 +176,26 @@ service.interceptors.response.use(
} }
); );
// 通用下载方法 // 通用下载方法
export function download(url: string, params: any, fileName: string) { export function download(url: string, params: any, fileName: string, isHeader?: boolean) {
downloadLoadingInstance = ElLoading.service({ text: '正在下载数据,请稍候', background: 'rgba(0, 0, 0, 0.7)' }); downloadLoadingInstance = ElLoading.service({ text: '正在下载数据,请稍候', background: 'rgba(0, 0, 0, 0.7)' });
// prettier-ignore // prettier-ignore
return service.post(url, params, { let data={
transformRequest: [ transformRequest: [
(params: any) => { (params: any) => {
return tansParams(params); return tansParams(params);
} }
], ],
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, headers: isHeader?{'Content-Type': 'application/json'}:{ 'Content-Type': 'application/x-www-form-urlencoded' },
responseType: 'blob' responseType: 'blob'
}).then(async (resp: any) => { }
if (isHeader) delete data.transformRequest;
return service
.post(url, params, data as any)
.then(async (resp: any) => {
const isLogin = blobValidate(resp); const isLogin = blobValidate(resp);
if (isLogin) { if (isLogin) {
console.log("🚀 ~ download ~ resp:", resp) console.log('🚀 ~ download ~ resp:', resp);
const blob = new Blob([resp]); const blob = new Blob([resp]);
FileSaver.saveAs(blob, fileName); FileSaver.saveAs(blob, fileName);
} else { } else {
@ -201,7 +205,8 @@ export function download(url: string, params: any, fileName: string) {
ElMessage.error(errMsg); ElMessage.error(errMsg);
} }
downloadLoadingInstance.close(); downloadLoadingInstance.close();
}).catch((r: any) => { })
.catch((r: any) => {
console.error(r); console.error(r);
ElMessage.error('下载文件出现错误,请联系管理员!'); ElMessage.error('下载文件出现错误,请联系管理员!');
downloadLoadingInstance.close(); downloadLoadingInstance.close();

View File

@ -20,7 +20,6 @@ export const initSSE = (url: any) => {
}); });
watch(error, () => { watch(error, () => {
console.log('SSE connection error:', error.value);
error.value = null; error.value = null;
}); });
@ -31,9 +30,12 @@ export const initSSE = (url: any) => {
try { try {
if (JSON.parse(data.value)) { if (JSON.parse(data.value)) {
const obj = JSON.parse(data.value); const obj = JSON.parse(data.value);
route1 = obj.route; route1 = obj.type;
label = obj.message; if (obj.type == 'count') {
detailId = obj.detailId; return;
}
label = obj.content;
// detailId = obj.detailId;
data.value = null; data.value = null;
} }
} catch (error) { } catch (error) {

View File

@ -1,7 +1,7 @@
<template> <template>
<div class="centerPage"> <div class="centerPage">
<div class="topPage"> <div class="topPage">
<img src="@/assets/projectLarge/center.png" alt=""> <div id="earth" style="width: 100%;height: 100%;"></div>
</div> </div>
<div class="endPage" :class="{ 'slide-out-down': isHide }"> <div class="endPage" :class="{ 'slide-out-down': isHide }">
<Title title="AI安全巡检"> <Title title="AI安全巡检">
@ -30,7 +30,7 @@
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup>
import { ref, onMounted, toRefs, getCurrentInstance } from "vue" import { ref, onMounted, toRefs, getCurrentInstance } from "vue"
import Title from './title.vue' import Title from './title.vue'
import { ArrowLeft, ArrowRight } from '@element-plus/icons-vue' import { ArrowLeft, ArrowRight } from '@element-plus/icons-vue'
@ -56,12 +56,12 @@ const inspectionList = ref([{
picture: "", picture: "",
createTime: "" createTime: ""
}]) }])
const swiperContent = ref<HTMLDivElement>() const swiperContent = ref()
const swiperItemWidth = ref(100) const swiperItemWidth = ref(100)
const canLeft = ref(false) const canLeft = ref(false)
const canRight = ref(true) const canRight = ref(true)
const swiperClick = (direction: 'left' | 'right') => { const swiperClick = (direction) => {
if (!swiperContent.value) return if (!swiperContent.value) return
if (direction === 'right') { if (direction === 'right') {
@ -90,18 +90,67 @@ const getInspectionList = async () => {
const { code, data } = res const { code, data } = res
if (code === 200) { if (code === 200) {
data.map(item => { data.map(item => {
item.label = violation_level_type.value.find((i: any) => i.value === item.violationType)?.label item.label = violation_level_type.value.find((i) => i.value === item.violationType)?.label
}) })
inspectionList.value = data inspectionList.value = data
} }
} }
// 创建地球
const createEarth = () => {
window.YJ.on({
ws: true,
// host: getIP(), //资源所在服务器地址
// username: this.loginForm.username, //用户名 可以不登录(不填写用户名),不登录时无法加载服务端的数据
// password: md5pass, //密码 生成方式md5(用户名_密码)
}).then((res) => {
let earth = new YJ.YJEarth("earth");
window.Earth1 = earth;
YJ.Global.openRightClick(window.Earth1);
YJ.Global.openLeftClick(window.Earth1);
let view = {
"position": {
"lng": 102.03643298211526,
"lat": 34.393586474501,
"alt": 11298179.51993155
},
"orientation": {
"heading": 360,
"pitch": -89.94481747201486,
"roll": 0
}
}
loadBaseMap(earth.viewer)
// YJ.Global.flyTo(earth, view);
// YJ.Global.setDefaultView(earth.viewer, view)
})
}
// 加载底图
const loadBaseMap = (viewer) => {
// 创建瓦片提供器
const imageryProvider = new Cesium.UrlTemplateImageryProvider({
url: 'https://webst01.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}',
// 可选:设置瓦片的格式
fileExtension: 'png',
// 可选:设置瓦片的范围和级别
minimumLevel: 0,
maximumLevel: 18,
// 可选设置瓦片的投影默认为Web Mercator
projection: Cesium.WebMercatorProjection,
// 可选:如果瓦片服务需要跨域请求,设置请求头部
credit: new Cesium.Credit('卫星图数据来源')
});
// 添加图层到视图
const layer = viewer.imageryLayers.addImageryProvider(imageryProvider);
}
onMounted(() => { onMounted(() => {
getInspectionList() getInspectionList()
createEarth()
if (swiperContent.value && swiperContent.value.children.length > 0) { if (swiperContent.value && swiperContent.value.children.length > 0) {
swiperItemWidth.value = swiperContent.value.children[0].clientWidth + 20 swiperItemWidth.value = swiperContent.value.children[0].clientWidth + 20
} }
}) })
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">

View File

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

View File

@ -5,7 +5,7 @@
<el-form :model="queryForm" :inline="true"> <el-form :model="queryForm" :inline="true">
<el-form-item label="版本号" prop="versions"> <el-form-item label="版本号" prop="versions">
<el-select v-model="queryForm.versions" placeholder="选择版本号" @change="changeVersions"> <el-select v-model="queryForm.versions" placeholder="选择版本号" @change="changeVersions">
<el-option v-for="item in options" :key="item.id" :label="item.versions" :value="item.id" /> <el-option v-for="item in options" :key="item.id" :label="item.versions" :value="item.versions" />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="表名" prop="sheet"> <el-form-item label="表名" prop="sheet">
@ -16,7 +16,7 @@
<el-form-item> <el-form-item>
<el-button type="primary" @click="toggleExpandAll">{{ isExpandAll ? '一键收起' : '一键展开' }}</el-button> <el-button type="primary" @click="toggleExpandAll">{{ isExpandAll ? '一键收起' : '一键展开' }}</el-button>
</el-form-item> </el-form-item>
<el-form-item> <!-- <el-form-item>
<el-upload <el-upload
ref="uploadRef" ref="uploadRef"
class="upload-demo" class="upload-demo"
@ -28,11 +28,11 @@
<el-button type="primary">导入excel</el-button> <el-button type="primary">导入excel</el-button>
</template> </template>
</el-upload> </el-upload>
</el-form-item> </el-form-item> -->
<el-form-item> <el-form-item>
<el-button type="primary" @click="handleExport()" v-hasPermi="['bidding:biddingLimitList:export']">导出excel</el-button> <el-button type="primary" @click="handleExport()" v-hasPermi="['bidding:biddingLimitList:export']">导出excel</el-button>
</el-form-item> </el-form-item>
<el-form-item> <!-- <el-form-item>
<el-button <el-button
type="primary" type="primary"
v-if="versionObj.status == 'draft' || versionObj.status == 'back'" v-if="versionObj.status == 'draft' || versionObj.status == 'back'"
@ -51,26 +51,20 @@
v-if="versionObj.status != 'draft'" v-if="versionObj.status != 'draft'"
>查看流程</el-button >查看流程</el-button
> >
</el-form-item> </el-form-item> -->
</el-form> </el-form>
</el-card> </el-card>
</transition> </transition>
<el-card shadow="never" class="mb8"> <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 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="num" label="编号" />
<el-table-column prop="name" label="工程或费用名称" /> <el-table-column prop="name" label="工程或费用名称" />
<el-table-column prop="unit" label="单位" /> <el-table-column prop="unit" label="单位" align="center" />
<el-table-column prop="quantity" label="数量" /> <el-table-column prop="quantity" label="数量" align="center" />
<el-table-column prop="specification" label="规格" align="center" />
<el-table-column prop="remark" label="单价" align="center"> <el-table-column prop="remark" label="单价" align="center">
<template #default="scope"> <template #default="scope">
<el-input-number <span>{{ scope.row.unitPrice }}</span>
:model-value="scope.row.unitPrice"
@change="(val) => (scope.row.unitPrice = val)"
:precision="2"
:step="0.1"
:controls="false"
v-if="scope.row.quantity && scope.row.quantity != 0"
/>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="price" label="总价" align="center"> <el-table-column prop="price" label="总价" align="center">
@ -78,7 +72,7 @@
{{ scope.row.price }} {{ scope.row.price }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="price" label="操作" align="center"> <!-- <el-table-column prop="price" label="操作" align="center">
<template #default="scope"> <template #default="scope">
<el-button <el-button
type="primary" type="primary"
@ -89,7 +83,7 @@
>修改</el-button >修改</el-button
> >
</template> </template>
</el-table-column> </el-table-column> -->
</el-table> </el-table>
</el-card> </el-card>
</div> </div>
@ -172,7 +166,9 @@ const getTableData = async () => {
loading.value = true; loading.value = true;
const params = { const params = {
projectId: currentProject.value?.id, projectId: currentProject.value?.id,
sheet: queryForm.value.sheet sheet: queryForm.value.sheet,
versions: queryForm.value.versions,
type: '1'
}; };
const res = await getTreeLimit(params); const res = await getTreeLimit(params);
loading.value = false; loading.value = false;
@ -215,8 +211,6 @@ const tableRef = ref<any>();
const toggleExpandAll = () => { const toggleExpandAll = () => {
isExpandAll.value = !isExpandAll.value; isExpandAll.value = !isExpandAll.value;
console.log(isExpandAll.value);
tableData.value.forEach((row) => { tableData.value.forEach((row) => {
tableRef.value.toggleRowExpansion(row, isExpandAll.value); tableRef.value.toggleRowExpansion(row, isExpandAll.value);
}); });
@ -254,7 +248,7 @@ const handleExport = () => {
projectId: currentProject.value?.id, projectId: currentProject.value?.id,
sheet: queryForm.value.sheet sheet: queryForm.value.sheet
}, },
`限价一览表${queryForm.value.sheet}.xlsx` `投标成本核算清单${queryForm.value.sheet}.xlsx`
); );
}; };
// 审核 // 审核

Some files were not shown because too many files have changed in this diff Show More