chore: biz_org 合并 / BizProject 重构 / 各角色页面调整 (上次重构遗留)
涵盖改动范围: - 后端 BizOrg / BizProject / BizProjectRating / BizSpecialPlan controller + domain + mapper + service - 前端 admin (BizSpecialPlanAdmin, ProjectCategory) / executor / leader / manager / sponsor 多页调整 - api/dict.js + AdminLayout.vue 同步
This commit is contained in:
@@ -51,7 +51,7 @@ async function loadStats() {
|
||||
try {
|
||||
const ps = await bizList('project', { pageNum: 1, pageSize: 1 })
|
||||
stats.value.totalProjects = ps.total || 0
|
||||
const settled = await bizList('project', { isSettled: '1', pageNum: 1, pageSize: 1 })
|
||||
const settled = await bizList('project', { isSettled: 'Y', pageNum: 1, pageSize: 1 })
|
||||
stats.value.settledProjects = settled.total || 0
|
||||
const finished = await bizList('project', { isFinished: '1', pageNum: 1, pageSize: 1 })
|
||||
stats.value.finishedProjects = finished.total || 0
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
<!-- ========== 批量按钮 (与 People.vue 风格一致) ========== -->
|
||||
<div class="batch-bar">
|
||||
<el-button type="primary" :disabled="!selected.length" @click="onAssign">项目分配</el-button>
|
||||
<el-button type="primary" :disabled="!selected.length" @click="onBatchRate">批量评价</el-button>
|
||||
<span class="filter-tip">已选 {{ selected.length }} 条</span>
|
||||
</div>
|
||||
|
||||
@@ -35,12 +34,12 @@
|
||||
<el-table-column prop="projectNo" label="项目编号" width="120" />
|
||||
<el-table-column prop="projectName" label="项目名称" min-width="200" show-overflow-tooltip />
|
||||
<el-table-column label="总场次/总期数" width="110" align="center">
|
||||
<template #default="{ row }">{{ row.totalSessions || 0 }}/{{ row.totalPeriods || 0 }}</template>
|
||||
<template #default="{ row }">{{ row.assignedSessions || 0 }}/{{ row.assignedSessions || 0 }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="doneSessions" label="已执行" width="80" align="center" />
|
||||
<el-table-column prop="todoSessions" label="未执行" width="80" align="center" />
|
||||
<el-table-column label="总金额" width="120" align="right">
|
||||
<template #default="{ row }">¥ {{ formatNum(row.totalAmount) }}</template>
|
||||
<template #default="{ row }">¥ {{ formatNum(row.assignedAmount) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="可用金额" width="120" align="right">
|
||||
<template #default="{ row }">¥ {{ formatNum(row.availableAmount) }}</template>
|
||||
@@ -51,9 +50,16 @@
|
||||
<el-table-column label="已支付会务费" width="120" align="right">
|
||||
<template #default="{ row }">¥ {{ formatNum(row.paidMeetingAmount) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="执行单位评价(支持方)" width="180" align="center">
|
||||
<el-table-column prop="managerScore" label="执行单位得分(合规)" width="140" align="center">
|
||||
<template #default="{ row }">
|
||||
<el-rate v-model="row.ratingScore" disabled show-score :max="5" />
|
||||
<span v-if="row.managerScore != null">{{ row.managerScore }}</span>
|
||||
<span v-else style="color:#c0c4cc">-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="sponsorScore" label="执行单位得分(支持)" width="140" align="center">
|
||||
<template #default="{ row }">
|
||||
<span v-if="row.sponsorScore != null">{{ row.sponsorScore }}</span>
|
||||
<span v-else style="color:#c0c4cc">-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="isFinished" label="是否结题" width="100" align="center">
|
||||
@@ -65,11 +71,10 @@
|
||||
</el-table-column>
|
||||
<el-table-column prop="startTime" label="项目开始时间" width="150" />
|
||||
<el-table-column prop="endTime" label="项目结束时间" width="150" />
|
||||
<el-table-column label="操作" width="220" fixed="right">
|
||||
<el-table-column label="操作" width="180" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<el-button link type="primary" @click="viewDetail(row)">查看</el-button>
|
||||
<el-button link type="primary" @click="onAssign(row)">分配</el-button>
|
||||
<el-button link type="primary" @click="onRate(row)">项目评价</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
@@ -97,27 +102,7 @@
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 批量评价 弹窗 -->
|
||||
<el-dialog v-model="rateOpen" :title="rateRow ? '项目评价' : '批量评价'" width="520px">
|
||||
<el-form label-width="100px">
|
||||
<el-form-item v-if="rateRow" label="项目名称">
|
||||
<span>{{ rateRow.projectName }}</span>
|
||||
</el-form-item>
|
||||
<el-form-item v-else label="已选项目">
|
||||
<span>{{ selected.length }} 个</span>
|
||||
</el-form-item>
|
||||
<el-form-item label="评分">
|
||||
<el-rate v-model="rateForm.score" :max="5" show-text />
|
||||
</el-form-item>
|
||||
<el-form-item label="评价说明">
|
||||
<el-input v-model="rateForm.comment" type="textarea" :rows="3" placeholder="请输入评价说明" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="rateOpen=false">取消</el-button>
|
||||
<el-button type="primary" @click="onSaveRate">确定</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<!-- 评分弹窗已移除: executor 不可评分 -->
|
||||
|
||||
<el-dialog v-model="detailOpen" title="项目详情" width="720px">
|
||||
<el-descriptions :column="2" border>
|
||||
@@ -143,7 +128,14 @@
|
||||
<script setup>
|
||||
import { ref, reactive, onMounted } from 'vue'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import { bizList, bizUpdate } from '@/api/public'
|
||||
import request from '@/utils/request'
|
||||
import { bizUpdate } from '@/api/public'
|
||||
|
||||
// executor 专属: 只查分给当前用户 (主账号 biz_org.org_id 或 子账号 exec_user_id) 的项目
|
||||
async function listExecutorProjects(params) {
|
||||
const { data } = await request.get('/business/project/executorList', { params })
|
||||
return data || { rows: [], total: 0 }
|
||||
}
|
||||
|
||||
const list = ref([])
|
||||
const loading = ref(false)
|
||||
@@ -159,10 +151,6 @@ const assignOpen = ref(false)
|
||||
const assignRow = ref({})
|
||||
const assignForm = reactive({ assignee: '' })
|
||||
|
||||
const rateOpen = ref(false)
|
||||
const rateRow = ref(null)
|
||||
const rateForm = reactive({ score: 5, comment: '' })
|
||||
|
||||
function formatNum(n) {
|
||||
if (n == null) return '0.00'
|
||||
return Number(n).toLocaleString('zh-CN', { minimumFractionDigits: 2, maximumFractionDigits: 2 })
|
||||
@@ -176,9 +164,9 @@ async function loadList() {
|
||||
params.startTime = dateRange.value[0]
|
||||
params.endTime = dateRange.value[1]
|
||||
}
|
||||
const r = await bizList('project', params)
|
||||
list.value = (r.data && r.data.rows) || r.rows || []
|
||||
page.total = (r.data && r.data.total) || r.total || 0
|
||||
const data = await listExecutorProjects(params)
|
||||
list.value = data.rows || []
|
||||
page.total = data.total || 0
|
||||
} catch (e) { list.value = []; page.total = 0 }
|
||||
finally { loading.value = false }
|
||||
}
|
||||
@@ -217,38 +205,7 @@ async function onSaveAssign() {
|
||||
} catch (e) { ElMessage.error(e?.msg || '分配失败') }
|
||||
}
|
||||
|
||||
function onRate(row) {
|
||||
rateRow.value = row
|
||||
rateForm.score = row?.ratingScore || 5
|
||||
rateForm.comment = row?.ratingComment || ''
|
||||
rateOpen.value = true
|
||||
}
|
||||
|
||||
function onBatchRate() {
|
||||
if (!selected.value.length) return
|
||||
rateRow.value = null
|
||||
rateForm.score = 5
|
||||
rateForm.comment = ''
|
||||
rateOpen.value = true
|
||||
}
|
||||
|
||||
async function onSaveRate() {
|
||||
try {
|
||||
let ok = 0
|
||||
const payload = { ratingScore: rateForm.score, ratingComment: rateForm.comment }
|
||||
if (rateRow.value) {
|
||||
await bizUpdate('project', { projectId: rateRow.value.projectId, ...payload })
|
||||
ok = 1
|
||||
} else {
|
||||
for (const r of selected.value) {
|
||||
try { await bizUpdate('project', { projectId: r.projectId, ...payload }); ok++ } catch {}
|
||||
}
|
||||
}
|
||||
ElMessage.success(rateRow.value ? '评价成功' : `已评价 ${ok} 个项目`)
|
||||
rateOpen.value = false
|
||||
loadList()
|
||||
} catch (e) { ElMessage.error(e?.msg || '评价失败') }
|
||||
}
|
||||
// 评价相关函数已移除: executor 不可评分
|
||||
|
||||
onMounted(() => { loadList(); loadPeople() })
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user