重要提交,可能会影响到其他模块及工作流。*****

This commit is contained in:
wuzhen committed 2025-08-07 18:37:28 +08:00
1 parent bab7b53074
commit e06d8fca2c
78 files changed
+3545 -3471

No files matched your search

@@ -17,39 +17,24 @@
<span>产出指标</span>
</div>
</template>
<!-- 数量指标 -->
<div class="indicator-item">
<h4 class="indicator-title">数量指标</h4>
<el-row :gutter="16">
<el-col :span="8">
<el-form-item label="绩效目标名称">
<el-input
v-model="indicators.quantity.goalName"
placeholder="请输入绩效目标名称"
maxlength="200"
@input="emitChange"
/>
<el-input v-model="indicators.quantity.goalName" placeholder="请输入绩效目标名称" maxlength="200" @input="emitChange" />
</el-form-item>
</el-col>
<el-col :span="4">
<el-form-item label="目标值">
<el-input
v-model="indicators.quantity.targetValue"
placeholder="目标值"
maxlength="100"
@input="emitChange"
/>
<el-input v-model="indicators.quantity.targetValue" placeholder="目标值" maxlength="100" @input="emitChange" />
</el-form-item>
</el-col>
<el-col :span="3">
<el-form-item label="单位">
<el-input
v-model="indicators.quantity.unit"
placeholder="单位"
maxlength="20"
@input="emitChange"
/>
<el-input v-model="indicators.quantity.unit" placeholder="单位" maxlength="20" @input="emitChange" />
</el-form-item>
</el-col>
<el-col :span="3">
@@ -67,12 +52,7 @@
</el-col>
<el-col :span="6">
<el-form-item label="详细说明">
<el-input
v-model="indicators.quantity.description"
placeholder="详细说明"
maxlength="500"
@input="emitChange"
/>
<el-input v-model="indicators.quantity.description" placeholder="详细说明" maxlength="500" @input="emitChange" />
</el-form-item>
</el-col>
</el-row>
@@ -84,32 +64,17 @@
<el-row :gutter="16">
<el-col :span="8">
<el-form-item label="绩效目标名称">
<el-input
v-model="indicators.quality.goalName"
placeholder="请输入绩效目标名称"
maxlength="200"
@input="emitChange"
/>
<el-input v-model="indicators.quality.goalName" placeholder="请输入绩效目标名称" maxlength="200" @input="emitChange" />
</el-form-item>
</el-col>
<el-col :span="4">
<el-form-item label="目标值">
<el-input
v-model="indicators.quality.targetValue"
placeholder="目标值"
maxlength="100"
@input="emitChange"
/>
<el-input v-model="indicators.quality.targetValue" placeholder="目标值" maxlength="100" @input="emitChange" />
</el-form-item>
</el-col>
<el-col :span="3">
<el-form-item label="单位">
<el-input
v-model="indicators.quality.unit"
placeholder="单位"
maxlength="20"
@input="emitChange"
/>
<el-input v-model="indicators.quality.unit" placeholder="单位" maxlength="20" @input="emitChange" />
</el-form-item>
</el-col>
<el-col :span="3">
@@ -127,12 +92,7 @@
</el-col>
<el-col :span="6">
<el-form-item label="详细说明">
<el-input
v-model="indicators.quality.description"
placeholder="详细说明"
maxlength="500"
@input="emitChange"
/>
<el-input v-model="indicators.quality.description" placeholder="详细说明" maxlength="500" @input="emitChange" />
</el-form-item>
</el-col>
</el-row>
@@ -144,32 +104,17 @@
<el-row :gutter="16">
<el-col :span="8">
<el-form-item label="绩效目标名称">
<el-input
v-model="indicators.timeliness.goalName"
placeholder="请输入绩效目标名称"
maxlength="200"
@input="emitChange"
/>
<el-input v-model="indicators.timeliness.goalName" placeholder="请输入绩效目标名称" maxlength="200" @input="emitChange" />
</el-form-item>
</el-col>
<el-col :span="4">
<el-form-item label="目标值">
<el-input
v-model="indicators.timeliness.targetValue"
placeholder="目标值"
maxlength="100"
@input="emitChange"
/>
<el-input v-model="indicators.timeliness.targetValue" placeholder="目标值" maxlength="100" @input="emitChange" />
</el-form-item>
</el-col>
<el-col :span="3">
<el-form-item label="单位">
<el-input
v-model="indicators.timeliness.unit"
placeholder="单位"
maxlength="20"
@input="emitChange"
/>
<el-input v-model="indicators.timeliness.unit" placeholder="单位" maxlength="20" @input="emitChange" />
</el-form-item>
</el-col>
<el-col :span="3">
@@ -187,12 +132,7 @@
</el-col>
<el-col :span="6">
<el-form-item label="详细说明">
<el-input
v-model="indicators.timeliness.description"
placeholder="详细说明"
maxlength="500"
@input="emitChange"
/>
<el-input v-model="indicators.timeliness.description" placeholder="详细说明" maxlength="500" @input="emitChange" />
</el-form-item>
</el-col>
</el-row>
@@ -204,32 +144,17 @@
<el-row :gutter="16">
<el-col :span="8">
<el-form-item label="绩效目标名称">
<el-input
v-model="indicators.cost.goalName"
placeholder="请输入绩效目标名称"
maxlength="200"
@input="emitChange"
/>
<el-input v-model="indicators.cost.goalName" placeholder="请输入绩效目标名称" maxlength="200" @input="emitChange" />
</el-form-item>
</el-col>
<el-col :span="4">
<el-form-item label="目标值">
<el-input
v-model="indicators.cost.targetValue"
placeholder="目标值"
maxlength="100"
@input="emitChange"
/>
<el-input v-model="indicators.cost.targetValue" placeholder="目标值" maxlength="100" @input="emitChange" />
</el-form-item>
</el-col>
<el-col :span="3">
<el-form-item label="单位">
<el-input
v-model="indicators.cost.unit"
placeholder="单位"
maxlength="20"
@input="emitChange"
/>
<el-input v-model="indicators.cost.unit" placeholder="单位" maxlength="20" @input="emitChange" />
</el-form-item>
</el-col>
<el-col :span="3">
@@ -247,12 +172,7 @@
</el-col>
<el-col :span="6">
<el-form-item label="详细说明">
<el-input
v-model="indicators.cost.description"
placeholder="详细说明"
maxlength="500"
@input="emitChange"
/>
<el-input v-model="indicators.cost.description" placeholder="详细说明" maxlength="500" @input="emitChange" />
</el-form-item>
</el-col>
</el-row>
@@ -267,39 +187,24 @@
<span>效益指标</span>
</div>
</template>
<!-- 经济效益指标 -->
<div class="indicator-item">
<h4 class="indicator-title">经济效益指标</h4>
<el-row :gutter="16">
<el-col :span="8">
<el-form-item label="绩效目标名称">
<el-input
v-model="indicators.economic.goalName"
placeholder="请输入绩效目标名称"
maxlength="200"
@input="emitChange"
/>
<el-input v-model="indicators.economic.goalName" placeholder="请输入绩效目标名称" maxlength="200" @input="emitChange" />
</el-form-item>
</el-col>
<el-col :span="4">
<el-form-item label="目标值">
<el-input
v-model="indicators.economic.targetValue"
placeholder="目标值"
maxlength="100"
@input="emitChange"
/>
<el-input v-model="indicators.economic.targetValue" placeholder="目标值" maxlength="100" @input="emitChange" />
</el-form-item>
</el-col>
<el-col :span="3">
<el-form-item label="单位">
<el-input
v-model="indicators.economic.unit"
placeholder="单位"
maxlength="20"
@input="emitChange"
/>
<el-input v-model="indicators.economic.unit" placeholder="单位" maxlength="20" @input="emitChange" />
</el-form-item>
</el-col>
<el-col :span="3">
@@ -317,12 +222,7 @@
</el-col>
<el-col :span="6">
<el-form-item label="详细说明">
<el-input
v-model="indicators.economic.description"
placeholder="详细说明"
maxlength="500"
@input="emitChange"
/>
<el-input v-model="indicators.economic.description" placeholder="详细说明" maxlength="500" @input="emitChange" />
</el-form-item>
</el-col>
</el-row>
@@ -334,32 +234,17 @@
<el-row :gutter="16">
<el-col :span="8">
<el-form-item label="绩效目标名称">
<el-input
v-model="indicators.social.goalName"
placeholder="请输入绩效目标名称"
maxlength="200"
@input="emitChange"
/>
<el-input v-model="indicators.social.goalName" placeholder="请输入绩效目标名称" maxlength="200" @input="emitChange" />
</el-form-item>
</el-col>
<el-col :span="4">
<el-form-item label="目标值">
<el-input
v-model="indicators.social.targetValue"
placeholder="目标值"
maxlength="100"
@input="emitChange"
/>
<el-input v-model="indicators.social.targetValue" placeholder="目标值" maxlength="100" @input="emitChange" />
</el-form-item>
</el-col>
<el-col :span="3">
<el-form-item label="单位">
<el-input
v-model="indicators.social.unit"
placeholder="单位"
maxlength="20"
@input="emitChange"
/>
<el-input v-model="indicators.social.unit" placeholder="单位" maxlength="20" @input="emitChange" />
</el-form-item>
</el-col>
<el-col :span="3">
@@ -377,12 +262,7 @@
</el-col>
<el-col :span="6">
<el-form-item label="详细说明">
<el-input
v-model="indicators.social.description"
placeholder="详细说明"
maxlength="500"
@input="emitChange"
/>
<el-input v-model="indicators.social.description" placeholder="详细说明" maxlength="500" @input="emitChange" />
</el-form-item>
</el-col>
</el-row>
@@ -394,32 +274,17 @@
<el-row :gutter="16">
<el-col :span="8">
<el-form-item label="绩效目标名称">
<el-input
v-model="indicators.ecological.goalName"
placeholder="请输入绩效目标名称"
maxlength="200"
@input="emitChange"
/>
<el-input v-model="indicators.ecological.goalName" placeholder="请输入绩效目标名称" maxlength="200" @input="emitChange" />
</el-form-item>
</el-col>
<el-col :span="4">
<el-form-item label="目标值">
<el-input
v-model="indicators.ecological.targetValue"
placeholder="目标值"
maxlength="100"
@input="emitChange"
/>
<el-input v-model="indicators.ecological.targetValue" placeholder="目标值" maxlength="100" @input="emitChange" />
</el-form-item>
</el-col>
<el-col :span="3">
<el-form-item label="单位">
<el-input
v-model="indicators.ecological.unit"
placeholder="单位"
maxlength="20"
@input="emitChange"
/>
<el-input v-model="indicators.ecological.unit" placeholder="单位" maxlength="20" @input="emitChange" />
</el-form-item>
</el-col>
<el-col :span="3">
@@ -437,12 +302,7 @@
</el-col>
<el-col :span="6">
<el-form-item label="详细说明">
<el-input
v-model="indicators.ecological.description"
placeholder="详细说明"
maxlength="500"
@input="emitChange"
/>
<el-input v-model="indicators.ecological.description" placeholder="详细说明" maxlength="500" @input="emitChange" />
</el-form-item>
</el-col>
</el-row>
@@ -457,39 +317,24 @@
<span>满意度指标</span>
</div>
</template>
<!-- 服务对象满意度指标 -->
<div class="indicator-item">
<h4 class="indicator-title">服务对象满意度指标</h4>
<el-row :gutter="16">
<el-col :span="8">
<el-form-item label="绩效目标名称">
<el-input
v-model="indicators.service_satisfaction.goalName"
placeholder="请输入绩效目标名称"
maxlength="200"
@input="emitChange"
/>
<el-input v-model="indicators.service_satisfaction.goalName" placeholder="请输入绩效目标名称" maxlength="200" @input="emitChange" />
</el-form-item>
</el-col>
<el-col :span="4">
<el-form-item label="目标值">
<el-input
v-model="indicators.service_satisfaction.targetValue"
placeholder="目标值"
maxlength="100"
@input="emitChange"
/>
<el-input v-model="indicators.service_satisfaction.targetValue" placeholder="目标值" maxlength="100" @input="emitChange" />
</el-form-item>
</el-col>
<el-col :span="3">
<el-form-item label="单位">
<el-input
v-model="indicators.service_satisfaction.unit"
placeholder="单位"
maxlength="20"
@input="emitChange"
/>
<el-input v-model="indicators.service_satisfaction.unit" placeholder="单位" maxlength="20" @input="emitChange" />
</el-form-item>
</el-col>
<el-col :span="3">
@@ -507,12 +352,7 @@
</el-col>
<el-col :span="6">
<el-form-item label="详细说明">
<el-input
v-model="indicators.service_satisfaction.description"
placeholder="详细说明"
maxlength="500"
@input="emitChange"
/>
<el-input v-model="indicators.service_satisfaction.description" placeholder="详细说明" maxlength="500" @input="emitChange" />
</el-form-item>
</el-col>
</el-row>
@@ -531,22 +371,22 @@
</template>
<script lang="ts">
import { defineComponent, ref, computed, watch } from 'vue'
import { TrendCharts, Money, Star } from '@element-plus/icons-vue'
import { defineComponent, ref, computed, watch } from 'vue';
import { TrendCharts, Money, Star } from '@element-plus/icons-vue';
interface PerformanceIndicator {
indicatorType: string
indicatorTypeName: string
goalName: string
targetValue: string
unit: string
weightPercentage: number
description: string
measurementMethod: string
dataSource: string
isQuantitative: boolean
sortOrder: number
status: string
indicatorType: string;
indicatorTypeName: string;
goalName: string;
targetValue: string;
unit: string;
weightPercentage: number;
description: string;
measurementMethod: string;
dataSource: string;
isQuantitative: boolean;
sortOrder: number;
status: string;
}
export default defineComponent({
@@ -582,7 +422,7 @@ export default defineComponent({
isQuantitative: true,
sortOrder: 0,
status: '1'
})
});
// 8种固定的指标类型
const indicators = ref({
@@ -594,46 +434,46 @@ export default defineComponent({
social: createIndicator('social', '社会效益指标'),
ecological: createIndicator('ecological', '生态效益指标'),
service_satisfaction: createIndicator('service_satisfaction', '服务对象满意度指标')
})
});
// 计算总分值占比
const totalWeight = computed(() => {
let total = 0
Object.values(indicators.value).forEach(indicator => {
total += indicator.weightPercentage || 0
})
return Math.round(total * 10) / 10
})
let total = 0;
Object.values(indicators.value).forEach((indicator) => {
total += indicator.weightPercentage || 0;
});
return Math.round(total * 10) / 10;
});
// 收集有效的指标数据
const collectValidIndicators = () => {
const validIndicators: PerformanceIndicator[] = []
let sortOrder = 0
Object.values(indicators.value).forEach(indicator => {
const validIndicators: PerformanceIndicator[] = [];
let sortOrder = 0;
Object.values(indicators.value).forEach((indicator) => {
// 只有填写了目标名称的指标才被认为是有效的
if (indicator.goalName?.trim()) {
validIndicators.push({
...indicator,
sortOrder: sortOrder++
})
});
}
})
return validIndicators
}
});
return validIndicators;
};
// 发出变化事件
const emitChange = () => {
const validIndicators = collectValidIndicators()
emit('update:modelValue', validIndicators)
emit('change', validIndicators)
}
const validIndicators = collectValidIndicators();
emit('update:modelValue', validIndicators);
emit('change', validIndicators);
};
// 从传入的数据初始化指标
const initializeFromData = (data: any[]) => {
if (!data || data.length === 0) return
if (!data || data.length === 0) return;
// 重置所有指标
indicators.value = {
quantity: createIndicator('quantity', '数量指标'),
@@ -644,57 +484,61 @@ export default defineComponent({
social: createIndicator('social', '社会效益指标'),
ecological: createIndicator('ecological', '生态效益指标'),
service_satisfaction: createIndicator('service_satisfaction', '服务对象满意度指标')
}
};
// 将数据填入对应的指标类型
data.forEach(item => {
data.forEach((item) => {
if (indicators.value[item.indicatorType]) {
indicators.value[item.indicatorType] = { ...item }
indicators.value[item.indicatorType] = { ...item };
}
})
}
});
};
// 监听外部数据变化
watch(() => props.modelValue, (newValue) => {
initializeFromData(newValue)
}, { deep: true, immediate: true })
watch(
() => props.modelValue,
(newValue) => {
initializeFromData(newValue);
},
{ deep: true, immediate: true }
);
// 校验方法
const validate = () => {
const validIndicators = collectValidIndicators()
const errors = []
const validIndicators = collectValidIndicators();
const errors = [];
if (validIndicators.length === 0) {
errors.push('请至少填写一个绩效指标')
errors.push('请至少填写一个绩效指标');
}
validIndicators.forEach((indicator, index) => {
if (!indicator.goalName?.trim()) {
errors.push(`第${index + 1}个指标未填写绩效目标名称`)
errors.push(`第${index + 1}个指标未填写绩效目标名称`);
}
if (!indicator.targetValue?.trim()) {
errors.push(`第${index + 1}个指标未填写目标值`)
errors.push(`第${index + 1}个指标未填写目标值`);
}
if (!indicator.weightPercentage || indicator.weightPercentage <= 0) {
errors.push(`第${index + 1}个指标未设置分值占比`)
errors.push(`第${index + 1}个指标未设置分值占比`);
}
})
});
if (Math.abs(totalWeight.value - 100) > 0.1) {
errors.push(`分值占比总和必须等于100%,当前为${totalWeight.value}%`)
errors.push(`分值占比总和必须等于100%,当前为${totalWeight.value}%`);
}
if (errors.length > 0) {
return { valid: false, message: errors.join(';') }
return { valid: false, message: errors.join(';') };
}
return { valid: true }
}
return { valid: true };
};
// 获取所有有效指标数据
const getAllIndicators = () => {
return collectValidIndicators()
}
return collectValidIndicators();
};
return {
indicators,
@@ -702,9 +546,9 @@ export default defineComponent({
emitChange,
validate,
getAllIndicators
}
};
}
})
});
</script>
<style scoped lang="scss">
@@ -715,34 +559,33 @@ export default defineComponent({
gap: 8px;
font-weight: bold;
font-size: 16px;
.el-icon {
font-size: 18px;
}
}
.indicator-item {
margin-bottom: 20px;
padding: 15px;
background-color: #fafafa;
border-radius: 6px;
border-left: 4px solid #409eff;
&:last-child {
margin-bottom: 0;
}
}
.indicator-title {
margin: 0 0 15px 0;
font-size: 14px;
font-weight: bold;
color: #606266;
}
.el-form-item {
margin-bottom: 10px;
}
}
</style>
+102 -108
View File
@@ -16,12 +16,7 @@
<!-- 审批流程 -->
<el-divider content-position="left">审批流程</el-divider>
<el-timeline>
<el-timeline-item
v-for="(item, index) in approvalTimeline"
:key="index"
:type="item.type"
:timestamp="item.timestamp"
>
<el-timeline-item v-for="(item, index) in approvalTimeline" :key="index" :type="item.type" :timestamp="item.timestamp">
<div class="timeline-content">
<h4>{{ item.title }}</h4>
<p>{{ item.description }}</p>
@@ -33,36 +28,25 @@
<!-- 操作日志 -->
<el-divider content-position="left">操作日志</el-divider>
<el-table :data="operationLogs" style="width: 100%">
<el-table-column prop="operation" label="操作" width="120"/>
<el-table-column prop="operator" label="操作人" width="100"/>
<el-table-column prop="operation" label="操作" width="120" />
<el-table-column prop="operator" label="操作人" width="100" />
<el-table-column prop="operateTime" label="操作时间" width="180">
<template #default="scope">
{{ parseTime(scope.row.operateTime, '{y}-{m}-{d} {h}:{i}:{s}') }}
</template>
</el-table-column>
<el-table-column prop="remark" label="备注" show-overflow-tooltip/>
<el-table-column prop="remark" label="备注" show-overflow-tooltip />
</el-table>
<!-- 操作按钮 -->
<div class="operation-buttons">
<el-button
v-if="detail.approvalStatus === 'draft'"
type="primary"
@click="handleEdit"
v-hasPermi="['cw:application:edit']"
>编辑</el-button>
<el-button
v-if="detail.approvalStatus === 'draft'"
type="success"
@click="handleSubmit"
v-hasPermi="['cw:application:submit']"
>提交</el-button>
<el-button
v-if="detail.approvalStatus === 'pending'"
type="warning"
@click="handleWithdraw"
v-hasPermi="['cw:application:withdraw']"
>撤回</el-button>
<el-button v-if="detail.approvalStatus === 'draft'" type="primary" @click="handleEdit" v-hasPermi="['cw:application:edit']">编辑</el-button>
<el-button v-if="detail.approvalStatus === 'draft'" type="success" @click="handleSubmit" v-hasPermi="['cw:application:submit']"
>提交</el-button
>
<el-button v-if="detail.approvalStatus === 'pending'" type="warning" @click="handleWithdraw" v-hasPermi="['cw:application:withdraw']"
>撤回</el-button
>
<el-button @click="goBack">返回</el-button>
</div>
</el-card>
@@ -72,9 +56,9 @@
<script setup name="CwApplicationDetail">
import { ref, getCurrentInstance, onMounted } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import { getProjectApplication, submitApplication, withdrawApplication } from "@/api/cw/projectApplication";
import ApplicationSummary from "./summary.vue";
import { parseTime } from "@/utils/ruoyi";
import { getProjectApplication, submitApplication, withdrawApplication } from '@/api/cw/projectApplication';
import ApplicationSummary from './summary.vue';
import { parseTime } from '@/utils/ruoyi';
console.log('=== detail.vue 组件开始加载 ===');
@@ -120,32 +104,40 @@ function getStatusText(status) {
/** 编辑按钮操作 */
function handleEdit() {
router.push("/cw/application/form?id=" + detail.value.id);
router.push('/cw/application/form?id=' + detail.value.id);
}
/** 提交按钮操作 */
function handleSubmit() {
proxy.$modal.confirm('是否确认提交申报编号为"' + detail.value.applicationNo + '"的数据项?').then(function() {
return submitApplication(detail.value.id);
}).then(() => {
getDetail();
proxy.$modal.msgSuccess("提交成功");
}).catch(() => {});
proxy.$modal
.confirm('是否确认提交申报编号为"' + detail.value.applicationNo + '"的数据项?')
.then(function () {
return submitApplication(detail.value.id);
})
.then(() => {
getDetail();
proxy.$modal.msgSuccess('提交成功');
})
.catch(() => {});
}
/** 撤回按钮操作 */
function handleWithdraw() {
proxy.$modal.confirm('是否确认撤回申报编号为"' + detail.value.applicationNo + '"的数据项?').then(function() {
return withdrawApplication(detail.value.id);
}).then(() => {
getDetail();
proxy.$modal.msgSuccess("撤回成功");
}).catch(() => {});
proxy.$modal
.confirm('是否确认撤回申报编号为"' + detail.value.applicationNo + '"的数据项?')
.then(function () {
return withdrawApplication(detail.value.id);
})
.then(() => {
getDetail();
proxy.$modal.msgSuccess('撤回成功');
})
.catch(() => {});
}
/** 返回按钮操作 */
function goBack() {
router.push("/cw/application");
router.push('/cw/application');
}
/** 获取详情数据 */
@@ -154,78 +146,80 @@ function getDetail() {
console.log('=== 开始获取详情数据 ===');
console.log('URL参数中的ID:', id);
console.log('完整query参数:', route.query);
if (id) {
console.log('开始调用API:getProjectApplication, ID:', id);
getProjectApplication(id).then(response => {
console.log('=== API调用成功 ===');
console.log('API响应:', response);
console.log('响应代码:', response.code);
console.log('响应数据:', response.data);
detail.value = response.data;
getProjectApplication(id)
.then((response) => {
console.log('=== API调用成功 ===');
console.log('API响应:', response);
console.log('响应代码:', response.code);
console.log('响应数据:', response.data);
// 调试日志:查看返回的数据
console.log('=== 项目申报详情数据 ===');
console.log('完整数据:', response.data);
console.log('绩效指标数据:', response.data.performanceIndicators);
console.log('绩效指标数量:', response.data.performanceIndicators ? response.data.performanceIndicators.length : 0);
detail.value = response.data;
// 模拟审批流程数据
approvalTimeline.value = [
{
type: 'success',
timestamp: detail.value.createTime,
title: '申报提交',
description: '申报人提交预算申报',
user: detail.value.applicantName
// 调试日志:查看返回的数据
console.log('=== 项目申报详情数据 ===');
console.log('完整数据:', response.data);
console.log('绩效指标数据:', response.data.performanceIndicators);
console.log('绩效指标数量:', response.data.performanceIndicators ? response.data.performanceIndicators.length : 0);
// 模拟审批流程数据
approvalTimeline.value = [
{
type: 'success',
timestamp: detail.value.createTime,
title: '申报提交',
description: '申报人提交预算申报',
user: detail.value.applicantName
}
];
if (detail.value.submitTime) {
approvalTimeline.value.push({
type: 'primary',
timestamp: detail.value.submitTime,
title: '提交审批',
description: '申报已提交,等待部门审批',
user: detail.value.applicantName
});
}
];
if (detail.value.submitTime) {
approvalTimeline.value.push({
type: 'primary',
timestamp: detail.value.submitTime,
title: '提交审批',
description: '申报已提交,等待部门审批',
user: detail.value.applicantName
});
}
if (detail.value.approveTime && detail.value.approvalStatus === 'approved') {
approvalTimeline.value.push({
type: 'success',
timestamp: detail.value.approveTime,
title: '审批通过',
description: '所有审批节点已通过',
user: '系统管理员'
});
}
// 模拟操作日志数据
operationLogs.value = [
{
operation: '创建申报',
operator: detail.value.applicantName,
operateTime: detail.value.createTime,
remark: '创建项目预算申报'
if (detail.value.approveTime && detail.value.approvalStatus === 'approved') {
approvalTimeline.value.push({
type: 'success',
timestamp: detail.value.approveTime,
title: '审批通过',
description: '所有审批节点已通过',
user: '系统管理员'
});
}
];
if (detail.value.submitTime) {
operationLogs.value.push({
operation: '提交审批',
operator: detail.value.applicantName,
operateTime: detail.value.submitTime,
remark: '提交预算申报进入审批流程'
});
}
}).catch(error => {
console.error('=== API调用失败 ===');
console.error('错误信息:', error);
console.error('错误响应:', error.response);
proxy.$modal.msgError('获取申报详情失败:' + (error.message || '未知错误'));
});
// 模拟操作日志数据
operationLogs.value = [
{
operation: '创建申报',
operator: detail.value.applicantName,
operateTime: detail.value.createTime,
remark: '创建项目预算申报'
}
];
if (detail.value.submitTime) {
operationLogs.value.push({
operation: '提交审批',
operator: detail.value.applicantName,
operateTime: detail.value.submitTime,
remark: '提交预算申报进入审批流程'
});
}
})
.catch((error) => {
console.error('=== API调用失败 ===');
console.error('错误信息:', error);
console.error('错误响应:', error.response);
proxy.$modal.msgError('获取申报详情失败:' + (error.message || '未知错误'));
});
} else {
console.error('=== URL参数错误 ===');
console.error('缺少ID参数,无法获取详情数据');
File diff suppressed because it is too large. Load diff
+216 -256
View File
@@ -64,71 +64,50 @@
</div>
</template>
<el-form :model="queryParams" ref="queryRef" label-width="100px">
<el-row :gutter="20">
<el-col :span="6">
<el-form-item label="申报编号" prop="applicationNo">
<el-input
v-model="queryParams.applicationNo"
placeholder="请输入申报编号"
clearable
@keyup.enter="handleQuery"
/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="项目名称" prop="projectName">
<el-input
v-model="queryParams.projectName"
placeholder="请输入项目名称"
clearable
@keyup.enter="handleQuery"
/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="项目负责人" prop="principal">
<el-input
v-model="queryParams.principal"
placeholder="请输入项目负责人"
clearable
@keyup.enter="handleQuery"
/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="审批状态" prop="approvalStatus">
<el-row :gutter="20">
<el-col :span="6">
<el-form-item label="申报编号" prop="applicationNo">
<el-input v-model="queryParams.applicationNo" placeholder="请输入申报编号" clearable @keyup.enter="handleQuery" />
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="项目名称" prop="projectName">
<el-input v-model="queryParams.projectName" placeholder="请输入项目名称" clearable @keyup.enter="handleQuery" />
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="项目负责人" prop="principal">
<el-input v-model="queryParams.principal" placeholder="请输入项目负责人" clearable @keyup.enter="handleQuery" />
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="审批状态" prop="approvalStatus">
<el-select v-model="queryParams.approvalStatus" placeholder="请选择审批状态" clearable style="width: 100%">
<el-option label="草稿" value="draft"/>
<el-option label="已提交" value="submitted"/>
<el-option label="审批中" value="approving"/>
<el-option label="已通过" value="approved"/>
<el-option label="已拒绝" value="rejected"/>
<el-option label="已退回" value="returned"/>
<el-option label="已取消" value="cancelled"/>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="6">
<el-form-item label="预算年度" prop="year">
<el-date-picker
v-model="queryParams.year"
type="year"
placeholder="选择年份"
value-format="YYYY"
style="width: 100%"
/>
</el-form-item>
</el-col>
<el-col :span="18">
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
</el-form-item>
</el-col>
</el-row>
</el-form>
<el-option label="草稿" value="draft" />
<el-option label="已提交" value="submitted" />
<el-option label="审批中" value="approving" />
<el-option label="已通过" value="approved" />
<el-option label="已拒绝" value="rejected" />
<el-option label="已退回" value="returned" />
<el-option label="已取消" value="cancelled" />
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="6">
<el-form-item label="预算年度" prop="year">
<el-date-picker v-model="queryParams.year" type="year" placeholder="选择年份" value-format="YYYY" style="width: 100%" />
</el-form-item>
</el-col>
<el-col :span="18">
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
</el-form-item>
</el-col>
</el-row>
</el-form>
</el-card>
<!-- 操作按钮区域 -->
@@ -137,40 +116,14 @@
<div class="card-header">
<span class="toolbar-title">项目申报管理</span>
<div class="toolbar-actions">
<el-button
type="primary"
icon="Plus"
@click="handleAdd"
v-hasPermi="['cw:application:add']"
>新增申报</el-button>
<el-button
type="success"
icon="Edit"
:disabled="single"
@click="handleUpdate"
v-hasPermi="['cw:application:edit']"
>修改</el-button>
<el-button
type="danger"
icon="Delete"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['cw:application:remove']"
>删除</el-button>
<el-button
type="info"
icon="Upload"
@click="handleSubmit"
:disabled="multiple"
v-hasPermi="['cw:application:submit']"
>提交审批</el-button>
<el-button
type="warning"
icon="Download"
@click="handleExport"
v-hasPermi="['cw:application:export']"
>导出</el-button>
<right-toolbar :showSearch="showSearch" @update:showSearch="showSearch = $event" @queryTable="getList"></right-toolbar>
<el-button type="primary" icon="Plus" @click="handleAdd" v-hasPermi="['cw:application:add']">新增申报</el-button>
<el-button type="success" icon="Edit" :disabled="single" @click="handleUpdate" v-hasPermi="['cw:application:edit']">修改</el-button>
<el-button type="danger" icon="Delete" :disabled="multiple" @click="handleDelete" v-hasPermi="['cw:application:remove']">删除</el-button>
<el-button type="info" icon="Upload" @click="handleSubmit" :disabled="multiple" v-hasPermi="['cw:application:submit']"
>提交审批</el-button
>
<el-button type="warning" icon="Download" @click="handleExport" v-hasPermi="['cw:application:export']">导出</el-button>
<right-toolbar :showSearch="showSearch" @update:showSearch="showSearch = $event" @queryTable="getList"></right-toolbar>
</div>
</div>
</template>
@@ -179,13 +132,8 @@
<!-- 数据表格区域 -->
<el-card class="table-card">
<div class="table-container">
<el-table
v-loading="loading"
:data="applicationList"
@selection-change="handleSelectionChange"
class="scroll-table"
>
<el-table-column type="selection" width="55" align="center" />
<el-table v-loading="loading" :data="applicationList" @selection-change="handleSelectionChange" class="scroll-table">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="申报编号" align="center" prop="applicationNo" min-width="140" />
<el-table-column label="项目名称" align="center" prop="projectName" min-width="180" show-overflow-tooltip />
<el-table-column label="项目负责人" align="center" prop="principal" min-width="100" />
@@ -197,43 +145,26 @@
</template>
</el-table-column>
<el-table-column label="审批状态" align="center" prop="approvalStatus" width="100">
<template #default="scope">
<el-tag
:type="getStatusTagType(scope.row.approvalStatus)"
effect="light"
>
{{ getStatusText(scope.row.approvalStatus) }}
</el-tag>
</template>
</el-table-column>
<template #default="scope">
<el-tag :type="getStatusTagType(scope.row.approvalStatus)" effect="light">
{{ getStatusText(scope.row.approvalStatus) }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="创建时间" align="center" prop="createTime" min-width="160">
<template #default="scope">
<template #default="scope">
<span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d} {h}:{i}') }}</span>
</template>
</el-table-column>
</template>
</el-table-column>
<el-table-column label="操作" align="center" width="280" class-name="small-padding fixed-width">
<template #default="scope">
<template #default="scope">
<div class="action-buttons">
<el-tooltip content="查看详情" placement="top">
<el-button
type="primary"
icon="View"
circle
size="small"
@click="handleView(scope.row)"
v-hasPermi="['cw:application:query']"
/>
</el-tooltip>
<el-tooltip content="查看详情" placement="top">
<el-button type="primary" icon="View" circle size="small" @click="handleView(scope.row)" v-hasPermi="['cw:application:query']" />
</el-tooltip>
<el-tooltip content="编辑" placement="top" v-if="['draft', 'returned'].includes(scope.row.approvalStatus)">
<el-button
type="success"
icon="Edit"
circle
size="small"
@click="handleUpdate(scope.row)"
v-hasPermi="['cw:application:edit']"
/>
</el-tooltip>
<el-button type="success" icon="Edit" circle size="small" @click="handleUpdate(scope.row)" v-hasPermi="['cw:application:edit']" />
</el-tooltip>
<el-tooltip content="提交审批" placement="top" v-if="['draft', 'returned'].includes(scope.row.approvalStatus)">
<el-button
type="warning"
@@ -243,7 +174,7 @@
@click="handleSubmit(scope.row)"
v-hasPermi="['cw:application:submit']"
/>
</el-tooltip>
</el-tooltip>
<el-tooltip content="撤回" placement="top" v-if="scope.row.approvalStatus === 'submitted'">
<el-button
type="info"
@@ -253,7 +184,7 @@
@click="handleWithdraw(scope.row)"
v-hasPermi="['cw:application:withdraw']"
/>
</el-tooltip>
</el-tooltip>
<el-tooltip content="删除" placement="top" v-if="['draft', 'cancelled', 'returned'].includes(scope.row.approvalStatus)">
<el-button
type="danger"
@@ -263,17 +194,17 @@
@click="handleDelete(scope.row)"
v-hasPermi="['cw:application:remove']"
/>
</el-tooltip>
</el-tooltip>
</div>
</template>
</el-table-column>
</el-table>
</template>
</el-table-column>
</el-table>
</div>
<!-- 分页 -->
<div class="pagination-container">
<pagination
v-show="total>0"
v-show="total > 0"
:total="total"
:page="queryParams.pageNum"
:limit="queryParams.pageSize"
@@ -307,13 +238,21 @@
</template>
<script>
import { listProjectApplication, getProjectApplication, delProjectApplication, addProjectApplication, updateProjectApplication, submitApplication, getApplicationStatistics } from "@/api/cw/projectApplication"
import ApplicationForm from "./form.vue"
import ApplicationSummary from "./summary.vue"
import Pagination from "@/components/Pagination/index.vue"
import {
listProjectApplication,
getProjectApplication,
delProjectApplication,
addProjectApplication,
updateProjectApplication,
submitApplication,
getApplicationStatistics
} from '@/api/cw/projectApplication';
import ApplicationForm from './form.vue';
import ApplicationSummary from './summary.vue';
import Pagination from '@/components/Pagination/index.vue';
export default {
name: "ProjectApplication",
name: 'ProjectApplication',
components: {
ApplicationForm,
ApplicationSummary,
@@ -336,7 +275,7 @@ export default {
// 项目申报表格数据
applicationList: [],
// 弹出层标题
title: "",
title: '',
// 是否显示弹出层
open: false,
// 是否显示查看对话框
@@ -362,52 +301,56 @@ export default {
approvedCount: 0,
pendingCount: 0,
draftCount: 0
}
};
},
created() {
this.getList()
this.getStatistics()
this.getList();
this.getStatistics();
},
methods: {
/** 查询项目申报列表 */
getList() {
this.loading = true
listProjectApplication(this.queryParams).then(response => {
this.applicationList = response.rows
this.total = response.total
this.loading = false
}).catch(error => {
console.error('获取项目申报列表失败:', error)
this.loading = false
this.applicationList = []
this.total = 0
// 可以添加用户友好的错误提示
this.$message.error('获取数据失败,请检查网络连接或联系管理员')
})
this.loading = true;
listProjectApplication(this.queryParams)
.then((response) => {
this.applicationList = response.rows;
this.total = response.total;
this.loading = false;
})
.catch((error) => {
console.error('获取项目申报列表失败:', error);
this.loading = false;
this.applicationList = [];
this.total = 0;
// 可以添加用户友好的错误提示
this.$message.error('获取数据失败,请检查网络连接或联系管理员');
});
},
/** 获取统计数据 */
getStatistics() {
// 调用专门的统计API接口
const year = this.queryParams.year ? parseInt(this.queryParams.year) : null
getApplicationStatistics(year).then(response => {
const data = response.data
this.totalCount = data.totalCount || 0
this.approvedCount = data.approvedCount || 0
this.pendingCount = data.approvingCount || 0 // 注意:后端返回的是approvingCount
this.draftCount = data.draftCount || 0
}).catch(error => {
console.error('获取统计数据失败:', error)
// 如果API失败,使用本地计算作为后备方案
this.totalCount = this.applicationList.length
this.approvedCount = this.applicationList.filter(item => item.approvalStatus === 'approved').length
this.pendingCount = this.applicationList.filter(item => item.approvalStatus === 'approving').length
this.draftCount = this.applicationList.filter(item => item.approvalStatus === 'draft').length
})
const year = this.queryParams.year ? parseInt(this.queryParams.year) : null;
getApplicationStatistics(year)
.then((response) => {
const data = response.data;
this.totalCount = data.totalCount || 0;
this.approvedCount = data.approvedCount || 0;
this.pendingCount = data.approvingCount || 0; // 注意:后端返回的是approvingCount
this.draftCount = data.draftCount || 0;
})
.catch((error) => {
console.error('获取统计数据失败:', error);
// 如果API失败,使用本地计算作为后备方案
this.totalCount = this.applicationList.length;
this.approvedCount = this.applicationList.filter((item) => item.approvalStatus === 'approved').length;
this.pendingCount = this.applicationList.filter((item) => item.approvalStatus === 'approving').length;
this.draftCount = this.applicationList.filter((item) => item.approvalStatus === 'draft').length;
});
},
/** 取消按钮 */
cancel() {
this.open = false
this.reset()
this.open = false;
this.reset();
},
/** 表单重置 */
reset() {
@@ -448,119 +391,136 @@ export default {
futureYearOther: 0,
performanceIndicators: [],
approvalStatus: 'draft'
}
};
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1
this.getList()
this.getStatistics() // 搜索时也更新统计数据
this.queryParams.pageNum = 1;
this.getList();
this.getStatistics(); // 搜索时也更新统计数据
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryRef")
this.handleQuery()
this.resetForm('queryRef');
this.handleQuery();
},
// 多选框选中数据
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id)
this.single = selection.length !== 1
this.multiple = !selection.length
this.ids = selection.map((item) => item.id);
this.single = selection.length !== 1;
this.multiple = !selection.length;
},
/** 新增按钮操作 */
handleAdd() {
this.reset()
this.open = true
this.title = "添加项目申报"
this.reset();
this.open = true;
this.title = '添加项目申报';
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset()
const id = row.id || this.ids
getProjectApplication(id).then(response => {
this.form = response.data
this.open = true
this.title = "修改项目申报"
})
this.reset();
const id = row.id || this.ids;
getProjectApplication(id).then((response) => {
this.form = response.data;
this.open = true;
this.title = '修改项目申报';
});
},
/** 查看详情 */
handleView(row) {
this.currentId = row.id
this.viewOpen = true
this.currentId = row.id;
this.viewOpen = true;
},
/** 提交按钮 */
submitForm() {
this.$refs["applicationFormRef"].validate((valid, formData) => {
this.$refs['applicationFormRef'].validate((valid, formData) => {
if (valid && formData) {
// 使用子组件回传的完整数据(包含绩效指标)
this.form = formData
console.log('提交表单数据:', this.form)
this.form = formData;
console.log('提交表单数据:', this.form);
if (this.form.id != null) {
updateProjectApplication(this.form).then(response => {
this.$modal.msgSuccess("修改成功")
this.open = false
this.getList()
this.getStatistics() // 修改后更新统计
})
updateProjectApplication(this.form).then((response) => {
this.$modal.msgSuccess('修改成功');
this.open = false;
this.getList();
this.getStatistics(); // 修改后更新统计
});
} else {
addProjectApplication(this.form).then(response => {
this.$modal.msgSuccess("新增成功")
this.open = false
this.getList()
this.getStatistics() // 新增后更新统计
})
addProjectApplication(this.form).then((response) => {
this.$modal.msgSuccess('新增成功');
this.open = false;
this.getList();
this.getStatistics(); // 新增后更新统计
});
}
} else {
this.$modal.msgError("请检查表单数据是否完整")
this.$modal.msgError('请检查表单数据是否完整');
}
})
});
},
/** 删除按钮操作 */
handleDelete(row) {
const ids = row.id || this.ids
this.$modal.confirm('是否确认删除项目申报编号为"' + ids + '"的数据项?').then(function() {
return delProjectApplication(ids)
}).then(() => {
this.getList()
this.getStatistics() // 删除后更新统计
this.$modal.msgSuccess("删除成功")
}).catch(() => {})
const ids = row.id || this.ids;
this.$modal
.confirm('是否确认删除项目申报编号为"' + ids + '"的数据项?')
.then(function () {
return delProjectApplication(ids);
})
.then(() => {
this.getList();
this.getStatistics(); // 删除后更新统计
this.$modal.msgSuccess('删除成功');
})
.catch(() => {});
},
/** 提交审批 */
handleSubmit(row) {
const applications = row?.applicationNo ? [row.applicationNo] : this.applicationList.filter(item => this.ids.includes(item.id)).map(item => item.applicationNo)
const applications = row?.applicationNo
? [row.applicationNo]
: this.applicationList.filter((item) => this.ids.includes(item.id)).map((item) => item.applicationNo);
this.$modal.confirm('是否确认提交申报编号为"' + applications.join('", "') + '"的数据项?').then(() => {
return submitApplication(row?.id || this.ids)
}).then(() => {
this.getList()
this.getStatistics() // 提交后更新统计
this.$modal.msgSuccess("提交成功")
}).catch(() => {})
this.$modal
.confirm('是否确认提交申报编号为"' + applications.join('", "') + '"的数据项?')
.then(() => {
return submitApplication(row?.id || this.ids);
})
.then(() => {
this.getList();
this.getStatistics(); // 提交后更新统计
this.$modal.msgSuccess('提交成功');
})
.catch(() => {});
},
/** 撤回申请 */
handleWithdraw(row) {
this.$modal.confirm('是否确认撤回该申报?').then(() => {
// 调用撤回接口
this.$modal.msgSuccess("撤回成功")
this.getList()
this.getStatistics() // 撤回后更新统计
}).catch(() => {})
this.$modal
.confirm('是否确认撤回该申报?')
.then(() => {
// 调用撤回接口
this.$modal.msgSuccess('撤回成功');
this.getList();
this.getStatistics(); // 撤回后更新统计
})
.catch(() => {});
},
/** 导出按钮操作 */
handleExport() {
this.download('cw/application/export', {
...this.queryParams
}, `application_${new Date().getTime()}.xlsx`)
this.download(
'cw/application/export',
{
...this.queryParams
},
`application_${new Date().getTime()}.xlsx`
);
},
/** 格式化金额 */
formatAmount(amount) {
if (!amount) return '0.00'
if (!amount) return '0.00';
return parseFloat(amount).toLocaleString('zh-CN', {
minimumFractionDigits: 2,
maximumFractionDigits: 2
})
});
},
/** 获取状态标签类型 */
getStatusTagType(status) {
@@ -572,8 +532,8 @@ export default {
rejected: 'danger',
returned: 'warning',
cancelled: 'info'
}
return statusMap[status] || 'info'
};
return statusMap[status] || 'info';
},
/** 获取状态文本 */
getStatusText(status) {
@@ -585,11 +545,11 @@ export default {
rejected: '已拒绝',
returned: '已退回',
cancelled: '已取消'
}
return statusMap[status] || '未知'
};
return statusMap[status] || '未知';
}
}
}
};
</script>
<style scoped lang="scss">
@@ -614,8 +574,8 @@ export default {
}
.stat-content {
display: flex;
align-items: center;
display: flex;
align-items: center;
padding: 5px 16px;
height: 100%;
box-sizing: border-box;
@@ -637,7 +597,7 @@ export default {
}
.stat-label {
font-size: 14px;
font-size: 14px;
opacity: 0.8;
line-height: 1;
}
+13 -14
View File
@@ -38,9 +38,7 @@
</template>
<el-row :gutter="20">
<el-col :span="8">
<el-tag :type="currentApplication.targetSme ? 'success' : 'info'">
小微企业发展: {{ currentApplication.targetSme ? '是' : '否' }}
</el-tag>
<el-tag :type="currentApplication.targetSme ? 'success' : 'info'"> 小微企业发展: {{ currentApplication.targetSme ? '是' : '否' }} </el-tag>
</el-col>
<el-col :span="8">
<el-tag :type="currentApplication.targetMicroSme ? 'success' : 'info'">
@@ -122,7 +120,7 @@
<div class="budget-section">
<h4>分年度预算明细</h4>
<el-table :data="budgetBreakdown" border>
<el-table-column prop="year" label="年度" width="120" align="center"/>
<el-table-column prop="year" label="年度" width="120" align="center" />
<el-table-column prop="total" label="总投资" align="right">
<template #default="scope">
{{ formatAmount(scope.row.total) }}
@@ -280,11 +278,15 @@ const fetchApplicationData = async (id) => {
};
// 监听applicationId变化
watch(() => props.applicationId, (newId) => {
if (newId && (!props.application || Object.keys(props.application).length === 0)) {
fetchApplicationData(newId);
}
}, { immediate: true });
watch(
() => props.applicationId,
(newId) => {
if (newId && (!props.application || Object.keys(props.application).length === 0)) {
fetchApplicationData(newId);
}
},
{ immediate: true }
);
// 组件挂载时检查是否需要获取数据
onMounted(() => {
@@ -301,10 +303,7 @@ onMounted(() => {
// 判断是否有项目内容
const hasProjectContent = computed(() => {
const app = currentApplication.value;
return app.applicationReason ||
app.constructionContent ||
app.totalPerformanceGoal ||
app.currentYearGoal;
return app.applicationReason || app.constructionContent || app.totalPerformanceGoal || app.currentYearGoal;
});
// 判断是否有绩效指标
@@ -352,7 +351,7 @@ const validPerformanceIndicators = computed(() => {
return [];
}
const validIndicators = app.performanceIndicators.filter(indicator => {
const validIndicators = app.performanceIndicators.filter((indicator) => {
const weight = parseFloat(indicator.weightPercentage) || 0;
console.log(`指标 ${indicator.goalName}: 权重=${indicator.weightPercentage}, 解析后权重=${weight}, 是否有效=${weight > 0}`);
return weight > 0;
+48 -95
View File
@@ -2,31 +2,13 @@
<div class="app-container">
<el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch">
<el-form-item label="申报编号" prop="applicationNo">
<el-input
v-model="queryParams.applicationNo"
placeholder="请输入申报编号"
clearable
style="width: 200px"
@keyup.enter="handleQuery"
/>
<el-input v-model="queryParams.applicationNo" placeholder="请输入申报编号" clearable style="width: 200px" @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item label="项目名称" prop="projectName">
<el-input
v-model="queryParams.projectName"
placeholder="请输入项目名称"
clearable
style="width: 200px"
@keyup.enter="handleQuery"
/>
<el-input v-model="queryParams.projectName" placeholder="请输入项目名称" clearable style="width: 200px" @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item label="申报人" prop="applicantName">
<el-input
v-model="queryParams.applicantName"
placeholder="请输入申报人"
clearable
style="width: 200px"
@keyup.enter="handleQuery"
/>
<el-input v-model="queryParams.applicantName" placeholder="请输入申报人" clearable style="width: 200px" @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
@@ -37,28 +19,13 @@
<!-- 快速操作按钮 -->
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="Check"
@click="showPendingApprovals"
>待我审批</el-button>
<el-button type="primary" plain icon="Check" @click="showPendingApprovals">待我审批</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="success"
plain
icon="CircleCheck"
@click="showMyApprovals"
>我已审批</el-button>
<el-button type="success" plain icon="CircleCheck" @click="showMyApprovals">我已审批</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="info"
plain
icon="Download"
@click="handleExport"
>导出</el-button>
<el-button type="info" plain icon="Download" @click="handleExport">导出</el-button>
</el-col>
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
@@ -73,7 +40,7 @@
<el-table-column label="审批节点" align="center" prop="nodeName" />
<el-table-column label="审批状态" align="center" prop="nodeStatus">
<template #default="scope">
<dict-tag :options="cw_approval_status" :value="scope.row.nodeStatus"/>
<dict-tag :options="cw_approval_status" :value="scope.row.nodeStatus" />
</template>
</el-table-column>
<el-table-column label="审批人" align="center" prop="approverName" />
@@ -95,13 +62,7 @@
</el-table-column>
</el-table>
<pagination
v-show="total > 0"
:total="total"
v-model:page="queryParams.pageNum"
v-model:limit="queryParams.pageSize"
@pagination="getList"
/>
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
<!-- 审批对话框 -->
<el-dialog title="审批处理" v-model="approvalOpen" width="500px" append-to-body>
@@ -113,14 +74,7 @@
</el-radio-group>
</el-form-item>
<el-form-item label="审批意见" prop="approvalComment">
<el-input
v-model="approvalForm.approvalComment"
type="textarea"
placeholder="请输入审批意见"
:rows="3"
maxlength="500"
show-word-limit
/>
<el-input v-model="approvalForm.approvalComment" type="textarea" placeholder="请输入审批意见" :rows="3" maxlength="500" show-word-limit />
</el-form-item>
</el-form>
<template #footer>
@@ -144,18 +98,12 @@
</template>
<script>
import {
listApprovalRecord,
exportApprovalRecord,
approveApplication,
getMyApprovals,
getDepartmentApprovals
} from '@/api/cw/approvalRecord';
import { listApprovalRecord, exportApprovalRecord, approveApplication, getMyApprovals, getDepartmentApprovals } from '@/api/cw/approvalRecord';
import { parseTime } from '@/utils/ruoyi';
import ApplicationSummary from '../application/summary.vue';
export default {
name: "ApprovalRecord",
name: 'ApprovalRecord',
components: {
ApplicationSummary
},
@@ -200,9 +148,7 @@ export default {
},
// 审批表单校验
approvalRules: {
approvalResult: [
{ required: true, message: "审批结果不能为空", trigger: "change" }
]
approvalResult: [{ required: true, message: '审批结果不能为空', trigger: 'change' }]
}
};
},
@@ -214,7 +160,7 @@ export default {
/** 查询审批记录列表 */
getList() {
this.loading = true;
listApprovalRecord(this.queryParams).then(response => {
listApprovalRecord(this.queryParams).then((response) => {
this.approvalRecordList = response.rows;
this.total = response.total;
this.loading = false;
@@ -223,25 +169,29 @@ export default {
/** 查询待我审批的记录 */
showPendingApprovals() {
this.loading = true;
getDepartmentApprovals({}).then(response => {
this.approvalRecordList = response.data || [];
this.total = this.approvalRecordList.length;
this.loading = false;
}).catch(() => {
this.loading = false;
});
getDepartmentApprovals({})
.then((response) => {
this.approvalRecordList = response.data || [];
this.total = this.approvalRecordList.length;
this.loading = false;
})
.catch(() => {
this.loading = false;
});
},
/** 查询我已审批的记录 */
showMyApprovals() {
this.loading = true;
getMyApprovals({}).then(response => {
this.approvalRecordList = response.data || [];
this.total = this.approvalRecordList.length;
this.loading = false;
}).catch(error => {
this.loading = false;
this.$modal.msgError('获取已审批记录失败:' + (error.message || '未知错误'));
});
getMyApprovals({})
.then((response) => {
this.approvalRecordList = response.data || [];
this.total = this.approvalRecordList.length;
this.loading = false;
})
.catch((error) => {
this.loading = false;
this.$modal.msgError('获取已审批记录失败:' + (error.message || '未知错误'));
});
},
/** 搜索按钮操作 */
handleQuery() {
@@ -250,12 +200,12 @@ export default {
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryRef");
this.resetForm('queryRef');
this.handleQuery();
},
// 多选框选中数据
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id);
this.ids = selection.map((item) => item.id);
this.single = selection.length !== 1;
this.multiple = !selection.length;
},
@@ -270,10 +220,10 @@ export default {
},
/** 提交审批 */
submitApproval() {
this.$refs.approvalRef.validate(valid => {
this.$refs.approvalRef.validate((valid) => {
if (valid) {
approveApplication(this.approvalForm).then(response => {
this.$modal.msgSuccess("审批成功");
approveApplication(this.approvalForm).then((response) => {
this.$modal.msgSuccess('审批成功');
this.approvalOpen = false;
this.getList();
});
@@ -288,7 +238,7 @@ export default {
approvalComment: ''
};
this.approvalOpen = false;
this.resetForm("approvalRef");
this.resetForm('approvalRef');
},
/** 详情操作 - 完全复制预算申报页面的实现 */
handleDetail(row) {
@@ -297,9 +247,13 @@ export default {
},
/** 导出按钮操作 */
handleExport() {
this.download('cw/approval/export', {
...this.queryParams
}, `approval_record_${new Date().getTime()}.xlsx`)
this.download(
'cw/approval/export',
{
...this.queryParams
},
`approval_record_${new Date().getTime()}.xlsx`
);
},
// 手动加载字典数据
async loadDictData() {
@@ -321,13 +275,13 @@ export default {
await this.loadDictFromApi();
}
},
// 从API直接加载字典数据
async loadDictFromApi() {
try {
const response = await this.$http.get('/system/dict/data/type/cw_approval_status');
if (response.code === 200 && response.data) {
this.cw_approval_status = response.data.map(item => ({
this.cw_approval_status = response.data.map((item) => ({
label: item.dictLabel,
value: item.dictValue,
cssClass: item.cssClass,
@@ -354,5 +308,4 @@ export default {
};
</script>
<style scoped>
</style>
<style scoped></style>
+34 -48
View File
@@ -32,7 +32,7 @@
{{ parseTime(config.createTime, '{y}-{m}-{d} {h}:{i}') }}
</el-descriptions-item>
</el-descriptions>
<div v-if="config.description" class="mt-4">
<h4 class="section-title">配置描述</h4>
<p class="description-text">{{ config.description }}</p>
@@ -48,22 +48,18 @@
<el-tag type="info" size="small">共 {{ config.steps.length }} 个步骤</el-tag>
</div>
</template>
<el-steps :active="config.steps.length" finish-status="success" align-center>
<el-step
v-for="(step, index) in config.steps"
<el-step
v-for="(step, index) in config.steps"
:key="index"
:title="step.stepName"
:description="`${getApprovalModeText(step.approvalMode)} | ${step.timeoutHours}小时`"
/>
</el-steps>
<div class="steps-detail mt-6">
<div
v-for="(step, index) in config.steps"
:key="index"
class="step-detail-item"
>
<div v-for="(step, index) in config.steps" :key="index" class="step-detail-item">
<el-card shadow="hover" class="step-detail-card">
<template #header>
<div class="step-header">
@@ -74,7 +70,7 @@
</el-tag>
</div>
</template>
<el-row :gutter="20">
<el-col :span="8">
<div class="step-info">
@@ -95,34 +91,24 @@
</div>
</el-col>
</el-row>
<div class="approvers-section mt-4" v-if="step.approvers && step.approvers.length > 0">
<label class="info-label">审批人员:</label>
<div class="approvers-list">
<el-tag
v-for="(approver, approverIndex) in step.approverNames"
:key="approverIndex"
class="approver-tag"
>
<el-tag v-for="(approver, approverIndex) in step.approverNames" :key="approverIndex" class="approver-tag">
{{ approver }}
</el-tag>
</div>
</div>
<div v-else-if="config.approvalType === 'custom'" class="custom-approver-notice">
<el-alert
title="自选审批人"
description="申报人在提交时自行选择审批人"
type="info"
show-icon
:closable="false"
/>
<el-alert title="自选审批人" description="申报人在提交时自行选择审批人" type="info" show-icon :closable="false" />
</div>
</el-card>
</div>
</div>
</el-card>
<!-- 无流程步骤时的提示 -->
<el-card class="detail-card" v-else>
<el-empty description="暂无配置的审批流程步骤" />
@@ -144,13 +130,13 @@ export default {
getApprovalTypeTag(type) {
const typeMap = {
'fixed': 'success',
'role': 'warning',
'role': 'warning',
'dept': 'info',
'custom': 'primary'
};
return typeMap[type] || 'info';
},
/** 获取审批类型文本 */
getApprovalTypeText(type) {
const textMap = {
@@ -161,7 +147,7 @@ export default {
};
return textMap[type] || type;
},
/** 获取适用范围文本 */
getScopeText(scope) {
const scopeMap = {
@@ -172,7 +158,7 @@ export default {
};
return scopeMap[scope] || scope;
},
/** 获取审批方式文本 */
getApprovalModeText(mode) {
const modeMap = {
@@ -182,7 +168,7 @@ export default {
};
return modeMap[mode] || mode;
},
/** 获取审批方式标签类型 */
getModeTagType(mode) {
const typeMap = {
@@ -201,7 +187,7 @@ export default {
.detail-card {
border-radius: 8px;
border: 1px solid #e4e7ed;
.card-header {
display: flex;
align-items: center;
@@ -210,14 +196,14 @@ export default {
color: #2c3e50;
}
}
.section-title {
margin: 0 0 12px 0;
font-size: 16px;
font-weight: 600;
color: #2c3e50;
}
.description-text {
margin: 0;
padding: 12px;
@@ -226,24 +212,24 @@ export default {
color: #606266;
line-height: 1.6;
}
.steps-detail {
.step-detail-item {
margin-bottom: 16px;
&:last-child {
margin-bottom: 0;
}
}
.step-detail-card {
border: 1px solid #e4e7ed;
.step-header {
display: flex;
align-items: center;
gap: 12px;
.step-number {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
@@ -252,7 +238,7 @@ export default {
font-size: 12px;
font-weight: 600;
}
.step-name {
font-weight: 600;
color: #2c3e50;
@@ -260,12 +246,12 @@ export default {
}
}
}
.step-info {
display: flex;
align-items: center;
margin-bottom: 8px;
.info-label {
font-weight: 600;
color: #909399;
@@ -273,23 +259,23 @@ export default {
min-width: 80px;
}
}
.approvers-section {
border-top: 1px solid #f0f0f0;
padding-top: 16px;
.info-label {
font-weight: 600;
color: #909399;
margin-bottom: 8px;
display: block;
}
.approvers-list {
display: flex;
flex-wrap: wrap;
gap: 8px;
.approver-tag {
background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
color: white;
@@ -297,7 +283,7 @@ export default {
}
}
}
.custom-approver-notice {
border-top: 1px solid #f0f0f0;
padding-top: 16px;
@@ -316,4 +302,4 @@ export default {
.mt-6 {
margin-top: 24px;
}
</style>
</style>
+131 -167
View File
@@ -85,10 +85,14 @@
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['cw:approverConfig:add']">新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate" v-hasPermi="['cw:approverConfig:edit']">修改</el-button>
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate" v-hasPermi="['cw:approverConfig:edit']"
>修改</el-button
>
</el-col>
<el-col :span="1.5">
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete" v-hasPermi="['cw:approverConfig:remove']">删除</el-button>
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete" v-hasPermi="['cw:approverConfig:remove']"
>删除</el-button
>
</el-col>
<el-col :span="1.5">
<el-button type="info" plain icon="Sort" @click="toggleExpandAll">展开/折叠</el-button>
@@ -125,12 +129,7 @@
</el-table-column>
<el-table-column label="审批人" align="center" prop="approverNames" min-width="180" show-overflow-tooltip>
<template #default="scope">
<el-tag
v-for="(name, index) in scope.row.approverNames"
:key="index"
size="small"
class="mr-1"
>
<el-tag v-for="(name, index) in scope.row.approverNames" :key="index" size="small" class="mr-1">
{{ name }}
</el-tag>
</template>
@@ -178,13 +177,7 @@
</el-table-column>
</el-table>
<pagination
v-show="total > 0"
:total="total"
v-model:page="queryParams.pageNum"
v-model:limit="queryParams.pageSize"
@pagination="getList"
/>
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
</el-card>
<!-- 添加或修改审批人配置对话框 -->
@@ -241,13 +234,9 @@
<el-button type="primary" size="small" icon="Plus" @click="addStep">添加步骤</el-button>
</div>
</template>
<div v-if="form.steps && form.steps.length > 0" class="steps-container">
<div
v-for="(step, index) in form.steps"
:key="index"
class="step-item"
>
<div v-for="(step, index) in form.steps" :key="index" class="step-item">
<el-card shadow="hover" class="step-card">
<template #header>
<div class="step-header">
@@ -268,7 +257,7 @@
</div>
</div>
</template>
<el-row :gutter="20">
<el-col :span="8">
<el-form-item label="步骤名称" :prop="`steps.${index}.stepName`" :rules="stepRules.stepName">
@@ -290,46 +279,25 @@
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="审批人设置" :prop="`steps.${index}.approvers`" :rules="stepRules.approvers">
<div class="approvers-container">
<!-- 固定审批人 -->
<div v-if="form.approvalType === 'fixed'">
<el-select
v-model="step.approvers"
multiple
placeholder="请选择审批人"
style="width: 100%"
@change="updateApproverNames"
>
<el-option
v-for="user in userList"
:key="user.userId"
:label="user.nickName"
:value="user.userId"
/>
<el-select v-model="step.approvers" multiple placeholder="请选择审批人" style="width: 100%" @change="updateApproverNames">
<el-option v-for="user in userList" :key="user.userId" :label="user.nickName" :value="user.userId" />
</el-select>
</div>
<!-- 角色审批 -->
<div v-else-if="form.approvalType === 'role'">
<el-select
v-model="step.approvers"
multiple
placeholder="请选择审批角色"
style="width: 100%"
>
<el-option
v-for="role in roleList"
:key="role.roleId"
:label="role.roleName"
:value="role.roleId"
/>
<el-select v-model="step.approvers" multiple placeholder="请选择审批角色" style="width: 100%">
<el-option v-for="role in roleList" :key="role.roleId" :label="role.roleName" :value="role.roleId" />
</el-select>
</div>
<!-- 部门审批 -->
<div v-else-if="form.approvalType === 'dept'">
<el-tree-select
@@ -341,7 +309,7 @@
style="width: 100%"
/>
</div>
<!-- 自选审批人 -->
<div v-else-if="form.approvalType === 'custom'">
<el-alert
@@ -359,12 +327,12 @@
</el-card>
</div>
</div>
<el-empty v-else description="暂无审批步骤,请添加步骤" />
</el-card>
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button @click="cancel">取消</el-button>
@@ -385,7 +353,7 @@
<!-- 流程图对话框 -->
<el-dialog v-model="flowDialog.visible" title="审批流程图" width="1200px" append-to-body>
<div ref="flowChartRef" style="height: 500px; border: 1px solid #e4e7ed;"></div>
<div ref="flowChartRef" style="height: 500px; border: 1px solid #e4e7ed"></div>
<template #footer>
<div class="dialog-footer">
<el-button @click="flowDialog.visible = false">关闭</el-button>
@@ -396,13 +364,7 @@
</template>
<script>
import {
listApproverConfig,
getApproverConfig,
addApproverConfig,
updateApproverConfig,
delApproverConfig
} from "@/api/cw/projectApplication";
import { listApproverConfig, getApproverConfig, addApproverConfig, updateApproverConfig, delApproverConfig } from '@/api/cw/projectApplication';
export default {
name: 'CwApproverConfig',
@@ -454,27 +416,17 @@ export default {
// 表单校验
rules: {
configName: [
{ required: true, message: "配置名称不能为空", trigger: "blur" },
{ min: 2, max: 50, message: "配置名称长度在 2 到 50 个字符", trigger: "blur" }
{ required: true, message: '配置名称不能为空', trigger: 'blur' },
{ min: 2, max: 50, message: '配置名称长度在 2 到 50 个字符', trigger: 'blur' }
],
approvalType: [
{ required: true, message: "审批类型不能为空", trigger: "change" }
],
applicableScope: [
{ required: true, message: "适用范围不能为空", trigger: "change" }
]
approvalType: [{ required: true, message: '审批类型不能为空', trigger: 'change' }],
applicableScope: [{ required: true, message: '适用范围不能为空', trigger: 'change' }]
},
// 步骤表单校验
stepRules: {
stepName: [
{ required: true, message: "步骤名称不能为空", trigger: "blur" }
],
approvalMode: [
{ required: true, message: "审批方式不能为空", trigger: "change" }
],
approvers: [
{ required: true, message: "请设置审批人", trigger: "change" }
]
stepName: [{ required: true, message: '步骤名称不能为空', trigger: 'blur' }],
approvalMode: [{ required: true, message: '审批方式不能为空', trigger: 'change' }],
approvers: [{ required: true, message: '请设置审批人', trigger: 'change' }]
},
// 用户列表
userList: [],
@@ -492,37 +444,35 @@ export default {
/** 查询审批人配置列表 */
getList() {
this.loading = true;
listApproverConfig(this.queryParams).then(response => {
this.configList = this.handleTree(response.data, "id", "parentId");
listApproverConfig(this.queryParams).then((response) => {
this.configList = this.handleTree(response.data, 'id', 'parentId');
this.total = response.total;
this.loading = false;
});
},
/** 加载基础数据 */
loadBasicData() {
// 加载用户列表
// listUser().then(response => {
// this.userList = response.rows;
// });
// 加载角色列表
// listRole().then(response => {
// this.roleList = response.rows;
// });
// 加载部门树
// listDept().then(response => {
// this.deptTreeData = this.handleTree(response.data, "deptId");
// });
},
/** 取消按钮 */
cancel() {
this.dialog.visible = false;
this.reset();
},
/** 表单重置 */
reset() {
this.form = {
@@ -532,92 +482,92 @@ export default {
applicableScope: 'all',
orderNum: 0,
description: null,
status: "1",
status: '1',
steps: []
};
if (this.$refs.formRef) {
this.$refs.formRef.resetFields();
}
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.$refs.queryFormRef.resetFields();
this.handleQuery();
},
/** 多选框选中数据 */
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id);
this.ids = selection.map((item) => item.id);
this.single = selection.length !== 1;
this.multiple = !selection.length;
},
/** 展开/折叠操作 */
toggleExpandAll() {
this.isExpandAll = !this.isExpandAll;
this.toggleExpandAllTree(this.configList, this.isExpandAll);
},
/** 快捷操作 */
showFlowDesigner() {
this.$modal.msgInfo("流程设计器功能开发中...");
this.$modal.msgInfo('流程设计器功能开发中...');
},
showTemplates() {
this.$modal.msgInfo("配置模板功能开发中...");
this.$modal.msgInfo('配置模板功能开发中...');
},
showTestFlow() {
this.$modal.msgInfo("流程测试功能开发中...");
this.$modal.msgInfo('流程测试功能开发中...');
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.dialog.visible = true;
this.dialog.title = "添加审批人配置";
this.dialog.title = '添加审批人配置';
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
const id = row?.id || this.ids[0];
getApproverConfig(id).then(response => {
getApproverConfig(id).then((response) => {
this.form = response.data;
this.dialog.visible = true;
this.dialog.title = "修改审批人配置";
this.dialog.title = '修改审批人配置';
});
},
/** 复制配置 */
handleCopy(row) {
getApproverConfig(row.id).then(response => {
getApproverConfig(row.id).then((response) => {
this.form = {
...response.data,
id: null,
configName: response.data.configName + '_副本'
};
this.dialog.visible = true;
this.dialog.title = "复制审批人配置";
this.dialog.title = '复制审批人配置';
});
},
/** 查看详情 */
handleDetail(row) {
getApproverConfig(row.id).then(response => {
getApproverConfig(row.id).then((response) => {
this.currentConfig = response.data;
this.detailDialog.visible = true;
this.detailDialog.title = "配置详情";
this.detailDialog.title = '配置详情';
});
},
/** 查看流程图 */
handleViewFlow(row) {
this.flowDialog.visible = true;
@@ -625,45 +575,55 @@ export default {
this.renderFlowChart(row);
});
},
/** 状态变更 */
handleStatusChange(row) {
let text = row.status === "1" ? "启用" : "停用";
this.$modal.confirm('确认要"' + text + '""' + row.configName + '"配置吗?').then(() => {
return updateApproverConfig(row);
}).then(() => {
this.$modal.msgSuccess(text + "成功");
}).catch(() => {
row.status = row.status === "0" ? "1" : "0";
});
let text = row.status === '1' ? '启用' : '停用';
this.$modal
.confirm('确认要"' + text + '""' + row.configName + '"配置吗?')
.then(() => {
return updateApproverConfig(row);
})
.then(() => {
this.$modal.msgSuccess(text + '成功');
})
.catch(() => {
row.status = row.status === '0' ? '1' : '0';
});
},
/** 删除按钮操作 */
handleDelete(row) {
const ids = row?.id ? [row.id] : this.ids;
const configs = row?.configName ? [row.configName] : this.configList.filter(item => this.ids.includes(item.id)).map(item => item.configName);
this.$modal.confirm('是否确认删除配置名称为"' + configs.join('", "') + '"的数据项?').then(() => {
return delApproverConfig(ids);
}).then(() => {
this.getList();
this.$modal.msgSuccess("删除成功");
}).catch(() => {});
const configs = row?.configName
? [row.configName]
: this.configList.filter((item) => this.ids.includes(item.id)).map((item) => item.configName);
this.$modal
.confirm('是否确认删除配置名称为"' + configs.join('", "') + '"的数据项?')
.then(() => {
return delApproverConfig(ids);
})
.then(() => {
this.getList();
this.$modal.msgSuccess('删除成功');
})
.catch(() => {});
},
/** 提交按钮 */
submitForm() {
this.$refs.formRef.validate(valid => {
this.$refs.formRef.validate((valid) => {
if (valid) {
if (this.form.id != null) {
updateApproverConfig(this.form).then(response => {
this.$modal.msgSuccess("修改成功");
updateApproverConfig(this.form).then((response) => {
this.$modal.msgSuccess('修改成功');
this.dialog.visible = false;
this.getList();
});
} else {
addApproverConfig(this.form).then(response => {
this.$modal.msgSuccess("新增成功");
addApproverConfig(this.form).then((response) => {
this.$modal.msgSuccess('新增成功');
this.dialog.visible = false;
this.getList();
});
@@ -671,17 +631,17 @@ export default {
}
});
},
/** 审批类型变更 */
handleTypeChange(value) {
// 清空已配置的审批人
if (this.form.steps) {
this.form.steps.forEach(step => {
this.form.steps.forEach((step) => {
step.approvers = [];
});
}
},
/** 添加步骤 */
addStep() {
if (!this.form.steps) {
@@ -694,12 +654,12 @@ export default {
approvers: []
});
},
/** 删除步骤 */
removeStep(index) {
this.form.steps.splice(index, 1);
},
/** 上移步骤 */
moveStepUp(index) {
if (index > 0) {
@@ -708,7 +668,7 @@ export default {
this.form.steps[index - 1] = temp;
}
},
/** 下移步骤 */
moveStepDown(index) {
if (index < this.form.steps.length - 1) {
@@ -717,36 +677,40 @@ export default {
this.form.steps[index + 1] = temp;
}
},
/** 更新审批人名称 */
updateApproverNames() {
// 更新审批人名称用于显示
},
/** 导出按钮操作 */
handleExport() {
this.download('cw/approverConfig/export', {
...this.queryParams
}, `approver_config_${new Date().getTime()}.xlsx`);
this.download(
'cw/approverConfig/export',
{
...this.queryParams
},
`approver_config_${new Date().getTime()}.xlsx`
);
},
/** 渲染流程图 */
renderFlowChart(row) {
// 使用流程图库渲染流程图
this.$modal.msgInfo("流程图功能开发中...");
this.$modal.msgInfo('流程图功能开发中...');
},
/** 获取审批类型标签 */
getApprovalTypeTag(type) {
const typeMap = {
'fixed': 'success',
'role': 'warning',
'role': 'warning',
'dept': 'info',
'custom': 'primary'
};
return typeMap[type] || 'info';
},
/** 获取审批类型文本 */
getApprovalTypeText(type) {
const textMap = {
@@ -771,25 +735,25 @@ export default {
cursor: pointer;
transition: all 0.3s ease;
border: 1px solid #e4e7ed;
&:hover {
transform: translateY(-2px);
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.1);
border-color: #409EFF;
border-color: #409eff;
}
.quick-action {
display: flex;
flex-direction: column;
align-items: center;
padding: 20px;
.quick-icon {
font-size: 28px;
color: #409EFF;
color: #409eff;
margin-bottom: 8px;
}
span {
font-size: 14px;
color: #606266;
@@ -807,14 +771,14 @@ export default {
// 步骤徽章
.step-badge {
:deep(.el-badge__content) {
background-color: #409EFF;
background-color: #409eff;
}
}
// 步骤配置卡片
.steps-card {
border: 1px solid #e4e7ed;
.steps-header {
display: flex;
justify-content: space-between;
@@ -827,32 +791,32 @@ export default {
.steps-container {
.step-item {
margin-bottom: 16px;
&:last-child {
margin-bottom: 0;
}
}
.step-card {
border: 1px solid #e4e7ed;
.step-header {
display: flex;
justify-content: space-between;
align-items: center;
.step-title {
display: flex;
align-items: center;
font-weight: 600;
color: #2c3e50;
.el-icon {
margin-right: 8px;
color: #409EFF;
color: #409eff;
}
}
.step-actions {
display: flex;
align-items: center;
@@ -877,14 +841,14 @@ export default {
@media (max-width: 768px) {
.quick-action {
padding: 15px;
.quick-icon {
font-size: 24px;
}
span {
font-size: 12px;
}
}
}
</style>
</style>
+3 -2
View File
@@ -6,9 +6,10 @@
<el-form-item label="预算年度" prop="budgetYear">
<el-select v-model="queryParams.budgetYear" placeholder="请选择预算年度" clearable style="width: 200px">
<el-option label="全部年度" value="" />
<el-option label="2024年" value="2024" />
<el-option label="2025年" value="2025" />
<el-option label="2026年" value="2026" />
<el-option label="2027年" value="2027" />
<el-option label="2028年" value="2028" />
</el-select>
</el-form-item>
<el-form-item>
@@ -241,7 +242,7 @@ export default {
queryParams: {
pageNum: 1,
pageSize: 10,
budgetYear: '2024' // 设置默认年度为2024
budgetYear: '' // 设置默认为空,查询所有年份数据
},
// 统计数据
statusStatistics: {