类型调整、员工表去除多余按键、测算页面红绿对换

This commit is contained in:
lzm
2026-05-21 10:40:37 +08:00
parent 4a0ff37963
commit 865ef2aebe
10 changed files with 222 additions and 161 deletions

View File

@@ -12,6 +12,7 @@ export interface ProjectProfitVO {
subcontractPlanningAmount?: number subcontractPlanningAmount?: number
specialSubcontractPlanningAmount?: number specialSubcontractPlanningAmount?: number
sourceCoopSubcontractPlanningAmount?: number sourceCoopSubcontractPlanningAmount?: number
comprehensiveSubcontractPlanningAmount?: number
majorOutputValue?: number majorOutputValue?: number
majorExpectedPerformance?: number majorExpectedPerformance?: number
innovationOutputRate?: number innovationOutputRate?: number

View File

@@ -142,7 +142,7 @@
width="180" width="180"
:formatter="dateFormatter" :formatter="dateFormatter"
/> />
<el-table-column align="center" fixed="right" label="操作" width="160"> <el-table-column align="center" fixed="right" label="操作" width="100">
<template #default="scope"> <template #default="scope">
<el-button <el-button
v-hasPermi="['tjt:employee:update']" v-hasPermi="['tjt:employee:update']"
@@ -152,14 +152,6 @@
> >
编辑 编辑
</el-button> </el-button>
<el-button
v-hasPermi="['tjt:employee:delete']"
link
type="danger"
@click="handleDelete(scope.row.id)"
>
删除
</el-button>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
@@ -495,15 +487,6 @@ const submitForm = async () => {
} }
} }
const handleDelete = async (id: number) => {
try {
await message.delConfirm()
await EmployeeApi.deleteEmployee(id)
message.success(t('common.delSuccess'))
await getList()
} catch {}
}
let activatedOnce = false let activatedOnce = false
onMounted(async () => { onMounted(async () => {

View File

@@ -292,6 +292,7 @@ import {
formatAmountText, formatAmountText,
fromPercentValue, fromPercentValue,
getOwnershipTypeLabel, getOwnershipTypeLabel,
OUTPUT_SPLIT_SPECIALTY,
OUTPUT_SPLIT_SPECIALTY_OPTIONS, OUTPUT_SPLIT_SPECIALTY_OPTIONS,
QUARTER_OPTIONS, QUARTER_OPTIONS,
toPercentValue toPercentValue
@@ -299,15 +300,7 @@ import {
defineOptions({ name: 'TjtOutputSplit' }) defineOptions({ name: 'TjtOutputSplit' })
type AnnualCategoryKey = type AnnualCategoryKey = (typeof OUTPUT_SPLIT_SPECIALTY)[keyof typeof OUTPUT_SPLIT_SPECIALTY]
| 'project_lead'
| 'arch'
| 'decor'
| 'struct'
| 'water'
| 'elec'
| 'hvac'
| 'digital'
interface QuarterYearRow { interface QuarterYearRow {
distributionYear: number distributionYear: number
@@ -315,14 +308,14 @@ interface QuarterYearRow {
} }
const annualCategoryOptions: { label: string; value: AnnualCategoryKey }[] = [ const annualCategoryOptions: { label: string; value: AnnualCategoryKey }[] = [
{ label: '项目经理/工程负责人', value: 'project_lead' }, { label: '项目经理/工程负责人', value: OUTPUT_SPLIT_SPECIALTY.projectLead },
{ label: '建筑专业', value: 'arch' }, { label: '建筑专业', value: OUTPUT_SPLIT_SPECIALTY.arch },
{ label: '装修专业', value: 'decor' }, { label: '装修专业', value: OUTPUT_SPLIT_SPECIALTY.decor },
{ label: '结构专业', value: 'struct' }, { label: '结构专业', value: OUTPUT_SPLIT_SPECIALTY.struct },
{ label: '水专业', value: 'water' }, { label: '水专业', value: OUTPUT_SPLIT_SPECIALTY.water },
{ label: '电气专业', value: 'elec' }, { label: '电气专业', value: OUTPUT_SPLIT_SPECIALTY.elec },
{ label: '暖通专业', value: 'hvac' }, { label: '暖通专业', value: OUTPUT_SPLIT_SPECIALTY.hvac },
{ label: '数字化设计专业', value: 'digital' } { label: '数字化设计专业', value: OUTPUT_SPLIT_SPECIALTY.digital }
] ]
const message = useMessage() const message = useMessage()
@@ -339,7 +332,7 @@ const currentPlanning = ref<PlanningApi.ProjectPlanningVO>()
const formData = ref<OutputSplitApi.ProjectOutputSplitVO>() const formData = ref<OutputSplitApi.ProjectOutputSplitVO>()
const editForm = ref<OutputSplitApi.ProjectOutputSplitVO>() const editForm = ref<OutputSplitApi.ProjectOutputSplitVO>()
const quarterRows = ref<QuarterYearRow[]>([]) const quarterRows = ref<QuarterYearRow[]>([])
const selectedAnnualCategory = ref<AnnualCategoryKey>('project_lead') const selectedAnnualCategory = ref<AnnualCategoryKey>(OUTPUT_SPLIT_SPECIALTY.projectLead)
const dialogVisible = ref(false) const dialogVisible = ref(false)
const queryFormRef = ref() const queryFormRef = ref()
const projectTableRef = ref() const projectTableRef = ref()
@@ -438,7 +431,7 @@ const annualCategoryMeta = computed(() => {
if (!model || !option) { if (!model || !option) {
return { label: '-', ratio: 0, totalAmount: 0 } return { label: '-', ratio: 0, totalAmount: 0 }
} }
if (selectedAnnualCategory.value === 'project_lead') { if (selectedAnnualCategory.value === OUTPUT_SPLIT_SPECIALTY.projectLead) {
const ratio = Number(toNumeric(model.projectLeadRatio).toFixed(4)) const ratio = Number(toNumeric(model.projectLeadRatio).toFixed(4))
return { return {
label: option.label, label: option.label,

View File

@@ -301,7 +301,7 @@
<el-table-column align="center" label="设计部位" min-width="120" fixed="left"> <el-table-column align="center" label="设计部位" min-width="120" fixed="left">
<template #default="{ row }"> <template #default="{ row }">
<el-tooltip <el-tooltip
:content="row.designPart" :content="getDesignPartLabel(row.designPart)"
:disabled="!hasValue(row.designPart)" :disabled="!hasValue(row.designPart)"
placement="top" placement="top"
> >
@@ -581,7 +581,7 @@
{{ activeRemarkRow.sortNo || '-' }} {{ activeRemarkRow.sortNo || '-' }}
</el-descriptions-item> </el-descriptions-item>
<el-descriptions-item label="设计部位"> <el-descriptions-item label="设计部位">
{{ activeRemarkRow.designPart || '-' }} {{ getDesignPartLabel(activeRemarkRow.designPart) }}
</el-descriptions-item> </el-descriptions-item>
<el-descriptions-item label="设计内容/设计类型"> <el-descriptions-item label="设计内容/设计类型">
{{ activeRemarkRow.buildingType || '-' }} {{ activeRemarkRow.buildingType || '-' }}
@@ -621,6 +621,7 @@ import {
fromPercentValue, fromPercentValue,
getCalculationRatioDefaultPercent, getCalculationRatioDefaultPercent,
getCalculationRatioLabel, getCalculationRatioLabel,
getDesignPartLabel,
getOwnershipTypeLabel, getOwnershipTypeLabel,
getReviewOutsourceDefaultPercent, getReviewOutsourceDefaultPercent,
isComprehensiveOwnership, isComprehensiveOwnership,

View File

@@ -105,16 +105,21 @@
{{ formatAmountText(scope.row.comprehensivePlanningAmount) }} {{ formatAmountText(scope.row.comprehensivePlanningAmount) }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column align="center" label="专项分包人工成本(元)" width="170"> <el-table-column align="center" label="专项分包-专业所人工成本(元)" width="210">
<template #default="scope"> <template #default="scope">
{{ formatAmountText(scope.row.specialSubcontractPlanningAmount) }} {{ formatAmountText(scope.row.specialSubcontractPlanningAmount) }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column align="center" label="源头合作分包人工成本(元)" width="200"> <el-table-column align="center" label="专项分包-源头合作分包人工成本(元)" width="250">
<template #default="scope"> <template #default="scope">
{{ formatAmountText(scope.row.sourceCoopSubcontractPlanningAmount) }} {{ formatAmountText(scope.row.sourceCoopSubcontractPlanningAmount) }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column align="center" label="专项分包-综合所人工成本(元)" width="230">
<template #default="scope">
{{ formatAmountText(scope.row.comprehensiveSubcontractPlanningAmount) }}
</template>
</el-table-column>
<el-table-column align="center" label="专业所考核产值(元)" width="150"> <el-table-column align="center" label="专业所考核产值(元)" width="150">
<template #default="scope"> <template #default="scope">
{{ formatAmountText(scope.row.majorOutputValue) }} {{ formatAmountText(scope.row.majorOutputValue) }}
@@ -198,12 +203,15 @@
<el-descriptions-item label="综合所人工成本(元)"> <el-descriptions-item label="综合所人工成本(元)">
{{ formatAmountText(currentProfit.comprehensivePlanningAmount) }} {{ formatAmountText(currentProfit.comprehensivePlanningAmount) }}
</el-descriptions-item> </el-descriptions-item>
<el-descriptions-item label="专项分包人工成本(元)"> <el-descriptions-item label="专项分包-专业所人工成本(元)">
{{ formatAmountText(currentProfit.specialSubcontractPlanningAmount) }} {{ formatAmountText(currentProfit.specialSubcontractPlanningAmount) }}
</el-descriptions-item> </el-descriptions-item>
<el-descriptions-item label="源头合作分包人工成本(元)"> <el-descriptions-item label="专项分包-源头合作分包人工成本(元)">
{{ formatAmountText(currentProfit.sourceCoopSubcontractPlanningAmount) }} {{ formatAmountText(currentProfit.sourceCoopSubcontractPlanningAmount) }}
</el-descriptions-item> </el-descriptions-item>
<el-descriptions-item label="专项分包-综合所人工成本(元)">
{{ formatAmountText(currentProfit.comprehensiveSubcontractPlanningAmount) }}
</el-descriptions-item>
<el-descriptions-item label="专业所考核产值(元)"> <el-descriptions-item label="专业所考核产值(元)">
{{ formatAmountText(currentProfit.majorOutputValue) }} {{ formatAmountText(currentProfit.majorOutputValue) }}
</el-descriptions-item> </el-descriptions-item>
@@ -453,10 +461,10 @@ const submitProfitForm = async () => {
const profitLossClass = (value?: number) => { const profitLossClass = (value?: number) => {
if ((value || 0) > 0) { if ((value || 0) > 0) {
return 'text-[var(--el-color-danger)] font-600' return 'text-[var(--el-color-success)] font-600'
} }
if ((value || 0) < 0) { if ((value || 0) < 0) {
return 'text-[var(--el-color-success)] font-600' return 'text-[var(--el-color-danger)] font-600'
} }
return 'text-[var(--el-text-color-primary)]' return 'text-[var(--el-text-color-primary)]'
} }

View File

@@ -139,13 +139,13 @@
<el-col :span="12"> <el-col :span="12">
<el-form-item :label="statusReasonLabel" :prop="statusReasonProp"> <el-form-item :label="statusReasonLabel" :prop="statusReasonProp">
<el-input <el-input
v-if="formData.projectStatus === '暂停'" v-if="formData.projectStatus === PROJECT_STATUS.paused"
v-model="formData.pauseReason" v-model="formData.pauseReason"
maxlength="255" maxlength="255"
placeholder="请输入暂停原因" placeholder="请输入暂停原因"
/> />
<el-input <el-input
v-else-if="formData.projectStatus === '中止'" v-else-if="formData.projectStatus === PROJECT_STATUS.terminated"
v-model="formData.terminateReason" v-model="formData.terminateReason"
maxlength="255" maxlength="255"
placeholder="请输入中止原因" placeholder="请输入中止原因"
@@ -276,37 +276,19 @@
import type { FormRules } from 'element-plus' import type { FormRules } from 'element-plus'
import * as EmployeeApi from '@/api/tjt/employee' import * as EmployeeApi from '@/api/tjt/employee'
import * as ProjectApi from '@/api/tjt/project' import * as ProjectApi from '@/api/tjt/project'
import {
DEFAULT_INNOVATION_OUTPUT_RATE,
OUTPUT_SPLIT_ROLE,
PROJECT_CATEGORY_OPTIONS,
PROJECT_STATUS,
PROJECT_STATUS_OPTIONS,
PROJECT_TYPE_OPTIONS
} from '@/views/tjt/shared/planning'
defineOptions({ name: 'TjtProjectForm' }) defineOptions({ name: 'TjtProjectForm' })
const ROLE_PROJECT_MANAGER = 'project_manager' const ROLE_PROJECT_MANAGER = OUTPUT_SPLIT_ROLE.projectManager
const ROLE_ENGINEERING_PRINCIPAL = 'engineering_principal' const ROLE_ENGINEERING_PRINCIPAL = OUTPUT_SPLIT_ROLE.engineeringPrincipal
const PROJECT_TYPE_OPTIONS = [
{ label: '建筑工程', value: '建筑工程' },
{ label: '精装工程', value: '精装工程' },
{ label: '综合工程', value: '综合工程' },
{ label: '专项设计', value: '专项设计' },
{ label: 'BIM设计', value: 'BIM设计' },
{ label: '其他', value: '其他' }
]
const PROJECT_CATEGORY_OPTIONS = [
{ label: '住宅', value: '住宅' },
{ label: '公建', value: '公建' },
{ label: '工业', value: '工业' },
{ label: '园林景观', value: '园林景观' },
{ label: '其他', value: '其他' }
]
const PROJECT_STATUS_OPTIONS = [
{ label: '进行中', value: '进行中' },
{ label: '完成', value: '完成' },
{ label: '暂停', value: '暂停' },
{ label: '中止', value: '中止' }
]
const DEFAULT_INNOVATION_OUTPUT_RATE = 0.01
const { t } = useI18n() const { t } = useI18n()
const message = useMessage() const message = useMessage()
@@ -340,7 +322,7 @@ const createFormData = (): ProjectApi.ProjectVO => ({
projectType: '', projectType: '',
projectCategory: '', projectCategory: '',
projectStartYear: new Date().getFullYear(), projectStartYear: new Date().getFullYear(),
projectStatus: '进行中', projectStatus: PROJECT_STATUS.inProgress,
pauseReason: '', pauseReason: '',
terminateReason: '', terminateReason: '',
innovationOutputRate: DEFAULT_INNOVATION_OUTPUT_RATE, innovationOutputRate: DEFAULT_INNOVATION_OUTPUT_RATE,
@@ -358,7 +340,7 @@ const normalizeFormData = (data: ProjectApi.ProjectVO): ProjectApi.ProjectVO =>
...data, ...data,
projectType: normalizeValue(data.projectType, PROJECT_TYPE_OPTIONS), projectType: normalizeValue(data.projectType, PROJECT_TYPE_OPTIONS),
projectCategory: normalizeValue(data.projectCategory, PROJECT_CATEGORY_OPTIONS), projectCategory: normalizeValue(data.projectCategory, PROJECT_CATEGORY_OPTIONS),
projectStatus: normalizeValue(data.projectStatus, PROJECT_STATUS_OPTIONS, '进行中'), projectStatus: normalizeValue(data.projectStatus, PROJECT_STATUS_OPTIONS, PROJECT_STATUS.inProgress),
innovationOutputRate: data.innovationOutputRate ?? DEFAULT_INNOVATION_OUTPUT_RATE, innovationOutputRate: data.innovationOutputRate ?? DEFAULT_INNOVATION_OUTPUT_RATE,
otherCost: data.otherCost ?? 0, otherCost: data.otherCost ?? 0,
pauseReason: data.pauseReason || '', pauseReason: data.pauseReason || '',
@@ -438,20 +420,20 @@ const projectStartYearValue = computed({
}) })
const statusReasonLabel = computed(() => const statusReasonLabel = computed(() =>
formData.value.projectStatus === '中止' ? '中止原因' : '暂停原因' formData.value.projectStatus === PROJECT_STATUS.terminated ? '中止原因' : '暂停原因'
) )
const statusReasonProp = computed(() => const statusReasonProp = computed(() =>
formData.value.projectStatus === '中止' ? 'terminateReason' : 'pauseReason' formData.value.projectStatus === PROJECT_STATUS.terminated ? 'terminateReason' : 'pauseReason'
) )
watch( watch(
() => formData.value.projectStatus, () => formData.value.projectStatus,
(status) => { (status) => {
if (status !== '暂停') { if (status !== PROJECT_STATUS.paused) {
formData.value.pauseReason = '' formData.value.pauseReason = ''
} }
if (status !== '中止') { if (status !== PROJECT_STATUS.terminated) {
formData.value.terminateReason = '' formData.value.terminateReason = ''
} }
} }
@@ -466,7 +448,7 @@ const formRules = reactive<FormRules>({
pauseReason: [ pauseReason: [
{ {
validator: (_rule, value, callback) => { validator: (_rule, value, callback) => {
if (formData.value.projectStatus === '暂停' && !String(value || '').trim()) { if (formData.value.projectStatus === PROJECT_STATUS.paused && !String(value || '').trim()) {
callback(new Error('暂停状态必须填写暂停原因')) callback(new Error('暂停状态必须填写暂停原因'))
return return
} }
@@ -478,7 +460,7 @@ const formRules = reactive<FormRules>({
terminateReason: [ terminateReason: [
{ {
validator: (_rule, value, callback) => { validator: (_rule, value, callback) => {
if (formData.value.projectStatus === '中止' && !String(value || '').trim()) { if (formData.value.projectStatus === PROJECT_STATUS.terminated && !String(value || '').trim()) {
callback(new Error('中止状态必须填写中止原因')) callback(new Error('中止状态必须填写中止原因'))
return return
} }

View File

@@ -255,6 +255,7 @@ import download from '@/utils/download'
import { import {
formatAmountText, formatAmountText,
getOwnershipTypeLabel, getOwnershipTypeLabel,
OUTPUT_SPLIT_SPECIALTY,
OUTPUT_SPLIT_SPECIALTY_OPTIONS, OUTPUT_SPLIT_SPECIALTY_OPTIONS,
QUARTER_OPTIONS, QUARTER_OPTIONS,
toPercentValue toPercentValue
@@ -262,15 +263,7 @@ import {
defineOptions({ name: 'TjtReportProjectQuarter' }) defineOptions({ name: 'TjtReportProjectQuarter' })
type AnnualCategoryKey = type AnnualCategoryKey = (typeof OUTPUT_SPLIT_SPECIALTY)[keyof typeof OUTPUT_SPLIT_SPECIALTY]
| 'project_lead'
| 'arch'
| 'decor'
| 'struct'
| 'water'
| 'elec'
| 'hvac'
| 'digital'
interface QuarterYearRow { interface QuarterYearRow {
distributionYear: number distributionYear: number
@@ -280,14 +273,14 @@ interface QuarterYearRow {
type ExportDialogType = 'projectQuarter' | 'projectLeadQuarter' type ExportDialogType = 'projectQuarter' | 'projectLeadQuarter'
const annualCategoryOptions: { label: string; value: AnnualCategoryKey }[] = [ const annualCategoryOptions: { label: string; value: AnnualCategoryKey }[] = [
{ label: '项目经理/工程负责人', value: 'project_lead' }, { label: '项目经理/工程负责人', value: OUTPUT_SPLIT_SPECIALTY.projectLead },
{ label: '建筑专业', value: 'arch' }, { label: '建筑专业', value: OUTPUT_SPLIT_SPECIALTY.arch },
{ label: '装修专业', value: 'decor' }, { label: '装修专业', value: OUTPUT_SPLIT_SPECIALTY.decor },
{ label: '结构专业', value: 'struct' }, { label: '结构专业', value: OUTPUT_SPLIT_SPECIALTY.struct },
{ label: '水专业', value: 'water' }, { label: '水专业', value: OUTPUT_SPLIT_SPECIALTY.water },
{ label: '电气专业', value: 'elec' }, { label: '电气专业', value: OUTPUT_SPLIT_SPECIALTY.elec },
{ label: '暖通专业', value: 'hvac' }, { label: '暖通专业', value: OUTPUT_SPLIT_SPECIALTY.hvac },
{ label: '数字化设计专业', value: 'digital' } { label: '数字化设计专业', value: OUTPUT_SPLIT_SPECIALTY.digital }
] ]
const message = useMessage() const message = useMessage()
@@ -308,7 +301,7 @@ const currentProject = ref<ProjectApi.ProjectVO>()
const currentPlanning = ref<PlanningApi.ProjectPlanningVO>() const currentPlanning = ref<PlanningApi.ProjectPlanningVO>()
const formData = ref<OutputSplitApi.ProjectOutputSplitVO>() const formData = ref<OutputSplitApi.ProjectOutputSplitVO>()
const quarterRows = ref<QuarterYearRow[]>([]) const quarterRows = ref<QuarterYearRow[]>([])
const selectedAnnualCategory = ref<AnnualCategoryKey>('project_lead') const selectedAnnualCategory = ref<AnnualCategoryKey>(OUTPUT_SPLIT_SPECIALTY.projectLead)
const queryFormRef = ref() const queryFormRef = ref()
const projectTableRef = ref() const projectTableRef = ref()
const planningTableRef = ref() const planningTableRef = ref()
@@ -416,7 +409,7 @@ const annualCategoryMeta = computed(() => {
if (!model || !option) { if (!model || !option) {
return { ratio: 0 } return { ratio: 0 }
} }
if (selectedAnnualCategory.value === 'project_lead') { if (selectedAnnualCategory.value === OUTPUT_SPLIT_SPECIALTY.projectLead) {
return { return {
ratio: Number(toNumeric(model.projectLeadRatio).toFixed(4)) ratio: Number(toNumeric(model.projectLeadRatio).toFixed(4))
} }

View File

@@ -267,11 +267,16 @@ import * as PlanningApi from '@/api/tjt/planning'
import * as ProjectApi from '@/api/tjt/project' import * as ProjectApi from '@/api/tjt/project'
import * as ReportApi from '@/api/tjt/report' import * as ReportApi from '@/api/tjt/report'
import download from '@/utils/download' import download from '@/utils/download'
import { formatAmountText, formatPercentText, getOwnershipTypeLabel } from '@/views/tjt/shared/planning' import {
formatAmountText,
formatPercentText,
getOwnershipTypeLabel,
OUTPUT_SPLIT_SPECIALTY
} from '@/views/tjt/shared/planning'
defineOptions({ name: 'TjtReportSpecialtyPerson' }) defineOptions({ name: 'TjtReportSpecialtyPerson' })
const PROJECT_LEAD_GROUP_CODE = 'project_lead' const PROJECT_LEAD_GROUP_CODE = OUTPUT_SPLIT_SPECIALTY.projectLead
const message = useMessage() const message = useMessage()
const currentYear = new Date().getFullYear() const currentYear = new Date().getFullYear()

View File

@@ -4,36 +4,75 @@ export type Option<T = string> = {
} }
export const OWNERSHIP_TYPE = { export const OWNERSHIP_TYPE = {
major: '专业所', major: 'major',
comprehensive: '综合所', comprehensive: 'comprehensive',
specialSubcontract: '专项分包', specialSubcontract: 'special_subcontract_major',
sourceCoopSubcontract: '源头合作分包' sourceCoopSubcontract: 'special_subcontract_source_coop',
comprehensiveSubcontract: 'special_subcontract_comprehensive'
} as const } as const
export const OWNERSHIP_TYPE_LABEL: Record<(typeof OWNERSHIP_TYPE)[keyof typeof OWNERSHIP_TYPE], string> = {
[OWNERSHIP_TYPE.major]: '专业所',
[OWNERSHIP_TYPE.comprehensive]: '综合所',
[OWNERSHIP_TYPE.specialSubcontract]: '专项分包-专业所',
[OWNERSHIP_TYPE.sourceCoopSubcontract]: '专项分包-源头合作分包',
[OWNERSHIP_TYPE.comprehensiveSubcontract]: '专项分包-综合所'
}
export const CALCULATION_METHOD = { export const CALCULATION_METHOD = {
guidancePrice: '指导价法', guidancePrice: 'guidance_price',
contractPrice: '合同价法', contractPrice: 'contract_price',
virtualOutput: '虚拟产值法' virtualOutput: 'virtual_output'
} as const } as const
export const CALCULATION_METHOD_LABEL: Record<
(typeof CALCULATION_METHOD)[keyof typeof CALCULATION_METHOD],
string
> = {
[CALCULATION_METHOD.guidancePrice]: '指导价法',
[CALCULATION_METHOD.contractPrice]: '合同价法',
[CALCULATION_METHOD.virtualOutput]: '虚拟产值法'
}
export const VIRTUAL_CALCULATION_METHOD = { export const VIRTUAL_CALCULATION_METHOD = {
guidancePrice: '指导单价法', guidancePrice: 'guidance_price',
guidanceTotalPrice: '指导总价法', guidanceTotalPrice: 'guidance_total_price',
workingDay: '工日法' workingDay: 'working_day'
} as const } as const
export const VIRTUAL_CALCULATION_METHOD_LABEL: Record<
(typeof VIRTUAL_CALCULATION_METHOD)[keyof typeof VIRTUAL_CALCULATION_METHOD],
string
> = {
[VIRTUAL_CALCULATION_METHOD.guidancePrice]: '指导单价法',
[VIRTUAL_CALCULATION_METHOD.guidanceTotalPrice]: '指导总价法',
[VIRTUAL_CALCULATION_METHOD.workingDay]: '工日法'
}
export const DESIGN_STAGE = { export const DESIGN_STAGE = {
scheme: '方案', scheme: 'scheme',
constructionDrawing: '施工图', constructionDrawing: 'construction_drawing',
schemeAndConstructionDrawing: '方案+施工图' schemeAndConstructionDrawing: 'scheme_and_construction_drawing'
} as const } as const
export const DESIGN_STAGE_LABEL: Record<(typeof DESIGN_STAGE)[keyof typeof DESIGN_STAGE], string> = {
[DESIGN_STAGE.scheme]: '方案',
[DESIGN_STAGE.constructionDrawing]: '施工图',
[DESIGN_STAGE.schemeAndConstructionDrawing]: '方案+施工图'
}
export const DESIGN_PART = { export const DESIGN_PART = {
realEstate: '地上部分', realEstate: 'above_ground',
underground: '地下部分', underground: 'underground',
other: '其他' other: 'other'
} as const } as const
export const DESIGN_PART_LABEL: Record<(typeof DESIGN_PART)[keyof typeof DESIGN_PART], string> = {
[DESIGN_PART.realEstate]: '地上部分',
[DESIGN_PART.underground]: '地下部分',
[DESIGN_PART.other]: '其他'
}
export const PROJECT_TYPE = { export const PROJECT_TYPE = {
building: '建筑工程', building: '建筑工程',
decoration: '精装工程', decoration: '精装工程',
@@ -52,12 +91,19 @@ export const PROJECT_CATEGORY = {
} as const } as const
export const PROJECT_STATUS = { export const PROJECT_STATUS = {
inProgress: '进行中', inProgress: 'in_progress',
completed: '完成', completed: 'completed',
paused: '暂停', paused: 'paused',
terminated: '中止' terminated: 'terminated'
} as const } as const
export const PROJECT_STATUS_LABEL: Record<(typeof PROJECT_STATUS)[keyof typeof PROJECT_STATUS], string> = {
[PROJECT_STATUS.inProgress]: '进行中',
[PROJECT_STATUS.completed]: '完成',
[PROJECT_STATUS.paused]: '暂停',
[PROJECT_STATUS.terminated]: '中止'
}
export const EMPLOYEE_GENDER = { export const EMPLOYEE_GENDER = {
male: '男', male: '男',
female: '女' female: '女'
@@ -100,46 +146,68 @@ export const normalizeProjectStatus = (value?: string) =>
normalizeValue(value, Object.values(PROJECT_STATUS)) normalizeValue(value, Object.values(PROJECT_STATUS))
export const OWNERSHIP_TYPE_OPTIONS: Option[] = [ export const OWNERSHIP_TYPE_OPTIONS: Option[] = [
{ label: OWNERSHIP_TYPE.major, value: OWNERSHIP_TYPE.major }, { label: OWNERSHIP_TYPE_LABEL[OWNERSHIP_TYPE.major], value: OWNERSHIP_TYPE.major },
{ label: OWNERSHIP_TYPE.comprehensive, value: OWNERSHIP_TYPE.comprehensive }, { label: OWNERSHIP_TYPE_LABEL[OWNERSHIP_TYPE.comprehensive], value: OWNERSHIP_TYPE.comprehensive },
{ label: OWNERSHIP_TYPE.specialSubcontract, value: OWNERSHIP_TYPE.specialSubcontract },
{ {
label: OWNERSHIP_TYPE.sourceCoopSubcontract, label: OWNERSHIP_TYPE_LABEL[OWNERSHIP_TYPE.specialSubcontract],
value: OWNERSHIP_TYPE.specialSubcontract
},
{
label: OWNERSHIP_TYPE_LABEL[OWNERSHIP_TYPE.sourceCoopSubcontract],
value: OWNERSHIP_TYPE.sourceCoopSubcontract value: OWNERSHIP_TYPE.sourceCoopSubcontract
},
{
label: OWNERSHIP_TYPE_LABEL[OWNERSHIP_TYPE.comprehensiveSubcontract],
value: OWNERSHIP_TYPE.comprehensiveSubcontract
} }
] ]
export const CALCULATION_METHOD_OPTIONS: Option[] = [ export const CALCULATION_METHOD_OPTIONS: Option[] = [
{ label: CALCULATION_METHOD.guidancePrice, value: CALCULATION_METHOD.guidancePrice }, {
{ label: CALCULATION_METHOD.contractPrice, value: CALCULATION_METHOD.contractPrice }, label: CALCULATION_METHOD_LABEL[CALCULATION_METHOD.guidancePrice],
{ label: CALCULATION_METHOD.virtualOutput, value: CALCULATION_METHOD.virtualOutput } value: CALCULATION_METHOD.guidancePrice
},
{
label: CALCULATION_METHOD_LABEL[CALCULATION_METHOD.contractPrice],
value: CALCULATION_METHOD.contractPrice
},
{
label: CALCULATION_METHOD_LABEL[CALCULATION_METHOD.virtualOutput],
value: CALCULATION_METHOD.virtualOutput
}
] ]
export const VIRTUAL_CALCULATION_METHOD_OPTIONS: Option[] = [ export const VIRTUAL_CALCULATION_METHOD_OPTIONS: Option[] = [
{ {
label: VIRTUAL_CALCULATION_METHOD.guidancePrice, label: VIRTUAL_CALCULATION_METHOD_LABEL[VIRTUAL_CALCULATION_METHOD.guidancePrice],
value: VIRTUAL_CALCULATION_METHOD.guidancePrice value: VIRTUAL_CALCULATION_METHOD.guidancePrice
}, },
{ {
label: VIRTUAL_CALCULATION_METHOD.guidanceTotalPrice, label: VIRTUAL_CALCULATION_METHOD_LABEL[VIRTUAL_CALCULATION_METHOD.guidanceTotalPrice],
value: VIRTUAL_CALCULATION_METHOD.guidanceTotalPrice value: VIRTUAL_CALCULATION_METHOD.guidanceTotalPrice
}, },
{ label: VIRTUAL_CALCULATION_METHOD.workingDay, value: VIRTUAL_CALCULATION_METHOD.workingDay } {
label: VIRTUAL_CALCULATION_METHOD_LABEL[VIRTUAL_CALCULATION_METHOD.workingDay],
value: VIRTUAL_CALCULATION_METHOD.workingDay
}
] ]
export const DESIGN_STAGE_OPTIONS: Option[] = [ export const DESIGN_STAGE_OPTIONS: Option[] = [
{ label: DESIGN_STAGE.scheme, value: DESIGN_STAGE.scheme }, { label: DESIGN_STAGE_LABEL[DESIGN_STAGE.scheme], value: DESIGN_STAGE.scheme },
{ label: DESIGN_STAGE.constructionDrawing, value: DESIGN_STAGE.constructionDrawing },
{ {
label: DESIGN_STAGE.schemeAndConstructionDrawing, label: DESIGN_STAGE_LABEL[DESIGN_STAGE.constructionDrawing],
value: DESIGN_STAGE.constructionDrawing
},
{
label: DESIGN_STAGE_LABEL[DESIGN_STAGE.schemeAndConstructionDrawing],
value: DESIGN_STAGE.schemeAndConstructionDrawing value: DESIGN_STAGE.schemeAndConstructionDrawing
} }
] ]
export const DESIGN_PART_OPTIONS: Option[] = [ export const DESIGN_PART_OPTIONS: Option[] = [
{ label: DESIGN_PART.realEstate, value: DESIGN_PART.realEstate }, { label: DESIGN_PART_LABEL[DESIGN_PART.realEstate], value: DESIGN_PART.realEstate },
{ label: DESIGN_PART.underground, value: DESIGN_PART.underground }, { label: DESIGN_PART_LABEL[DESIGN_PART.underground], value: DESIGN_PART.underground },
{ label: DESIGN_PART.other, value: DESIGN_PART.other } { label: DESIGN_PART_LABEL[DESIGN_PART.other], value: DESIGN_PART.other }
] ]
export const CONTRACT_SIGN_OPTIONS: Option<boolean>[] = [ export const CONTRACT_SIGN_OPTIONS: Option<boolean>[] = [
@@ -165,10 +233,10 @@ export const PROJECT_CATEGORY_OPTIONS: Option[] = [
] ]
export const PROJECT_STATUS_OPTIONS: Option[] = [ export const PROJECT_STATUS_OPTIONS: Option[] = [
{ label: PROJECT_STATUS.inProgress, value: PROJECT_STATUS.inProgress }, { label: PROJECT_STATUS_LABEL[PROJECT_STATUS.inProgress], value: PROJECT_STATUS.inProgress },
{ label: PROJECT_STATUS.completed, value: PROJECT_STATUS.completed }, { label: PROJECT_STATUS_LABEL[PROJECT_STATUS.completed], value: PROJECT_STATUS.completed },
{ label: PROJECT_STATUS.paused, value: PROJECT_STATUS.paused }, { label: PROJECT_STATUS_LABEL[PROJECT_STATUS.paused], value: PROJECT_STATUS.paused },
{ label: PROJECT_STATUS.terminated, value: PROJECT_STATUS.terminated } { label: PROJECT_STATUS_LABEL[PROJECT_STATUS.terminated], value: PROJECT_STATUS.terminated }
] ]
export const EMPLOYEE_GENDER_OPTIONS: Option[] = [ export const EMPLOYEE_GENDER_OPTIONS: Option[] = [
@@ -206,22 +274,43 @@ export const QUARTER_OPTIONS: Option<number>[] = [
{ label: '四季度', value: 4 } { label: '四季度', value: 4 }
] ]
export const OUTPUT_SPLIT_SPECIALTY = {
projectLead: 'project_lead',
arch: 'arch',
decor: 'decor',
struct: 'struct',
water: 'water',
elec: 'elec',
hvac: 'hvac',
digital: 'digital'
} as const
export const OUTPUT_SPLIT_ROLE = {
director: 'director',
check: 'check',
review: 'review',
approve: 'approve',
design: 'design',
projectManager: 'project_manager',
engineeringPrincipal: 'engineering_principal'
} as const
export const OUTPUT_SPLIT_SPECIALTY_OPTIONS: Option[] = [ export const OUTPUT_SPLIT_SPECIALTY_OPTIONS: Option[] = [
{ label: '建筑', value: 'arch' }, { label: '建筑', value: OUTPUT_SPLIT_SPECIALTY.arch },
{ label: '装饰', value: 'decor' }, { label: '装饰', value: OUTPUT_SPLIT_SPECIALTY.decor },
{ label: '结构', value: 'struct' }, { label: '结构', value: OUTPUT_SPLIT_SPECIALTY.struct },
{ label: '给排水', value: 'water' }, { label: '给排水', value: OUTPUT_SPLIT_SPECIALTY.water },
{ label: '电气', value: 'elec' }, { label: '电气', value: OUTPUT_SPLIT_SPECIALTY.elec },
{ label: '暖通', value: 'hvac' }, { label: '暖通', value: OUTPUT_SPLIT_SPECIALTY.hvac },
{ label: '数字化设计', value: 'digital' } { label: '数字化设计', value: OUTPUT_SPLIT_SPECIALTY.digital }
] ]
export const SPECIALTY_ROLE_OPTIONS: Option[] = [ export const SPECIALTY_ROLE_OPTIONS: Option[] = [
{ label: '专业负责人', value: 'director' }, { label: '专业负责人', value: OUTPUT_SPLIT_ROLE.director },
{ label: '校对', value: 'check' }, { label: '校对', value: OUTPUT_SPLIT_ROLE.check },
{ label: '审核', value: 'review' }, { label: '审核', value: OUTPUT_SPLIT_ROLE.review },
{ label: '审定', value: 'approve' }, { label: '审定', value: OUTPUT_SPLIT_ROLE.approve },
{ label: '设计', value: 'design' } { label: '设计', value: OUTPUT_SPLIT_ROLE.design }
] ]
export const isMajorOwnership = (value?: string) => export const isMajorOwnership = (value?: string) =>
@@ -232,8 +321,12 @@ export const isSpecialSubcontractOwnership = (value?: string) =>
normalizeOwnershipType(value) === OWNERSHIP_TYPE.specialSubcontract normalizeOwnershipType(value) === OWNERSHIP_TYPE.specialSubcontract
export const isSourceCoopSubcontractOwnership = (value?: string) => export const isSourceCoopSubcontractOwnership = (value?: string) =>
normalizeOwnershipType(value) === OWNERSHIP_TYPE.sourceCoopSubcontract normalizeOwnershipType(value) === OWNERSHIP_TYPE.sourceCoopSubcontract
export const isComprehensiveSubcontractOwnership = (value?: string) =>
normalizeOwnershipType(value) === OWNERSHIP_TYPE.comprehensiveSubcontract
export const isSubcontractOwnership = (value?: string) => export const isSubcontractOwnership = (value?: string) =>
isSpecialSubcontractOwnership(value) || isSourceCoopSubcontractOwnership(value) isSpecialSubcontractOwnership(value) ||
isSourceCoopSubcontractOwnership(value) ||
isComprehensiveSubcontractOwnership(value)
export const isGuidancePriceMethod = (value?: string) => export const isGuidancePriceMethod = (value?: string) =>
normalizeCalculationMethod(value) === CALCULATION_METHOD.guidancePrice normalizeCalculationMethod(value) === CALCULATION_METHOD.guidancePrice

View File

@@ -325,15 +325,17 @@ import {
formatPercentText, formatPercentText,
fromPercentValue, fromPercentValue,
getOwnershipTypeLabel, getOwnershipTypeLabel,
OUTPUT_SPLIT_ROLE,
OUTPUT_SPLIT_SPECIALTY,
toPercentValue toPercentValue
} from '@/views/tjt/shared/planning' } from '@/views/tjt/shared/planning'
defineOptions({ name: 'TjtStaffAssignment' }) defineOptions({ name: 'TjtStaffAssignment' })
const DESIGN_ROLE_CODE = 'design' const DESIGN_ROLE_CODE = OUTPUT_SPLIT_ROLE.design
const PROJECT_LEAD_GROUP_CODE = 'project_lead' const PROJECT_LEAD_GROUP_CODE = OUTPUT_SPLIT_SPECIALTY.projectLead
const ROLE_PROJECT_MANAGER = 'project_manager' const ROLE_PROJECT_MANAGER = OUTPUT_SPLIT_ROLE.projectManager
const ROLE_ENGINEERING_PRINCIPAL = 'engineering_principal' const ROLE_ENGINEERING_PRINCIPAL = OUTPUT_SPLIT_ROLE.engineeringPrincipal
const EPSILON = 0.0001 const EPSILON = 0.0001
type SpecialtyRolePersonVO = SpecialtyRoleSplitApi.SpecialtyRolePersonVO type SpecialtyRolePersonVO = SpecialtyRoleSplitApi.SpecialtyRolePersonVO