路由更新
This commit is contained in:
@@ -0,0 +1,37 @@
|
||||
<template>
|
||||
<div class="study-management">
|
||||
<h1 class="page-title">学习管理</h1>
|
||||
|
||||
<el-tabs v-model="activeTab">
|
||||
<el-tab-pane label="学习任务发布" name="task-publish">
|
||||
<TaskPublish />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="学习记录" name="task-records">
|
||||
<StudyRecords />
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import { ElTabs, ElTabPane } from 'element-plus';
|
||||
import TaskPublish from './components/TaskPublish.vue';
|
||||
import StudyRecords from './components/StudyRecords.vue';
|
||||
|
||||
const activeTab = ref('task-publish');
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.study-management {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.page-title {
|
||||
font-size: 28px;
|
||||
font-weight: 600;
|
||||
color: #141F38;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
</style>
|
||||
|
||||
149
schoolNewsWeb/src/views/admin/manage/study/StudyRecordsView.vue
Normal file
149
schoolNewsWeb/src/views/admin/manage/study/StudyRecordsView.vue
Normal file
@@ -0,0 +1,149 @@
|
||||
<template>
|
||||
<div class="study-records">
|
||||
<div class="filter-bar">
|
||||
<el-input
|
||||
v-model="searchKeyword"
|
||||
placeholder="搜索用户..."
|
||||
style="width: 200px"
|
||||
clearable
|
||||
/>
|
||||
<el-select v-model="selectedTask" placeholder="选择任务" style="width: 200px" clearable>
|
||||
<el-option
|
||||
v-for="task in tasks"
|
||||
:key="task.id"
|
||||
:label="task.name"
|
||||
:value="task.id"
|
||||
/>
|
||||
</el-select>
|
||||
<el-date-picker
|
||||
v-model="dateRange"
|
||||
type="daterange"
|
||||
range-separator="至"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
/>
|
||||
<el-button type="primary" @click="handleSearch">查询</el-button>
|
||||
<el-button @click="handleExport">导出</el-button>
|
||||
</div>
|
||||
|
||||
<el-table :data="records" style="width: 100%">
|
||||
<el-table-column prop="userName" label="用户" width="120" />
|
||||
<el-table-column prop="taskName" label="任务名称" min-width="180" />
|
||||
<el-table-column prop="progress" label="完成进度" width="120">
|
||||
<template #default="{ row }">
|
||||
<el-progress :percentage="row.progress" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="duration" label="学习时长" width="120" />
|
||||
<el-table-column prop="startDate" label="开始时间" width="150" />
|
||||
<el-table-column prop="status" label="状态" width="100">
|
||||
<template #default="{ row }">
|
||||
<el-tag :type="getStatusType(row.status)">
|
||||
{{ getStatusText(row.status) }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="120" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<el-button size="small" @click="viewDetail(row)">查看详情</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<el-pagination
|
||||
v-model:current-page="currentPage"
|
||||
v-model:page-size="pageSize"
|
||||
:total="total"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted } from 'vue';
|
||||
import { ElInput, ElSelect, ElOption, ElDatePicker, ElButton, ElTable, ElTableColumn, ElTag, ElProgress, ElPagination, ElMessage } from 'element-plus';
|
||||
|
||||
const searchKeyword = ref('');
|
||||
const selectedTask = ref('');
|
||||
const dateRange = ref<[Date, Date] | null>(null);
|
||||
const currentPage = ref(1);
|
||||
const pageSize = ref(10);
|
||||
const total = ref(0);
|
||||
const records = ref<any[]>([]);
|
||||
const tasks = ref<any[]>([]);
|
||||
|
||||
onMounted(() => {
|
||||
loadTasks();
|
||||
loadRecords();
|
||||
});
|
||||
|
||||
function loadTasks() {
|
||||
// TODO: 加载任务列表
|
||||
}
|
||||
|
||||
function loadRecords() {
|
||||
// TODO: 加载学习记录
|
||||
}
|
||||
|
||||
function handleSearch() {
|
||||
currentPage.value = 1;
|
||||
loadRecords();
|
||||
}
|
||||
|
||||
function handleExport() {
|
||||
// TODO: 导出学习记录
|
||||
ElMessage.info('导出功能开发中');
|
||||
}
|
||||
|
||||
function getStatusType(status: string) {
|
||||
const typeMap: Record<string, any> = {
|
||||
'completed': 'success',
|
||||
'in-progress': 'warning',
|
||||
'not-started': 'info'
|
||||
};
|
||||
return typeMap[status] || 'info';
|
||||
}
|
||||
|
||||
function getStatusText(status: string) {
|
||||
const textMap: Record<string, string> = {
|
||||
'completed': '已完成',
|
||||
'in-progress': '进行中',
|
||||
'not-started': '未开始'
|
||||
};
|
||||
return textMap[status] || status;
|
||||
}
|
||||
|
||||
function viewDetail(row: any) {
|
||||
// TODO: 查看学习记录详情
|
||||
}
|
||||
|
||||
function handleSizeChange(val: number) {
|
||||
pageSize.value = val;
|
||||
loadRecords();
|
||||
}
|
||||
|
||||
function handleCurrentChange(val: number) {
|
||||
currentPage.value = val;
|
||||
loadRecords();
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.study-records {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.filter-bar {
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
margin-bottom: 20px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.el-table {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
</style>
|
||||
|
||||
135
schoolNewsWeb/src/views/admin/manage/study/TaskPublishView.vue
Normal file
135
schoolNewsWeb/src/views/admin/manage/study/TaskPublishView.vue
Normal file
@@ -0,0 +1,135 @@
|
||||
<template>
|
||||
<div class="task-publish">
|
||||
<el-form :model="taskForm" :rules="taskRules" ref="taskFormRef" label-width="120px">
|
||||
<el-form-item label="任务名称" prop="name">
|
||||
<el-input v-model="taskForm.name" placeholder="请输入任务名称" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="任务描述" prop="description">
|
||||
<el-input
|
||||
v-model="taskForm.description"
|
||||
type="textarea"
|
||||
:rows="4"
|
||||
placeholder="请输入任务描述"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="任务周期" prop="period">
|
||||
<el-date-picker
|
||||
v-model="taskForm.period"
|
||||
type="daterange"
|
||||
range-separator="至"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="关联资源" prop="resources">
|
||||
<el-button @click="showResourceSelector">选择资源</el-button>
|
||||
<div class="selected-resources" v-if="taskForm.resources.length">
|
||||
<el-tag
|
||||
v-for="resource in taskForm.resources"
|
||||
:key="resource.id"
|
||||
closable
|
||||
@close="removeResource(resource)"
|
||||
>
|
||||
{{ resource.name }}
|
||||
</el-tag>
|
||||
</div>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="任务接受对象" prop="targets">
|
||||
<el-radio-group v-model="taskForm.targetType">
|
||||
<el-radio label="dept">按部门</el-radio>
|
||||
<el-radio label="role">按权限</el-radio>
|
||||
<el-radio label="user">选人员</el-radio>
|
||||
</el-radio-group>
|
||||
<el-button @click="showTargetSelector" style="margin-left: 16px;">
|
||||
选择对象
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="handlePublish">发布任务</el-button>
|
||||
<el-button @click="handleReset">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import { ElForm, ElFormItem, ElInput, ElDatePicker, ElButton, ElRadioGroup, ElRadio, ElTag, ElMessage, type FormInstance, type FormRules } from 'element-plus';
|
||||
|
||||
const taskFormRef = ref<FormInstance>();
|
||||
|
||||
const taskForm = ref({
|
||||
name: '',
|
||||
description: '',
|
||||
period: null as [Date, Date] | null,
|
||||
resources: [] as any[],
|
||||
targetType: 'dept',
|
||||
targets: [] as any[]
|
||||
});
|
||||
|
||||
const taskRules: FormRules = {
|
||||
name: [
|
||||
{ required: true, message: '请输入任务名称', trigger: 'blur' }
|
||||
],
|
||||
description: [
|
||||
{ required: true, message: '请输入任务描述', trigger: 'blur' }
|
||||
],
|
||||
period: [
|
||||
{ required: true, message: '请选择任务周期', trigger: 'change' }
|
||||
]
|
||||
};
|
||||
|
||||
function showResourceSelector() {
|
||||
// TODO: 显示资源选择器
|
||||
}
|
||||
|
||||
function removeResource(resource: any) {
|
||||
const index = taskForm.value.resources.indexOf(resource);
|
||||
if (index > -1) {
|
||||
taskForm.value.resources.splice(index, 1);
|
||||
}
|
||||
}
|
||||
|
||||
function showTargetSelector() {
|
||||
// TODO: 显示对象选择器
|
||||
}
|
||||
|
||||
async function handlePublish() {
|
||||
if (!taskFormRef.value) return;
|
||||
|
||||
try {
|
||||
await taskFormRef.value.validate();
|
||||
// TODO: 调用发布任务API
|
||||
ElMessage.success('任务发布成功');
|
||||
handleReset();
|
||||
} catch (error) {
|
||||
console.error('表单验证失败', error);
|
||||
}
|
||||
}
|
||||
|
||||
function handleReset() {
|
||||
taskFormRef.value?.resetFields();
|
||||
taskForm.value.resources = [];
|
||||
taskForm.value.targets = [];
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.task-publish {
|
||||
padding: 20px;
|
||||
max-width: 800px;
|
||||
}
|
||||
|
||||
.selected-resources {
|
||||
margin-top: 12px;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user