1. 动态加载选项数据
- 从API获取团队、成员、课程列表
- 替换硬编码选项为动态渲染
2. 编辑任务功能
- 复用创建对话框,添加编辑模式
- 填充表单数据并调用updateTask API
3. 查看详情弹窗
- 展示任务基本信息、进度、课程、要求
- 调用getTaskDetail API获取详情
4. 结束任务功能
- 确认后调用updateTask API更新状态为completed
- 刷新列表和统计数据
5. 复制任务功能
- 复制任务内容到表单(标题添加"副本"后缀)
- 打开创建对话框
6. 发送提醒功能
- 后端新增 /tasks/{id}/remind API
- 前端调用API并显示结果
This commit is contained in:
@@ -106,3 +106,10 @@ export function deleteTask(id: number): Promise<ResponseModel<void>> {
|
||||
return http.delete(`/api/v1/manager/tasks/${id}`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送任务提醒
|
||||
*/
|
||||
export function sendTaskReminder(id: number): Promise<ResponseModel<void>> {
|
||||
return http.post(`/api/v1/manager/tasks/${id}/remind`)
|
||||
}
|
||||
|
||||
|
||||
@@ -134,12 +134,13 @@
|
||||
<el-empty v-if="taskList.length === 0" description="暂无任务" />
|
||||
</div>
|
||||
|
||||
<!-- 创建任务弹窗 -->
|
||||
<!-- 创建/编辑任务弹窗 -->
|
||||
<el-dialog
|
||||
v-model="createDialogVisible"
|
||||
title="创建学习任务"
|
||||
:title="isEditMode ? '编辑学习任务' : '创建学习任务'"
|
||||
width="680px"
|
||||
:close-on-click-modal="false"
|
||||
@close="resetForm"
|
||||
>
|
||||
<el-form ref="formRef" :model="taskForm" :rules="rules" label-width="100px">
|
||||
<el-form-item label="任务名称" prop="title">
|
||||
@@ -165,7 +166,7 @@
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="分配对象" prop="assignType">
|
||||
<el-form-item v-if="!isEditMode" label="分配对象" prop="assignType">
|
||||
<el-radio-group v-model="taskForm.assignType" @change="handleAssignTypeChange">
|
||||
<el-radio label="all">全体成员</el-radio>
|
||||
<el-radio label="team">指定团队</el-radio>
|
||||
@@ -173,34 +174,36 @@
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item v-if="taskForm.assignType === 'team'" label="选择团队" prop="teams">
|
||||
<el-select v-model="taskForm.teams" multiple placeholder="请选择团队" style="width: 100%">
|
||||
<el-option label="销售一组" value="team1" />
|
||||
<el-option label="销售二组" value="team2" />
|
||||
<el-option label="销售三组" value="team3" />
|
||||
<el-form-item v-if="!isEditMode && taskForm.assignType === 'team'" label="选择团队" prop="teams">
|
||||
<el-select v-model="taskForm.teams" multiple placeholder="请选择团队" style="width: 100%" filterable>
|
||||
<el-option
|
||||
v-for="team in teamOptions"
|
||||
:key="team.id"
|
||||
:label="team.name"
|
||||
:value="team.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item v-if="taskForm.assignType === 'member'" label="选择成员" prop="members">
|
||||
<el-select v-model="taskForm.members" multiple placeholder="请选择成员" style="width: 100%">
|
||||
<el-option label="张三" value="user1" />
|
||||
<el-option label="李四" value="user2" />
|
||||
<el-option label="王五" value="user3" />
|
||||
<el-option label="赵六" value="user4" />
|
||||
<el-form-item v-if="!isEditMode && taskForm.assignType === 'member'" label="选择成员" prop="members">
|
||||
<el-select v-model="taskForm.members" multiple placeholder="请选择成员" style="width: 100%" filterable>
|
||||
<el-option
|
||||
v-for="member in memberOptions"
|
||||
:key="member.id"
|
||||
:label="member.full_name || member.username"
|
||||
:value="member.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="选择课程" prop="courses">
|
||||
<el-select v-model="taskForm.courses" multiple placeholder="请选择课程" style="width: 100%">
|
||||
<el-option-group label="销售技巧">
|
||||
<el-option label="客户沟通技巧" value="course1" />
|
||||
<el-option label="需求挖掘方法" value="course2" />
|
||||
<el-option label="异议处理技巧" value="course3" />
|
||||
</el-option-group>
|
||||
<el-option-group label="产品知识">
|
||||
<el-option label="产品基础知识" value="course4" />
|
||||
<el-option label="竞品分析" value="course5" />
|
||||
</el-option-group>
|
||||
<el-form-item v-if="!isEditMode" label="选择课程" prop="courses">
|
||||
<el-select v-model="taskForm.courses" multiple placeholder="请选择课程" style="width: 100%" filterable>
|
||||
<el-option
|
||||
v-for="course in courseOptions"
|
||||
:key="course.id"
|
||||
:label="course.name"
|
||||
:value="course.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
@@ -228,11 +231,91 @@
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="createDialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleCreateTask" :loading="createLoading">
|
||||
确定
|
||||
{{ isEditMode ? '保存' : '确定' }}
|
||||
</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 任务详情弹窗 -->
|
||||
<el-dialog
|
||||
v-model="detailDialogVisible"
|
||||
title="任务详情"
|
||||
width="600px"
|
||||
>
|
||||
<div v-loading="detailLoading" class="task-detail-content">
|
||||
<template v-if="currentTaskDetail">
|
||||
<div class="detail-section">
|
||||
<h4>基本信息</h4>
|
||||
<el-descriptions :column="2" border>
|
||||
<el-descriptions-item label="任务名称" :span="2">
|
||||
{{ currentTaskDetail.title }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="任务描述" :span="2">
|
||||
{{ currentTaskDetail.description || '暂无描述' }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="优先级">
|
||||
<el-tag :type="getTaskTagType(currentTaskDetail.priority)" size="small">
|
||||
{{ currentTaskDetail.priority }}
|
||||
</el-tag>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="状态">
|
||||
<el-tag :type="currentTaskDetail.status === 'completed' ? 'success' : 'warning'" size="small">
|
||||
{{ currentTaskDetail.status === 'completed' ? '已完成' : currentTaskDetail.status === 'ongoing' ? '进行中' : currentTaskDetail.status }}
|
||||
</el-tag>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="截止时间">
|
||||
{{ formatDeadline(currentTaskDetail.deadline) }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="创建时间">
|
||||
{{ formatDeadline(currentTaskDetail.created_at) }}
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</div>
|
||||
|
||||
<div class="detail-section">
|
||||
<h4>完成进度</h4>
|
||||
<div class="progress-info">
|
||||
<el-progress
|
||||
:percentage="currentTaskDetail.progress"
|
||||
:color="getProgressColor(currentTaskDetail.progress)"
|
||||
:stroke-width="20"
|
||||
/>
|
||||
<p class="progress-text">
|
||||
{{ currentTaskDetail.completed_count }}/{{ currentTaskDetail.assigned_count }} 人完成
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="detail-section" v-if="currentTaskDetail.courses && currentTaskDetail.courses.length > 0">
|
||||
<h4>包含课程 ({{ currentTaskDetail.courses.length }}门)</h4>
|
||||
<div class="course-tags">
|
||||
<el-tag v-for="course in currentTaskDetail.courses" :key="course" class="course-tag">
|
||||
{{ course }}
|
||||
</el-tag>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="detail-section" v-if="currentTaskDetail.requirements">
|
||||
<h4>任务要求</h4>
|
||||
<ul class="requirements-list">
|
||||
<li v-if="currentTaskDetail.requirements.mustComplete">
|
||||
<el-icon><CircleCheck /></el-icon> 必须完成所有课程
|
||||
</li>
|
||||
<li v-if="currentTaskDetail.requirements.mustPass">
|
||||
<el-icon><CircleCheck /></el-icon> 考试必须及格
|
||||
</li>
|
||||
<li v-if="currentTaskDetail.requirements.mustPractice">
|
||||
<el-icon><CircleCheck /></el-icon> 必须完成AI陪练
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
<template #footer>
|
||||
<el-button @click="detailDialogVisible = false">关闭</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -240,16 +323,30 @@
|
||||
import { ref, reactive, computed, onMounted } from 'vue'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import type { FormInstance, FormRules } from 'element-plus'
|
||||
import { getTasks, getTaskStats, createTask as createTaskApi, deleteTask, type Task } from '@/api/task'
|
||||
import { getTasks, getTaskStats, createTask as createTaskApi, deleteTask, updateTask, getTaskDetail, sendTaskReminder, type Task } from '@/api/task'
|
||||
import { getUserList, getTeamList } from '@/api/user/index'
|
||||
import { getCourseList } from '@/api/score'
|
||||
|
||||
// 当前标签页
|
||||
const activeTab = ref('ongoing')
|
||||
|
||||
// 创建任务弹窗
|
||||
// 创建/编辑任务弹窗
|
||||
const createDialogVisible = ref(false)
|
||||
const formRef = ref<FormInstance>()
|
||||
const createLoading = ref(false)
|
||||
const loading = ref(false)
|
||||
const isEditMode = ref(false)
|
||||
const editingTaskId = ref<number | null>(null)
|
||||
|
||||
// 详情弹窗
|
||||
const detailDialogVisible = ref(false)
|
||||
const detailLoading = ref(false)
|
||||
const currentTaskDetail = ref<Task | null>(null)
|
||||
|
||||
// 选项数据
|
||||
const teamOptions = ref<Array<{ id: number; name: string }>>([])
|
||||
const memberOptions = ref<Array<{ id: number; username: string; full_name?: string }>>([])
|
||||
const courseOptions = ref<Array<{ id: number; name: string; category?: string }>>([])
|
||||
|
||||
// 任务统计数据
|
||||
const taskStats = ref([
|
||||
@@ -292,9 +389,9 @@ const taskForm = reactive({
|
||||
description: '',
|
||||
priority: '中',
|
||||
assignType: 'all',
|
||||
teams: [],
|
||||
members: [],
|
||||
courses: [],
|
||||
teams: [] as number[],
|
||||
members: [] as number[],
|
||||
courses: [] as number[],
|
||||
deadline: '',
|
||||
requirements: ['mustComplete']
|
||||
})
|
||||
@@ -382,10 +479,62 @@ const formatDeadline = (deadline?: string) => {
|
||||
return `${year}-${month}-${day}`
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载选项数据(团队、成员、课程)
|
||||
*/
|
||||
const loadOptions = async () => {
|
||||
try {
|
||||
// 并行加载
|
||||
const [teamsRes, usersRes, coursesRes] = await Promise.all([
|
||||
getTeamList({ page: 1, page_size: 100 }).catch(() => null),
|
||||
getUserList({ page: 1, page_size: 500 }).catch(() => null),
|
||||
getCourseList().catch(() => null)
|
||||
])
|
||||
|
||||
// 处理团队数据
|
||||
if (teamsRes?.code === 200 && teamsRes.data) {
|
||||
const teamsData = teamsRes.data.items || teamsRes.data
|
||||
teamOptions.value = Array.isArray(teamsData) ? teamsData : []
|
||||
}
|
||||
|
||||
// 处理成员数据
|
||||
if (usersRes?.code === 200 && usersRes.data) {
|
||||
const usersData = usersRes.data.items || usersRes.data
|
||||
memberOptions.value = Array.isArray(usersData) ? usersData : []
|
||||
}
|
||||
|
||||
// 处理课程数据
|
||||
if (coursesRes?.code === 200 && coursesRes.data) {
|
||||
const coursesData = coursesRes.data.items || coursesRes.data
|
||||
courseOptions.value = Array.isArray(coursesData) ? coursesData : []
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载选项数据失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置表单
|
||||
*/
|
||||
const resetForm = () => {
|
||||
taskForm.title = ''
|
||||
taskForm.description = ''
|
||||
taskForm.priority = '中'
|
||||
taskForm.assignType = 'all'
|
||||
taskForm.teams = []
|
||||
taskForm.members = []
|
||||
taskForm.courses = []
|
||||
taskForm.deadline = ''
|
||||
taskForm.requirements = ['mustComplete']
|
||||
isEditMode.value = false
|
||||
editingTaskId.value = null
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建任务
|
||||
*/
|
||||
const createTask = () => {
|
||||
resetForm()
|
||||
createDialogVisible.value = true
|
||||
}
|
||||
|
||||
@@ -398,7 +547,7 @@ const handleAssignTypeChange = () => {
|
||||
}
|
||||
|
||||
/**
|
||||
* 提交创建任务
|
||||
* 提交创建/编辑任务
|
||||
*/
|
||||
const handleCreateTask = async () => {
|
||||
if (!formRef.value) return
|
||||
@@ -418,24 +567,38 @@ const handleCreateTask = async () => {
|
||||
user_ids: taskForm.assignType === 'all' ? [] : taskForm.members,
|
||||
requirements: {
|
||||
mustComplete: taskForm.requirements.includes('mustComplete'),
|
||||
allowRetake: taskForm.requirements.includes('allowRetake')
|
||||
mustPass: taskForm.requirements.includes('mustPass'),
|
||||
mustPractice: taskForm.requirements.includes('mustPractice')
|
||||
}
|
||||
}
|
||||
|
||||
const res = await createTaskApi(taskData)
|
||||
let res
|
||||
if (isEditMode.value && editingTaskId.value) {
|
||||
// 编辑模式
|
||||
res = await updateTask(editingTaskId.value, {
|
||||
title: taskData.title,
|
||||
description: taskData.description,
|
||||
priority: taskData.priority,
|
||||
deadline: taskData.deadline
|
||||
})
|
||||
} else {
|
||||
// 创建模式
|
||||
res = await createTaskApi(taskData)
|
||||
}
|
||||
|
||||
if (res.code === 200) {
|
||||
ElMessage.success('任务创建成功')
|
||||
ElMessage.success(isEditMode.value ? '任务更新成功' : '任务创建成功')
|
||||
createDialogVisible.value = false
|
||||
formRef.value?.resetFields()
|
||||
resetForm()
|
||||
// 刷新数据
|
||||
await loadTaskStats()
|
||||
await loadTasks()
|
||||
} else {
|
||||
ElMessage.error(res.message || '创建任务失败')
|
||||
ElMessage.error(res.message || (isEditMode.value ? '更新任务失败' : '创建任务失败'))
|
||||
}
|
||||
} catch (error: any) {
|
||||
console.error('创建任务失败:', error)
|
||||
ElMessage.error(error.message || '创建任务失败')
|
||||
console.error(isEditMode.value ? '更新任务失败:' : '创建任务失败:', error)
|
||||
ElMessage.error(error.message || (isEditMode.value ? '更新任务失败' : '创建任务失败'))
|
||||
} finally {
|
||||
createLoading.value = false
|
||||
}
|
||||
@@ -446,48 +609,113 @@ const handleCreateTask = async () => {
|
||||
/**
|
||||
* 查看详情
|
||||
*/
|
||||
const viewDetail = (task: any) => {
|
||||
ElMessage.info(`查看任务详情:${task.title}`)
|
||||
const viewDetail = async (task: Task) => {
|
||||
detailLoading.value = true
|
||||
detailDialogVisible.value = true
|
||||
|
||||
try {
|
||||
const res = await getTaskDetail(task.id)
|
||||
if (res.code === 200 && res.data) {
|
||||
currentTaskDetail.value = res.data
|
||||
} else {
|
||||
currentTaskDetail.value = task
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取任务详情失败:', error)
|
||||
currentTaskDetail.value = task
|
||||
} finally {
|
||||
detailLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送提醒
|
||||
*/
|
||||
const sendReminder = (_task: any) => {
|
||||
ElMessageBox.confirm(
|
||||
`确定要向未完成的成员发送任务提醒吗?`,
|
||||
'发送提醒',
|
||||
{
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'info'
|
||||
const sendReminder = async (task: Task) => {
|
||||
try {
|
||||
await ElMessageBox.confirm(
|
||||
`确定要向未完成的成员发送任务提醒吗?`,
|
||||
'发送提醒',
|
||||
{
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'info'
|
||||
}
|
||||
)
|
||||
|
||||
const res = await sendTaskReminder(task.id)
|
||||
if (res.code === 200) {
|
||||
ElMessage.success(res.message || '提醒发送成功')
|
||||
} else {
|
||||
ElMessage.error(res.message || '发送提醒失败')
|
||||
}
|
||||
).then(() => {
|
||||
ElMessage.success('提醒发送成功')
|
||||
}).catch(() => {})
|
||||
} catch (error: any) {
|
||||
if (error !== 'cancel') {
|
||||
console.error('发送提醒失败:', error)
|
||||
ElMessage.error(error.message || '发送提醒失败')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑任务
|
||||
*/
|
||||
const editTask = async (task: Task) => {
|
||||
// 这里可以打开编辑对话框,填充task数据
|
||||
// 简化实现:直接提示
|
||||
ElMessage.info(`编辑任务功能开发中:${task.title}`)
|
||||
// TODO: 实现完整的编辑功能
|
||||
isEditMode.value = true
|
||||
editingTaskId.value = task.id
|
||||
|
||||
// 填充表单数据
|
||||
taskForm.title = task.title
|
||||
taskForm.description = task.description || ''
|
||||
taskForm.priority = task.priority === 'high' ? '高' : task.priority === 'low' ? '低' : '中'
|
||||
taskForm.deadline = task.deadline || ''
|
||||
taskForm.assignType = 'all'
|
||||
taskForm.teams = []
|
||||
taskForm.members = []
|
||||
taskForm.courses = []
|
||||
|
||||
// 解析 requirements
|
||||
if (task.requirements) {
|
||||
taskForm.requirements = []
|
||||
if (task.requirements.mustComplete) taskForm.requirements.push('mustComplete')
|
||||
if (task.requirements.mustPass) taskForm.requirements.push('mustPass')
|
||||
if (task.requirements.mustPractice) taskForm.requirements.push('mustPractice')
|
||||
}
|
||||
|
||||
createDialogVisible.value = true
|
||||
}
|
||||
|
||||
/**
|
||||
* 复制任务
|
||||
*/
|
||||
const copyTask = (task: any) => {
|
||||
ElMessage.success(`已复制任务:${task.title}`)
|
||||
const copyTask = async (task: Task) => {
|
||||
resetForm()
|
||||
|
||||
// 填充表单数据(标题添加"副本"后缀)
|
||||
taskForm.title = `${task.title} (副本)`
|
||||
taskForm.description = task.description || ''
|
||||
taskForm.priority = task.priority === 'high' ? '高' : task.priority === 'low' ? '低' : '中'
|
||||
taskForm.deadline = '' // 截止时间需要重新设置
|
||||
|
||||
// 解析 requirements
|
||||
if (task.requirements) {
|
||||
taskForm.requirements = []
|
||||
if (task.requirements.mustComplete) taskForm.requirements.push('mustComplete')
|
||||
if (task.requirements.mustPass) taskForm.requirements.push('mustPass')
|
||||
if (task.requirements.mustPractice) taskForm.requirements.push('mustPractice')
|
||||
}
|
||||
|
||||
isEditMode.value = false
|
||||
editingTaskId.value = null
|
||||
createDialogVisible.value = true
|
||||
|
||||
ElMessage.info('已复制任务内容,请修改后保存')
|
||||
}
|
||||
|
||||
/**
|
||||
* 结束任务
|
||||
*/
|
||||
const endTask = async (_task: Task) => {
|
||||
const endTask = async (task: Task) => {
|
||||
try {
|
||||
await ElMessageBox.confirm(
|
||||
'确定要结束这个任务吗?结束后将不能再修改。',
|
||||
@@ -498,8 +726,22 @@ const endTask = async (_task: Task) => {
|
||||
type: 'warning'
|
||||
}
|
||||
)
|
||||
ElMessage.success('任务已结束')
|
||||
} catch {}
|
||||
|
||||
const res = await updateTask(task.id, { status: 'completed' })
|
||||
if (res.code === 200) {
|
||||
ElMessage.success('任务已结束')
|
||||
// 刷新数据
|
||||
await loadTaskStats()
|
||||
await loadTasks()
|
||||
} else {
|
||||
ElMessage.error(res.message || '结束任务失败')
|
||||
}
|
||||
} catch (error: any) {
|
||||
if (error !== 'cancel') {
|
||||
console.error('结束任务失败:', error)
|
||||
ElMessage.error(error.message || '结束任务失败')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -558,8 +800,11 @@ const getProgressColor = (percentage: number) => {
|
||||
|
||||
// 组件挂载时加载数据
|
||||
onMounted(async () => {
|
||||
await loadTaskStats()
|
||||
await loadTasks()
|
||||
await Promise.all([
|
||||
loadTaskStats(),
|
||||
loadTasks(),
|
||||
loadOptions()
|
||||
])
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -744,6 +989,60 @@ onMounted(async () => {
|
||||
}
|
||||
}
|
||||
|
||||
// 任务详情弹窗样式
|
||||
.task-detail-content {
|
||||
.detail-section {
|
||||
margin-bottom: 24px;
|
||||
|
||||
h4 {
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
margin-bottom: 12px;
|
||||
padding-bottom: 8px;
|
||||
border-bottom: 1px solid #ebeef5;
|
||||
}
|
||||
|
||||
.progress-info {
|
||||
.progress-text {
|
||||
margin-top: 8px;
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.course-tags {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
|
||||
.course-tag {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.requirements-list {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
|
||||
li {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 8px 0;
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
|
||||
.el-icon {
|
||||
color: #67c23a;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 响应式
|
||||
@media (max-width: 768px) {
|
||||
.assignment-center-container {
|
||||
|
||||
Reference in New Issue
Block a user