hdc,绩效和工资单
This commit is contained in:
parent
ba041b3f3a
commit
a3b11c9971
|
@ -40,7 +40,7 @@ export function createHealthRecord(data: HealthRecord) {
|
||||||
return request({
|
return request({
|
||||||
url: '/health-record',
|
url: '/health-record',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data
|
data,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,7 +49,7 @@ export function getHealthRecordList(params: HealthRecordListParams) {
|
||||||
return request<HealthRecordListResponse>({
|
return request<HealthRecordListResponse>({
|
||||||
url: '/health-record/list',
|
url: '/health-record/list',
|
||||||
method: 'get',
|
method: 'get',
|
||||||
params
|
params,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ export function getHealthRecordList(params: HealthRecordListParams) {
|
||||||
export function getHealthRecordDetail(id: string) {
|
export function getHealthRecordDetail(id: string) {
|
||||||
return request<HealthRecord>({
|
return request<HealthRecord>({
|
||||||
url: `/health-record/detail/${id}`,
|
url: `/health-record/detail/${id}`,
|
||||||
method: 'get'
|
method: 'get',
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ export function updateHealthRecord(id: string, data: HealthRecord) {
|
||||||
return request({
|
return request({
|
||||||
url: `/health-record/${id}`,
|
url: `/health-record/${id}`,
|
||||||
method: 'put',
|
method: 'put',
|
||||||
data
|
data,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,7 +74,7 @@ export function updateHealthRecord(id: string, data: HealthRecord) {
|
||||||
export function deleteHealthRecord(id: string) {
|
export function deleteHealthRecord(id: string) {
|
||||||
return request({
|
return request({
|
||||||
url: `/health-record/${id}`,
|
url: `/health-record/${id}`,
|
||||||
method: 'delete'
|
method: 'delete',
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,8 +89,8 @@ export function uploadHealthReport(file: File, recordId: string) {
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data: formData,
|
data: formData,
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'multipart/form-data'
|
'Content-Type': 'multipart/form-data',
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,7 +99,7 @@ export function downloadHealthReport(fileId: string) {
|
||||||
return request({
|
return request({
|
||||||
url: `/health-record/download-report/${fileId}`,
|
url: `/health-record/download-report/${fileId}`,
|
||||||
method: 'get',
|
method: 'get',
|
||||||
responseType: 'blob'
|
responseType: 'blob',
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,7 +107,7 @@ export function downloadHealthReport(fileId: string) {
|
||||||
export function getEmployeeHealthHistory(employeeId: string) {
|
export function getEmployeeHealthHistory(employeeId: string) {
|
||||||
return request<HealthRecord[]>({
|
return request<HealthRecord[]>({
|
||||||
url: `/health-record/employee/${employeeId}`,
|
url: `/health-record/employee/${employeeId}`,
|
||||||
method: 'get'
|
method: 'get',
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,7 +117,7 @@ export function exportHealthRecords(params: HealthRecordListParams) {
|
||||||
url: '/health-record/export',
|
url: '/health-record/export',
|
||||||
method: 'get',
|
method: 'get',
|
||||||
params,
|
params,
|
||||||
responseType: 'blob'
|
responseType: 'blob',
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,6 +131,6 @@ export function scheduleHealthCheck(data: {
|
||||||
return request({
|
return request({
|
||||||
url: '/health-record/schedule',
|
url: '/health-record/schedule',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data
|
data,
|
||||||
})
|
})
|
||||||
}
|
}
|
|
@ -9,6 +9,7 @@ export * from './project'
|
||||||
export * from './project/task'
|
export * from './project/task'
|
||||||
export * from './attach-info'
|
export * from './attach-info'
|
||||||
export * from './model-config'
|
export * from './model-config'
|
||||||
|
export * from './performance'
|
||||||
// 保险相关模块
|
// 保险相关模块
|
||||||
export * as InsuranceAPI from './insurance'
|
export * as InsuranceAPI from './insurance'
|
||||||
export * as InsuranceCompanyAPI from './insurance-company'
|
export * as InsuranceCompanyAPI from './insurance-company'
|
||||||
|
@ -27,3 +28,5 @@ export * from './schedule/type'
|
||||||
export * from './project/type'
|
export * from './project/type'
|
||||||
export * from './attach-info/type'
|
export * from './attach-info/type'
|
||||||
export * from './model-config/type'
|
export * from './model-config/type'
|
||||||
|
export * from './performance/type'
|
||||||
|
export * from './salary'
|
||||||
|
|
|
@ -0,0 +1,59 @@
|
||||||
|
import type * as T from './type'
|
||||||
|
import http from '@/utils/http'
|
||||||
|
|
||||||
|
const BASE_URL = '/performance'
|
||||||
|
|
||||||
|
/* ===== 维度 ===== */
|
||||||
|
export const getDimensionList = () => http.get<T.DimensionResp[]>(`${BASE_URL}/dimension`)
|
||||||
|
|
||||||
|
export const addDimension = (data: T.DimensionAddReq) =>
|
||||||
|
http.post<boolean>(`${BASE_URL}/dimension`, data)
|
||||||
|
|
||||||
|
export const updateDimension = (id: string, data: T.DimensionUpdateReq) =>
|
||||||
|
http.put<boolean>(`${BASE_URL}/dimension/${id}`, data)
|
||||||
|
|
||||||
|
export const deleteDimension = (id: string) =>
|
||||||
|
http.del<boolean>(`${BASE_URL}/dimension/${id}`)
|
||||||
|
|
||||||
|
/** 维度详情(RuleDrawer.vue 需要) */
|
||||||
|
export const getDimensionDetail = (id: string) =>
|
||||||
|
http.get<T.DimensionResp>(`${BASE_URL}/dimension/${id}`)
|
||||||
|
|
||||||
|
/* ===== 细则 ===== */
|
||||||
|
export const getRuleList = (dimensionId: string) =>
|
||||||
|
http.get<T.RuleResp[]>(`${BASE_URL}/rule`, { dimensionId })
|
||||||
|
|
||||||
|
export const addRule = (data: T.RuleAddReq) =>
|
||||||
|
http.post<boolean>(`${BASE_URL}/rule`, data)
|
||||||
|
|
||||||
|
export const updateRule = (id: string, data: T.RuleUpdateReq) =>
|
||||||
|
http.put<boolean>(`${BASE_URL}/rule/${id}`, data)
|
||||||
|
|
||||||
|
export const deleteRule = (id: string) =>
|
||||||
|
http.del<boolean>(`${BASE_URL}/rule/${id}`)
|
||||||
|
|
||||||
|
/** 细则详情(RuleDrawer.vue 需要) */
|
||||||
|
export const getRuleDetail = (id: string) =>
|
||||||
|
http.get<T.RuleResp>(`${BASE_URL}/rule/${id}`)
|
||||||
|
|
||||||
|
/* ===== 周期 ===== */
|
||||||
|
export const getPeriodList = () => http.get<T.PeriodResp[]>(`${BASE_URL}/period`)
|
||||||
|
export const addPeriod = (data: T.PeriodResp) => http.post<boolean>(`${BASE_URL}/period`, data)
|
||||||
|
export const deletePeriod = (id: string) => http.del<boolean>(`${BASE_URL}/period/${id}`)
|
||||||
|
export const updataPeriod = (id: string, data: T.PeriodResp) => http.post<boolean>(`${BASE_URL}/period/${id}`, data)
|
||||||
|
|
||||||
|
/* ===== 评估 ===== */
|
||||||
|
export const startEvaluate = (data: T.EvaluateReq) =>
|
||||||
|
http.post<boolean>(`${BASE_URL}/evaluate`, data)
|
||||||
|
|
||||||
|
export const getEvaluatePage = (query?: T.EvaluateQuery) =>
|
||||||
|
http.get<PageRes<T.EvaluateResp[]>>(`${BASE_URL}/evaluate/page`, query)
|
||||||
|
// 同样的修改和删除评估接口
|
||||||
|
|
||||||
|
/** 员工查看自己的绩效 */
|
||||||
|
export const getMyEvaluate = (query?: T.EvaluateQuery) =>
|
||||||
|
http.get<PageRes<T.EvaluateResp[]>>(`${BASE_URL}/evaluate/my`, query)
|
||||||
|
|
||||||
|
/* ===== 反馈 ===== */
|
||||||
|
export const submitFeedback = (data: T.FeedbackReq) =>
|
||||||
|
http.post<boolean>(`${BASE_URL}/feedback`, data)
|
|
@ -0,0 +1,87 @@
|
||||||
|
// ========== 维度 ==========
|
||||||
|
export interface DimensionResp {
|
||||||
|
id: string
|
||||||
|
name: string
|
||||||
|
desc: string
|
||||||
|
weight: number
|
||||||
|
status: 0 | 1
|
||||||
|
ruleCount: number
|
||||||
|
deptId: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DimensionAddReq {
|
||||||
|
name: string
|
||||||
|
desc: string
|
||||||
|
weight: number
|
||||||
|
deptId: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DimensionUpdateReq extends DimensionAddReq {
|
||||||
|
status: 0 | 1
|
||||||
|
}
|
||||||
|
|
||||||
|
// ========== 细则 ==========
|
||||||
|
export interface RuleResp {
|
||||||
|
id: string
|
||||||
|
dimensionId: string
|
||||||
|
name: string
|
||||||
|
ruleDesc: string
|
||||||
|
score: number
|
||||||
|
weight: number
|
||||||
|
isExtra: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface RuleAddReq {
|
||||||
|
dimensionId: string
|
||||||
|
name: string
|
||||||
|
ruleDesc: string
|
||||||
|
score: number
|
||||||
|
weight: number
|
||||||
|
isExtra: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface RuleUpdateReq extends RuleAddReq {}
|
||||||
|
|
||||||
|
// ========== 绩效周期 ==========
|
||||||
|
export interface PeriodResp {
|
||||||
|
id: string
|
||||||
|
name: string
|
||||||
|
startDate: string
|
||||||
|
endDate: string
|
||||||
|
}
|
||||||
|
|
||||||
|
// ========== 评估 ==========
|
||||||
|
export interface EvaluateReq {
|
||||||
|
userId: string
|
||||||
|
dimensionId: string
|
||||||
|
ruleId: string
|
||||||
|
periodId: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface EvaluateResp {
|
||||||
|
id: string // 细则id
|
||||||
|
userId: string
|
||||||
|
userName: string
|
||||||
|
dimensionName: string
|
||||||
|
ruleName: string
|
||||||
|
periodName: string
|
||||||
|
score: number
|
||||||
|
aiComment: string
|
||||||
|
status: 0 | 1 // 0待反馈 1已反馈
|
||||||
|
}
|
||||||
|
|
||||||
|
// ========== 查询 ==========
|
||||||
|
export interface EvaluateQuery {
|
||||||
|
keyword?: string
|
||||||
|
periodId?: string
|
||||||
|
dimensionId?: string
|
||||||
|
status?: 0 | 1
|
||||||
|
}
|
||||||
|
|
||||||
|
// ========== 反馈 ==========
|
||||||
|
export interface FeedbackReq {
|
||||||
|
evaluateId: string
|
||||||
|
level: 0 | 1 | 2
|
||||||
|
content: string
|
||||||
|
userId: string
|
||||||
|
}
|
|
@ -0,0 +1,64 @@
|
||||||
|
import type { SalaryRecord, SalaryQuery, SalaryCreateRequest } from '@/views/salary-management/types'
|
||||||
|
import http from '@/utils/http'
|
||||||
|
|
||||||
|
const BASE_URL = '/salary'
|
||||||
|
|
||||||
|
// 获取工资单列表
|
||||||
|
export const getSalaryList = (query?: SalaryQuery) => {
|
||||||
|
return http.get<PageRes<SalaryRecord[]>>(`${BASE_URL}/list`, query)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取工资单详情
|
||||||
|
export const getSalaryDetail = (id: string) => {
|
||||||
|
return http.get<SalaryRecord>(`${BASE_URL}/${id}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建工资单
|
||||||
|
export const createSalary = (data: SalaryCreateRequest) => {
|
||||||
|
return http.post<SalaryRecord>(`${BASE_URL}`, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新工资单
|
||||||
|
export const updateSalary = (id: string, data: Partial<SalaryRecord>) => {
|
||||||
|
return http.put<SalaryRecord>(`${BASE_URL}/${id}`, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除工资单
|
||||||
|
export const deleteSalary = (id: string) => {
|
||||||
|
return http.del<boolean>(`${BASE_URL}/${id}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 提交审批
|
||||||
|
export const submitApproval = (id: string) => {
|
||||||
|
return http.post<boolean>(`${BASE_URL}/${id}/submit`)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 审批工资单
|
||||||
|
export const approveSalary = (id: string, data: { status: string; comment?: string }) => {
|
||||||
|
return http.put<boolean>(`${BASE_URL}/${id}/approve`, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 导出工资单
|
||||||
|
export const exportSalary = (id: string, format: 'excel' | 'pdf' = 'excel') => {
|
||||||
|
return http.download(`${BASE_URL}/${id}/export`, { format })
|
||||||
|
}
|
||||||
|
|
||||||
|
// 批量导出
|
||||||
|
export const exportSalaryBatch = (ids: string[], format: 'excel' | 'pdf' = 'excel') => {
|
||||||
|
return http.download(`${BASE_URL}/export/batch`, { ids, format })
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取实习生配置
|
||||||
|
export const getInternConfig = () => {
|
||||||
|
return http.get<any>(`${BASE_URL}/config/intern`)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取员工列表
|
||||||
|
export const getEmployeeList = (type?: string) => {
|
||||||
|
return http.get<any[]>(`${BASE_URL}/employees`, { type })
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取项目列表
|
||||||
|
export const getProjectList = () => {
|
||||||
|
return http.get<any[]>(`${BASE_URL}/projects`)
|
||||||
|
}
|
|
@ -67,7 +67,7 @@ export const systemRoutes: RouteRecordRaw[] = [
|
||||||
{
|
{
|
||||||
path: '/organization/hr/performance',
|
path: '/organization/hr/performance',
|
||||||
name: 'HRPerformance',
|
name: 'HRPerformance',
|
||||||
component: () => import('@/views/hr/performance/index.vue'),
|
component: () => import('@/views/performance/index.vue'),
|
||||||
meta: { title: '绩效', icon: 'performance', hidden: false },
|
meta: { title: '绩效', icon: 'performance', hidden: false },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -83,7 +83,7 @@ export const systemRoutes: RouteRecordRaw[] = [
|
||||||
component: () => import('@/views/hr/salary/index.vue'),
|
component: () => import('@/views/hr/salary/index.vue'),
|
||||||
meta: { title: '工资概览', icon: 'salary', hidden: false },
|
meta: { title: '工资概览', icon: 'salary', hidden: false },
|
||||||
},
|
},
|
||||||
]
|
],
|
||||||
},
|
},
|
||||||
// {
|
// {
|
||||||
// path: '/organization/hr/salary/insurance',
|
// path: '/organization/hr/salary/insurance',
|
||||||
|
@ -166,8 +166,8 @@ export const systemRoutes: RouteRecordRaw[] = [
|
||||||
name: 'HRSystemTypeManagement',
|
name: 'HRSystemTypeManagement',
|
||||||
component: () => import('@/views/hr/salary/system-insurance/type-management/index.vue'),
|
component: () => import('@/views/hr/salary/system-insurance/type-management/index.vue'),
|
||||||
meta: { title: '保险类型管理', icon: 'category', hidden: false },
|
meta: { title: '保险类型管理', icon: 'category', hidden: false },
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/organization/hr/salary/certification',
|
path: '/organization/hr/salary/certification',
|
||||||
|
@ -180,15 +180,54 @@ export const systemRoutes: RouteRecordRaw[] = [
|
||||||
name: 'HRContribution',
|
name: 'HRContribution',
|
||||||
component: () => import('@/views/hr/contribution/index.vue'),
|
component: () => import('@/views/hr/contribution/index.vue'),
|
||||||
meta: { title: '责献积分制度', icon: 'contribution', hidden: false },
|
meta: { title: '责献积分制度', icon: 'contribution', hidden: false },
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/organization/role',
|
path: '/organization/role',
|
||||||
name: 'OrganizationRole',
|
name: 'OrganizationRole',
|
||||||
component: () => import('@/views/system/role/index.vue'),
|
component: () => import('@/views/system/role/index.vue'),
|
||||||
meta: { title: '角色管理', icon: 'role', hidden: false },
|
meta: { title: '角色管理', icon: 'role', hidden: false },
|
||||||
}
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/performance',
|
||||||
|
name: 'Performance',
|
||||||
|
component: Layout,
|
||||||
|
redirect: '/performance/dimension',
|
||||||
|
meta: { title: '绩效管理', icon: 'chart', hidden: false, sort: 3 },
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: '/performance/dimension',
|
||||||
|
name: 'PerformanceDimension',
|
||||||
|
component: () => import('@/views/performance/dimension.vue'),
|
||||||
|
meta: { title: '绩效维度管理', icon: 'dashboard', hidden: false },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/performance/rule',
|
||||||
|
name: 'PerformanceRule',
|
||||||
|
component: () => import('@/views/performance/rule.vue'),
|
||||||
|
meta: { title: '细则管理', icon: 'setting', hidden: false },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/performance/evaluate',
|
||||||
|
name: 'PerformanceEvaluate',
|
||||||
|
component: () => import('@/views/performance/evaluate.vue'),
|
||||||
|
meta: { title: '员工评估', icon: 'user', hidden: false },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/performance/my',
|
||||||
|
name: 'PerformanceMy',
|
||||||
|
component: () => import('@/views/performance/my.vue'),
|
||||||
|
meta: { title: '我的绩效', icon: 'user', hidden: false },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/salary-management',
|
||||||
|
name: 'SalaryManagement',
|
||||||
|
component: () => import('@/views/salary-management/index.vue'),
|
||||||
|
meta: { title: '工资管理', hidden: false },
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -203,7 +242,7 @@ export const systemRoutes: RouteRecordRaw[] = [
|
||||||
name: 'IntellectualProperty',
|
name: 'IntellectualProperty',
|
||||||
component: () => import('@/views/system-resource/information-system/software-management/index.vue'),
|
component: () => import('@/views/system-resource/information-system/software-management/index.vue'),
|
||||||
meta: { title: '其他资产', icon: 'copyright', hidden: false },
|
meta: { title: '其他资产', icon: 'copyright', hidden: false },
|
||||||
}
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -250,8 +289,8 @@ export const systemRoutes: RouteRecordRaw[] = [
|
||||||
name: 'BladeRobot',
|
name: 'BladeRobot',
|
||||||
component: () => import('@/views/service/lightning-detection/index.vue'),
|
component: () => import('@/views/service/lightning-detection/index.vue'),
|
||||||
meta: { title: '叶片维修机器人', icon: 'robot', hidden: false },
|
meta: { title: '叶片维修机器人', icon: 'robot', hidden: false },
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/products-services/products/software',
|
path: '/products-services/products/software',
|
||||||
|
@ -277,10 +316,10 @@ export const systemRoutes: RouteRecordRaw[] = [
|
||||||
name: 'GroundStation',
|
name: 'GroundStation',
|
||||||
component: () => import('@/views/service/lightning-detection/index.vue'),
|
component: () => import('@/views/service/lightning-detection/index.vue'),
|
||||||
meta: { title: '无人机地面站软件', icon: 'station', hidden: false },
|
meta: { title: '无人机地面站软件', icon: 'station', hidden: false },
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/products-services/services',
|
path: '/products-services/services',
|
||||||
|
@ -342,9 +381,9 @@ export const systemRoutes: RouteRecordRaw[] = [
|
||||||
name: 'BladeMaintenance',
|
name: 'BladeMaintenance',
|
||||||
component: () => import('@/views/service/lightning-detection/index.vue'),
|
component: () => import('@/views/service/lightning-detection/index.vue'),
|
||||||
meta: { title: '叶片维修', icon: 'maintenance', hidden: false },
|
meta: { title: '叶片维修', icon: 'maintenance', hidden: false },
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
}
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -362,7 +401,7 @@ export const systemRoutes: RouteRecordRaw[] = [
|
||||||
meta: {
|
meta: {
|
||||||
title: '施工立项',
|
title: '施工立项',
|
||||||
icon: 'file-protect',
|
icon: 'file-protect',
|
||||||
hidden: false
|
hidden: false,
|
||||||
},
|
},
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
|
@ -372,8 +411,8 @@ export const systemRoutes: RouteRecordRaw[] = [
|
||||||
meta: {
|
meta: {
|
||||||
title: '招标文件',
|
title: '招标文件',
|
||||||
icon: 'file-text',
|
icon: 'file-text',
|
||||||
hidden: false
|
hidden: false,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/project-management/project-template/bid-documents',
|
path: '/project-management/project-template/bid-documents',
|
||||||
|
@ -382,8 +421,8 @@ export const systemRoutes: RouteRecordRaw[] = [
|
||||||
meta: {
|
meta: {
|
||||||
title: '投标文件',
|
title: '投标文件',
|
||||||
icon: 'file-text',
|
icon: 'file-text',
|
||||||
hidden: false
|
hidden: false,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/project-management/project-template/award-notice',
|
path: '/project-management/project-template/award-notice',
|
||||||
|
@ -392,8 +431,8 @@ export const systemRoutes: RouteRecordRaw[] = [
|
||||||
meta: {
|
meta: {
|
||||||
title: '中标通知书',
|
title: '中标通知书',
|
||||||
icon: 'trophy',
|
icon: 'trophy',
|
||||||
hidden: false
|
hidden: false,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/project-management/projects/initiation',
|
path: '/project-management/projects/initiation',
|
||||||
|
@ -402,10 +441,10 @@ export const systemRoutes: RouteRecordRaw[] = [
|
||||||
meta: {
|
meta: {
|
||||||
title: '立项管理',
|
title: '立项管理',
|
||||||
icon: 'plus-circle',
|
icon: 'plus-circle',
|
||||||
hidden: false
|
hidden: false,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
]
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/project-management/contract',
|
path: '/project-management/contract',
|
||||||
|
@ -415,7 +454,7 @@ export const systemRoutes: RouteRecordRaw[] = [
|
||||||
meta: {
|
meta: {
|
||||||
title: '市场商务管理',
|
title: '市场商务管理',
|
||||||
icon: 'file-text',
|
icon: 'file-text',
|
||||||
hidden: false
|
hidden: false,
|
||||||
},
|
},
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
|
@ -425,8 +464,8 @@ export const systemRoutes: RouteRecordRaw[] = [
|
||||||
meta: {
|
meta: {
|
||||||
title: '收入合同',
|
title: '收入合同',
|
||||||
icon: 'dollar',
|
icon: 'dollar',
|
||||||
hidden: false
|
hidden: false,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/project-management/contract/expense-contract',
|
path: '/project-management/contract/expense-contract',
|
||||||
|
@ -435,8 +474,8 @@ export const systemRoutes: RouteRecordRaw[] = [
|
||||||
meta: {
|
meta: {
|
||||||
title: '支出合同',
|
title: '支出合同',
|
||||||
icon: 'credit-card',
|
icon: 'credit-card',
|
||||||
hidden: false
|
hidden: false,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/project-management/contract/cost-management',
|
path: '/project-management/contract/cost-management',
|
||||||
|
@ -445,10 +484,10 @@ export const systemRoutes: RouteRecordRaw[] = [
|
||||||
meta: {
|
meta: {
|
||||||
title: '成本费用',
|
title: '成本费用',
|
||||||
icon: 'bar-chart',
|
icon: 'bar-chart',
|
||||||
hidden: false
|
hidden: false,
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/project-management/projects',
|
path: '/project-management/projects',
|
||||||
|
@ -458,7 +497,7 @@ export const systemRoutes: RouteRecordRaw[] = [
|
||||||
meta: {
|
meta: {
|
||||||
title: '组织实施管理',
|
title: '组织实施管理',
|
||||||
icon: 'briefcase',
|
icon: 'briefcase',
|
||||||
hidden: false
|
hidden: false,
|
||||||
},
|
},
|
||||||
children: [
|
children: [
|
||||||
|
|
||||||
|
@ -469,8 +508,8 @@ export const systemRoutes: RouteRecordRaw[] = [
|
||||||
meta: {
|
meta: {
|
||||||
title: '进度管理',
|
title: '进度管理',
|
||||||
icon: 'schedule',
|
icon: 'schedule',
|
||||||
hidden: false
|
hidden: false,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/project-management/projects/budget',
|
path: '/project-management/projects/budget',
|
||||||
|
@ -479,8 +518,8 @@ export const systemRoutes: RouteRecordRaw[] = [
|
||||||
meta: {
|
meta: {
|
||||||
title: '预算管理',
|
title: '预算管理',
|
||||||
icon: 'fund',
|
icon: 'fund',
|
||||||
hidden: false
|
hidden: false,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/project-management/projects/personnel-distribution',
|
path: '/project-management/projects/personnel-distribution',
|
||||||
|
@ -489,8 +528,8 @@ export const systemRoutes: RouteRecordRaw[] = [
|
||||||
meta: {
|
meta: {
|
||||||
title: '人员分布图',
|
title: '人员分布图',
|
||||||
icon: 'team',
|
icon: 'team',
|
||||||
hidden: false
|
hidden: false,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/project-management/projects/device',
|
path: '/project-management/projects/device',
|
||||||
|
@ -499,8 +538,8 @@ export const systemRoutes: RouteRecordRaw[] = [
|
||||||
meta: {
|
meta: {
|
||||||
title: '设备管理',
|
title: '设备管理',
|
||||||
icon: 'plus-circle',
|
icon: 'plus-circle',
|
||||||
hidden: false
|
hidden: false,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/project-management/projects/safety',
|
path: '/project-management/projects/safety',
|
||||||
|
@ -509,8 +548,8 @@ export const systemRoutes: RouteRecordRaw[] = [
|
||||||
meta: {
|
meta: {
|
||||||
title: '安全管理',
|
title: '安全管理',
|
||||||
icon: 'safety',
|
icon: 'safety',
|
||||||
hidden: false
|
hidden: false,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/project-management/projects/quality',
|
path: '/project-management/projects/quality',
|
||||||
|
@ -519,11 +558,11 @@ export const systemRoutes: RouteRecordRaw[] = [
|
||||||
meta: {
|
meta: {
|
||||||
title: '质量管理',
|
title: '质量管理',
|
||||||
icon: 'audit',
|
icon: 'audit',
|
||||||
hidden: false
|
hidden: false,
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
}
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -554,16 +593,16 @@ export const systemRoutes: RouteRecordRaw[] = [
|
||||||
meta: {
|
meta: {
|
||||||
title: '项目列表',
|
title: '项目列表',
|
||||||
icon: 'unordered-list',
|
icon: 'unordered-list',
|
||||||
hidden: false
|
hidden: false,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/construction-operation-platform/implementation-workflow/field-construction/technology',
|
path: '/construction-operation-platform/implementation-workflow/field-construction/technology',
|
||||||
name: 'FieldConstructionTechnology',
|
name: 'FieldConstructionTechnology',
|
||||||
component: () => import('@/views/project-operation-platform/implementation-workflow/field-construction/project-list/index.vue'),
|
component: () => import('@/views/project-operation-platform/implementation-workflow/field-construction/project-list/index.vue'),
|
||||||
meta: { title: '现场工艺', icon: 'tool', hidden: false },
|
meta: { title: '现场工艺', icon: 'tool', hidden: false },
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/construction-operation-platform/implementation-workflow/data-processing',
|
path: '/construction-operation-platform/implementation-workflow/data-processing',
|
||||||
|
@ -604,7 +643,7 @@ export const systemRoutes: RouteRecordRaw[] = [
|
||||||
meta: { title: '模型配置', icon: 'robot', hidden: false },
|
meta: { title: '模型配置', icon: 'robot', hidden: false },
|
||||||
},
|
},
|
||||||
|
|
||||||
]
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/construction-operation-platform/implementation-workflow/data-processing/intelligent-inspection',
|
path: '/construction-operation-platform/implementation-workflow/data-processing/intelligent-inspection',
|
||||||
|
@ -654,10 +693,10 @@ export const systemRoutes: RouteRecordRaw[] = [
|
||||||
name: 'ReportReview',
|
name: 'ReportReview',
|
||||||
component: () => import('@/views/project-operation-platform/data-processing/report-review/index.vue'),
|
component: () => import('@/views/project-operation-platform/data-processing/report-review/index.vue'),
|
||||||
meta: { title: '报告修改审核', icon: 'audit', hidden: false },
|
meta: { title: '报告修改审核', icon: 'audit', hidden: false },
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/construction-operation-platform/implementation-workflow/tower-monitoring-video',
|
path: '/construction-operation-platform/implementation-workflow/tower-monitoring-video',
|
||||||
|
@ -683,8 +722,8 @@ export const systemRoutes: RouteRecordRaw[] = [
|
||||||
name: 'ImageDetection',
|
name: 'ImageDetection',
|
||||||
component: () => import('@/views/project-operation-platform/data-processing/wide-angle-video/index.vue'),
|
component: () => import('@/views/project-operation-platform/data-processing/wide-angle-video/index.vue'),
|
||||||
meta: { title: '图像检测', icon: 'picture', hidden: false },
|
meta: { title: '图像检测', icon: 'picture', hidden: false },
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/construction-operation-platform/implementation-workflow/project-delivery',
|
path: '/construction-operation-platform/implementation-workflow/project-delivery',
|
||||||
|
@ -734,11 +773,11 @@ export const systemRoutes: RouteRecordRaw[] = [
|
||||||
name: 'ReportTemplateOther',
|
name: 'ReportTemplateOther',
|
||||||
component: () => import('@/views/project-operation-platform/data-processing/report-template/index.vue'),
|
component: () => import('@/views/project-operation-platform/data-processing/report-template/index.vue'),
|
||||||
meta: { title: '报告模版库', icon: 'book', hidden: false },
|
meta: { title: '报告模版库', icon: 'book', hidden: false },
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
}
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -758,7 +797,7 @@ export const systemRoutes: RouteRecordRaw[] = [
|
||||||
// hidden: false
|
// hidden: false
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
]
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/enterprise-settings',
|
path: '/enterprise-settings',
|
||||||
|
@ -773,9 +812,9 @@ export const systemRoutes: RouteRecordRaw[] = [
|
||||||
component: () => import('@/views/enterprise-settings/company-info/index.vue'),
|
component: () => import('@/views/enterprise-settings/company-info/index.vue'),
|
||||||
meta: {
|
meta: {
|
||||||
title: '企业信息',
|
title: '企业信息',
|
||||||
icon: 'info-circle',
|
icon: 'info-circle',
|
||||||
hidden: false
|
hidden: false,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/enterprise-settings/admin-permissions',
|
path: '/enterprise-settings/admin-permissions',
|
||||||
|
@ -784,8 +823,8 @@ export const systemRoutes: RouteRecordRaw[] = [
|
||||||
meta: {
|
meta: {
|
||||||
title: '管理员权限',
|
title: '管理员权限',
|
||||||
icon: 'lock',
|
icon: 'lock',
|
||||||
hidden: false
|
hidden: false,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/enterprise-settings/data-migration',
|
path: '/enterprise-settings/data-migration',
|
||||||
|
@ -794,8 +833,8 @@ export const systemRoutes: RouteRecordRaw[] = [
|
||||||
meta: {
|
meta: {
|
||||||
title: '数据迁移',
|
title: '数据迁移',
|
||||||
icon: 'database',
|
icon: 'database',
|
||||||
hidden: false
|
hidden: false,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/enterprise-settings/version-upgrade',
|
path: '/enterprise-settings/version-upgrade',
|
||||||
|
@ -804,10 +843,10 @@ export const systemRoutes: RouteRecordRaw[] = [
|
||||||
meta: {
|
meta: {
|
||||||
title: '版本升级提醒',
|
title: '版本升级提醒',
|
||||||
icon: 'upgrade',
|
icon: 'upgrade',
|
||||||
hidden: false
|
hidden: false,
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/enterprise-dashboard',
|
path: '/enterprise-dashboard',
|
||||||
|
@ -823,8 +862,8 @@ export const systemRoutes: RouteRecordRaw[] = [
|
||||||
meta: {
|
meta: {
|
||||||
title: '数据概览',
|
title: '数据概览',
|
||||||
icon: 'bar-chart',
|
icon: 'bar-chart',
|
||||||
hidden: false
|
hidden: false,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/enterprise-dashboard/member-data',
|
path: '/enterprise-dashboard/member-data',
|
||||||
|
@ -833,8 +872,8 @@ export const systemRoutes: RouteRecordRaw[] = [
|
||||||
meta: {
|
meta: {
|
||||||
title: '成员活跃数据',
|
title: '成员活跃数据',
|
||||||
icon: 'team',
|
icon: 'team',
|
||||||
hidden: false
|
hidden: false,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/enterprise-dashboard/function-usage',
|
path: '/enterprise-dashboard/function-usage',
|
||||||
|
@ -843,8 +882,8 @@ export const systemRoutes: RouteRecordRaw[] = [
|
||||||
meta: {
|
meta: {
|
||||||
title: '功能使用情况',
|
title: '功能使用情况',
|
||||||
icon: 'appstore',
|
icon: 'appstore',
|
||||||
hidden: false
|
hidden: false,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/enterprise-dashboard/application-data',
|
path: '/enterprise-dashboard/application-data',
|
||||||
|
@ -853,10 +892,10 @@ export const systemRoutes: RouteRecordRaw[] = [
|
||||||
meta: {
|
meta: {
|
||||||
title: '应用使用数据',
|
title: '应用使用数据',
|
||||||
icon: 'pie-chart',
|
icon: 'pie-chart',
|
||||||
hidden: false
|
hidden: false,
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/system-resource',
|
path: '/system-resource',
|
||||||
|
@ -865,60 +904,59 @@ export const systemRoutes: RouteRecordRaw[] = [
|
||||||
redirect: '/system-resource/device-management/warehouse',
|
redirect: '/system-resource/device-management/warehouse',
|
||||||
meta: { title: '关于平台', icon: 'server', hidden: false, sort: 9 },
|
meta: { title: '关于平台', icon: 'server', hidden: false, sort: 9 },
|
||||||
children: [
|
children: [
|
||||||
|
{
|
||||||
|
path: '/system-resource/device-management/warehouse',
|
||||||
|
name: 'DeviceWarehouse',
|
||||||
|
component: () => import('@/views/system-resource/device-management/index.vue'),
|
||||||
|
meta: {
|
||||||
|
title: '库存管理',
|
||||||
|
icon: 'warehouse',
|
||||||
|
hidden: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/system-resource/device-management/online',
|
||||||
|
name: 'DeviceOnline',
|
||||||
|
component: () => import('@/components/ParentView/index.vue'),
|
||||||
|
redirect: '/system-resource/device-management/online/drone',
|
||||||
|
meta: {
|
||||||
|
title: '在线管理',
|
||||||
|
icon: 'cloud',
|
||||||
|
hidden: false,
|
||||||
|
},
|
||||||
|
children: [
|
||||||
{
|
{
|
||||||
path: '/system-resource/device-management/warehouse',
|
path: '/system-resource/device-management/online/drone',
|
||||||
name: 'DeviceWarehouse',
|
name: 'DeviceDrone',
|
||||||
component: () => import('@/views/system-resource/device-management/index.vue'),
|
component: () => import('@/views/system-resource/device-management/index.vue'),
|
||||||
meta: {
|
meta: {
|
||||||
title: '库存管理',
|
title: '无人机',
|
||||||
icon: 'warehouse',
|
icon: 'drone',
|
||||||
hidden: false
|
hidden: false,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/system-resource/device-management/online',
|
path: '/system-resource/device-management/online/nest',
|
||||||
name: 'DeviceOnline',
|
name: 'DeviceNest',
|
||||||
component: () => import('@/components/ParentView/index.vue'),
|
component: () => import('@/views/system-resource/device-management/index.vue'),
|
||||||
redirect: '/system-resource/device-management/online/drone',
|
|
||||||
meta: {
|
meta: {
|
||||||
title: '在线管理',
|
title: '机巢',
|
||||||
icon: 'cloud',
|
icon: 'nest',
|
||||||
hidden: false
|
hidden: false,
|
||||||
},
|
},
|
||||||
children: [
|
},
|
||||||
{
|
{
|
||||||
path: '/system-resource/device-management/online/drone',
|
path: '/system-resource/device-management/online/smart-terminal',
|
||||||
name: 'DeviceDrone',
|
name: 'DeviceSmartTerminal',
|
||||||
component: () => import('@/views/system-resource/device-management/index.vue'),
|
component: () => import('@/views/system-resource/device-management/index.vue'),
|
||||||
meta: {
|
meta: {
|
||||||
title: '无人机',
|
title: '其他智能终端',
|
||||||
icon: 'drone',
|
icon: 'terminal',
|
||||||
hidden: false
|
hidden: false,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
{
|
],
|
||||||
path: '/system-resource/device-management/online/nest',
|
},
|
||||||
name: 'DeviceNest',
|
|
||||||
component: () => import('@/views/system-resource/device-management/index.vue'),
|
|
||||||
meta: {
|
|
||||||
title: '机巢',
|
|
||||||
icon: 'nest',
|
|
||||||
hidden: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/system-resource/device-management/online/smart-terminal',
|
|
||||||
name: 'DeviceSmartTerminal',
|
|
||||||
component: () => import('@/views/system-resource/device-management/index.vue'),
|
|
||||||
meta: {
|
|
||||||
title: '其他智能终端',
|
|
||||||
icon: 'terminal',
|
|
||||||
hidden: false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
,
|
|
||||||
{
|
{
|
||||||
path: '/system-resource/information-system',
|
path: '/system-resource/information-system',
|
||||||
name: 'InformationSystem',
|
name: 'InformationSystem',
|
||||||
|
@ -927,7 +965,7 @@ export const systemRoutes: RouteRecordRaw[] = [
|
||||||
meta: {
|
meta: {
|
||||||
title: '信息化系统管理',
|
title: '信息化系统管理',
|
||||||
icon: 'code',
|
icon: 'code',
|
||||||
hidden: false
|
hidden: false,
|
||||||
},
|
},
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
|
@ -937,8 +975,8 @@ export const systemRoutes: RouteRecordRaw[] = [
|
||||||
meta: {
|
meta: {
|
||||||
title: '软件管理',
|
title: '软件管理',
|
||||||
icon: 'appstore',
|
icon: 'appstore',
|
||||||
hidden: false
|
hidden: false,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/system-resource/information-system/system-backup',
|
path: '/system-resource/information-system/system-backup',
|
||||||
|
@ -947,10 +985,10 @@ export const systemRoutes: RouteRecordRaw[] = [
|
||||||
meta: {
|
meta: {
|
||||||
title: '系统备份管理',
|
title: '系统备份管理',
|
||||||
icon: 'save',
|
icon: 'save',
|
||||||
hidden: false
|
hidden: false,
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/system-resource/about',
|
path: '/system-resource/about',
|
||||||
|
@ -959,10 +997,10 @@ export const systemRoutes: RouteRecordRaw[] = [
|
||||||
meta: {
|
meta: {
|
||||||
title: '关于我们',
|
title: '关于我们',
|
||||||
icon: 'info-circle',
|
icon: 'info-circle',
|
||||||
hidden: false
|
hidden: false,
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -1001,4 +1039,3 @@ export const constantRoutes: RouteRecordRaw[] = [
|
||||||
meta: { hidden: true },
|
meta: { hidden: true },
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,75 @@
|
||||||
|
<template>
|
||||||
|
<a-drawer
|
||||||
|
v-model:visible="visible"
|
||||||
|
:title="isUpdate ? '修改维度' : '新增维度'"
|
||||||
|
@before-ok="save"
|
||||||
|
@cancel="reset"
|
||||||
|
>
|
||||||
|
<a-form ref="formRef" :model="form" auto-label-width>
|
||||||
|
<a-form-item label="维度名称" field="name" required>
|
||||||
|
<a-input v-model="form.name" />
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item label="权重%" field="weight" required>
|
||||||
|
<a-input-number v-model="form.weight" :min="1" :max="100" />
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item label="描述" field="desc">
|
||||||
|
<a-textarea v-model="form.desc" :rows="3" />
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item label="状态" field="status">
|
||||||
|
<a-switch v-model="form.status" :checked-value="0" :unchecked-value="1" />
|
||||||
|
</a-form-item>
|
||||||
|
</a-form>
|
||||||
|
</a-drawer>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { reactive, ref } from 'vue'
|
||||||
|
import { addDimension, getDimensionDetail, updateDimension } from '@/apis/performance'
|
||||||
|
|
||||||
|
const emit = defineEmits<{
|
||||||
|
(e: 'success'): void
|
||||||
|
}>()
|
||||||
|
const visible = ref(false)
|
||||||
|
const isUpdate = ref(false)
|
||||||
|
const formRef = ref()
|
||||||
|
const id = ref('')
|
||||||
|
const form = reactive({
|
||||||
|
name: '',
|
||||||
|
weight: 50,
|
||||||
|
desc: '',
|
||||||
|
status: 0 as 0 | 1,
|
||||||
|
})
|
||||||
|
|
||||||
|
const reset = () => {
|
||||||
|
formRef.value?.resetFields()
|
||||||
|
Object.assign(form, { name: '', weight: 50, desc: '', status: 0 })
|
||||||
|
id.value = ''
|
||||||
|
}
|
||||||
|
|
||||||
|
const save = async () => {
|
||||||
|
if (isUpdate.value) {
|
||||||
|
await updateDimension(id.value, form)
|
||||||
|
} else {
|
||||||
|
await addDimension(form)
|
||||||
|
}
|
||||||
|
visible.value = false
|
||||||
|
emit('success')
|
||||||
|
}
|
||||||
|
|
||||||
|
const onAdd = () => {
|
||||||
|
reset()
|
||||||
|
isUpdate.value = false
|
||||||
|
visible.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
const onUpdate = async (dimensionId: string) => {
|
||||||
|
reset()
|
||||||
|
isUpdate.value = true
|
||||||
|
id.value = dimensionId
|
||||||
|
const data = await getDimensionDetail(dimensionId)
|
||||||
|
Object.assign(form, data)
|
||||||
|
visible.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({ onAdd, onUpdate })
|
||||||
|
</script>
|
|
@ -0,0 +1,100 @@
|
||||||
|
<template>
|
||||||
|
<a-spin :loading="loading">
|
||||||
|
<a-descriptions :data="detailData" bordered>
|
||||||
|
<a-descriptions-item label="员工">
|
||||||
|
{{ data.userName }}
|
||||||
|
</a-descriptions-item>
|
||||||
|
<a-descriptions-item label="维度">
|
||||||
|
{{ data.dimensionName }}
|
||||||
|
</a-descriptions-item>
|
||||||
|
<a-descriptions-item label="周期">
|
||||||
|
{{ data.periodName }}
|
||||||
|
</a-descriptions-item>
|
||||||
|
<a-descriptions-item label="评分">
|
||||||
|
<a-tag color="blue" size="large">{{ data.score }}</a-tag>
|
||||||
|
</a-descriptions-item>
|
||||||
|
<a-descriptions-item label="AI评价" :span="2">
|
||||||
|
{{ data.aiComment }}
|
||||||
|
</a-descriptions-item>
|
||||||
|
</a-descriptions>
|
||||||
|
|
||||||
|
<!-- 反馈表单 -->
|
||||||
|
<a-divider orientation="left">评价反馈</a-divider>
|
||||||
|
<a-form ref="feedbackRef" :model="feedback" :rules="rules" layout="vertical">
|
||||||
|
<a-form-item label="是否有异议" field="level" required>
|
||||||
|
<a-radio-group v-model="feedback.level">
|
||||||
|
<a-radio :value="0">无异议</a-radio>
|
||||||
|
<a-radio :value="1">部分有异议</a-radio>
|
||||||
|
<a-radio :value="2">完全不同意</a-radio>
|
||||||
|
</a-radio-group>
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<a-form-item label="请说明理由" field="content" required>
|
||||||
|
<a-textarea
|
||||||
|
v-model="feedback.content"
|
||||||
|
:rows="4"
|
||||||
|
placeholder="请具体描述您对评价结果的看法..."
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<a-form-item>
|
||||||
|
<a-button type="primary" :loading="submitting" @click="handleSubmit">
|
||||||
|
提交反馈
|
||||||
|
</a-button>
|
||||||
|
</a-form-item>
|
||||||
|
</a-form>
|
||||||
|
</a-spin>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { computed, reactive, ref } from 'vue'
|
||||||
|
import { Message } from '@arco-design/web-vue'
|
||||||
|
import { submitFeedback } from '@/apis/performance'
|
||||||
|
import type { EvaluateResp, FeedbackReq } from '@/apis/performance/type'
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
data: EvaluateResp
|
||||||
|
}
|
||||||
|
|
||||||
|
const props = defineProps<Props>()
|
||||||
|
const emit = defineEmits<{
|
||||||
|
(e: 'feedback'): void
|
||||||
|
}>()
|
||||||
|
|
||||||
|
const loading = ref(false)
|
||||||
|
const submitting = ref(false)
|
||||||
|
const feedbackRef = ref()
|
||||||
|
|
||||||
|
const feedback = reactive<FeedbackReq>({
|
||||||
|
evaluateId: props.data.id,
|
||||||
|
level: 0,
|
||||||
|
content: '',
|
||||||
|
})
|
||||||
|
|
||||||
|
const rules = {
|
||||||
|
level: [{ required: true, message: '请选择异议等级' }],
|
||||||
|
content: [{ required: true, message: '请填写反馈内容' }],
|
||||||
|
}
|
||||||
|
|
||||||
|
const detailData = computed(() => [
|
||||||
|
{ label: '员工', value: props.data.userName },
|
||||||
|
{ label: '维度', value: props.data.dimensionName },
|
||||||
|
{ label: '周期', value: props.data.periodName },
|
||||||
|
{ label: '评分', value: props.data.score },
|
||||||
|
{ label: 'AI评价', value: props.data.aiComment },
|
||||||
|
])
|
||||||
|
|
||||||
|
const handleSubmit = async () => {
|
||||||
|
const ok = await feedbackRef.value?.validate()
|
||||||
|
if (ok) return
|
||||||
|
|
||||||
|
submitting.value = true
|
||||||
|
try {
|
||||||
|
await submitFeedback(feedback)
|
||||||
|
Message.success('反馈已提交')
|
||||||
|
emit('feedback')
|
||||||
|
} finally {
|
||||||
|
submitting.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -0,0 +1,18 @@
|
||||||
|
<template>
|
||||||
|
<a-menu
|
||||||
|
:default-selected-keys="['dimension']"
|
||||||
|
@menu-item-click="handleClick"
|
||||||
|
>
|
||||||
|
<a-menu-item key="dimension">绩效维度</a-menu-item>
|
||||||
|
<a-menu-item key="evaluate">员工评估</a-menu-item>
|
||||||
|
<a-menu-item key="my">我的绩效</a-menu-item>
|
||||||
|
</a-menu>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
const emit = defineEmits<{
|
||||||
|
(e: 'select', key: string): void
|
||||||
|
}>()
|
||||||
|
|
||||||
|
const handleClick = (key: string) => emit('select', key)
|
||||||
|
</script>
|
|
@ -0,0 +1,131 @@
|
||||||
|
<template>
|
||||||
|
<a-drawer
|
||||||
|
v-model:visible="visible"
|
||||||
|
:title="isUpdate ? '编辑细则' : '新增细则'"
|
||||||
|
:width="480"
|
||||||
|
@before-ok="handleSave"
|
||||||
|
@cancel="reset"
|
||||||
|
>
|
||||||
|
<a-form ref="formRef" :model="form" auto-label-width>
|
||||||
|
<a-form-item label="所属维度" field="dimensionId" required>
|
||||||
|
<a-select v-model="form.dimensionId" placeholder="请选择维度">
|
||||||
|
<a-option
|
||||||
|
v-for="item in dimensionOptions"
|
||||||
|
:key="item.id"
|
||||||
|
:value="item.id"
|
||||||
|
:label="item.name"
|
||||||
|
/>
|
||||||
|
</a-select>
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<a-form-item label="细则名称" field="name" required>
|
||||||
|
<a-input v-model="form.name" placeholder="如:持有基础资质证书" />
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<a-form-item label="评分规则描述" field="ruleDesc" required>
|
||||||
|
<a-textarea
|
||||||
|
v-model="form.ruleDesc"
|
||||||
|
:rows="4"
|
||||||
|
placeholder="详细说明评分标准"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<a-form-item label="满分" field="score" required>
|
||||||
|
<a-input-number v-model="form.score" :min="0" :precision="0" />
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<a-form-item label="权重" field="weight" required>
|
||||||
|
<a-input-number v-model="form.weight" :min="0" :max="100" />
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<a-form-item label="是否加分项" field="isExtra">
|
||||||
|
<a-switch v-model="form.isExtra" />
|
||||||
|
</a-form-item>
|
||||||
|
</a-form>
|
||||||
|
</a-drawer>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { onMounted, reactive, ref } from 'vue'
|
||||||
|
import { Message } from '@arco-design/web-vue'
|
||||||
|
import {
|
||||||
|
addRule,
|
||||||
|
getDimensionList,
|
||||||
|
getRuleDetail,
|
||||||
|
updateRule,
|
||||||
|
} from '@/apis/performance'
|
||||||
|
import type { DimensionResp, RuleAddReq, RuleUpdateReq } from '@/apis/performance/type'
|
||||||
|
|
||||||
|
const emit = defineEmits<{
|
||||||
|
(e: 'success'): void
|
||||||
|
}>()
|
||||||
|
|
||||||
|
const visible = ref(false)
|
||||||
|
const isUpdate = ref(false)
|
||||||
|
const id = ref('')
|
||||||
|
const formRef = ref()
|
||||||
|
const dimensionOptions = ref<DimensionResp[]>([])
|
||||||
|
|
||||||
|
const form = reactive<RuleAddReq>({
|
||||||
|
dimensionId: '',
|
||||||
|
name: '',
|
||||||
|
ruleDesc: '',
|
||||||
|
score: 100,
|
||||||
|
weight: 10,
|
||||||
|
isExtra: false,
|
||||||
|
})
|
||||||
|
|
||||||
|
const reset = () => {
|
||||||
|
formRef.value?.resetFields()
|
||||||
|
Object.assign(form, {
|
||||||
|
dimensionId: '',
|
||||||
|
name: '',
|
||||||
|
ruleDesc: '',
|
||||||
|
score: 100,
|
||||||
|
weight: 10,
|
||||||
|
isExtra: false,
|
||||||
|
})
|
||||||
|
id.value = ''
|
||||||
|
}
|
||||||
|
|
||||||
|
const openAdd = () => {
|
||||||
|
reset()
|
||||||
|
isUpdate.value = false
|
||||||
|
visible.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
const openUpdate = async (ruleId: string) => {
|
||||||
|
reset()
|
||||||
|
isUpdate.value = true
|
||||||
|
id.value = ruleId
|
||||||
|
const detail = await getRuleDetail(ruleId)
|
||||||
|
Object.assign(form, detail)
|
||||||
|
visible.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleSave = async () => {
|
||||||
|
const ok = await formRef.value?.validate()
|
||||||
|
if (ok) return false
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (isUpdate.value) {
|
||||||
|
await updateRule(id.value, form as RuleUpdateReq)
|
||||||
|
Message.success('细则已更新')
|
||||||
|
} else {
|
||||||
|
await addRule(form)
|
||||||
|
Message.success('细则已新增')
|
||||||
|
}
|
||||||
|
visible.value = false
|
||||||
|
emit('success')
|
||||||
|
return true
|
||||||
|
} catch {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
dimensionOptions.value = await getDimensionList()
|
||||||
|
})
|
||||||
|
|
||||||
|
defineExpose({ openAdd, openUpdate })
|
||||||
|
</script>
|
|
@ -0,0 +1,67 @@
|
||||||
|
<template>
|
||||||
|
<a-modal
|
||||||
|
v-model:visible="visible"
|
||||||
|
title="细则管理"
|
||||||
|
:width="800"
|
||||||
|
@before-ok="handleSave"
|
||||||
|
@cancel="reset"
|
||||||
|
>
|
||||||
|
<a-table :data="rules" :columns="columns" row-key="id">
|
||||||
|
<template #action="{ record }">
|
||||||
|
<a-space>
|
||||||
|
<a-button type="text" @click="RuleDrawerRef?.openUpdate(record.id)">
|
||||||
|
编辑
|
||||||
|
</a-button>
|
||||||
|
<a-button type="text" status="danger" @click="handleDelete(record.id)">
|
||||||
|
删除
|
||||||
|
</a-button>
|
||||||
|
</a-space>
|
||||||
|
</template>
|
||||||
|
</a-table>
|
||||||
|
|
||||||
|
<a-button type="primary" @click="RuleDrawerRef?.openAdd()">
|
||||||
|
<icon-plus /> 新增细则
|
||||||
|
</a-button>
|
||||||
|
</a-modal>
|
||||||
|
|
||||||
|
<RuleDrawer ref="RuleDrawerRef" @success="load" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { onMounted, ref } from 'vue'
|
||||||
|
import RuleDrawer from './RuleDrawer.vue'
|
||||||
|
import { deleteRule, getRuleList } from '@/apis/performance'
|
||||||
|
import type { RuleResp } from '@/apis/performance/type'
|
||||||
|
import { Message } from '@arco-design/web-vue'
|
||||||
|
|
||||||
|
const visible = ref(false)
|
||||||
|
const rules = ref<RuleResp[]>([])
|
||||||
|
const RuleDrawerRef = ref()
|
||||||
|
|
||||||
|
const columns = [
|
||||||
|
{ title: '细则名称', dataIndex: 'name' },
|
||||||
|
{ title: '评分规则描述', dataIndex: 'ruleDesc' },
|
||||||
|
{ title: '满分', dataIndex: 'score' },
|
||||||
|
{ title: '权重', dataIndex: 'weight' },
|
||||||
|
{ title: '是否加分项', dataIndex: 'isExtra', render: ({ record }) => record.isExtra ? '是' : '否' },
|
||||||
|
{ title: '操作', slotName: 'action' },
|
||||||
|
]
|
||||||
|
|
||||||
|
const open = async (dimensionId: string) => {
|
||||||
|
visible.value = true
|
||||||
|
rules.value = await getRuleList(dimensionId)
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleDelete = async (id: string) => {
|
||||||
|
await deleteRule(id)
|
||||||
|
Message.success('删除成功')
|
||||||
|
load()
|
||||||
|
}
|
||||||
|
|
||||||
|
const load = async () => {
|
||||||
|
// 重新加载规则列表
|
||||||
|
rules.value = await getRuleList(dimensionId.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({ open })
|
||||||
|
</script>
|
|
@ -0,0 +1,72 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<a-card title="绩效维度管理">
|
||||||
|
<template #extra>
|
||||||
|
<a-button type="primary" @click="DimensionDrawerRef?.onAdd()">
|
||||||
|
<icon-plus /> 添加维度
|
||||||
|
</a-button>
|
||||||
|
</template>
|
||||||
|
<a-table :data="dimensions" :columns="columns" row-key="id">
|
||||||
|
<template #status="{ record }">
|
||||||
|
<a-tag :color="record.status === 0 ? 'green' : 'red'">
|
||||||
|
{{ record.status === 0 ? '启用' : '禁用' }}
|
||||||
|
</a-tag>
|
||||||
|
</template>
|
||||||
|
<template #action="{ record }">
|
||||||
|
<a-space>
|
||||||
|
<a-button type="text" @click="DimensionDrawerRef?.onUpdate(record.id)">
|
||||||
|
编辑
|
||||||
|
</a-button>
|
||||||
|
<a-button type="text" status="danger" @click="handleDelete(record.id)">
|
||||||
|
删除
|
||||||
|
</a-button>
|
||||||
|
<a-button type="text" @click="openRuleList(record.id)">
|
||||||
|
管理细则
|
||||||
|
</a-button>
|
||||||
|
</a-space>
|
||||||
|
</template>
|
||||||
|
</a-table>
|
||||||
|
</a-card>
|
||||||
|
|
||||||
|
<!-- 维度抽屉 -->
|
||||||
|
<DimensionDrawer ref="DimensionDrawerRef" @success="load" />
|
||||||
|
<!-- 细则列表 -->
|
||||||
|
<RuleList ref="RuleListRef" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, onMounted } from 'vue'
|
||||||
|
import { getDimensionList, deleteDimension } from '@/apis/performance'
|
||||||
|
import DimensionDrawer from './components/DimensionDrawer.vue'
|
||||||
|
import RuleList from './components/RuleList.vue'
|
||||||
|
import type { DimensionResp } from '@/apis/performance/type'
|
||||||
|
|
||||||
|
const dimensions = ref<DimensionResp[]>([])
|
||||||
|
const DimensionDrawerRef = ref()
|
||||||
|
const RuleListRef = ref()
|
||||||
|
|
||||||
|
const columns = [
|
||||||
|
{ title: '维度名称', dataIndex: 'name' },
|
||||||
|
{ title: '权重', dataIndex: 'weight', render: ({ record }) => `${record.weight}%` },
|
||||||
|
{ title: '细则数量', dataIndex: 'ruleCount' },
|
||||||
|
{ title: '状态', slotName: 'status' },
|
||||||
|
{ title: '操作', slotName: 'action' },
|
||||||
|
]
|
||||||
|
|
||||||
|
const load = async () => {
|
||||||
|
const response=await getDimensionList()
|
||||||
|
dimensions.value = await getDimensionList().data||[]
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(load)
|
||||||
|
|
||||||
|
const handleDelete = async (id: string) => {
|
||||||
|
await deleteDimension(id)
|
||||||
|
load()
|
||||||
|
}
|
||||||
|
|
||||||
|
const openRuleList = (dimensionId: string) => {
|
||||||
|
RuleListRef.value.open(dimensionId)
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -0,0 +1,70 @@
|
||||||
|
<template>
|
||||||
|
<a-card title="员工绩效评估">
|
||||||
|
<a-form layout="inline" style="margin-bottom: 16px">
|
||||||
|
<a-form-item label="绩效周期">
|
||||||
|
<a-select v-model="query.periodId" placeholder="请选择周期" allow-clear>
|
||||||
|
<a-option v-for="p in periods" :key="p.id" :value="p.id">{{ p.name }}</a-option>
|
||||||
|
</a-select>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item label="维度">
|
||||||
|
<a-select v-model="query.dimensionId" placeholder="请选择维度" allow-clear>
|
||||||
|
<a-option v-for="d in dimensions" :key="d.id" :value="d.id">{{ d.name }}</a-option>
|
||||||
|
</a-select>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item>
|
||||||
|
<a-input v-model="query.keyword" placeholder="姓名/工号" />
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item>
|
||||||
|
<a-button type="primary" @click="load">查询</a-button>
|
||||||
|
</a-form-item>
|
||||||
|
</a-form>
|
||||||
|
|
||||||
|
<a-table :data="data" :columns="columns" row-key="id">
|
||||||
|
<template #action="{ record }">
|
||||||
|
<a-button type="text" @click="openEvaluate(record)">
|
||||||
|
开始评估
|
||||||
|
</a-button>
|
||||||
|
</template>
|
||||||
|
</a-table>
|
||||||
|
</a-card>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { onMounted, ref } from 'vue'
|
||||||
|
import { getDimensionList, getEvaluatePage, getPeriodList, startEvaluate } from '@/apis/performance'
|
||||||
|
import type { EvaluateQuery, EvaluateResp } from '@/apis/performance/type'
|
||||||
|
|
||||||
|
const periods = ref([])
|
||||||
|
const dimensions = ref([])
|
||||||
|
const query = ref<EvaluateQuery>({})
|
||||||
|
const data = ref<EvaluateResp[]>([])
|
||||||
|
|
||||||
|
const columns = [
|
||||||
|
{ title: '员工', dataIndex: 'userName' },
|
||||||
|
{ title: '维度', dataIndex: 'dimensionName' },
|
||||||
|
{ title: '周期', dataIndex: 'periodName' },
|
||||||
|
{ title: '评分', dataIndex: 'score' },
|
||||||
|
{ title: '操作', slotName: 'action' },
|
||||||
|
]
|
||||||
|
|
||||||
|
const load = async () => {
|
||||||
|
data.value = await getEvaluatePage(query.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
periods.value = await getPeriodList()
|
||||||
|
dimensions.value = await getDimensionList()
|
||||||
|
load()
|
||||||
|
})
|
||||||
|
|
||||||
|
const openEvaluate = async (row: EvaluateResp) => {
|
||||||
|
await startEvaluate({
|
||||||
|
userId: row.userId,
|
||||||
|
dimensionId: row.dimensionId,
|
||||||
|
ruleId: row.ruleId,
|
||||||
|
periodId: row.periodId,
|
||||||
|
})
|
||||||
|
Message.success('评估已启动')
|
||||||
|
load()
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -0,0 +1,19 @@
|
||||||
|
<template>
|
||||||
|
<GiPageLayout>
|
||||||
|
<template #left>
|
||||||
|
<PerformanceMenu @select="handleSelectMenu" />
|
||||||
|
</template>
|
||||||
|
<router-view />
|
||||||
|
</GiPageLayout>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { useRouter } from 'vue-router'
|
||||||
|
import PerformanceMenu from './components/PerformanceMenu.vue'
|
||||||
|
|
||||||
|
const router = useRouter()
|
||||||
|
|
||||||
|
const handleSelectMenu = (key: string) => {
|
||||||
|
router.push(`/performance/${key}`)
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -0,0 +1,48 @@
|
||||||
|
<template>
|
||||||
|
<a-card title="我的绩效">
|
||||||
|
<a-table :data="data" :columns="columns" row-key="id">
|
||||||
|
<template #action="{ record }">
|
||||||
|
<a-button type="text" @click="openDetail(record)">查看详情</a-button>
|
||||||
|
</template>
|
||||||
|
</a-table>
|
||||||
|
</a-card>
|
||||||
|
|
||||||
|
<a-modal v-model:visible="visible" title="绩效详情">
|
||||||
|
<EvaluateDetail v-if="selected" :data="selected" @feedback="handleFeedback" />
|
||||||
|
</a-modal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { onMounted, ref } from 'vue'
|
||||||
|
import EvaluateDetail from './components/EvaluateDetail.vue'
|
||||||
|
import { getMyEvaluate } from '@/apis/performance'
|
||||||
|
import type { EvaluateResp } from '@/apis/performance/type'
|
||||||
|
|
||||||
|
const data = ref<EvaluateResp[]>([])
|
||||||
|
const visible = ref(false)
|
||||||
|
const selected = ref<EvaluateResp>()
|
||||||
|
|
||||||
|
const columns = [
|
||||||
|
{ title: '维度', dataIndex: 'dimensionName' },
|
||||||
|
{ title: '周期', dataIndex: 'periodName' },
|
||||||
|
{ title: '评分', dataIndex: 'score' },
|
||||||
|
{ title: '操作', slotName: 'action' },
|
||||||
|
]
|
||||||
|
|
||||||
|
const load = async () => {
|
||||||
|
const response = await getMyEvaluate()
|
||||||
|
data.value = response.data?.list || []
|
||||||
|
}
|
||||||
|
|
||||||
|
const openDetail = (row: EvaluateResp) => {
|
||||||
|
selected.value = row
|
||||||
|
visible.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleFeedback = () => {
|
||||||
|
visible.value = false
|
||||||
|
load()
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(load)
|
||||||
|
</script>
|
|
@ -0,0 +1,61 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<a-card title="绩效细则管理">
|
||||||
|
<template #extra>
|
||||||
|
<a-button type="primary" @click="RuleDrawerRef?.openAdd()">
|
||||||
|
<icon-plus /> 新增细则
|
||||||
|
</a-button>
|
||||||
|
</template>
|
||||||
|
<a-table :data="rules" :columns="columns" row-key="id">
|
||||||
|
<template #action="{ record }">
|
||||||
|
<a-space>
|
||||||
|
<a-button type="text" @click="RuleDrawerRef?.openUpdate(record.id)">
|
||||||
|
编辑
|
||||||
|
</a-button>
|
||||||
|
<a-button type="text" status="danger" @click="handleDelete(record.id)">
|
||||||
|
删除
|
||||||
|
</a-button>
|
||||||
|
</a-space>
|
||||||
|
</template>
|
||||||
|
</a-table>
|
||||||
|
</a-card>
|
||||||
|
|
||||||
|
<!-- 细则抽屉 -->
|
||||||
|
<RuleDrawer ref="RuleDrawerRef" @success="load" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { onMounted, ref } from 'vue'
|
||||||
|
import { Message } from '@arco-design/web-vue'
|
||||||
|
import RuleDrawer from './components/RuleDrawer.vue'
|
||||||
|
import { deleteRule, getRuleList } from '@/apis/performance'
|
||||||
|
import type { RuleResp } from '@/apis/performance/type'
|
||||||
|
|
||||||
|
const rules = ref<RuleResp[]>([])
|
||||||
|
const RuleDrawerRef = ref()
|
||||||
|
|
||||||
|
const columns = [
|
||||||
|
{ title: '细则名称', dataIndex: 'name' },
|
||||||
|
{ title: '评分规则描述', dataIndex: 'ruleDesc' },
|
||||||
|
{ title: '满分', dataIndex: 'score' },
|
||||||
|
{ title: '权重', dataIndex: 'weight' },
|
||||||
|
{ title: '是否加分项', dataIndex: 'isExtra', render: ({ record }) => record.isExtra ? '是' : '否' },
|
||||||
|
{ title: '操作', slotName: 'action' },
|
||||||
|
]
|
||||||
|
|
||||||
|
const load = async (dimensionId: string) => {
|
||||||
|
rules.value = await getRuleList(dimensionId)
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
// 假设默认加载某个维度的细则
|
||||||
|
load('default-dimension-id')
|
||||||
|
})
|
||||||
|
|
||||||
|
const handleDelete = async (id: string) => {
|
||||||
|
await deleteRule(id)
|
||||||
|
Message.success('删除成功')
|
||||||
|
load('default-dimension-id') // 重新加载数据
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -0,0 +1,229 @@
|
||||||
|
<template>
|
||||||
|
<div class="salary-management">
|
||||||
|
<GiPageLayout>
|
||||||
|
<template #header>
|
||||||
|
<a-row justify="space-between" align="center">
|
||||||
|
<a-col>
|
||||||
|
<h1>工资管理系统</h1>
|
||||||
|
</a-col>
|
||||||
|
<a-col>
|
||||||
|
<a-space>
|
||||||
|
<a-button type="primary" @click="handleAdd">
|
||||||
|
<template #icon><icon-plus /></template>
|
||||||
|
新建工资单
|
||||||
|
</a-button>
|
||||||
|
<a-button @click="handleExport">
|
||||||
|
<template #icon><icon-download /></template>
|
||||||
|
导出Excel
|
||||||
|
</a-button>
|
||||||
|
</a-space>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<a-card>
|
||||||
|
<a-row :gutter="16" class="search-section">
|
||||||
|
<a-col :span="6">
|
||||||
|
<a-input
|
||||||
|
v-model="searchParams.keyword"
|
||||||
|
placeholder="搜索员工姓名/工号"
|
||||||
|
allow-clear
|
||||||
|
/>
|
||||||
|
</a-col>
|
||||||
|
<a-col :span="6">
|
||||||
|
<a-select
|
||||||
|
v-model="searchParams.employeeType"
|
||||||
|
placeholder="员工类型"
|
||||||
|
allow-clear
|
||||||
|
>
|
||||||
|
<a-option value="intern">实习生</a-option>
|
||||||
|
<a-option value="fulltime">正式员工</a-option>
|
||||||
|
<a-option value="parttime">兼职员工</a-option>
|
||||||
|
</a-select>
|
||||||
|
</a-col>
|
||||||
|
<a-col :span="6">
|
||||||
|
<a-range-picker
|
||||||
|
v-model="searchParams.dateRange"
|
||||||
|
style="width: 100%"
|
||||||
|
/>
|
||||||
|
</a-col>
|
||||||
|
<a-col :span="6">
|
||||||
|
<a-space>
|
||||||
|
<a-button type="primary" @click="handleSearch">查询</a-button>
|
||||||
|
<a-button @click="handleReset">重置</a-button>
|
||||||
|
</a-space>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
|
||||||
|
<a-table
|
||||||
|
:data="tableData"
|
||||||
|
:columns="columns"
|
||||||
|
:loading="loading"
|
||||||
|
row-key="id"
|
||||||
|
:scroll="{ x: 1500 }"
|
||||||
|
>
|
||||||
|
<template #action="{ record }">
|
||||||
|
<a-space>
|
||||||
|
<a-button type="text" @click="handleEdit(record)">编辑</a-button>
|
||||||
|
<a-button type="text" @click="handleDetail(record)">详情</a-button>
|
||||||
|
<a-button type="text" status="danger" @click="handleDelete(record)">删除</a-button>
|
||||||
|
</a-space>
|
||||||
|
</template>
|
||||||
|
</a-table>
|
||||||
|
</a-card>
|
||||||
|
</GiPageLayout>
|
||||||
|
|
||||||
|
<SalaryFormDrawer
|
||||||
|
v-model:visible="drawerVisible"
|
||||||
|
:data="currentData"
|
||||||
|
:mode="drawerMode"
|
||||||
|
@success="handleSuccess"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<SalaryDetailModal
|
||||||
|
v-model:visible="detailVisible"
|
||||||
|
:data="currentData"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { onMounted, reactive, ref } from 'vue'
|
||||||
|
import { Message, Modal } from '@arco-design/web-vue'
|
||||||
|
import SalaryFormDrawer from './components/SalaryFormDrawer.vue'
|
||||||
|
import SalaryDetailModal from './components/SalaryDetailModal.vue'
|
||||||
|
import type { SalaryRecord } from './types'
|
||||||
|
|
||||||
|
const loading = ref(false)
|
||||||
|
const drawerVisible = ref(false)
|
||||||
|
const detailVisible = ref(false)
|
||||||
|
const drawerMode = ref<'add' | 'edit'>('add')
|
||||||
|
const currentData = ref<SalaryRecord | null>(null)
|
||||||
|
|
||||||
|
const searchParams = reactive({
|
||||||
|
keyword: '',
|
||||||
|
employeeType: '',
|
||||||
|
dateRange: [],
|
||||||
|
})
|
||||||
|
|
||||||
|
const tableData = ref<SalaryRecord[]>([])
|
||||||
|
|
||||||
|
const columns = [
|
||||||
|
{ title: '员工姓名', dataIndex: 'employeeName', fixed: 'left', width: 100 },
|
||||||
|
{ title: '员工类型', dataIndex: 'employeeType', width: 100 },
|
||||||
|
{ title: '项目名称', dataIndex: 'projectName', width: 150 },
|
||||||
|
{ title: '工作天数', dataIndex: 'workDays', width: 80 },
|
||||||
|
{ title: '基本工资', dataIndex: 'baseSalary', width: 100 },
|
||||||
|
{ title: '绩效奖金', dataIndex: 'performanceBonus', width: 100 },
|
||||||
|
{ title: '各类补助', dataIndex: 'allowances', width: 100 },
|
||||||
|
{ title: '应发总额', dataIndex: 'totalPayable', width: 100 },
|
||||||
|
{ title: '实发金额', dataIndex: 'netPay', width: 100 },
|
||||||
|
{ title: '状态', dataIndex: 'status', width: 80 },
|
||||||
|
{ title: '创建时间', dataIndex: 'createdAt', width: 150 },
|
||||||
|
{ title: '操作', slotName: 'action', fixed: 'right', width: 150 },
|
||||||
|
]
|
||||||
|
|
||||||
|
const loadData = async () => {
|
||||||
|
loading.value = true
|
||||||
|
try {
|
||||||
|
// 模拟数据
|
||||||
|
tableData.value = [
|
||||||
|
{
|
||||||
|
id: '1',
|
||||||
|
employeeId: 'E001',
|
||||||
|
employeeName: '张三',
|
||||||
|
employeeType: 'intern',
|
||||||
|
idCard: '123456789012345678',
|
||||||
|
phone: '13800000000',
|
||||||
|
bankCard: '6222021234567890',
|
||||||
|
bankName: '中国银行',
|
||||||
|
projectName: '海上风电项目A',
|
||||||
|
projectPeriod: '2025-06',
|
||||||
|
workDays: 22,
|
||||||
|
offshoreDays: 5,
|
||||||
|
baseSalary: 3500,
|
||||||
|
baseSalaryStandard: 3500,
|
||||||
|
performanceBonus: 2200,
|
||||||
|
allowances: 660,
|
||||||
|
performanceItems: [],
|
||||||
|
allowanceItems: [],
|
||||||
|
totalPayable: 6360,
|
||||||
|
deductions: 0,
|
||||||
|
netPay: 6360,
|
||||||
|
status: 'approved',
|
||||||
|
approvalFlow: [],
|
||||||
|
salaryMonth: '2025-07',
|
||||||
|
createdAt: '2025-07-01',
|
||||||
|
updatedAt: '2025-07-01',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleAdd = () => {
|
||||||
|
drawerMode.value = 'add'
|
||||||
|
currentData.value = null
|
||||||
|
drawerVisible.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleEdit = (record: SalaryRecord) => {
|
||||||
|
drawerMode.value = 'edit'
|
||||||
|
currentData.value = record
|
||||||
|
drawerVisible.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleDetail = (record: SalaryRecord) => {
|
||||||
|
currentData.value = record
|
||||||
|
detailVisible.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleDelete = async (_record: SalaryRecord) => {
|
||||||
|
try {
|
||||||
|
await Modal.confirm({
|
||||||
|
title: '确认删除',
|
||||||
|
content: '确定要删除这条记录吗?',
|
||||||
|
})
|
||||||
|
Message.success('删除成功')
|
||||||
|
loadData()
|
||||||
|
} catch {
|
||||||
|
// 用户取消
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleSearch = () => {
|
||||||
|
loadData()
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleReset = () => {
|
||||||
|
searchParams.keyword = ''
|
||||||
|
searchParams.employeeType = ''
|
||||||
|
searchParams.dateRange = []
|
||||||
|
loadData()
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleExport = () => {
|
||||||
|
// 导出Excel逻辑
|
||||||
|
Message.success('导出功能开发中...')
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleSuccess = () => {
|
||||||
|
drawerVisible.value = false
|
||||||
|
loadData()
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
loadData()
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.salary-management {
|
||||||
|
padding: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-section {
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
</style>
|
Loading…
Reference in New Issue