library-picturebook-activity/frontend/src/views/contests/judges/Index.vue

604 lines
16 KiB
Vue
Raw Normal View History

2026-01-08 09:17:46 +08:00
<template>
<div class="judges-page">
<a-card class="mb-4">
2026-01-16 16:35:43 +08:00
<template #title>评委管理</template>
2026-01-08 09:17:46 +08:00
<template #extra>
<a-space>
<a-button
v-permission="'judge:create'"
type="primary"
@click="handleAdd"
>
<template #icon><PlusOutlined /></template>
新增
</a-button>
Day5: 租户端全面优化 + 数据统计看板 + 成果发布完善 租户端基础设施: - 新增工作台首页(欢迎信息/统计/待办/快捷操作/新手引导) - 新增机构信息管理页(自助查看编辑机构信息) - 修复403报错(fetchTenants加超管守卫) - 修复权限(log:read/notice:update/notice:delete/contest:work:read) - 修复评审规则组件映射 活动管理全模块优化(机构端视角): - 活动列表:加统计概览+精简列+筛选自动查询+发布弹窗修复+操作逻辑优化 - 创建/编辑活动:重构布局(去card嵌套+栅格响应式+分区卡片) - 评委管理:统一主色调+冻结确认+导入导出disabled - 报名管理:去Tab+统计+审核状态列+批量审核接口 - 报名记录:统计概览+去机构列+撤销审核+返回按钮+去参与方式列 - 作品管理:去Tab+统计+递交进度彩色+筛选修复(assignStatus/submitTime) - 评审进度:去Tab+统计+实际完成率状态+筛选修复 - 评审规则:表格加评委数/计算方式+描述列修复+删除保护 - 成果发布:去Tab+统计+操作文案优化 - 通知公告:统一主色调+发布确认+操作逻辑+状态筛选+时间范围 成果发布详情功能补全: - 计算得分/排名/设置奖项三步操作流程 - 排名列(金银铜徽章)+奖项列+奖项筛选 - 自定义奖项(动态添加行替代硬编码一二三等奖) - 后端AutoSetAwardsDto改为awards数组格式 数据统计看板(新模块): - 后端analytics module(overview+review两个接口) - 运营概览:6指标卡片+报名转化漏斗+ECharts月度趋势+活动对比表 - 评审分析:4效率卡片+评委工作量表+ECharts奖项分布饼图 - 菜单注册:数据统计→运营概览+评审分析 Bug修复: - 超管重置其他租户用户密码报"用户不存在" - gdlib登录快捷标签密码不一致 - 分配评委去掉评审时间限制 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 20:02:24 +08:00
<a-tooltip title="功能开发中,敬请期待">
<a-button v-permission="'judge:create'" disabled>
<template #icon><UploadOutlined /></template>
导入
</a-button>
</a-tooltip>
<a-tooltip title="功能开发中,敬请期待">
<a-button v-permission="'judge:read'" disabled>
<template #icon><DownloadOutlined /></template>
导出
</a-button>
</a-tooltip>
2026-01-08 09:17:46 +08:00
<a-popconfirm
v-permission="'judge:delete'"
title="确定要删除选中的评委吗?"
:disabled="selectedRowKeys.length === 0 || selectedRows.every(r => r.isPlatform)"
2026-01-08 09:17:46 +08:00
@confirm="handleBatchDelete"
>
<a-button danger :disabled="selectedRowKeys.length === 0 || selectedRows.every(r => r.isPlatform)">
2026-01-08 09:17:46 +08:00
<template #icon><DeleteOutlined /></template>
删除
</a-button>
</a-popconfirm>
</a-space>
</template>
</a-card>
<!-- 搜索表单 -->
<a-form
:model="searchParams"
layout="inline"
class="search-form"
@finish="handleSearch"
>
2026-01-12 16:06:34 +08:00
<a-form-item label="所属单位">
<a-input
v-model:value="searchParams.organization"
placeholder="请输入所属单位"
2026-01-08 09:17:46 +08:00
allow-clear
style="width: 200px"
2026-01-12 16:06:34 +08:00
/>
2026-01-08 09:17:46 +08:00
</a-form-item>
<a-form-item label="姓名">
<a-input
v-model:value="searchParams.nickname"
placeholder="请输入姓名"
allow-clear
style="width: 150px"
/>
</a-form-item>
<a-form-item label="账号">
<a-input
v-model:value="searchParams.username"
placeholder="请输入账号"
allow-clear
style="width: 150px"
/>
</a-form-item>
<a-form-item label="状态">
<a-select
v-model:value="searchParams.status"
placeholder="请选择状态"
allow-clear
style="width: 120px"
Day5: 租户端全面优化 + 数据统计看板 + 成果发布完善 租户端基础设施: - 新增工作台首页(欢迎信息/统计/待办/快捷操作/新手引导) - 新增机构信息管理页(自助查看编辑机构信息) - 修复403报错(fetchTenants加超管守卫) - 修复权限(log:read/notice:update/notice:delete/contest:work:read) - 修复评审规则组件映射 活动管理全模块优化(机构端视角): - 活动列表:加统计概览+精简列+筛选自动查询+发布弹窗修复+操作逻辑优化 - 创建/编辑活动:重构布局(去card嵌套+栅格响应式+分区卡片) - 评委管理:统一主色调+冻结确认+导入导出disabled - 报名管理:去Tab+统计+审核状态列+批量审核接口 - 报名记录:统计概览+去机构列+撤销审核+返回按钮+去参与方式列 - 作品管理:去Tab+统计+递交进度彩色+筛选修复(assignStatus/submitTime) - 评审进度:去Tab+统计+实际完成率状态+筛选修复 - 评审规则:表格加评委数/计算方式+描述列修复+删除保护 - 成果发布:去Tab+统计+操作文案优化 - 通知公告:统一主色调+发布确认+操作逻辑+状态筛选+时间范围 成果发布详情功能补全: - 计算得分/排名/设置奖项三步操作流程 - 排名列(金银铜徽章)+奖项列+奖项筛选 - 自定义奖项(动态添加行替代硬编码一二三等奖) - 后端AutoSetAwardsDto改为awards数组格式 数据统计看板(新模块): - 后端analytics module(overview+review两个接口) - 运营概览:6指标卡片+报名转化漏斗+ECharts月度趋势+活动对比表 - 评审分析:4效率卡片+评委工作量表+ECharts奖项分布饼图 - 菜单注册:数据统计→运营概览+评审分析 Bug修复: - 超管重置其他租户用户密码报"用户不存在" - gdlib登录快捷标签密码不一致 - 分配评委去掉评审时间限制 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 20:02:24 +08:00
@change="handleSearch"
2026-01-08 09:17:46 +08:00
>
<a-select-option value="disabled">停用</a-select-option>
<a-select-option value="enabled">启用</a-select-option>
</a-select>
</a-form-item>
<a-form-item>
<a-button type="primary" html-type="submit">
<template #icon><SearchOutlined /></template>
搜索
</a-button>
<a-button style="margin-left: 8px" @click="handleReset">
<template #icon><ReloadOutlined /></template>
重置
</a-button>
</a-form-item>
</a-form>
<!-- 数据表格 -->
<a-table
:columns="columns"
:data-source="dataSource"
:loading="loading"
:pagination="pagination"
:row-selection="rowSelection"
row-key="id"
@change="handleTableChange"
>
<template #bodyCell="{ column, record, index }">
<template v-if="column.key === 'index'">
{{ (pagination.current - 1) * pagination.pageSize + index + 1 }}
</template>
2026-01-12 16:06:34 +08:00
<template v-else-if="column.key === 'organization'">
{{ record.organization || "-" }}
2026-01-08 09:17:46 +08:00
</template>
<template v-else-if="column.key === 'gender'">
<span v-if="record.gender === 'male'"></span>
<span v-else-if="record.gender === 'female'"></span>
<span v-else>-</span>
</template>
<template v-else-if="column.key === 'source'">
<a-tag v-if="record.isPlatform" color="blue">平台</a-tag>
<span v-else>-</span>
</template>
2026-01-08 09:17:46 +08:00
<template v-else-if="column.key === 'status'">
<a-tag :color="record.status === 'enabled' ? 'success' : 'error'">
{{ record.status === "enabled" ? "启用" : "停用" }}
</a-tag>
</template>
<template v-else-if="column.key === 'ongoingContests'">
<template
v-if="record.contestJudges && record.contestJudges.length > 0"
>
<a-tooltip>
<template #title>
<div v-for="cj in record.contestJudges" :key="cj.contest.id">
{{ cj.contest.contestName }}
</div>
</template>
<a-tag color="processing">
{{ record.contestJudges.length }}个活动
2026-01-08 09:17:46 +08:00
</a-tag>
</a-tooltip>
</template>
<span v-else>-</span>
</template>
<template v-else-if="column.key === 'action'">
<a-space>
<template v-if="!record.isPlatform">
<a-button
v-permission="'judge:update'"
type="link"
size="small"
@click="handleToggleStatus(record)"
>
{{ record.status === "enabled" ? "冻结" : "解冻" }}
</a-button>
</template>
<template v-if="!record.isPlatform">
<a-button
v-permission="'judge:update'"
type="link"
size="small"
@click="handleEdit(record)"
>
编辑
</a-button>
</template>
2026-01-08 09:17:46 +08:00
<a-popconfirm
v-if="!record.isPlatform"
2026-01-08 09:17:46 +08:00
v-permission="'judge:delete'"
title="确定要删除这个评委吗?"
@confirm="handleDelete(record.id)"
>
<a-button type="link" danger size="small">删除</a-button>
</a-popconfirm>
</a-space>
</template>
</template>
</a-table>
<!-- 新增/编辑评委抽屉 -->
<a-drawer
v-model:open="drawerVisible"
:title="isEditing ? '编辑评委' : '新增评委'"
placement="right"
width="500px"
:footer-style="{ textAlign: 'right' }"
>
<a-form
ref="formRef"
:model="form"
:rules="rules"
:label-col="{ span: 6 }"
:wrapper-col="{ span: 18 }"
>
2026-01-09 18:14:35 +08:00
<a-form-item label="账号" name="username">
<a-input
v-model:value="form.username"
placeholder="请输入账号"
:maxlength="50"
:disabled="isEditing"
/>
</a-form-item>
2026-01-08 09:17:46 +08:00
<a-form-item label="姓名" name="nickname">
<a-input
v-model:value="form.nickname"
placeholder="请输入姓名"
:maxlength="50"
/>
</a-form-item>
<a-form-item label="性别" name="gender">
<a-radio-group v-model:value="form.gender">
<a-radio value="male"></a-radio>
<a-radio value="female"></a-radio>
</a-radio-group>
</a-form-item>
2026-01-12 16:06:34 +08:00
<a-form-item label="所属单位" name="organization">
2026-01-08 09:17:46 +08:00
<a-input
2026-01-12 16:06:34 +08:00
v-model:value="form.organization"
placeholder="请输入所属单位"
:maxlength="100"
2026-01-08 09:17:46 +08:00
/>
</a-form-item>
<a-form-item label="联系方式" name="phone">
<a-input
v-model:value="form.phone"
placeholder="请输入联系方式"
:maxlength="20"
/>
</a-form-item>
<a-form-item label="初始密码" name="password">
<a-input-password
v-model:value="form.password"
:placeholder="isEditing ? '请输入新密码' : '请输入初始密码'"
:maxlength="50"
/>
</a-form-item>
</a-form>
<template #footer>
<a-button style="margin-right: 8px" @click="handleCancel"
>取消</a-button
>
<a-button type="primary" :loading="submitLoading" @click="handleSubmit">
确定
</a-button>
</template>
</a-drawer>
</div>
</template>
<script setup lang="ts">
import { ref, reactive, computed, onMounted } from "vue"
import { useRoute } from "vue-router"
Day5: 租户端全面优化 + 数据统计看板 + 成果发布完善 租户端基础设施: - 新增工作台首页(欢迎信息/统计/待办/快捷操作/新手引导) - 新增机构信息管理页(自助查看编辑机构信息) - 修复403报错(fetchTenants加超管守卫) - 修复权限(log:read/notice:update/notice:delete/contest:work:read) - 修复评审规则组件映射 活动管理全模块优化(机构端视角): - 活动列表:加统计概览+精简列+筛选自动查询+发布弹窗修复+操作逻辑优化 - 创建/编辑活动:重构布局(去card嵌套+栅格响应式+分区卡片) - 评委管理:统一主色调+冻结确认+导入导出disabled - 报名管理:去Tab+统计+审核状态列+批量审核接口 - 报名记录:统计概览+去机构列+撤销审核+返回按钮+去参与方式列 - 作品管理:去Tab+统计+递交进度彩色+筛选修复(assignStatus/submitTime) - 评审进度:去Tab+统计+实际完成率状态+筛选修复 - 评审规则:表格加评委数/计算方式+描述列修复+删除保护 - 成果发布:去Tab+统计+操作文案优化 - 通知公告:统一主色调+发布确认+操作逻辑+状态筛选+时间范围 成果发布详情功能补全: - 计算得分/排名/设置奖项三步操作流程 - 排名列(金银铜徽章)+奖项列+奖项筛选 - 自定义奖项(动态添加行替代硬编码一二三等奖) - 后端AutoSetAwardsDto改为awards数组格式 数据统计看板(新模块): - 后端analytics module(overview+review两个接口) - 运营概览:6指标卡片+报名转化漏斗+ECharts月度趋势+活动对比表 - 评审分析:4效率卡片+评委工作量表+ECharts奖项分布饼图 - 菜单注册:数据统计→运营概览+评审分析 Bug修复: - 超管重置其他租户用户密码报"用户不存在" - gdlib登录快捷标签密码不一致 - 分配评委去掉评审时间限制 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 20:02:24 +08:00
import { message, Modal } from "ant-design-vue"
2026-01-08 09:17:46 +08:00
import type { FormInstance, TableProps } from "ant-design-vue"
import {
PlusOutlined,
UploadOutlined,
DownloadOutlined,
DeleteOutlined,
SearchOutlined,
ReloadOutlined,
} from "@ant-design/icons-vue"
import { useListRequest } from "@/composables/useListRequest"
import { contestsApi } from "@/api/contests"
import {
judgesManagementApi,
type Judge,
type QueryJudgeParams,
} from "@/api/judges-management"
const route = useRoute()
const contestId = route.params.id ? Number(route.params.id) : null
const tenantCode = route.params.tenantCode as string
// 检查 contestId 是否有效
const isValidContestId =
contestId !== null && !isNaN(contestId) && contestId > 0
// 获取评委列表
const fetchJudgesList = async (params: QueryJudgeParams) => {
const response = await judgesManagementApi.getList(params)
return response
}
// 使用列表请求组合函数
const {
loading,
dataSource,
pagination,
searchParams,
fetchList,
resetSearch,
search,
handleTableChange,
} = useListRequest<Judge, QueryJudgeParams>({
requestFn: fetchJudgesList,
defaultSearchParams: {} as QueryJudgeParams,
defaultPageSize: 10,
errorMessage: "获取评委列表失败",
})
// 活动信息
2026-01-08 09:17:46 +08:00
const contestName = ref("")
// 表格选择
const selectedRowKeys = ref<number[]>([])
2026-01-16 16:35:43 +08:00
const rowSelection = computed<TableProps["rowSelection"]>(() => ({
2026-01-08 09:17:46 +08:00
selectedRowKeys: selectedRowKeys.value,
onChange: (keys: any) => {
selectedRowKeys.value = keys
},
2026-01-16 16:35:43 +08:00
}))
2026-01-08 09:17:46 +08:00
// 抽屉相关
const drawerVisible = ref(false)
const isEditing = ref(false)
const editingId = ref<number | null>(null)
const submitLoading = ref(false)
const formRef = ref<FormInstance>()
const form = reactive<{
2026-01-09 18:14:35 +08:00
username: string
2026-01-08 09:17:46 +08:00
nickname: string
gender: "male" | "female" | undefined
2026-01-12 16:06:34 +08:00
organization: string
2026-01-08 09:17:46 +08:00
phone: string
password: string
}>({
2026-01-09 18:14:35 +08:00
username: "",
2026-01-08 09:17:46 +08:00
nickname: "",
gender: undefined,
2026-01-12 16:06:34 +08:00
organization: "",
2026-01-08 09:17:46 +08:00
phone: "",
password: "",
})
// 表单验证规则
const rules = computed(() => ({
2026-01-09 18:14:35 +08:00
username: isEditing.value
? []
: [{ required: true, message: "请输入账号", trigger: "blur" }],
2026-01-08 09:17:46 +08:00
nickname: [{ required: true, message: "请输入姓名", trigger: "blur" }],
gender: [{ required: true, message: "请选择性别", trigger: "change" }],
2026-01-12 16:06:34 +08:00
organization: [{ required: true, message: "请输入所属单位", trigger: "blur" }],
2026-01-08 09:17:46 +08:00
phone: [{ required: true, message: "请输入联系方式", trigger: "blur" }],
password: isEditing.value
? []
: [{ required: true, message: "请输入初始密码", trigger: "blur" }],
}))
// 表格列定义
const columns = [
{
title: "序号",
key: "index",
width: 70,
},
{
title: "来源",
key: "source",
width: 80,
},
2026-01-08 09:17:46 +08:00
{
title: "所属单位",
2026-01-12 16:06:34 +08:00
key: "organization",
dataIndex: "organization",
2026-01-08 09:17:46 +08:00
width: 150,
},
{
title: "姓名",
dataIndex: "nickname",
key: "nickname",
width: 120,
},
{
title: "性别",
key: "gender",
width: 80,
},
{
title: "账号",
dataIndex: "username",
key: "username",
width: 150,
},
{
title: "联系方式",
dataIndex: "phone",
key: "phone",
width: 130,
},
{
title: "关联进行中的活动",
2026-01-08 09:17:46 +08:00
key: "ongoingContests",
width: 150,
},
{
title: "状态",
key: "status",
width: 80,
},
{
title: "操作",
key: "action",
width: 180,
fixed: "right" as const,
},
]
// 加载活动信息
2026-01-08 09:17:46 +08:00
const loadContestInfo = async () => {
// 如果 contestId 无效,跳过加载
if (!isValidContestId) {
return
}
try {
const contest = await contestsApi.getDetail(contestId!)
contestName.value = contest.contestName
} catch (error) {
console.error("获取活动信息失败", error)
2026-01-08 09:17:46 +08:00
}
}
// 搜索
const handleSearch = () => {
search()
}
// 重置搜索
const handleReset = () => {
resetSearch()
}
// 新增
const handleAdd = () => {
isEditing.value = false
editingId.value = null
drawerVisible.value = true
2026-01-09 18:14:35 +08:00
form.username = ""
2026-01-08 09:17:46 +08:00
form.nickname = ""
form.gender = undefined
2026-01-12 16:06:34 +08:00
form.organization = ""
2026-01-08 09:17:46 +08:00
form.phone = ""
form.password = ""
}
// 编辑
const handleEdit = (record: Judge) => {
isEditing.value = true
editingId.value = record.id
drawerVisible.value = true
2026-01-09 18:14:35 +08:00
form.username = record.username || ""
2026-01-08 09:17:46 +08:00
form.nickname = record.nickname || ""
form.gender = record.gender as "male" | "female" | undefined
2026-01-12 16:06:34 +08:00
form.organization = record.organization || ""
2026-01-08 09:17:46 +08:00
form.phone = record.phone || ""
form.password = ""
}
Day5: 租户端全面优化 + 数据统计看板 + 成果发布完善 租户端基础设施: - 新增工作台首页(欢迎信息/统计/待办/快捷操作/新手引导) - 新增机构信息管理页(自助查看编辑机构信息) - 修复403报错(fetchTenants加超管守卫) - 修复权限(log:read/notice:update/notice:delete/contest:work:read) - 修复评审规则组件映射 活动管理全模块优化(机构端视角): - 活动列表:加统计概览+精简列+筛选自动查询+发布弹窗修复+操作逻辑优化 - 创建/编辑活动:重构布局(去card嵌套+栅格响应式+分区卡片) - 评委管理:统一主色调+冻结确认+导入导出disabled - 报名管理:去Tab+统计+审核状态列+批量审核接口 - 报名记录:统计概览+去机构列+撤销审核+返回按钮+去参与方式列 - 作品管理:去Tab+统计+递交进度彩色+筛选修复(assignStatus/submitTime) - 评审进度:去Tab+统计+实际完成率状态+筛选修复 - 评审规则:表格加评委数/计算方式+描述列修复+删除保护 - 成果发布:去Tab+统计+操作文案优化 - 通知公告:统一主色调+发布确认+操作逻辑+状态筛选+时间范围 成果发布详情功能补全: - 计算得分/排名/设置奖项三步操作流程 - 排名列(金银铜徽章)+奖项列+奖项筛选 - 自定义奖项(动态添加行替代硬编码一二三等奖) - 后端AutoSetAwardsDto改为awards数组格式 数据统计看板(新模块): - 后端analytics module(overview+review两个接口) - 运营概览:6指标卡片+报名转化漏斗+ECharts月度趋势+活动对比表 - 评审分析:4效率卡片+评委工作量表+ECharts奖项分布饼图 - 菜单注册:数据统计→运营概览+评审分析 Bug修复: - 超管重置其他租户用户密码报"用户不存在" - gdlib登录快捷标签密码不一致 - 分配评委去掉评审时间限制 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 20:02:24 +08:00
// 切换状态(冻结/解冻)+ 二次确认
const handleToggleStatus = (record: Judge) => {
const isFreeze = record.status === "enabled"
Modal.confirm({
title: isFreeze ? '确定冻结该评委?' : '确定解冻该评委?',
content: isFreeze
? `冻结后「${record.nickname}」将无法登录评委端,进行中的评审任务将暂停`
: `解冻后「${record.nickname}」将恢复登录和评审功能`,
okText: isFreeze ? '确定冻结' : '确定解冻',
okType: isFreeze ? 'danger' : 'primary',
onOk: async () => {
try {
if (isFreeze) {
await judgesManagementApi.freeze(record.id)
message.success("冻结成功")
} else {
await judgesManagementApi.unfreeze(record.id)
message.success("解冻成功")
}
fetchList()
} catch (error: any) {
message.error(error?.response?.data?.message || "操作失败")
}
},
})
2026-01-08 09:17:46 +08:00
}
// 删除
const handleDelete = async (id: number) => {
try {
await judgesManagementApi.delete(id)
message.success("删除成功")
fetchList()
} catch (error: any) {
message.error(error?.response?.data?.message || "删除失败")
}
}
// 批量删除
const handleBatchDelete = async () => {
if (selectedRowKeys.value.length === 0) return
try {
await judgesManagementApi.batchDelete(selectedRowKeys.value)
message.success("批量删除成功")
selectedRowKeys.value = []
fetchList()
} catch (error: any) {
message.error(error?.response?.data?.message || "批量删除失败")
}
}
// 提交表单
const handleSubmit = async () => {
try {
await formRef.value?.validate()
submitLoading.value = true
if (isEditing.value && editingId.value) {
// 编辑评委
await judgesManagementApi.update(editingId.value, {
nickname: form.nickname,
gender: form.gender,
2026-01-12 16:06:34 +08:00
organization: form.organization,
2026-01-08 09:17:46 +08:00
phone: form.phone,
...(form.password && { password: form.password }),
})
message.success("编辑成功")
} else {
// 新增评委
await judgesManagementApi.create({
2026-01-09 18:14:35 +08:00
username: form.username,
2026-01-08 09:17:46 +08:00
nickname: form.nickname,
gender: form.gender!,
2026-01-12 16:06:34 +08:00
organization: form.organization,
2026-01-08 09:17:46 +08:00
phone: form.phone,
password: form.password,
status: "enabled",
})
message.success("创建成功")
}
drawerVisible.value = false
fetchList()
} catch (error: any) {
if (error?.errorFields) {
return
}
message.error(
error?.response?.data?.message ||
(isEditing.value ? "编辑失败" : "创建失败")
)
} finally {
submitLoading.value = false
}
}
// 取消
const handleCancel = () => {
drawerVisible.value = false
formRef.value?.resetFields()
}
onMounted(() => {
loadContestInfo()
})
</script>
2026-01-16 16:35:43 +08:00
<style scoped lang="scss">
Day5: 租户端全面优化 + 数据统计看板 + 成果发布完善 租户端基础设施: - 新增工作台首页(欢迎信息/统计/待办/快捷操作/新手引导) - 新增机构信息管理页(自助查看编辑机构信息) - 修复403报错(fetchTenants加超管守卫) - 修复权限(log:read/notice:update/notice:delete/contest:work:read) - 修复评审规则组件映射 活动管理全模块优化(机构端视角): - 活动列表:加统计概览+精简列+筛选自动查询+发布弹窗修复+操作逻辑优化 - 创建/编辑活动:重构布局(去card嵌套+栅格响应式+分区卡片) - 评委管理:统一主色调+冻结确认+导入导出disabled - 报名管理:去Tab+统计+审核状态列+批量审核接口 - 报名记录:统计概览+去机构列+撤销审核+返回按钮+去参与方式列 - 作品管理:去Tab+统计+递交进度彩色+筛选修复(assignStatus/submitTime) - 评审进度:去Tab+统计+实际完成率状态+筛选修复 - 评审规则:表格加评委数/计算方式+描述列修复+删除保护 - 成果发布:去Tab+统计+操作文案优化 - 通知公告:统一主色调+发布确认+操作逻辑+状态筛选+时间范围 成果发布详情功能补全: - 计算得分/排名/设置奖项三步操作流程 - 排名列(金银铜徽章)+奖项列+奖项筛选 - 自定义奖项(动态添加行替代硬编码一二三等奖) - 后端AutoSetAwardsDto改为awards数组格式 数据统计看板(新模块): - 后端analytics module(overview+review两个接口) - 运营概览:6指标卡片+报名转化漏斗+ECharts月度趋势+活动对比表 - 评审分析:4效率卡片+评委工作量表+ECharts奖项分布饼图 - 菜单注册:数据统计→运营概览+评审分析 Bug修复: - 超管重置其他租户用户密码报"用户不存在" - gdlib登录快捷标签密码不一致 - 分配评委去掉评审时间限制 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 20:02:24 +08:00
$primary: #6366f1;
2026-01-16 16:35:43 +08:00
.judges-page {
:deep(.ant-card) {
border: none;
border-radius: 12px;
Day5: 租户端全面优化 + 数据统计看板 + 成果发布完善 租户端基础设施: - 新增工作台首页(欢迎信息/统计/待办/快捷操作/新手引导) - 新增机构信息管理页(自助查看编辑机构信息) - 修复403报错(fetchTenants加超管守卫) - 修复权限(log:read/notice:update/notice:delete/contest:work:read) - 修复评审规则组件映射 活动管理全模块优化(机构端视角): - 活动列表:加统计概览+精简列+筛选自动查询+发布弹窗修复+操作逻辑优化 - 创建/编辑活动:重构布局(去card嵌套+栅格响应式+分区卡片) - 评委管理:统一主色调+冻结确认+导入导出disabled - 报名管理:去Tab+统计+审核状态列+批量审核接口 - 报名记录:统计概览+去机构列+撤销审核+返回按钮+去参与方式列 - 作品管理:去Tab+统计+递交进度彩色+筛选修复(assignStatus/submitTime) - 评审进度:去Tab+统计+实际完成率状态+筛选修复 - 评审规则:表格加评委数/计算方式+描述列修复+删除保护 - 成果发布:去Tab+统计+操作文案优化 - 通知公告:统一主色调+发布确认+操作逻辑+状态筛选+时间范围 成果发布详情功能补全: - 计算得分/排名/设置奖项三步操作流程 - 排名列(金银铜徽章)+奖项列+奖项筛选 - 自定义奖项(动态添加行替代硬编码一二三等奖) - 后端AutoSetAwardsDto改为awards数组格式 数据统计看板(新模块): - 后端analytics module(overview+review两个接口) - 运营概览:6指标卡片+报名转化漏斗+ECharts月度趋势+活动对比表 - 评审分析:4效率卡片+评委工作量表+ECharts奖项分布饼图 - 菜单注册:数据统计→运营概览+评审分析 Bug修复: - 超管重置其他租户用户密码报"用户不存在" - gdlib登录快捷标签密码不一致 - 分配评委去掉评审时间限制 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 20:02:24 +08:00
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.06);
2026-01-16 16:35:43 +08:00
margin-bottom: 16px;
.ant-card-head {
border-bottom: none;
Day5: 租户端全面优化 + 数据统计看板 + 成果发布完善 租户端基础设施: - 新增工作台首页(欢迎信息/统计/待办/快捷操作/新手引导) - 新增机构信息管理页(自助查看编辑机构信息) - 修复403报错(fetchTenants加超管守卫) - 修复权限(log:read/notice:update/notice:delete/contest:work:read) - 修复评审规则组件映射 活动管理全模块优化(机构端视角): - 活动列表:加统计概览+精简列+筛选自动查询+发布弹窗修复+操作逻辑优化 - 创建/编辑活动:重构布局(去card嵌套+栅格响应式+分区卡片) - 评委管理:统一主色调+冻结确认+导入导出disabled - 报名管理:去Tab+统计+审核状态列+批量审核接口 - 报名记录:统计概览+去机构列+撤销审核+返回按钮+去参与方式列 - 作品管理:去Tab+统计+递交进度彩色+筛选修复(assignStatus/submitTime) - 评审进度:去Tab+统计+实际完成率状态+筛选修复 - 评审规则:表格加评委数/计算方式+描述列修复+删除保护 - 成果发布:去Tab+统计+操作文案优化 - 通知公告:统一主色调+发布确认+操作逻辑+状态筛选+时间范围 成果发布详情功能补全: - 计算得分/排名/设置奖项三步操作流程 - 排名列(金银铜徽章)+奖项列+奖项筛选 - 自定义奖项(动态添加行替代硬编码一二三等奖) - 后端AutoSetAwardsDto改为awards数组格式 数据统计看板(新模块): - 后端analytics module(overview+review两个接口) - 运营概览:6指标卡片+报名转化漏斗+ECharts月度趋势+活动对比表 - 评审分析:4效率卡片+评委工作量表+ECharts奖项分布饼图 - 菜单注册:数据统计→运营概览+评审分析 Bug修复: - 超管重置其他租户用户密码报"用户不存在" - gdlib登录快捷标签密码不一致 - 分配评委去掉评审时间限制 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 20:02:24 +08:00
.ant-card-head-title { font-size: 18px; font-weight: 600; }
2026-01-16 16:35:43 +08:00
}
Day5: 租户端全面优化 + 数据统计看板 + 成果发布完善 租户端基础设施: - 新增工作台首页(欢迎信息/统计/待办/快捷操作/新手引导) - 新增机构信息管理页(自助查看编辑机构信息) - 修复403报错(fetchTenants加超管守卫) - 修复权限(log:read/notice:update/notice:delete/contest:work:read) - 修复评审规则组件映射 活动管理全模块优化(机构端视角): - 活动列表:加统计概览+精简列+筛选自动查询+发布弹窗修复+操作逻辑优化 - 创建/编辑活动:重构布局(去card嵌套+栅格响应式+分区卡片) - 评委管理:统一主色调+冻结确认+导入导出disabled - 报名管理:去Tab+统计+审核状态列+批量审核接口 - 报名记录:统计概览+去机构列+撤销审核+返回按钮+去参与方式列 - 作品管理:去Tab+统计+递交进度彩色+筛选修复(assignStatus/submitTime) - 评审进度:去Tab+统计+实际完成率状态+筛选修复 - 评审规则:表格加评委数/计算方式+描述列修复+删除保护 - 成果发布:去Tab+统计+操作文案优化 - 通知公告:统一主色调+发布确认+操作逻辑+状态筛选+时间范围 成果发布详情功能补全: - 计算得分/排名/设置奖项三步操作流程 - 排名列(金银铜徽章)+奖项列+奖项筛选 - 自定义奖项(动态添加行替代硬编码一二三等奖) - 后端AutoSetAwardsDto改为awards数组格式 数据统计看板(新模块): - 后端analytics module(overview+review两个接口) - 运营概览:6指标卡片+报名转化漏斗+ECharts月度趋势+活动对比表 - 评审分析:4效率卡片+评委工作量表+ECharts奖项分布饼图 - 菜单注册:数据统计→运营概览+评审分析 Bug修复: - 超管重置其他租户用户密码报"用户不存在" - gdlib登录快捷标签密码不一致 - 分配评委去掉评审时间限制 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 20:02:24 +08:00
.ant-card-body { padding: 0; }
2026-01-16 16:35:43 +08:00
}
:deep(.ant-table-wrapper) {
background: #fff;
border-radius: 12px;
Day5: 租户端全面优化 + 数据统计看板 + 成果发布完善 租户端基础设施: - 新增工作台首页(欢迎信息/统计/待办/快捷操作/新手引导) - 新增机构信息管理页(自助查看编辑机构信息) - 修复403报错(fetchTenants加超管守卫) - 修复权限(log:read/notice:update/notice:delete/contest:work:read) - 修复评审规则组件映射 活动管理全模块优化(机构端视角): - 活动列表:加统计概览+精简列+筛选自动查询+发布弹窗修复+操作逻辑优化 - 创建/编辑活动:重构布局(去card嵌套+栅格响应式+分区卡片) - 评委管理:统一主色调+冻结确认+导入导出disabled - 报名管理:去Tab+统计+审核状态列+批量审核接口 - 报名记录:统计概览+去机构列+撤销审核+返回按钮+去参与方式列 - 作品管理:去Tab+统计+递交进度彩色+筛选修复(assignStatus/submitTime) - 评审进度:去Tab+统计+实际完成率状态+筛选修复 - 评审规则:表格加评委数/计算方式+描述列修复+删除保护 - 成果发布:去Tab+统计+操作文案优化 - 通知公告:统一主色调+发布确认+操作逻辑+状态筛选+时间范围 成果发布详情功能补全: - 计算得分/排名/设置奖项三步操作流程 - 排名列(金银铜徽章)+奖项列+奖项筛选 - 自定义奖项(动态添加行替代硬编码一二三等奖) - 后端AutoSetAwardsDto改为awards数组格式 数据统计看板(新模块): - 后端analytics module(overview+review两个接口) - 运营概览:6指标卡片+报名转化漏斗+ECharts月度趋势+活动对比表 - 评审分析:4效率卡片+评委工作量表+ECharts奖项分布饼图 - 菜单注册:数据统计→运营概览+评审分析 Bug修复: - 超管重置其他租户用户密码报"用户不存在" - gdlib登录快捷标签密码不一致 - 分配评委去掉评审时间限制 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 20:02:24 +08:00
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.06);
2026-01-16 16:35:43 +08:00
overflow: hidden;
Day5: 租户端全面优化 + 数据统计看板 + 成果发布完善 租户端基础设施: - 新增工作台首页(欢迎信息/统计/待办/快捷操作/新手引导) - 新增机构信息管理页(自助查看编辑机构信息) - 修复403报错(fetchTenants加超管守卫) - 修复权限(log:read/notice:update/notice:delete/contest:work:read) - 修复评审规则组件映射 活动管理全模块优化(机构端视角): - 活动列表:加统计概览+精简列+筛选自动查询+发布弹窗修复+操作逻辑优化 - 创建/编辑活动:重构布局(去card嵌套+栅格响应式+分区卡片) - 评委管理:统一主色调+冻结确认+导入导出disabled - 报名管理:去Tab+统计+审核状态列+批量审核接口 - 报名记录:统计概览+去机构列+撤销审核+返回按钮+去参与方式列 - 作品管理:去Tab+统计+递交进度彩色+筛选修复(assignStatus/submitTime) - 评审进度:去Tab+统计+实际完成率状态+筛选修复 - 评审规则:表格加评委数/计算方式+描述列修复+删除保护 - 成果发布:去Tab+统计+操作文案优化 - 通知公告:统一主色调+发布确认+操作逻辑+状态筛选+时间范围 成果发布详情功能补全: - 计算得分/排名/设置奖项三步操作流程 - 排名列(金银铜徽章)+奖项列+奖项筛选 - 自定义奖项(动态添加行替代硬编码一二三等奖) - 后端AutoSetAwardsDto改为awards数组格式 数据统计看板(新模块): - 后端analytics module(overview+review两个接口) - 运营概览:6指标卡片+报名转化漏斗+ECharts月度趋势+活动对比表 - 评审分析:4效率卡片+评委工作量表+ECharts奖项分布饼图 - 菜单注册:数据统计→运营概览+评审分析 Bug修复: - 超管重置其他租户用户密码报"用户不存在" - gdlib登录快捷标签密码不一致 - 分配评委去掉评审时间限制 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 20:02:24 +08:00
.ant-table-thead > tr > th { background: #fafafa; font-weight: 600; }
.ant-table-tbody > tr:hover > td { background: rgba($primary, 0.03); }
.ant-table-pagination { padding: 16px; margin: 0; }
2026-01-16 16:35:43 +08:00
}
}
2026-01-08 09:17:46 +08:00
.search-form {
margin-bottom: 16px;
2026-01-16 16:35:43 +08:00
padding: 20px 24px;
background: #fff;
border-radius: 12px;
Day5: 租户端全面优化 + 数据统计看板 + 成果发布完善 租户端基础设施: - 新增工作台首页(欢迎信息/统计/待办/快捷操作/新手引导) - 新增机构信息管理页(自助查看编辑机构信息) - 修复403报错(fetchTenants加超管守卫) - 修复权限(log:read/notice:update/notice:delete/contest:work:read) - 修复评审规则组件映射 活动管理全模块优化(机构端视角): - 活动列表:加统计概览+精简列+筛选自动查询+发布弹窗修复+操作逻辑优化 - 创建/编辑活动:重构布局(去card嵌套+栅格响应式+分区卡片) - 评委管理:统一主色调+冻结确认+导入导出disabled - 报名管理:去Tab+统计+审核状态列+批量审核接口 - 报名记录:统计概览+去机构列+撤销审核+返回按钮+去参与方式列 - 作品管理:去Tab+统计+递交进度彩色+筛选修复(assignStatus/submitTime) - 评审进度:去Tab+统计+实际完成率状态+筛选修复 - 评审规则:表格加评委数/计算方式+描述列修复+删除保护 - 成果发布:去Tab+统计+操作文案优化 - 通知公告:统一主色调+发布确认+操作逻辑+状态筛选+时间范围 成果发布详情功能补全: - 计算得分/排名/设置奖项三步操作流程 - 排名列(金银铜徽章)+奖项列+奖项筛选 - 自定义奖项(动态添加行替代硬编码一二三等奖) - 后端AutoSetAwardsDto改为awards数组格式 数据统计看板(新模块): - 后端analytics module(overview+review两个接口) - 运营概览:6指标卡片+报名转化漏斗+ECharts月度趋势+活动对比表 - 评审分析:4效率卡片+评委工作量表+ECharts奖项分布饼图 - 菜单注册:数据统计→运营概览+评审分析 Bug修复: - 超管重置其他租户用户密码报"用户不存在" - gdlib登录快捷标签密码不一致 - 分配评委去掉评审时间限制 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 20:02:24 +08:00
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.06);
2026-01-08 09:17:46 +08:00
}
</style>