15 changed files with 1915 additions and 958 deletions
-
2work/package.json
-
17work/src/api/AddWorkApi.js
-
20work/src/api/ClassListApi.js
-
12work/src/api/LoginApi.js
-
20work/src/api/UpdateWorkApi.js
-
89work/src/api/index.js
-
48work/src/router/index.js
-
403work/src/views/AddWork.vue
-
366work/src/views/DoHomeworkView.vue
-
258work/src/views/HomeWork.vue
-
145work/src/views/Login.vue
-
535work/src/views/UpdateWork.vue
-
391work/src/views/WorkDetail.vue
-
563work/src/views/WorksShowView.vue
-
4work/vite.config.js
@ -0,0 +1,17 @@ |
|||
import service from "."; |
|||
const AddWorkApi={ |
|||
|
|||
//获取关联文章列表(关键字)
|
|||
getArticleList(Name){ |
|||
return service.post("/api/homework_manage/get-article-list",{Name}); |
|||
}, |
|||
//获取关联直播列表
|
|||
getLiveList(){ |
|||
return service.post("/api/homework_manage/get-live-list"); |
|||
}, |
|||
//添加作业
|
|||
addWork(data){ |
|||
return service.post("/api/homework_manage/add-homework",data); |
|||
}, |
|||
} |
|||
export default AddWorkApi; |
@ -0,0 +1,20 @@ |
|||
import service from "."; |
|||
const ClassListApi={ |
|||
//获取作业列表
|
|||
getClassList(PageNo,PageSize){ |
|||
return service.post("/api/homework_manage/get-homework-list",{PageNo,PageSize}) |
|||
}, |
|||
//为了编辑,首先获取单个作业内容
|
|||
getClassListOne(Id){ |
|||
return service.post("/api/homework_manage/get-homework",{Id}) |
|||
}, |
|||
//获取作业详情
|
|||
getWorkDetail(id,pageNo,pageSize){ |
|||
return service.post("/api/homework_manage/getrecordlist",{id,pageNo,pageSize}) |
|||
}, |
|||
//编辑作业
|
|||
editWork(data){ |
|||
return service.post("/api/homework_manage/edit-homework",data) |
|||
}, |
|||
} |
|||
export default ClassListApi; |
@ -0,0 +1,12 @@ |
|||
import service from "."; |
|||
const LoginApi={ |
|||
//登录
|
|||
login(username,password){ |
|||
return service.post("/api/login",username,password) |
|||
}, |
|||
//退出登录
|
|||
logout(){ |
|||
return service.post("/api/logout") |
|||
} |
|||
} |
|||
export default LoginApi; |
@ -0,0 +1,20 @@ |
|||
import service from "."; |
|||
const UpdateWorkApi={ |
|||
//查询分部
|
|||
getdeptinfo(){ |
|||
return service.post("/api/homework_manage/getdeptinfo") |
|||
}, |
|||
//查询分部门店
|
|||
getshopinfo(deptId){ |
|||
return service.post("/api/homework_manage/getshopinfo",{deptId}) |
|||
}, |
|||
//查询功能
|
|||
getrecordbycondition(data){ |
|||
return service.post("/api/homework_manage/getrecordbycondition",data) |
|||
}, |
|||
//数据导出
|
|||
excelexport(data){ |
|||
return service.post("/api/homework_manage/export-record",data) |
|||
} |
|||
} |
|||
export default UpdateWorkApi; |
@ -1,30 +1,83 @@ |
|||
import axios from "axios"; |
|||
// import axios from "axios";
|
|||
|
|||
// const service = axios.create({
|
|||
// // baseURL: 'http://192.168.8.191:8080',
|
|||
// // baseURL: 'http://localhost:8080',
|
|||
// baseURL: '/api',
|
|||
// });
|
|||
// // http://192.168.8.191:8080
|
|||
|
|||
// //Axios的响应拦截器..
|
|||
// service.interceptors.response.use(resp => {
|
|||
// return resp.data;
|
|||
// }, error => {
|
|||
// return Promise.reject(error);
|
|||
// });
|
|||
// export default service;
|
|||
|
|||
|
|||
import axios from "axios"; |
|||
import { useTokenStore } from "../stores/token"; |
|||
const service = axios.create({ |
|||
// baseURL: 'http://192.168.8.191:8080',
|
|||
// baseURL: 'http://localhost:8080',
|
|||
baseURL: '/api', |
|||
}); |
|||
|
|||
// 添加请求拦截器
|
|||
service.interceptors.request.use( |
|||
config => { |
|||
// 假设你的token存储在Vuex、Pinia或者本地存储中,这里直接用一个变量代替
|
|||
// 请确保在实际应用中从安全的地方获取token
|
|||
const token = "9ior41AF0xTIbIG2pRnnbZi0+fEeMx8pywnIlrmTwo5FbqJ9lWrSWOxp9MkpKiNtedtUafqvzIwpFKrwuMs"; |
|||
if (token) { |
|||
config.headers['token'] = ` ${token}`; |
|||
} |
|||
return config; |
|||
}, |
|||
error => { |
|||
return Promise.reject(error); |
|||
// Axios的请求拦截器,在这里添加token到请求头
|
|||
|
|||
axios.interceptors.request.use(config => { |
|||
const tokenStore = useTokenStore(); |
|||
if (tokenStore.token) { |
|||
config.headers.token = tokenStore.token; |
|||
} |
|||
); |
|||
return config; |
|||
}, error => { |
|||
return Promise.reject(error); |
|||
}); |
|||
|
|||
// 添加响应拦截器
|
|||
service.interceptors.response.use(resp => { |
|||
return resp.data; |
|||
service.interceptors.request.use(config => { |
|||
const tokenStore = useTokenStore(); |
|||
if (tokenStore.token) { |
|||
// 一般后端会约定一个请求头的字段名来接收token,常见的如 'Authorization',并要求按照一定格式传递,比如 'Bearer <token>',这里按照此格式添加,你需要根据后端实际要求调整
|
|||
config.headers.token =tokenStore.token; |
|||
} |
|||
return config; |
|||
}, error => { |
|||
return Promise.reject(error); |
|||
}); |
|||
|
|||
// // Axios的响应拦截器
|
|||
// service.interceptors.response.use(resp => {
|
|||
// return resp.data;
|
|||
// }, error => {
|
|||
// return Promise.reject(error);
|
|||
// });
|
|||
|
|||
//响应拦截器
|
|||
service.interceptors.response.use(response => { |
|||
return response.data; |
|||
}, error =>{ |
|||
if(error.code === "500"){ |
|||
ElMessage.error("服务器错误!"); |
|||
} |
|||
const response = error.response; |
|||
if(error.response && error.response.status === 403){ |
|||
//提示一下权限不足
|
|||
ElMessage.warning(response.data.message); |
|||
} else if(response && response.code === 401){ |
|||
//提示一下未登录
|
|||
ElMessage.warning(response.data.message); |
|||
//跳转登录页面
|
|||
const curURL = router.currentRoute.value.path; |
|||
if(curURL.startsWith('/')){ |
|||
router.push('/login') |
|||
} else{ |
|||
router.push('/login'); |
|||
} |
|||
console.log(); |
|||
} |
|||
return Promise.reject(error); |
|||
}) |
|||
|
|||
export default service; |
@ -1,21 +1,53 @@ |
|||
import { createRouter, createWebHistory } from 'vue-router'; |
|||
import WorksShowView from '../views/WorksShowView.vue'; |
|||
import DoHomeworkView from "@/views/DoHomeworkView.vue"; |
|||
import HomeWork from '../views/HomeWork.vue'; |
|||
import Login from '../views/Login.vue'; |
|||
import AddWork from '../views/AddWork.vue'; |
|||
import WorkDetail from '../views/WorkDetail.vue'; |
|||
import UpdateWork from '../views/UpdateWork.vue'; |
|||
import { useTokenStore } from '../stores/token'; |
|||
|
|||
const router = createRouter({ |
|||
history: createWebHistory(), |
|||
routes: [ |
|||
{ |
|||
path: '/show', |
|||
name: 'workshow', |
|||
component: WorksShowView |
|||
path: '/', |
|||
name: 'login', |
|||
component: Login, |
|||
}, |
|||
{ |
|||
path:'/doWork/:id?/:sub?', |
|||
name:'doWork', |
|||
component: DoHomeworkView |
|||
path: '/list', |
|||
name: 'homeWorklist', |
|||
component: HomeWork, |
|||
}, |
|||
{ |
|||
path:'/addwork', |
|||
name:'addwork', |
|||
component: AddWork |
|||
}, |
|||
{ |
|||
path:'/workdetail/:id', |
|||
name:'workdetail', |
|||
component: WorkDetail |
|||
}, |
|||
{ |
|||
path:'/updatework/:id', |
|||
name:'updatework', |
|||
component: UpdateWork |
|||
} |
|||
] |
|||
}) |
|||
|
|||
// 添加全局前置守卫
|
|||
router.beforeEach((to, from, next) => { |
|||
const tokenStore = useTokenStore(); |
|||
const token = tokenStore.token; |
|||
if (!token && to.name !== 'login') { |
|||
// 如果没有token且要访问的不是登录页面,就跳转到登录页面
|
|||
next({ name: 'login' }); |
|||
} else { |
|||
// 有token或者要访问的是登录页面,正常放行
|
|||
next(); |
|||
} |
|||
}); |
|||
|
|||
export default router |
@ -0,0 +1,403 @@ |
|||
<template> |
|||
<div class="common-layout"> |
|||
<el-container> |
|||
<el-header class="header"> |
|||
<el-text class="header-text">抢点班作业后台管理</el-text> |
|||
<el-button class="header-button" type="primary" text style="float: right;" @click="logout">退出登录</el-button> |
|||
</el-header> |
|||
<el-main class="main"> |
|||
<div class="main-title"> |
|||
<div class="main-title-text" style="float: left;"> |
|||
新建作业 |
|||
</div> |
|||
<div> |
|||
<el-button class="main-button" @click="back">返回上一页</el-button> |
|||
</div> |
|||
</div> |
|||
<div class="main-back"> |
|||
<el-form :model="form" label-width="auto" style="max-width: 700px" size="large"> |
|||
<el-form-item label="作业名称"> |
|||
<el-input v-model="form.Name" placeholder="请输入"></el-input> |
|||
</el-form-item> |
|||
<el-form-item label="提交时间" style="width: 70%"> |
|||
<el-date-picker v-model="form.picker" type="daterange" range-separator="至" start-placeholder="开始日期" |
|||
end-placeholder="结束日期" /> |
|||
</el-form-item> |
|||
<el-form-item label="作业归属"> |
|||
<el-select v-model="form.ClubType" placeholder="请选择" style="width: 100%"> |
|||
<el-option v-for="item in options" :key="item.id" :label="item.name" :value="item.id" /> |
|||
</el-select> |
|||
</el-form-item> |
|||
<el-form-item label="关联文章"> |
|||
<el-autocomplete v-model="articleTitle" :fetch-suggestions="queryArticleList" placeholder="请输入" |
|||
@select="handleSelectArticle" clearable @change="handleArticleChange"/> |
|||
</el-form-item> |
|||
<el-form-item label="关联直播"> |
|||
<el-select v-model="form.LiveId" placeholder="请选择" style="width: 100%" clearable @change="handleLiveChange"> |
|||
<el-option v-for="item in live" :key="item.id" :label="item.name" :value="item.id" /> |
|||
</el-select> |
|||
</el-form-item> |
|||
<el-form-item label="选择类型"> |
|||
<div> |
|||
<el-button type="primary" @click="addSingleChoice">添加单选</el-button> |
|||
<el-button type="primary" @click="addMultipleChoice">添加多选</el-button> |
|||
<el-button type="primary" @click="addBlank">添加单选填空</el-button> |
|||
</div> |
|||
</el-form-item> |
|||
<div class="question-container" v-for="(question, index) in questions" :key="index" |
|||
:class="{ 'bg-change': isHovered[index] }" @mouseenter="handleMouseEnter(index)" |
|||
@mouseleave="handleMouseLeave(index)"> |
|||
<div class="question-title"> |
|||
{{ questionPrefix(index) }} {{ getQuestionTypeText(question.type) }} |
|||
</div> |
|||
<div style="width: 600px;"> |
|||
<el-input v-model="question.description" /> |
|||
</div> |
|||
<div class="add" v-if="question.type !== 'blank'"> |
|||
<div class="question-option"> |
|||
<span>设置选项:</span> |
|||
<el-button type="primary" text @click="addOption(index)">添加</el-button> |
|||
</div> |
|||
<div v-for="(option, optionIndex) in question.content" :key="optionIndex"> |
|||
<div class="select" style="display: flex;"> |
|||
<div class="selection-item" style="display: flex;"> |
|||
<div style="width: 550px;"> |
|||
<el-input v-model="question.content[optionIndex].text" /> |
|||
</div> |
|||
<div> |
|||
<el-button type="primary" text @click="removeOption(index, optionIndex)">删除</el-button> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<div class="delete" style="margin-left: 50px;"> |
|||
<el-button type="info" plain @click="removeQuestion(index)">删除</el-button> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<div class="submit"> |
|||
<el-button type="primary" :disabled="!form.Name||!form.picker" @click="onSubmit">确认</el-button> |
|||
</div> |
|||
</el-form> |
|||
</div> |
|||
</el-main> |
|||
</el-container> |
|||
</div> |
|||
|
|||
</template> |
|||
|
|||
<script lang="ts" setup> |
|||
import { ref, onMounted, computed } from 'vue' |
|||
import AddWorkApi from '../api/AddWorkApi'; |
|||
import _ from 'lodash'; |
|||
import dayjs from 'dayjs'; |
|||
import { ElMessage } from 'element-plus' |
|||
import LoginApi from '../api/LoginApi'; |
|||
import axios from 'axios'; |
|||
import { useRouter } from 'vue-router'; |
|||
import { useTokenStore } from '../stores/token'; |
|||
import { useUserStore } from '../stores/user'; |
|||
|
|||
const router = useRouter(); |
|||
|
|||
const options = ref([ |
|||
{ id: 1, name: '牧民俱乐部' }, |
|||
{ id: 2, name: '博古论坛' }, |
|||
{ id: 3, name: '神枪手俱乐部' }, |
|||
{ id: 4, name: '环球俱乐部' }, |
|||
{ id: 5, name: '价值投资' }, |
|||
{ id: 6, name: '波段行情' }, |
|||
{ id: 7, name: '抄底卖顶' }, |
|||
{ id: 8, name: '资金及仓位管理' }, |
|||
{ id: 9, name: '财富的游戏' }, |
|||
|
|||
]); |
|||
|
|||
// do not use same name with ref |
|||
const form = ref({ |
|||
Name: '', |
|||
ClubType: '', |
|||
ArticleId: '', |
|||
LiveId: '', |
|||
picker: [], |
|||
StartDate: '', |
|||
EndDate: '', |
|||
Questions: [] |
|||
}); |
|||
const articleTitle = ref(''); |
|||
// 问题列表数据 |
|||
const questions = ref([]); |
|||
const onSubmit = () => { |
|||
// 从picker中获取日期数据并进行格式转换 |
|||
if (form.value.picker && form.value.picker.length === 2) { |
|||
const startDate = dayjs(form.value.picker[0]).format('YYYY-MM-DD HH:mm:00'); |
|||
const endDate = dayjs(form.value.picker[1]).format('YYYY-MM-DD HH:mm:00'); |
|||
form.value.StartDate = startDate; |
|||
form.value.EndDate = endDate; |
|||
} |
|||
form.value.Questions = questions.value; |
|||
AddWorkApi.addWork(form.value) |
|||
console.log(questions.value+'--------------') |
|||
ElMessage.success('添加成功'); |
|||
router.push('/list') |
|||
} |
|||
const back = () => { |
|||
window.history.back() |
|||
} |
|||
|
|||
|
|||
// 存储根据文章输入内容查询到的关联文章结果列表 |
|||
const articleSearchResults = ref([]); |
|||
// 根据文章输入内容查询关联文章的函数 |
|||
const queryArticleList = async (queryString: string) => { |
|||
if (form.value.LiveId) { |
|||
ElMessage.warning('您已关联直播,暂无法关联文章'); |
|||
articleTitle.value = ''; // 清空文章标题输入框 |
|||
form.value.LiveId = ''; |
|||
return []; |
|||
} |
|||
try { |
|||
const response = await AddWorkApi.getArticleList(queryString); |
|||
const formattedResults = response.data.map(article => ({ |
|||
value: article.title, |
|||
label: article.id |
|||
})); |
|||
articleSearchResults.value = formattedResults; |
|||
return formattedResults; |
|||
} catch (error) { |
|||
console.error('查询关联文章失败', error); |
|||
return []; |
|||
} |
|||
}; |
|||
// 处理选择文章的函数 |
|||
const handleSelectArticle = (article: { label: string }) => { |
|||
// 这里可以根据业务需求,比如将选中的文章id(article.label)传递给其他地方使用等 |
|||
console.log('选中的文章id', article.label); |
|||
form.value.ArticleId = article.label; // 将选中文章的id赋值给对应表单字段,用于传递给后端 |
|||
const selectedArticle = articleSearchResults.value.find(a => a.label === article.label); |
|||
if (selectedArticle) { |
|||
articleTitle.value = selectedArticle.value; // 更新显示的文章题目 |
|||
} |
|||
}; |
|||
const handleLiveChange = () => { |
|||
if (form.value.ArticleId) { |
|||
ElMessage.warning('您已关联文章,暂无法关联直播'); |
|||
form.value.LiveId = ''; // 清空关联直播选择框的值 |
|||
form.value.ArticleId = ''; |
|||
articleTitle.value = ''; |
|||
} |
|||
}; |
|||
|
|||
//获取直播列表 |
|||
const live = ref([]); |
|||
function getLive() { |
|||
AddWorkApi.getLiveList() |
|||
.then(res => { |
|||
live.value = res.data; |
|||
console.log(live.value); |
|||
}) |
|||
.catch(error => { |
|||
console.error('获取直播列表失败', error) |
|||
}) |
|||
} |
|||
getLive(); |
|||
|
|||
// 根据类型获取对应的题目类型文本显示 |
|||
const getQuestionTypeText = (type) => { |
|||
switch (type) { |
|||
case 1: |
|||
return '作业题目(单选)'; |
|||
case 2: |
|||
return '作业题目(多选)'; |
|||
case 3: |
|||
return '作业题目(简答题)'; |
|||
default: |
|||
return '未知类型题目'; |
|||
} |
|||
}; |
|||
|
|||
const addSingleChoice = () => { |
|||
questions.value.push({ |
|||
type: 1, // 假设1代表单选,和后端格式对应起来 |
|||
description: '', |
|||
content: [{ "id": "", "text": "" },{ "id": "", "text": "" }] |
|||
}); |
|||
}; |
|||
|
|||
const addMultipleChoice = () => { |
|||
questions.value.push({ |
|||
type: 2, // 假设2代表多选,和后端格式对应起来 |
|||
description: '', |
|||
content: [{ "id": "", "text": "" },{ "id": "", "text": "" }] |
|||
}); |
|||
}; |
|||
|
|||
const addBlank = () => { |
|||
questions.value.push({ |
|||
type: 3, // 假设3代表简答题,和后端格式对应起来 |
|||
description: '', |
|||
content: [{ "id": "", "text": "" }] |
|||
}); |
|||
}; |
|||
|
|||
// const addOption = (questionIndex) => { |
|||
// const currentQuestion = questions.value[questionIndex]; |
|||
// const currentContent = JSON.parse(currentQuestion.content); |
|||
// currentContent.push({ "id": "", "text": "" }); |
|||
// currentQuestion.content = JSON.stringify(currentContent); |
|||
// }; |
|||
|
|||
// const removeOption = (questionIndex, optionIndex) => { |
|||
// const currentQuestion = questions.value[questionIndex]; |
|||
// const currentContent = JSON.parse(currentQuestion.content); |
|||
// currentContent.splice(optionIndex, 1); |
|||
// currentQuestion.content = JSON.stringify(currentContent); |
|||
// }; |
|||
const addOption = (questionIndex) => { |
|||
const currentQuestion = questions.value[questionIndex]; |
|||
// 如果当前题目没有content属性,则初始化一个空数组 |
|||
if (!currentQuestion.content) { |
|||
currentQuestion.content = []; |
|||
} |
|||
currentQuestion.content.push({ id: "", text: "" }); |
|||
}; |
|||
const removeOption = (questionIndex, optionIndex) => { |
|||
const currentQuestion = questions.value[questionIndex]; |
|||
currentQuestion.content.splice(optionIndex, 1); |
|||
}; |
|||
const removeQuestion = (questionIndex) => { |
|||
questions.value.splice(questionIndex, 1); |
|||
}; |
|||
|
|||
// 计算属性,用于生成序号前缀 |
|||
const questionPrefix = computed(() => { |
|||
return (index) => { |
|||
return `${index + 1}、`; |
|||
}; |
|||
}) |
|||
|
|||
// 用于存储每个问题标题是否被鼠标悬停的状态,初始化为false |
|||
const isHovered = ref(Array(questions.value.length).fill(false)); |
|||
const handleMouseEnter = (index) => { |
|||
isHovered.value[index] = true; |
|||
}; |
|||
|
|||
const handleMouseLeave = (index) => { |
|||
isHovered.value[index] = false; |
|||
}; |
|||
|
|||
// 在组件挂载后初始化 `isHovered` 数组长度与 `questions` 数组长度一致 |
|||
onMounted(() => { |
|||
isHovered.value = Array(questions.value.length).fill(false); |
|||
}); |
|||
|
|||
|
|||
//退出 |
|||
function logout(){ |
|||
//清除登录信息 |
|||
const tokenStore = useTokenStore(); |
|||
const userStore = useUserStore(); |
|||
tokenStore.clear(); |
|||
userStore.clear(); |
|||
LoginApi.logout().then(res => { |
|||
console.log(res) |
|||
}) |
|||
router.push('/') |
|||
} |
|||
</script> |
|||
|
|||
<style scoped> |
|||
.submit { |
|||
margin: 100px 212px; |
|||
} |
|||
|
|||
.submit .el-button { |
|||
padding: 25px 150px; |
|||
} |
|||
|
|||
.question-title { |
|||
transition: background-color 0.3s ease; |
|||
} |
|||
|
|||
.bg-change { |
|||
background-color: rgba(200, 200, 200, 0.3); |
|||
} |
|||
|
|||
.question-title { |
|||
margin-bottom: 10px; |
|||
} |
|||
|
|||
.select { |
|||
margin: 10px 0px 0px; |
|||
} |
|||
|
|||
.delete { |
|||
position: absolute; |
|||
right: 10px; |
|||
bottom: 0px; |
|||
} |
|||
|
|||
.add { |
|||
position: relative; |
|||
} |
|||
|
|||
.question-container { |
|||
margin: 20px 0; |
|||
padding: 10px 20px; |
|||
width: 750px; |
|||
border-bottom: 1px solid #e5e5e5; |
|||
} |
|||
|
|||
.header { |
|||
height: 100px; |
|||
line-height: 100px; |
|||
padding: 0 80px; |
|||
} |
|||
|
|||
.header-text { |
|||
font-size: 22px; |
|||
font-weight: 500; |
|||
color: black; |
|||
float: left; |
|||
} |
|||
|
|||
.header-button { |
|||
margin-top: 30px; |
|||
} |
|||
|
|||
.main { |
|||
padding: 30px 212px; |
|||
background-color: #F8F8F8; |
|||
} |
|||
|
|||
.main-title { |
|||
font-size: 16px; |
|||
background-color: white; |
|||
font-weight: bold; |
|||
height: 60px; |
|||
border-bottom: 2px solid #ececec; |
|||
padding: 0 15px; |
|||
line-height: 52px; |
|||
} |
|||
|
|||
.main-button { |
|||
margin: 10px 15px 0 0; |
|||
padding: 12px 20px; |
|||
height: 40px; |
|||
float: right; |
|||
} |
|||
|
|||
.el-form { |
|||
padding: 30px 78.5px; |
|||
margin: auto; |
|||
} |
|||
|
|||
.el-form-item { |
|||
--font-size: 16px; |
|||
margin: 0 0 25px; |
|||
} |
|||
|
|||
.main-back { |
|||
background-color: white; |
|||
} |
|||
</style> |
@ -1,366 +0,0 @@ |
|||
<template> |
|||
<div class="container"> |
|||
<div class="main"> |
|||
<div class="content"> |
|||
<div class="title"> |
|||
{{ questionList[0].name }} |
|||
</div> |
|||
<template v-for="(question, questionIndex) in questionList" :key="questionIndex"> |
|||
<!-- 单选 --> |
|||
<template v-if="question.type == 1"> |
|||
<div class="question"> |
|||
{{ questionIndex + 1 }}. {{ question.description }}(单选) |
|||
</div> |
|||
<div v-for="(answer, index) in question.content" :key="index" class="answer"> |
|||
<div class="selected"> |
|||
<input :id="`select-${questionIndex}-${index}`" :name="`radio-group-${questionIndex}`" type="radio" |
|||
v-model="selectedAnswers[questionIndex]" |
|||
:value="answer.text" |
|||
> |
|||
<label :for="`select-${questionIndex}-${index}`">{{ answer.text }}</label> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<!-- 多选 --> |
|||
<template v-if="question.type == 2"> |
|||
<div class="question"> |
|||
{{ questionIndex + 1 }}. {{ question.description }}(多选) |
|||
</div> |
|||
<div v-for="(answer, index) in question.content" :key="index" class="answer"> |
|||
<div class="selected"> |
|||
<input :id="`checkbox-${questionIndex}-${index}`" name="checkbox" type="checkbox" |
|||
v-model="selectedAnswers[questionIndex]" |
|||
:value="answer.text" |
|||
> |
|||
<label :for="`checkbox-${questionIndex}-${index}`">{{ answer.text }}</label> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<!-- 简答题 --> |
|||
<template v-if="question.type == 3"> |
|||
<div class="Short-answers"> |
|||
<div class="question"> |
|||
{{ questionIndex + 1 }}. {{ question.description }} |
|||
</div> |
|||
<el-input |
|||
v-model="editorTitles[questionIndex]" |
|||
style="width: 100%; padding: 3.5%" |
|||
size="large" |
|||
placeholder="请输入标题(5-100字符)" |
|||
maxlength="100" |
|||
minlength="5" |
|||
show-word-limit |
|||
/> |
|||
<div class="editor"> |
|||
<div style="border: 1px solid #ccc"> |
|||
<Toolbar |
|||
style="border-bottom: 1px solid #ccc" |
|||
:editor="editorRefs[questionIndex]" |
|||
:defaultConfig="toolbarConfig" |
|||
:mode="mode" |
|||
/> |
|||
<Editor |
|||
style="height: 500px; overflow-y: hidden;" |
|||
v-model="editorContents[questionIndex]" |
|||
:defaultConfig="editorConfig" |
|||
:mode="mode" |
|||
@onCreated="editor => handleCreated(editor, questionIndex)" |
|||
|
|||
/> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
</template> |
|||
|
|||
<!-- 提交按钮 --> |
|||
<div class="submit"> |
|||
<img src="https://d31zlh4on95l9h.cloudfront.net/images/5iujb101000d2foxm6thylaa50qz6lgl.png" @click="submit"> |
|||
</div> |
|||
<!-- 提交次数 --> |
|||
<div class="submit-times"> |
|||
<span>您已提交{{sub}}次,每个作业可以提交3次</span> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
|
|||
|
|||
</template> |
|||
|
|||
<script setup> |
|||
import { onMounted, ref, shallowRef } from 'vue'; |
|||
import homeworkApi from "@/api/HomeworkApi.js"; |
|||
import { ElMessage } from "element-plus"; |
|||
import '@wangeditor/editor/dist/css/style.css' // 引入 css |
|||
import { onBeforeUnmount } from 'vue' |
|||
import { Editor, Toolbar } from '@wangeditor/editor-for-vue' |
|||
import {useRoute, useRouter} from "vue-router"; |
|||
|
|||
const router = useRouter(); |
|||
const route = useRoute(); |
|||
let groupId = route.params.id; |
|||
let sub = route.params.sub; |
|||
// 编辑器实例,必须用 shallowRef |
|||
const editorRefs = ref([]); |
|||
|
|||
// 内容 HTML |
|||
const editorContents = ref([]); |
|||
const editorTitles = ref([]); |
|||
|
|||
// 模拟 ajax 异步获取内容 |
|||
onMounted(() => { |
|||
setTimeout(() => { |
|||
editorContents.value = editorContents.value.map(() => ''); |
|||
}, 1500) |
|||
}) |
|||
|
|||
const toolbarConfig = { |
|||
excludeKeys: [ |
|||
'justify', |
|||
'table', |
|||
'codeBlock', |
|||
'divider', |
|||
'undo', |
|||
'redo', |
|||
'insertImage', // 去掉插入图片 |
|||
'insertLink', // 去掉插入链接 |
|||
'insertTable', // 去掉插入表格 |
|||
'video', |
|||
'group-more-style', |
|||
'group-image', |
|||
'group-video', |
|||
'fullScreen', |
|||
'todo' |
|||
], |
|||
insertKeys: { |
|||
index: 0, |
|||
keys: ['bold', 'italic'] |
|||
} |
|||
} |
|||
|
|||
|
|||
const editorConfig = { |
|||
placeholder: '请输入内容...', |
|||
toolbarKeys: toolbarConfig.toolbarKeys |
|||
} |
|||
|
|||
// 组件销毁时,也及时销毁编辑器 |
|||
onBeforeUnmount(() => { |
|||
editorRefs.value.forEach(editor => { |
|||
if (editor == null) return; |
|||
editor.destroy(); |
|||
}); |
|||
}) |
|||
|
|||
const handleCreated = (editor, questionIndex) => { |
|||
editorRefs.value[questionIndex] = editor; // 记录 editor 实例 |
|||
editor.config.toolbarConfig = toolbarConfig; // 确保配置正确应用 |
|||
} |
|||
|
|||
const questionList = ref([]); |
|||
|
|||
function getQuestionList() { |
|||
console.log("ljghasjkhdjksahjkhsajkhjkasd",groupId); |
|||
homeworkApi.getHomeworkQuestion(groupId).then(resp => { |
|||
if (resp.code == 200) { |
|||
questionList.value = resp.data; |
|||
for (let i = 0; i < questionList.value.length; i++) { |
|||
questionList.value[i].content = JSON.parse(questionList.value[i].content); |
|||
// 初始化 editorTitles 和 editorContents |
|||
editorTitles.value.push(''); |
|||
editorContents.value.push(''); |
|||
// 初始化 selectedAnswers 为数组 |
|||
selectedAnswers.value.push([]); |
|||
} |
|||
} else { |
|||
ElMessage.error("未知错误,请联系管理员"); |
|||
} |
|||
}); |
|||
} |
|||
getQuestionList(); |
|||
|
|||
// 提交作业 |
|||
const homework = ref([]); |
|||
|
|||
const selectedAnswers = ref([]); |
|||
questionList.value.forEach(() => { |
|||
selectedAnswers.value.push([]); |
|||
}); |
|||
|
|||
// 上一个页面传递的参数 groupId |
|||
function submit() { |
|||
homework.value = []; |
|||
for (let i = 0; i < questionList.value.length; i++) { |
|||
if (questionList.value[i].type == 1 || questionList.value[i].type == 2) { |
|||
homework.value.push({ |
|||
"id": questionList.value[i].id, |
|||
"answer": selectedAnswers.value[i], |
|||
"type": questionList.value[i].type |
|||
}); |
|||
} else if (questionList.value[i].type == 3) { |
|||
const editor = editorRefs.value[i]; |
|||
const plainText = editor ? editor.getText() : ''; |
|||
homework.value.push({ |
|||
"id": questionList.value[i].id, |
|||
"answer": [editorTitles.value[i], plainText], |
|||
"type": questionList.value[i].type |
|||
}); |
|||
} |
|||
} |
|||
let groupId = route.params.id; |
|||
let sub = route.params.sub; |
|||
if (sub <=2){ |
|||
homeworkApi.submitHomework(homework.value, groupId).then(resp => { |
|||
if (resp.code == 200) { |
|||
ElMessage.success("提交成功"); |
|||
homework.value = []; |
|||
router.push("/show"); |
|||
} else { |
|||
ElMessage.error("未知错误,请联系管理员"); |
|||
} |
|||
}); |
|||
}else { |
|||
ElMessage.error("提交失败您,已提交3次,每个作业可以提交3次"); |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style scoped> |
|||
.container { |
|||
text-align: center; |
|||
margin-left: auto; |
|||
margin-right: auto; |
|||
width: 34.375rem; |
|||
height: 114.399375rem; |
|||
} |
|||
|
|||
.main { |
|||
background-image: url("https://lfjf.rzfwq.com/jtzy/Product/pcjingwang/images/20230823/qiangdianbanHomeWorkBg.png"); |
|||
background-size: contain; |
|||
background-position: center 0; |
|||
background-repeat: no-repeat; |
|||
margin: 0; |
|||
width: 100%; |
|||
height: 1830px; |
|||
text-align: center; |
|||
position: relative; |
|||
} |
|||
|
|||
.content { |
|||
position: absolute; |
|||
width: 93%; |
|||
height: 80%; |
|||
overflow-y: scroll; |
|||
/* 居中显示 */ |
|||
left: 50%; |
|||
transform: translate(-50%, 0); |
|||
top: 12.5%; |
|||
text-align: left; |
|||
} |
|||
|
|||
/* 滚动条样式 */ |
|||
.content::-webkit-scrollbar { |
|||
width: 3px; |
|||
} |
|||
|
|||
.content::-webkit-scrollbar-track { |
|||
background: #f1f1f1; /* 滚动条轨道的背景色 */ |
|||
} |
|||
|
|||
.content::-webkit-scrollbar-thumb { |
|||
background: #d9d9d9; /* 滚动条滑块的颜色 */ |
|||
border-radius: 6px; /* 滑块的圆角 */ |
|||
} |
|||
|
|||
.title { |
|||
font-size: 1.65rem; |
|||
font-weight: 600; |
|||
/* 居中显示 */ |
|||
text-align: center; |
|||
/*字体颜色*/ |
|||
color: #3f27b1; |
|||
} |
|||
|
|||
.question { |
|||
padding-top: 10%; |
|||
padding-left: 4%; |
|||
font-size: 1.35rem; |
|||
font-weight: 500; |
|||
} |
|||
|
|||
.answer { |
|||
padding-top: 2.5%; |
|||
padding-left: 7%; |
|||
font-size: 1.35rem; |
|||
} |
|||
|
|||
.selected { |
|||
display: block; |
|||
padding: 1% 0 1.2% 0; |
|||
} |
|||
|
|||
|
|||
.selected input[name="checkbox"] { |
|||
margin-right: 1%; |
|||
width: 1.2rem; |
|||
height: 1rem; |
|||
/* 透明度 */ |
|||
opacity: 0.8; |
|||
cursor: pointer; /* 鼠标悬停时变成手的形状 */ |
|||
} |
|||
.selected input[type="radio"]{ |
|||
margin-right: 1%; |
|||
width: 1.2rem; |
|||
height: 1rem; |
|||
/* 透明度 */ |
|||
opacity: 0.8; |
|||
cursor: pointer; /* 鼠标悬停时变成手的形状 */ |
|||
} |
|||
|
|||
/* 单选按钮选中时的样式 */ |
|||
.selected input[type="radio"]:checked { |
|||
accent-color: blue; /* 设置选中时的颜色为蓝色 */ |
|||
} |
|||
|
|||
/* 多选按钮选中时的样式 */ |
|||
.selected input[type="checkbox"]:checked { |
|||
accent-color: blue; /* 设置选中时的颜色为蓝色 */ |
|||
} |
|||
|
|||
.selected label { |
|||
cursor: pointer; |
|||
} |
|||
|
|||
.editor { |
|||
padding-top: 2.5%; |
|||
padding-left: 3.5%; |
|||
padding-right: 3.5%; |
|||
height: 30rem; |
|||
} |
|||
|
|||
.Short-answers { |
|||
height: 48rem; |
|||
} |
|||
|
|||
.submit { |
|||
display: block; |
|||
text-align: center; |
|||
} |
|||
|
|||
.submit img { |
|||
padding-top: 2.5%; |
|||
padding-left: 3.5%; |
|||
padding-right: 3.5%; |
|||
cursor: pointer; |
|||
width: 67%; |
|||
} |
|||
|
|||
.submit-times { |
|||
font-size: 0.8rem; |
|||
color: #858585; |
|||
text-align: center; |
|||
} |
|||
</style> |
@ -0,0 +1,258 @@ |
|||
<template> |
|||
<div class="common-layout"> |
|||
<el-container> |
|||
<el-header class="header"> |
|||
<el-text class="header-text">抢点班作业后台管理</el-text> |
|||
<el-button class="header-button" type="primary" text style="float: right;" @click="logout">退出登录</el-button> |
|||
</el-header> |
|||
<el-main class="main"> |
|||
<div class="main-title"> |
|||
抢点班作业列表 |
|||
</div> |
|||
<div class="list"> |
|||
<el-button class="main-button" type="primary" style="float: left;" @click="newAssignment">新建作业</el-button> |
|||
<el-table :data="assignments" style="width: 100%" :header-cell-style="{ 'text-align': 'center' }" |
|||
:cell-style="{ 'text-align': 'center' }"> |
|||
<el-table-column label="序号"> |
|||
<template #default="scope"> |
|||
{{ scope.$index + (PageNo - 1) * PageSize + 1 }} |
|||
</template> |
|||
</el-table-column> |
|||
<el-table-column prop="name" label="作业名称"></el-table-column> |
|||
<el-table-column label="内容归属"> |
|||
<template v-slot="scope"> |
|||
<span v-if="scope.row.clubType == '1'">牧民俱乐部</span> |
|||
<span v-else-if="scope.row.clubType == '2'">博古论坛</span> |
|||
<span v-else-if="scope.row.clubType == '3'">神枪手俱乐部</span> |
|||
<span v-else-if="scope.row.clubType == '4'">环球俱乐部</span> |
|||
<span v-else-if="scope.row.clubType == '5'">价值投资</span> |
|||
<span v-else-if="scope.row.clubType == '6'">波段行情</span> |
|||
<span v-else-if="scope.row.clubType == '7'">抄底卖顶</span> |
|||
<span v-else-if="scope.row.clubType == '8'">资金及仓位管理</span> |
|||
<span v-else-if="scope.row.clubType == '9'">财富的游戏</span> |
|||
</template> |
|||
</el-table-column> |
|||
<el-table-column prop="article" label="关联文章"> |
|||
<template #default="{ row }"> |
|||
<el-tooltip class="tooltip" v-if="row.article" :content="row.article.title" placement="bottom" |
|||
:disabled="row.article.title.length <= 10" effect="light"> |
|||
{{ row.article.title.slice(0, 10) || '—' }} |
|||
</el-tooltip> |
|||
<span v-else>—</span> |
|||
</template> |
|||
</el-table-column> |
|||
<el-table-column prop="live" label="关联直播"> |
|||
<template #default="{ row }"> |
|||
<el-tooltip class="tooltip" v-if="row.live" :content="row.live.name" placement="bottom" |
|||
:disabled="row.live.name.length <= 10" effect="light"> |
|||
{{ row.live.name.slice(0, 10) || '—' }} |
|||
</el-tooltip> |
|||
<span v-else>—</span> |
|||
</template> |
|||
</el-table-column> |
|||
<el-table-column prop="count" label="填写份数"></el-table-column> |
|||
<el-table-column label="提交时间"> |
|||
<template v-slot="scope"> |
|||
{{ scope.row.startDate.split(' ')[0] }} 至 {{ scope.row.endDate.split(' ')[0] }} |
|||
</template> |
|||
</el-table-column> |
|||
<el-table-column prop="status" label="状态"> |
|||
<template #default="{ row }"> |
|||
<span v-if="row.status === 0">未上架</span> |
|||
<span v-else-if="row.status === 1">发布中</span> |
|||
<span v-else-if="row.status === 2">已下架</span> |
|||
</template> |
|||
</el-table-column> |
|||
<el-table-column prop="createdAt" label="发布时间"></el-table-column> |
|||
<el-table-column label="操作"> |
|||
<template #default="scope"> |
|||
<el-button type="primary" link @click="viewDetails(scope.row)">查看明细</el-button> |
|||
<el-button type="primary" link v-if="scope.row.status != '2'" @click="editAssignment(scope.row)">编辑</el-button> |
|||
</template> |
|||
</el-table-column> |
|||
</el-table> |
|||
|
|||
</div> |
|||
<div class="page"> |
|||
<el-pagination v-model:current-page="PageNo" v-model:page-size="PageSize" :page-sizes="[20, 50, 100, 200]" |
|||
:size="size" :disabled="disabled" :background="background" layout="total,prev,next,sizes,jumper" |
|||
:total="total" @size-change="handleSizeChange" @current-change="handleCurrentChange" /> |
|||
</div> |
|||
</el-main> |
|||
</el-container> |
|||
</div> |
|||
</template> |
|||
|
|||
<script setup> |
|||
import { ref, onMounted } from 'vue'; |
|||
import { ElMessage } from 'element-plus'; |
|||
import ClassListApi from '../api/ClassListApi'; |
|||
import axios from 'axios'; |
|||
import { useRouter } from 'vue-router'; |
|||
import LoginApi from '../api/LoginApi'; |
|||
import { useTokenStore } from '../stores/token'; |
|||
import { useUserStore } from '../stores/user'; |
|||
|
|||
const router = useRouter(); |
|||
|
|||
const assignments = ref([]); |
|||
|
|||
// 初始化页码,这里假设初始页码为1,你可以根据实际需求修改 |
|||
const PageNo = ref(1); |
|||
// 初始化页面大小,这里假设初始页面大小为10,同样可按需修改 |
|||
const PageSize = ref(20); |
|||
const size = ref('default'); |
|||
const disabled = ref(false); |
|||
const background = ref(true); |
|||
const total = ref(0); |
|||
// 处理页面大小改变的事件函数,将新的页面大小赋值给PageSize变量 |
|||
const handleSizeChange = (newPageSize) => { |
|||
PageSize.value = newPageSize; |
|||
getAssignments(PageNo.value, PageSize.value); |
|||
}; |
|||
|
|||
// 处理当前页码改变的事件函数,将新的页码赋值给PageNo变量 |
|||
const handleCurrentChange = (newPageNo) => { |
|||
PageNo.value = newPageNo; |
|||
getAssignments(PageNo.value, PageSize.value); |
|||
}; |
|||
const getAssignments = (PageNo, PageSize) => { |
|||
ClassListApi.getClassList(PageNo, PageSize) |
|||
.then((response) => { |
|||
assignments.value = response.data.list; |
|||
total.value = response.data.total; |
|||
console.log(assignments.value); |
|||
}) |
|||
.catch((error) => { |
|||
console.error('获取作业列表失败', error); |
|||
}); |
|||
}; |
|||
//在组件初始化时(类似mounted生命周期的效果)获取一次初始数据 |
|||
onMounted(() => { |
|||
getAssignments(PageNo.value, PageSize.value); |
|||
const token = useTokenStore(); |
|||
console.log(token); |
|||
console.log(token.value); |
|||
console.log(token.token) |
|||
console.log("============="); |
|||
}); |
|||
|
|||
const newAssignment = () => { |
|||
router.push('/addwork') |
|||
} |
|||
|
|||
// 查看明细按钮的点击事件处理函数 |
|||
const viewDetails = async(row) => { |
|||
try { |
|||
router.push({ |
|||
name: 'workdetail', |
|||
params: { id: row.id }, |
|||
}); |
|||
console.log(row.id) |
|||
} catch (error) { |
|||
console.log('获取数据出错:', error) |
|||
} |
|||
}; |
|||
|
|||
|
|||
// 编辑按钮的点击事件处理函数 |
|||
const editAssignment = async (row) => { |
|||
try { |
|||
router.push({ |
|||
name: 'updatework', |
|||
params: { id: row.id }, |
|||
}); |
|||
console.log(row.id) |
|||
} catch (error) { |
|||
console.log('获取数据出错:', error) |
|||
} |
|||
}; |
|||
// // 退出登录 |
|||
// const logout = () => { |
|||
// LoginApi.logout().then(res => { |
|||
// console.log(res); |
|||
// // 移除axios请求拦截器中设置token的逻辑,恢复到初始状态 |
|||
// // axios.interceptors.request.eject(axios.interceptors.request.handlers.find( |
|||
// // handler => handler.fulfilled && handler.fulfilled.toString().includes('token') |
|||
// // )); |
|||
// config.headers['token'] = ` `; |
|||
// }).catch(err => { |
|||
// // 处理退出登录接口调用失败的情况,比如提示错误信息等 |
|||
// ElMessage.error('退出登录失败,请稍后重试'); |
|||
// }).finally(() => { |
|||
// // 无论接口调用成功与否,都进行页面跳转 |
|||
// router.push('/'); |
|||
// }); |
|||
// } |
|||
// //退出登录 |
|||
// const logout = () => { |
|||
// LoginApi.logout().then(res => { |
|||
// console.log(res) |
|||
// }) |
|||
// router.push('/') |
|||
// } |
|||
|
|||
//退出 |
|||
const logout=async()=>{ |
|||
try { |
|||
await LoginApi.logout() |
|||
} catch (error) { |
|||
console.log(error) |
|||
} |
|||
//清除登录信息 |
|||
const tokenStore = useTokenStore(); |
|||
const userStore = useUserStore(); |
|||
tokenStore.clear(); |
|||
userStore.clear(); |
|||
router.push('/') |
|||
} |
|||
</script> |
|||
|
|||
<style scoped> |
|||
.page { |
|||
margin-left: 70%; |
|||
} |
|||
|
|||
.header { |
|||
height: 100px; |
|||
line-height: 100px; |
|||
padding: 0 80px; |
|||
} |
|||
|
|||
.header-text { |
|||
font-size: 22px; |
|||
font-weight: 500; |
|||
color: black; |
|||
float: left; |
|||
} |
|||
|
|||
.header-button { |
|||
margin-top: 30px; |
|||
} |
|||
|
|||
.main { |
|||
padding: 20px 203px; |
|||
background-color: #F8F8F8; |
|||
} |
|||
|
|||
.list { |
|||
padding: 0 60px; |
|||
background-color: white; |
|||
} |
|||
|
|||
.main-title { |
|||
font-size: 16px; |
|||
background-color: white; |
|||
font-weight: bold; |
|||
height: 52px; |
|||
border-bottom: 2px solid #ececec; |
|||
padding: 0 60px; |
|||
line-height: 52px; |
|||
} |
|||
|
|||
.main-button { |
|||
margin: 15px 0; |
|||
padding: 12px 20px; |
|||
height: 40px; |
|||
} |
|||
</style> |
@ -0,0 +1,145 @@ |
|||
<template> |
|||
<div class="login-container"> |
|||
<div class="title1">管理后台</div> |
|||
<div class="login-box"> |
|||
<div class="title2">欢迎登录</div> |
|||
<div class="username"> |
|||
<el-input type="text" v-model="username" placeholder="请输入账号"> |
|||
<template #prefix> |
|||
<img class="img" src="../assets/login/denglu.png" /> |
|||
</template> |
|||
</el-input> |
|||
</div> |
|||
<div class="password"> |
|||
<el-input type="password" v-model="password" placeholder="请输入密码"> |
|||
<template #prefix> |
|||
<img class="img" src="../assets/login/mima.png" /> |
|||
</template> |
|||
</el-input> |
|||
</div> |
|||
<button @click="login">登录</button> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script setup> |
|||
import { ref } from 'vue'; |
|||
import LoginApi from '../api/LoginApi'; |
|||
import { ElMessage } from 'element-plus'; |
|||
import { useRouter } from 'vue-router'; |
|||
import axios from 'axios'; |
|||
import { useTokenStore } from '../stores/token'; |
|||
// 使用ref创建响应式数据 |
|||
const username = ref(''); |
|||
const password = ref(''); |
|||
// 用于存储token的响应式变量 |
|||
const token = ref(''); |
|||
|
|||
const router = useRouter(); |
|||
// 定义登录函数 |
|||
const login = async () => { |
|||
if (!username.value ||!password.value) { |
|||
ElMessage.error('账号和密码不能为空,请输入完整信息'); |
|||
return; |
|||
} |
|||
try { |
|||
// 调用登录接口,假设LoginApi.login接收一个包含用户名和密码的对象作为参数,你需要根据实际接口情况调整 |
|||
const response = await LoginApi.login({ |
|||
username: username.value, |
|||
password: password.value |
|||
}); |
|||
if (response.code === 200) { |
|||
// 获取登录成功返回的token并存储 |
|||
token.value = response.data.token; |
|||
const tokenStore=useTokenStore(); |
|||
tokenStore.changeToken(token.value); |
|||
// const userStore=useUserStore(); |
|||
// userStore.changeUser(response.data.user); |
|||
console.log(token.value); |
|||
console.log("=--------"); |
|||
// 登录成功提示 |
|||
ElMessage.success('登录成功'); |
|||
// 这里可以根据实际业务逻辑,比如跳转到管理后台的首页等操作 |
|||
router.push('/list'); |
|||
} else { |
|||
// 登录失败提示,展示接口返回的错误信息,如果有的话 |
|||
ElMessage.error(response.message || '登录失败,请稍后重试'); |
|||
} |
|||
} catch (error) { |
|||
// 捕获接口请求过程中的其他错误,比如网络问题等 |
|||
ElMessage.error('网络异常,请检查网络连接后重试'); |
|||
console.error(error); |
|||
} |
|||
}; |
|||
</script> |
|||
|
|||
<style scoped> |
|||
.title1 { |
|||
font-size: 40px; |
|||
color: #21d3ca; |
|||
margin-bottom: 20px; |
|||
} |
|||
|
|||
.title2 { |
|||
font-size: 20px; |
|||
color: #21d3ca; |
|||
margin-bottom: 20px; |
|||
} |
|||
|
|||
.username, |
|||
.password { |
|||
display: flex; |
|||
align-items: center; |
|||
margin-bottom: 20px; |
|||
background-color: #e6e6e6; |
|||
} |
|||
|
|||
:deep(.el-input__wrapper) { |
|||
background-color: rgba(0, 0, 0, 0); |
|||
} |
|||
|
|||
.img { |
|||
width: 25px; |
|||
height: 25px; |
|||
} |
|||
|
|||
.login-container { |
|||
display: flex; |
|||
flex-direction: column; |
|||
align-items: center; |
|||
justify-content: center; |
|||
height: 100vh; |
|||
} |
|||
|
|||
.login-box { |
|||
background-color: white; |
|||
border-radius: 5px; |
|||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); |
|||
padding: 50px; |
|||
text-align: center; |
|||
height: 200px; |
|||
width: 250px; |
|||
} |
|||
|
|||
h1 { |
|||
margin-bottom: 20px; |
|||
} |
|||
|
|||
input { |
|||
width: 100%; |
|||
padding: 10px; |
|||
margin-bottom: 10px; |
|||
border: 1px solid #ccc; |
|||
border-radius: 3px; |
|||
} |
|||
|
|||
button { |
|||
width: 100%; |
|||
padding: 10px; |
|||
background-color: #21d3ca; |
|||
color: white; |
|||
border: none; |
|||
border-radius: 3px; |
|||
cursor: pointer; |
|||
} |
|||
</style> |
@ -0,0 +1,535 @@ |
|||
<template> |
|||
<div class="common-layout"> |
|||
<el-container> |
|||
<el-header class="header"> |
|||
<el-text class="header-text">抢点班作业后台管理</el-text> |
|||
<el-button class="header-button" type="primary" text style="float: right;" @click="logout">退出登录</el-button> |
|||
</el-header> |
|||
<el-main class="main"> |
|||
<div class="main-title"> |
|||
<div class="main-title-text" style="float: left;"> |
|||
编辑作业 |
|||
</div> |
|||
<div> |
|||
<el-button class="main-button" @click="back">返回上一页</el-button> |
|||
</div> |
|||
</div> |
|||
<div class="main-back"> |
|||
<el-form :model="form" label-width="auto" style="max-width: 700px" size="large"> |
|||
<el-form-item label="作业名称"> |
|||
<el-input v-model="form.Name" placeholder="请输入"></el-input> |
|||
</el-form-item> |
|||
<el-form-item label="提交时间" style="width: 70%"> |
|||
<el-date-picker v-model="form.picker" type="daterange" range-separator="至" start-placeholder="开始日期" |
|||
end-placeholder="结束日期" /> |
|||
</el-form-item> |
|||
<el-form-item label="作业归属"> |
|||
<el-select v-model="form.ClubType" placeholder="请选择" style="width: 100%"> |
|||
<el-option v-for="item in options" :key="item.id" :label="item.name" :value="item.id" /> |
|||
</el-select> |
|||
</el-form-item> |
|||
<el-form-item label="关联文章"> |
|||
<el-autocomplete v-model="articleTitle" :fetch-suggestions="queryArticleList" placeholder="请输入" |
|||
@select="handleSelectArticle" clearable /> |
|||
</el-form-item> |
|||
<el-form-item label="关联直播"> |
|||
<el-select v-model="form.LiveId" placeholder="请选择" style="width: 100%" clearable |
|||
@change="handleLiveChange"> |
|||
<el-option v-for="item in live" :key="item.id" :label="item.name" :value="item.id" /> |
|||
</el-select> |
|||
</el-form-item> |
|||
<el-form-item label="选择类型"> |
|||
<div> |
|||
<el-button type="primary" @click="addSingleChoice">添加单选</el-button> |
|||
<el-button type="primary" @click="addMultipleChoice">添加多选</el-button> |
|||
<el-button type="primary" @click="addBlank">添加单选填空</el-button> |
|||
</div> |
|||
</el-form-item> |
|||
<div class="question-container" v-for="(question, index) in questions" :key="index" |
|||
:class="{ 'bg-change': isHovered[index] }" @mouseenter="handleMouseEnter(index)" |
|||
@mouseleave="handleMouseLeave(index)"> |
|||
<div class="question-title"> |
|||
{{ questionPrefix(index) }} {{ getQuestionTypeText(question.type) }} |
|||
</div> |
|||
<div style="width: 600px;"> |
|||
<el-input v-model="question.description" /> |
|||
</div> |
|||
<div class="add" v-if="question.type !== 'blank'"> |
|||
<div class="question-option"> |
|||
<span>设置选项:</span> |
|||
<el-button type="primary" text @click="addOption(index)">添加</el-button> |
|||
</div> |
|||
<div v-for="(option, optionIndex) in question.content" :key="optionIndex"> |
|||
<div class="select" style="display: flex;"> |
|||
<div class="selection-item" style="display: flex;"> |
|||
<div style="width: 550px;"> |
|||
<el-input v-model="question.content[optionIndex].text" /> |
|||
</div> |
|||
<div> |
|||
<el-button type="primary" text @click="removeOption(index, optionIndex)">删除</el-button> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<div class="delete" style="margin-left: 50px;"> |
|||
<el-button type="info" plain @click="removeQuestion(index)">删除</el-button> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<div class="submit"> |
|||
<el-button type="primary" :disabled="!form.Name || !form.picker" @click="onSubmit">确认</el-button> |
|||
</div> |
|||
</el-form> |
|||
</div> |
|||
</el-main> |
|||
</el-container> |
|||
</div> |
|||
|
|||
</template> |
|||
|
|||
<script lang="ts" setup> |
|||
import { ref, onMounted, computed } from 'vue' |
|||
import { useRouter, useRoute } from 'vue-router'; |
|||
import AddWorkApi from '../api/AddWorkApi'; |
|||
import _ from 'lodash'; |
|||
import dayjs from 'dayjs'; |
|||
import ClassListApi from '../api/ClassListApi'; |
|||
import { ElMessage } from 'element-plus'; |
|||
import LoginApi from '../api/LoginApi'; |
|||
|
|||
import { useTokenStore } from '../stores/token'; |
|||
import { useUserStore } from '../stores/user'; |
|||
|
|||
const router = useRouter(); |
|||
const options = ref([ |
|||
{ id: 1, name: '牧民俱乐部' }, |
|||
{ id: 2, name: '博古论坛' }, |
|||
{ id: 3, name: '神枪手俱乐部' }, |
|||
{ id: 4, name: '环球俱乐部' }, |
|||
{ id: 5, name: '价值投资' }, |
|||
{ id: 6, name: '波段行情' }, |
|||
{ id: 7, name: '抄底卖顶' }, |
|||
{ id: 8, name: '资金及仓位管理' }, |
|||
{ id: 9, name: '财富的游戏' }, |
|||
]); |
|||
|
|||
const route = useRoute(); |
|||
const id = ref(route.params.id) |
|||
console.log(id.value + '============') |
|||
|
|||
// 用于存储获取到的作业数据 |
|||
const homeworkData = ref<{ |
|||
name: string; |
|||
startDate: string; |
|||
endDate: string; |
|||
clubType: string; |
|||
article: { |
|||
id: string; |
|||
title: string; |
|||
}; |
|||
live: { |
|||
id: string; |
|||
name: string; |
|||
}; |
|||
status: number; |
|||
form: FormItemType[]; |
|||
|
|||
}>({ |
|||
name: '', |
|||
startDate: '', |
|||
endDate: '', |
|||
clubType: '', |
|||
article: { |
|||
id: '', |
|||
title: '', |
|||
}, |
|||
live: { |
|||
id: '', |
|||
name: '' |
|||
}, |
|||
status: 0, |
|||
form: [] |
|||
}); |
|||
|
|||
// 定义form数组中每个元素的类型接口 |
|||
interface FormItemType { |
|||
id: number; |
|||
type: number; |
|||
description: string; |
|||
content: string; // 这里先定义为string,因为从数据看是JSON字符串格式,后续需要解析 |
|||
groupId: number; |
|||
name: string; |
|||
sort: number; |
|||
status: number; |
|||
createdAt: string; |
|||
updatedAt: string; |
|||
} |
|||
|
|||
|
|||
const form = ref({ |
|||
id: '', |
|||
Name: '', |
|||
ClubType: '', |
|||
ArticleId: '', |
|||
LiveId: '', |
|||
picker: [], |
|||
StartDate: '', |
|||
EndDate: '', |
|||
Questions: [] |
|||
}); |
|||
|
|||
// 新增一个变量用于标识是否发布,这里先设为false表示未发布 |
|||
const isPublished = ref(0); |
|||
onMounted(async () => { |
|||
try { |
|||
const response = await ClassListApi.getClassListOne(id.value); |
|||
homeworkData.value = response.data; |
|||
console.log(homeworkData.value) |
|||
form.value.Name = homeworkData.value.name; |
|||
// 根据后端返回数据设置发布状态变量的值 |
|||
isPublished.value = homeworkData.value.status; |
|||
|
|||
const start = dayjs(homeworkData.value.startDate).format('YYYY-MM-DD'); |
|||
const end = dayjs(homeworkData.value.endDate).format('YYYY-MM-DD'); |
|||
form.value.picker = [start, end]; |
|||
|
|||
if (homeworkData.value.article && homeworkData.value.article.title) { |
|||
articleTitle.value = homeworkData.value.article.title; |
|||
} else if (homeworkData.value.live && homeworkData.value.live.name) { |
|||
form.value.LiveId = homeworkData.value.live.name; |
|||
} |
|||
form.value.ClubType = homeworkData.value.clubType; |
|||
const processFormData = () => { |
|||
const newQuestions = []; |
|||
homeworkData.value.form.forEach((formItem: FormItemType) => { |
|||
// 解析content字段中的JSON字符串为实际的数组对象 |
|||
const contentArray = JSON.parse(formItem.content) as { id: string, text: string }[]; |
|||
// 创建一个新的符合questions结构的对象 |
|||
const question = { |
|||
id: formItem.id, |
|||
type: formItem.type, |
|||
description: formItem.description, |
|||
content: contentArray, |
|||
groupId: formItem.groupId, |
|||
name: formItem.name, |
|||
sort: formItem.sort, |
|||
status: formItem.status, |
|||
createdAt: formItem.createdAt, |
|||
updatedAt: formItem.updatedAt, |
|||
}; |
|||
newQuestions.push(question); |
|||
}); |
|||
return newQuestions; |
|||
}; |
|||
questions.value = processFormData(); |
|||
} catch (error) { |
|||
console.error('接口请求出现错误:', error); |
|||
} |
|||
}); |
|||
|
|||
|
|||
const articleTitle = ref(''); |
|||
// 问题列表数据 |
|||
const questions = ref([]); |
|||
const onSubmit = () => { |
|||
// 从picker中获取日期数据并进行格式转换 |
|||
if (form.value.picker && form.value.picker.length === 2) { |
|||
const startDate = dayjs(form.value.picker[0]).format('YYYY-MM-DD HH:mm:00'); |
|||
const endDate = dayjs(form.value.picker[1]).format('YYYY-MM-DD HH:mm:00'); |
|||
form.value.StartDate = startDate; |
|||
form.value.EndDate = endDate; |
|||
} |
|||
form.value.Questions = questions.value; |
|||
if (form.value.LiveId) { |
|||
// 如果form.value.liveid有值,优先使用liveid,清空ArticleId(假设后端不接受同时传这两个值且以liveid为准,可根据实际情况调整) |
|||
form.value.ArticleId = ''; |
|||
articleTitle.value = ''; |
|||
} else if (form.value.ArticleId) { |
|||
|
|||
// 如果手动选择了关联文章,使用手动选择后更新的文章id(form.value.ArticleId) |
|||
} else if (homeworkData.value.article && homeworkData.value.article.id) { |
|||
// 如果没有手动选择,使用后端传回的数据中的关联文章id(homeworkData.value.article.id) |
|||
form.value.ArticleId = homeworkData.value.article.id; |
|||
} |
|||
if (typeof id.value === 'string') { |
|||
form.value.id = id.value; |
|||
} |
|||
if(!form.value.ArticleId&&!form.value.LiveId){ |
|||
ElMessage.error('编辑失败'); |
|||
}else{ |
|||
ClassListApi.editWork(form.value) |
|||
.then((response) => { |
|||
console.log(response); |
|||
ElMessage.success('编辑成功'); |
|||
router.push('/list') |
|||
}) |
|||
} |
|||
|
|||
console.log(id.value + '--------------') |
|||
console.log(form.value) |
|||
} |
|||
const back = () => { |
|||
window.history.back() |
|||
} |
|||
|
|||
// 存储根据文章输入内容查询到的关联文章结果列表 |
|||
const articleSearchResults = ref([]); |
|||
// 根据文章输入内容查询关联文章的函数 |
|||
const queryArticleList = async (queryString: string) => { |
|||
if (form.value.LiveId) { |
|||
ElMessage.warning('您已关联直播,暂无法关联文章'); |
|||
articleTitle.value = ''; // 清空文章标题输入框 |
|||
form.value.LiveId = ''; |
|||
return []; |
|||
} |
|||
try { |
|||
const response = await AddWorkApi.getArticleList(queryString); |
|||
const formattedResults = response.data.map(article => ({ |
|||
value: article.title, |
|||
label: article.id |
|||
})); |
|||
articleSearchResults.value = formattedResults; |
|||
return formattedResults; |
|||
} catch (error) { |
|||
console.error('查询关联文章失败', error); |
|||
return []; |
|||
} |
|||
}; |
|||
const handleLiveChange = () => { |
|||
if (articleTitle.value) { |
|||
ElMessage.warning('您已关联文章,暂无法关联直播'); |
|||
form.value.LiveId = ''; // 清空关联直播选择框的值 |
|||
form.value.ArticleId = ''; |
|||
articleTitle.value = ''; |
|||
} |
|||
}; |
|||
// 处理选择文章的函数 |
|||
const handleSelectArticle = (article: { label: string }) => { |
|||
// 这里可以根据业务需求,比如将选中的文章id(article.label)传递给其他地方使用等 |
|||
console.log('选中的文章id', article.label); |
|||
form.value.ArticleId = article.label; // 将选中文章的id赋值给对应表单字段,用于传递给后端 |
|||
const selectedArticle = articleSearchResults.value.find(a => a.label === article.label); |
|||
if (selectedArticle) { |
|||
articleTitle.value = selectedArticle.value; // 更新显示的文章题目 |
|||
} |
|||
}; |
|||
|
|||
//获取直播列表 |
|||
const live = ref([]); |
|||
function getLive() { |
|||
AddWorkApi.getLiveList() |
|||
.then(res => { |
|||
live.value = res.data; |
|||
console.log(live.value); |
|||
}) |
|||
.catch(error => { |
|||
console.error('获取直播列表失败', error) |
|||
}) |
|||
} |
|||
getLive(); |
|||
|
|||
// 根据类型获取对应的题目类型文本显示 |
|||
const getQuestionTypeText = (type) => { |
|||
switch (type) { |
|||
case 1: |
|||
return '作业题目(单选)'; |
|||
case 2: |
|||
return '作业题目(多选)'; |
|||
case 3: |
|||
return '作业题目(简答题)'; |
|||
default: |
|||
return '未知类型题目'; |
|||
} |
|||
}; |
|||
|
|||
const addSingleChoice = () => { |
|||
if (isPublished.value === 1) { |
|||
ElMessage.warning('处于发布中,不能添加新题目'); |
|||
} else { |
|||
questions.value.push({ |
|||
type: 1, // 假设1代表单选,和后端格式对应起来 |
|||
description: '', |
|||
content: [{ "id": "", "text": "" }, { "id": "", "text": "" }] |
|||
}); |
|||
} |
|||
|
|||
}; |
|||
|
|||
const addMultipleChoice = () => { |
|||
if (isPublished.value === 1) { |
|||
ElMessage.warning('处于发布中,不能添加新题目'); |
|||
} else { |
|||
questions.value.push({ |
|||
type: 2, // 假设2代表多选,和后端格式对应起来 |
|||
description: '', |
|||
content: [{ "id": "", "text": "" }, { "id": "", "text": "" }] |
|||
}); |
|||
} |
|||
|
|||
}; |
|||
|
|||
const addBlank = () => { |
|||
if (isPublished.value === 1) { |
|||
ElMessage.warning('处于发布中,不能添加新题目'); |
|||
} else { |
|||
questions.value.push({ |
|||
type: 3, // 假设3代表简答题,和后端格式对应起来 |
|||
description: '', |
|||
content: [{ "id": "", "text": "" }] |
|||
}); |
|||
} |
|||
}; |
|||
|
|||
const addOption = (questionIndex) => { |
|||
const currentQuestion = questions.value[questionIndex]; |
|||
// 如果当前题目没有content属性,则初始化一个空数组 |
|||
if (!currentQuestion.content) { |
|||
currentQuestion.content = []; |
|||
} |
|||
currentQuestion.content.push({ id: "", text: "" }); |
|||
}; |
|||
const removeOption = (questionIndex, optionIndex) => { |
|||
const currentQuestion = questions.value[questionIndex]; |
|||
currentQuestion.content.splice(optionIndex, 1); |
|||
}; |
|||
|
|||
const removeQuestion = (questionIndex) => { |
|||
if(isPublished.value === 1){ |
|||
ElMessage.warning('处于发布中,不能删除题目'); |
|||
}else{ |
|||
questions.value.splice(questionIndex, 1); |
|||
} |
|||
}; |
|||
|
|||
// 计算属性,用于生成序号前缀 |
|||
const questionPrefix = computed(() => { |
|||
return (index) => { |
|||
return `${index + 1}、`; |
|||
}; |
|||
}) |
|||
|
|||
// 用于存储每个问题标题是否被鼠标悬停的状态,初始化为false |
|||
const isHovered = ref(Array(questions.value.length).fill(false)); |
|||
const handleMouseEnter = (index) => { |
|||
isHovered.value[index] = true; |
|||
}; |
|||
|
|||
const handleMouseLeave = (index) => { |
|||
isHovered.value[index] = false; |
|||
}; |
|||
|
|||
// 在组件挂载后初始化 `isHovered` 数组长度与 `questions` 数组长度一致 |
|||
onMounted(() => { |
|||
isHovered.value = Array(questions.value.length).fill(false); |
|||
}); |
|||
|
|||
|
|||
//退出 |
|||
function logout() { |
|||
//清除登录信息 |
|||
const tokenStore = useTokenStore(); |
|||
const userStore = useUserStore(); |
|||
tokenStore.clear(); |
|||
userStore.clear(); |
|||
LoginApi.logout().then(res => { |
|||
console.log(res) |
|||
}) |
|||
router.push('/') |
|||
} |
|||
</script> |
|||
|
|||
<style scoped> |
|||
.submit { |
|||
margin: 100px 212px; |
|||
} |
|||
|
|||
.submit .el-button { |
|||
padding: 25px 150px; |
|||
} |
|||
|
|||
.question-title { |
|||
transition: background-color 0.3s ease; |
|||
} |
|||
|
|||
.bg-change { |
|||
background-color: rgba(200, 200, 200, 0.3); |
|||
} |
|||
|
|||
.question-title { |
|||
margin-bottom: 10px; |
|||
} |
|||
|
|||
.select { |
|||
margin: 10px 0px 0px; |
|||
} |
|||
|
|||
.delete { |
|||
position: absolute; |
|||
right: 10px; |
|||
bottom: 0px; |
|||
} |
|||
|
|||
.add { |
|||
position: relative; |
|||
} |
|||
|
|||
.question-container { |
|||
margin: 20px 0; |
|||
padding: 10px 20px; |
|||
width: 750px; |
|||
border-bottom: 1px solid #e5e5e5; |
|||
} |
|||
|
|||
.header { |
|||
height: 100px; |
|||
line-height: 100px; |
|||
padding: 0 80px; |
|||
} |
|||
|
|||
.header-text { |
|||
font-size: 22px; |
|||
font-weight: 500; |
|||
color: black; |
|||
float: left; |
|||
} |
|||
|
|||
.header-button { |
|||
margin-top: 30px; |
|||
} |
|||
|
|||
.main { |
|||
padding: 30px 212px; |
|||
background-color: #F8F8F8; |
|||
} |
|||
|
|||
.main-title { |
|||
font-size: 16px; |
|||
background-color: white; |
|||
font-weight: bold; |
|||
height: 60px; |
|||
border-bottom: 2px solid #ececec; |
|||
padding: 0 15px; |
|||
line-height: 52px; |
|||
} |
|||
|
|||
.main-button { |
|||
margin: 10px 15px 0 0; |
|||
padding: 12px 20px; |
|||
height: 40px; |
|||
float: right; |
|||
} |
|||
|
|||
.el-form { |
|||
padding: 30px 78.5px; |
|||
margin: auto; |
|||
} |
|||
|
|||
.el-form-item { |
|||
--font-size: 16px; |
|||
margin: 0 0 25px; |
|||
} |
|||
|
|||
.main-back { |
|||
background-color: white; |
|||
} |
|||
</style> |
@ -0,0 +1,391 @@ |
|||
<template> |
|||
<div class="common-layout"> |
|||
<el-container> |
|||
<el-header class="header"> |
|||
<el-text class="header-text">抢点班作业后台管理</el-text> |
|||
<el-button class="header-button" type="primary" text style="float: right;" |
|||
@click="logout">退出登录</el-button> |
|||
</el-header> |
|||
<el-main class="main"> |
|||
<div class="main-title"> |
|||
<div class="main-title-text" style="float: left;"> |
|||
作业详情 |
|||
</div> |
|||
<div> |
|||
<el-button class="main-button" @click="back">返回上一页</el-button> |
|||
</div> |
|||
</div> |
|||
<div class="table-container"> |
|||
<div class="search-bar" :v-model="form"> |
|||
<el-input v-model="form.jwcode" type="text" placeholder="请输入精网号" style="width: 180px;" |
|||
size="large" clearable /> |
|||
<el-select v-model="form.deptId" placeholder="选择分店门部" size="large" |
|||
style="width: 180px; margin-left: 15px;" clearable @change="handleDeptSelect"> |
|||
<el-option v-for="item in dept" :key="item.id" :label="item.deptName" |
|||
:value="item.deptId" /> |
|||
</el-select> |
|||
|
|||
<el-select v-model="form.shopId" placeholder="--请选择所属门店--" size="large" |
|||
style="width: 180px; margin-left: 15px" clearable> |
|||
<el-option v-for="item in shop" :key="item.id" :label="item.shopName" |
|||
:value="item.shopId" /> |
|||
</el-select> |
|||
<el-button class="search-btn" type="primary" size="large" @click="searchData">搜索</el-button> |
|||
<div class="export"> |
|||
<el-button class="export-btn" type="primary" size="large" |
|||
@click="exportData">导出数据</el-button> |
|||
</div> |
|||
</div> |
|||
<el-table :data="workdetailData" style="width: 100%"> |
|||
<el-table-column label="序号"> |
|||
<template #default="scope"> |
|||
{{ scope.$index + (PageNo - 1) * PageSize + 1 }} |
|||
</template> |
|||
</el-table-column> |
|||
<el-table-column prop="name" label="姓名"></el-table-column> |
|||
<el-table-column prop="jwcode" label="精网号"></el-table-column> |
|||
<el-table-column label="分布-门店"> |
|||
<template v-slot="scope"> |
|||
{{ scope.row.deptName }} - {{ scope.row.shopName }} |
|||
</template> |
|||
</el-table-column> |
|||
<el-table-column label="作业详情"> |
|||
<template v-slot="{ $index }"> |
|||
<el-popover placement="bottom" title="详情" :width="500" trigger="click"> |
|||
<template #reference> |
|||
<el-button link type="primary">查看</el-button> |
|||
</template> |
|||
<div v-for="(r, subIndex) in getContent($index).replies" :key="subIndex"> |
|||
<div>{{ r.formTitle }}</div> |
|||
<div>{{ r.contentTitle }}</div> |
|||
<div>{{ r.content }}</div> |
|||
<div style="margin-bottom: 10px;"></div> |
|||
</div> |
|||
</el-popover> |
|||
</template> |
|||
</el-table-column> |
|||
<el-table-column prop="submitTime" label="提交时间"> |
|||
<template v-slot="scope"> |
|||
{{ scope.row.Reply[0].submitTime }} |
|||
</template> |
|||
</el-table-column> |
|||
</el-table> |
|||
<div class="page"> |
|||
<el-pagination v-model:current-page="PageNo" v-model:page-size="PageSize" |
|||
:page-sizes="[20, 50, 100, 200]" :size="size" :disabled="disabled" :background="background" |
|||
layout="sizes,prev,next,jumper" :total="10" @size-change="handleSizeChange" |
|||
@current-change="handleCurrentChange" /> |
|||
</div> |
|||
</div> |
|||
</el-main> |
|||
</el-container> |
|||
</div> |
|||
</template> |
|||
|
|||
<script lang="ts" setup> |
|||
import { ref, onMounted, watch } from 'vue' |
|||
import { useRoute, useRouter } from 'vue-router'; |
|||
import ClassListApi from '../api/ClassListApi'; |
|||
import { ElMessage } from 'element-plus'; |
|||
import UpdateWorkApi from '../api/UpdateWorkApi'; |
|||
import * as XLSX from 'xlsx'; |
|||
import axios from 'axios'; |
|||
import LoginApi from '../api/LoginApi'; |
|||
import { useTokenStore } from '../stores/token'; |
|||
import { useUserStore } from '../stores/user'; |
|||
|
|||
const router = useRouter(); |
|||
|
|||
const back = () => { |
|||
window.history.back() |
|||
} |
|||
//获取门店列表 |
|||
const shop = ref([]); |
|||
// 处理部门选择变化的事件函数 |
|||
const handleDeptSelect = async (val) => { |
|||
console.log(val); |
|||
const res = await UpdateWorkApi.getshopinfo(val); |
|||
shop.value = res.data; |
|||
console.log(shop.value); |
|||
form.value.shopId = ""; |
|||
}; |
|||
|
|||
// 初始化页码,这里假设初始页码为1 |
|||
const PageNo = ref(1); |
|||
// 初始化页面大小,这里假设初始页面大小为10 |
|||
const PageSize = ref(20); |
|||
|
|||
// 处理页面大小改变的事件函数,将新的页面大小赋值给PageSize变量 |
|||
const handleSizeChange = (newPageSize) => { |
|||
PageSize.value = newPageSize; |
|||
ClassListApi.getWorkDetail(id.value, PageNo.value, PageSize.value); |
|||
}; |
|||
|
|||
// 处理当前页码改变的事件函数,将新的页码赋值给PageNo变量 |
|||
const handleCurrentChange = (newPageNo) => { |
|||
PageNo.value = newPageNo; |
|||
ClassListApi.getWorkDetail(id.value, PageNo.value, PageSize.value); |
|||
}; |
|||
|
|||
const form = ref({ |
|||
jwcode: "", |
|||
deptId: "", |
|||
shopId: "", |
|||
}); |
|||
|
|||
// 搜索方法 |
|||
const searchData = async () => { |
|||
try { |
|||
const params = { |
|||
id: id.value, |
|||
...form.value |
|||
}; |
|||
const res = await UpdateWorkApi.getrecordbycondition(params); |
|||
console.log('搜索结果:', res); |
|||
workdetailData.value = res.data; |
|||
} catch (error) { |
|||
console.error('搜索失败', error); |
|||
} |
|||
// form.value.jwcode = ""; |
|||
// form.value.deptId = ""; |
|||
// form.value.shopId = ""; |
|||
} |
|||
//获取门部列表 |
|||
const dept = ref([]); |
|||
const getDept = async () => { |
|||
try { |
|||
const res = await UpdateWorkApi.getdeptinfo(); |
|||
dept.value = res.data; |
|||
console.log(dept.value); |
|||
} catch (error) { |
|||
console.error('获取分部失败', error); |
|||
} |
|||
}; |
|||
getDept(); |
|||
|
|||
|
|||
const route = useRoute(); |
|||
const id = ref(route.params.id) |
|||
console.log(id.value + '============') |
|||
|
|||
const workdetailData = ref([]); |
|||
// onMounted(async () => { |
|||
// try { |
|||
// const response = await ClassListApi.getWorkDetail(id.value, PageNo.value, PageSize.value); |
|||
// workdetailData.value = response.data; |
|||
// console.log(workdetailData.value); |
|||
// } catch (error) { |
|||
// console.error('接口请求出现错误:', error); |
|||
// } |
|||
// }); |
|||
onMounted(async () => { |
|||
const refdata = { |
|||
id: id.value, |
|||
pageNo: PageNo.value, |
|||
pageSize: PageSize.value |
|||
} |
|||
try { |
|||
const response = await UpdateWorkApi.getrecordbycondition(refdata); |
|||
workdetailData.value = response.data; |
|||
console.log(workdetailData.value); |
|||
} catch (error) { |
|||
console.error('接口请求出现错误:', error); |
|||
} |
|||
}) |
|||
const getContent = (index) => { |
|||
if (workdetailData.value && workdetailData.value[index] && workdetailData.value[index].Reply) { |
|||
const replies = workdetailData.value[index].Reply; |
|||
return { |
|||
// 这里直接返回包含所有reply数据的数组 |
|||
replies: replies.map((reply) => ({ |
|||
formTitle: reply.formTitle, |
|||
contentTitle: reply.contentTitle, |
|||
content: reply.content |
|||
})) |
|||
}; |
|||
} |
|||
return { |
|||
replies: [] |
|||
}; |
|||
}; |
|||
const exportData = async () => { |
|||
if(!workdetailData.value){ |
|||
ElMessage.warning('暂无数据可导出'); |
|||
} |
|||
try { |
|||
const params = { |
|||
// 这里假设form.value和id.value是你已有的正确数据获取方式,按需替换成实际的准确值 |
|||
...form.value, |
|||
id: id.value, |
|||
}; |
|||
const response = await axios.post('/api/api/homework_manage/export-record', params, { |
|||
responseType: 'arraybuffer' |
|||
}); |
|||
console.log('导出数据:', response); |
|||
console.log('导出数据:', response.data); |
|||
// 将返回的二进制数据转换为Blob对象,用于创建下载链接 |
|||
const blob = new Blob([response.data], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' }); |
|||
const url = URL.createObjectURL(blob); |
|||
const a = document.createElement('a'); |
|||
a.href = url; |
|||
// 尝试从响应头中获取Content-Disposition字段来解析文件名 |
|||
const contentDisposition = response.headers['content-disposition']; |
|||
console.log('文件名:', contentDisposition); |
|||
if (contentDisposition) { |
|||
// 使用正则表达式匹配filename |
|||
const fileNameMatch = contentDisposition.match(/filename=([^"]+)/); |
|||
if (fileNameMatch && fileNameMatch.length > 1) { |
|||
const fileName = fileNameMatch[1]; |
|||
a.download = fileName; |
|||
} else { |
|||
console.error('无法从Content-Disposition中解析出文件名'); |
|||
return; |
|||
} |
|||
} else { |
|||
console.error('响应头中不存在Content-Disposition字段'); |
|||
return; |
|||
} |
|||
document.body.appendChild(a); |
|||
a.click(); |
|||
document.body.removeChild(a); |
|||
URL.revokeObjectURL(url); |
|||
} catch (error) { |
|||
console.error('详细的请求错误信息:', error); |
|||
ElMessage.error('导出失败'); |
|||
} |
|||
}; |
|||
|
|||
const tokenStore = useTokenStore(); |
|||
// // 退出登录 |
|||
// const logout = () => { |
|||
// LoginApi.logout().then(res => { |
|||
// console.log(tokenStore); |
|||
// tokenStore.clear(); |
|||
// localStorage.removeItem('token'); |
|||
// console.log(tokenStore); |
|||
// router.push('/'); |
|||
// }).catch(err => { |
|||
// // 处理退出登录接口调用失败的情况,比如提示错误信息等 |
|||
// ElMessage.error('退出登录失败,请稍后重试'); |
|||
// }) |
|||
// } |
|||
|
|||
|
|||
//退出 |
|||
function logout(){ |
|||
//清除登录信息 |
|||
const tokenStore = useTokenStore(); |
|||
const userStore = useUserStore(); |
|||
tokenStore.clear(); |
|||
userStore.clear(); |
|||
LoginApi.logout().then(res => { |
|||
console.log(res) |
|||
}) |
|||
router.push('/') |
|||
} |
|||
</script> |
|||
|
|||
<style scoped> |
|||
.look { |
|||
color: rgb(69, 131, 254); |
|||
cursor: pointer; |
|||
} |
|||
|
|||
.table-container { |
|||
margin: 6px 0 0; |
|||
padding: 15px 60px; |
|||
} |
|||
|
|||
.search-bar { |
|||
margin-bottom: 10px; |
|||
position: relative; |
|||
} |
|||
|
|||
.search-btn { |
|||
padding: 10px 20px; |
|||
margin: 0 0 0 15px; |
|||
} |
|||
|
|||
.export { |
|||
position: absolute; |
|||
right: 20px; |
|||
top: 0px; |
|||
} |
|||
|
|||
.export-btn { |
|||
padding: 12px 20px; |
|||
text-align: right; |
|||
} |
|||
|
|||
table { |
|||
width: 100%; |
|||
border-collapse: collapse; |
|||
} |
|||
|
|||
th, |
|||
td { |
|||
border: 1px solid #ccc; |
|||
padding: 5px; |
|||
text-align: left; |
|||
} |
|||
|
|||
.pagination { |
|||
display: flex; |
|||
align-items: center; |
|||
margin-top: 10px; |
|||
} |
|||
|
|||
.pagination select { |
|||
margin-right: 10px; |
|||
} |
|||
|
|||
.pagination button { |
|||
margin-right: 5px; |
|||
cursor: pointer; |
|||
} |
|||
|
|||
|
|||
|
|||
.header { |
|||
height: 100px; |
|||
line-height: 100px; |
|||
padding: 0 80px; |
|||
} |
|||
|
|||
.header-text { |
|||
font-size: 22px; |
|||
font-weight: 500; |
|||
color: black; |
|||
float: left; |
|||
} |
|||
|
|||
.header-button { |
|||
margin-top: 30px; |
|||
} |
|||
|
|||
.main { |
|||
padding: 30px 212px; |
|||
background-color: #F8F8F8; |
|||
} |
|||
|
|||
.main-title { |
|||
font-size: 16px; |
|||
background-color: white; |
|||
font-weight: bold; |
|||
height: 60px; |
|||
border-bottom: 2px solid #ececec; |
|||
padding: 0 60px; |
|||
line-height: 52px; |
|||
} |
|||
|
|||
.main-button { |
|||
margin: 10px 15px 0 0; |
|||
padding: 12px 20px; |
|||
height: 40px; |
|||
float: right; |
|||
} |
|||
|
|||
.main-back { |
|||
background-color: white; |
|||
} |
|||
</style> |
@ -1,563 +0,0 @@ |
|||
<script setup> |
|||
import { ref } from 'vue'; |
|||
import ShowApi from '../api/ShowApi'; |
|||
import { format } from 'date-fns'; |
|||
import {useRouter} from "vue-router"; |
|||
import {ElMessage} from "element-plus"; |
|||
|
|||
const router = useRouter() |
|||
|
|||
//作业展示列表 |
|||
const works = ref([]); |
|||
function loadWorks() { |
|||
ShowApi.getWorks().then(result => { |
|||
works.value = result.data; |
|||
console.log(works.value); |
|||
console.log(result.data); |
|||
works.value.forEach(work => { |
|||
let date = work.endData; |
|||
work.endData = format(new Date(date), 'yyyy-MM-dd'); |
|||
}); |
|||
}) |
|||
} |
|||
loadWorks(); |
|||
//跳转写作业页面 |
|||
function writeWorks(id,sub){ |
|||
if(sub >= 3){ |
|||
ElMessage.error('每个作业可提交3次,您已提交3次。') |
|||
}else{ |
|||
router.push({ |
|||
path:`/doWork/${id}/${sub}` |
|||
}) |
|||
} |
|||
|
|||
} |
|||
</script> |
|||
|
|||
<template> |
|||
<div class="container"> |
|||
<div class="works"> |
|||
<div class="work-header"> |
|||
<img class="ketangzuoye" src="http://39.101.133.168:8857/LiveActivity/img/ketangzuoye.cc888815.png"> |
|||
<img class="book" |
|||
src="https://img.js.design/assets/img/65f9235904fb00a3ea731672.png#dcda48ae8da37daeccd6583d45c7790b"> |
|||
</div> |
|||
<div class="work-list"> |
|||
<div class="list" v-for="work in works"> |
|||
<div class="work-item"> |
|||
<div class="work-name"> |
|||
{{ work.name }} |
|||
</div> |
|||
<div class="work-content"> |
|||
<div class="work-time"> |
|||
<span class="deadline">截止时间:{{ work.endData }}</span> |
|||
<!-- 作业提价状态 --> |
|||
<div v-if="work.submit == 0" class="work-status">未提交</div> |
|||
<div v-else class="work-status2">已提交</div> |
|||
</div> |
|||
<div class="work-bottem" @click="writeWorks(work.groupId,work.submit)"> |
|||
<span class="write">写作业</span> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<style scoped> |
|||
.container { |
|||
width: 27%; /* 假设桌面布局的容器宽度为 80% */ |
|||
margin: 0 auto; /* 居中对齐 */ |
|||
} |
|||
body{ |
|||
margin: 0; |
|||
} |
|||
.work-name { |
|||
opacity: 1; |
|||
/** 文本1 */ |
|||
font-size: 1.5vw; |
|||
font-weight: 700; |
|||
letter-spacing: 0px; |
|||
color: rgba(53, 56, 112, 1); |
|||
text-align: left; |
|||
/*左对齐*/ |
|||
vertical-align: top; |
|||
/* 这个属性在 Flex 容器中不起作用,将被移除 */ |
|||
display: flex; |
|||
/* 启用 Flexbox 布局 */ |
|||
align-items: center; |
|||
/* 垂直居中 */ |
|||
height: 30%; |
|||
/* 设置高度,根据需要调整 */ |
|||
width: 50%; |
|||
/* 如果需要,也可以设置宽度 */ |
|||
} |
|||
|
|||
|
|||
.ketangzuoye { |
|||
margin-top: 2vh; |
|||
margin-left: 2vw; |
|||
width: 43%; |
|||
} |
|||
|
|||
.book { |
|||
float: right; |
|||
margin-right: 1vw; |
|||
width: 30%; |
|||
} |
|||
|
|||
|
|||
/* 手机 */ |
|||
@media (max-width: 768px) { |
|||
.container { |
|||
width: 100%; |
|||
margin: auto; |
|||
} |
|||
.works { |
|||
/* ../api/ShowApi |
|||
work\src\assets\bg@3x.png */ |
|||
background-image: url('../assets/bg.png'); |
|||
background-size: 100% 100%; |
|||
background-color: #8f98f6; |
|||
width: 100%; |
|||
min-height: 100vh; |
|||
position: relative; |
|||
margin: auto; |
|||
} |
|||
|
|||
.work-list { |
|||
width: 95%; |
|||
display: flex; |
|||
justify-content: center; |
|||
align-items: center; |
|||
flex-direction: column; |
|||
margin: auto; |
|||
} |
|||
|
|||
.list { |
|||
display: flex; |
|||
justify-content: center; |
|||
align-items: center; |
|||
width: 97%; |
|||
height: 16vh; |
|||
opacity: 1; |
|||
border-radius: 10px; |
|||
background-color: rgba(255, 225, 174, 1); |
|||
margin-bottom: 3%; |
|||
} |
|||
|
|||
.work-item { |
|||
|
|||
width: 87%; |
|||
height: 63%; |
|||
padding: 10px; |
|||
position: relative; |
|||
background: linear-gradient(180deg, rgba(255, 255, 255, 1) 0%, rgba(250, 245, 235, 1) 100%); |
|||
border-radius: 10px; |
|||
border-radius: 10px; |
|||
} |
|||
.work-name { |
|||
opacity: 1; |
|||
/** 文本1 */ |
|||
font-size: 4vw; |
|||
font-weight: 700; |
|||
letter-spacing: 0px; |
|||
color: rgba(53, 56, 112, 1); |
|||
text-align: left; |
|||
/*左对齐*/ |
|||
vertical-align: top; |
|||
/* 这个属性在 Flex 容器中不起作用,将被移除 */ |
|||
display: flex; |
|||
/* 启用 Flexbox 布局 */ |
|||
align-items: center; |
|||
/* 垂直居中 */ |
|||
height: 30%; |
|||
/* 设置高度,根据需要调整 */ |
|||
width: 50%; |
|||
/* 如果需要,也可以设置宽度 */ |
|||
} |
|||
|
|||
.work-content { |
|||
width: 95%; |
|||
height: 35%; |
|||
position: absolute; |
|||
bottom: 10%; |
|||
display: flex; |
|||
} |
|||
|
|||
.work-time { |
|||
position: absolute; |
|||
display: flex; |
|||
width: 70%; |
|||
bottom: 12%; |
|||
} |
|||
|
|||
.deadline { |
|||
color: rgba(142, 142, 142, 1); |
|||
font-size: 3.6vw; |
|||
opacity: 1; |
|||
align-items: center; |
|||
padding-top: 0.5vw; |
|||
/* 水平居中 */ |
|||
/* justify-content: center; */ |
|||
} |
|||
|
|||
.work-status { |
|||
font-size: 3.8vw; |
|||
display: inline-block; |
|||
background: rgba(53, 56, 112, 0.1); |
|||
padding: 1% 3.5%; |
|||
text-align: center; |
|||
color: #353870; |
|||
border-radius: 5px; |
|||
opacity: 2; |
|||
margin-left: 5px; |
|||
} |
|||
.work-status2 { |
|||
font-size: 3.8vw; |
|||
display: inline-block; |
|||
background: #ffe1ae; |
|||
padding: 1% 3.5%; |
|||
text-align: center; |
|||
color: #353870; |
|||
border-radius: 5px; |
|||
opacity: 2; |
|||
margin-left: 5px; |
|||
} |
|||
|
|||
.work-bottem { |
|||
cursor: pointer; |
|||
display: flex; |
|||
position: absolute; |
|||
width: 28%; |
|||
height: 70%; |
|||
right: 0; |
|||
bottom: 2%; |
|||
opacity: 1; |
|||
border-radius: 50px; |
|||
background: linear-gradient(270deg, rgba(4, 15, 179, 1) 0%, rgba(120, 89, 255, 1) 100%); |
|||
border: 1px solid #a5e0f3; |
|||
justify-content: center; |
|||
/* 水平居中 */ |
|||
align-items: center; |
|||
/* 垂直居中 */ |
|||
text-align: center; |
|||
/* 确保文本在其容器内居中 */ |
|||
} |
|||
|
|||
.write { |
|||
opacity: 1; |
|||
/** 文本1 */ |
|||
padding: auto; |
|||
font-size: 18px; |
|||
font-weight: 700; |
|||
letter-spacing: 0px; |
|||
line-height: 26.06px; |
|||
color: rgba(255, 255, 255, 1); |
|||
|
|||
} |
|||
} |
|||
|
|||
/* 平板 */ |
|||
@media (min-width: 768px) and (max-width:1280px) { |
|||
.container { |
|||
width: 100%; |
|||
margin: auto; |
|||
} |
|||
.works { |
|||
/* ../api/ShowApi |
|||
work\src\assets\bg@3x.png */ |
|||
background-image: url('../assets/bg@2x.png'); |
|||
background-color: #8f98f6; |
|||
width: 100%; |
|||
min-height: 100vh; |
|||
position: relative; |
|||
margin: auto; |
|||
background-size: 100% 100%; |
|||
} |
|||
|
|||
.work-list { |
|||
width: 95%; |
|||
display: flex; |
|||
justify-content: center; |
|||
align-items: center; |
|||
flex-direction: column; |
|||
margin: auto; |
|||
} |
|||
|
|||
.list { |
|||
display: flex; |
|||
justify-content: center; |
|||
align-items: center; |
|||
width: 97%; |
|||
height: 17vh; |
|||
opacity: 1; |
|||
border-radius: 10px; |
|||
background-color: rgba(255, 225, 174, 1); |
|||
margin-bottom: 3%; |
|||
} |
|||
|
|||
.work-item { |
|||
|
|||
width: 90%; |
|||
height: 70%; |
|||
padding: 10px; |
|||
position: relative; |
|||
background: linear-gradient(180deg, rgba(255, 255, 255, 1) 0%, rgba(250, 245, 235, 1) 100%); |
|||
border-radius: 10px; |
|||
border-radius: 10px; |
|||
} |
|||
.work-name { |
|||
opacity: 1; |
|||
/** 文本1 */ |
|||
font-size: 1.6rem; |
|||
font-weight: 700; |
|||
letter-spacing: 0px; |
|||
color: rgba(53, 56, 112, 1); |
|||
text-align: left; |
|||
/*左对齐*/ |
|||
vertical-align: top; |
|||
/* 这个属性在 Flex 容器中不起作用,将被移除 */ |
|||
display: flex; |
|||
/* 启用 Flexbox 布局 */ |
|||
align-items: center; |
|||
/* 垂直居中 */ |
|||
height: 30%; |
|||
/* 设置高度,根据需要调整 */ |
|||
width: 50%; |
|||
/* 如果需要,也可以设置宽度 */ |
|||
} |
|||
.work-content { |
|||
width: 90%; |
|||
height: 35%; |
|||
position: absolute; |
|||
bottom: 10%; |
|||
display: flex; |
|||
} |
|||
|
|||
.work-time { |
|||
position: absolute; |
|||
display: flex; |
|||
width: 70%; |
|||
bottom: 20%; |
|||
} |
|||
|
|||
.deadline { |
|||
color: rgba(142, 142, 142, 1); |
|||
font-size: 14px; |
|||
opacity: 1; |
|||
} |
|||
|
|||
.work-status { |
|||
display: inline-block; |
|||
background: rgba(53, 56, 112, 0.1); |
|||
padding: 0.5% 2%; |
|||
text-align: center; |
|||
color: #353870; |
|||
font-size: 1rem; |
|||
border-radius: 5px; |
|||
opacity: 2; |
|||
margin-left: 5px; |
|||
} |
|||
.work-status2 { |
|||
display: inline-block; |
|||
background: #ffe1ae; |
|||
padding: 0.5% 2%; |
|||
text-align: center; |
|||
color: #353870; |
|||
font-size: 1rem; |
|||
border-radius: 5px; |
|||
opacity: 2; |
|||
margin-left: 5px; |
|||
} |
|||
|
|||
.work-bottem { |
|||
cursor: pointer; |
|||
display: flex; |
|||
position: absolute; |
|||
width: 25%; |
|||
height: 70%; |
|||
right: 0%; |
|||
bottom: 2%; |
|||
opacity: 1; |
|||
border-radius: 50px; |
|||
background: linear-gradient(270deg, rgba(4, 15, 179, 1) 0%, rgba(120, 89, 255, 1) 100%); |
|||
border: 1px solid #a5e0f3; |
|||
justify-content: center; |
|||
/* 水平居中 */ |
|||
align-items: center; |
|||
/* 垂直居中 */ |
|||
text-align: center; |
|||
/* 确保文本在其容器内居中 */ |
|||
} |
|||
|
|||
.write { |
|||
opacity: 1; |
|||
/** 文本1 */ |
|||
padding: auto; |
|||
font-size: 1.125rem; |
|||
font-weight: 700; |
|||
letter-spacing: 0px; |
|||
line-height: 26.06px; |
|||
color: rgba(255, 255, 255, 1); |
|||
} |
|||
} |
|||
/* 电脑 */ |
|||
@media (min-width: 1280px) { |
|||
.container { |
|||
width: 27%; |
|||
margin: auto; |
|||
} |
|||
.works { |
|||
/* ../api/ShowApi |
|||
work\src\assets\bg@3x.png */ |
|||
background-image: url('../assets/bg@3x.png'); |
|||
background-color: #8f98f6; |
|||
width: 100%; |
|||
min-height: 100vh; |
|||
position: relative; |
|||
margin: auto; |
|||
background-size: 100% 100%; |
|||
} |
|||
.work-name { |
|||
opacity: 1; |
|||
/** 文本1 */ |
|||
font-size: 1.4vw; |
|||
font-weight: 700; |
|||
letter-spacing: 0px; |
|||
color: rgba(53, 56, 112, 1); |
|||
text-align: left; |
|||
/*左对齐*/ |
|||
vertical-align: top; |
|||
/* 这个属性在 Flex 容器中不起作用,将被移除 */ |
|||
display: flex; |
|||
/* 启用 Flexbox 布局 */ |
|||
align-items: center; |
|||
/* 垂直居中 */ |
|||
height: 30%; |
|||
/* 设置高度,根据需要调整 */ |
|||
width: 70%; |
|||
} |
|||
|
|||
.work-list { |
|||
width: 95%; |
|||
display: flex; |
|||
justify-content: center; |
|||
align-items: center; |
|||
flex-direction: column; |
|||
margin: auto; |
|||
} |
|||
|
|||
.list { |
|||
display: flex; |
|||
justify-content: center; |
|||
align-items: center; |
|||
width: 97%; |
|||
height: 17vh; |
|||
opacity: 1; |
|||
border-radius: 10px; |
|||
background-color: rgba(255, 225, 174, 1); |
|||
margin-bottom: 3%; |
|||
} |
|||
|
|||
.work-item { |
|||
|
|||
width: 90%; |
|||
height: 70%; |
|||
padding: 10px; |
|||
position: relative; |
|||
background: linear-gradient(180deg, rgba(255, 255, 255, 1) 0%, rgba(250, 245, 235, 1) 100%); |
|||
border-radius: 10px; |
|||
border-radius: 10px; |
|||
} |
|||
.work-content { |
|||
width: 90%; |
|||
height: 35%; |
|||
position: absolute; |
|||
bottom: 10%; |
|||
display: flex; |
|||
} |
|||
|
|||
.work-time { |
|||
position: absolute; |
|||
display: flex; |
|||
width: 70%; |
|||
bottom: 15%; |
|||
} |
|||
|
|||
.deadline { |
|||
color: rgba(142, 142, 142, 1); |
|||
font-size: 14px; |
|||
opacity: 1; |
|||
align-items: center; |
|||
padding-top: 0.2vw; |
|||
} |
|||
|
|||
.work-status { |
|||
display: inline-block; |
|||
background: rgba(53, 56, 112, 0.1); |
|||
padding: 0.5% 2%; |
|||
text-align: center; |
|||
color: #353870; |
|||
font-size: 1rem; |
|||
border-radius: 5px; |
|||
opacity: 2; |
|||
margin-left: 5px; |
|||
} |
|||
.work-status2 { |
|||
display: inline-block; |
|||
background: #ffe1ae; |
|||
padding: 0.5% 2%; |
|||
text-align: center; |
|||
color: #353870; |
|||
font-size: 1rem; |
|||
border-radius: 5px; |
|||
opacity: 2; |
|||
margin-left: 5px; |
|||
} |
|||
.work-bottem { |
|||
cursor: pointer; |
|||
display: flex; |
|||
position: absolute; |
|||
width: 25%; |
|||
height: 70%; |
|||
right: 0%; |
|||
bottom: 2%; |
|||
opacity: 1; |
|||
border-radius: 50px; |
|||
background: linear-gradient(270deg, rgba(4, 15, 179, 1) 0%, rgba(120, 89, 255, 1) 100%); |
|||
border: 1px solid #a5e0f3; |
|||
justify-content: center; |
|||
/* 水平居中 */ |
|||
align-items: center; |
|||
/* 垂直居中 */ |
|||
text-align: center; |
|||
/* 确保文本在其容器内居中 */ |
|||
} |
|||
|
|||
.write { |
|||
opacity: 1; |
|||
/** 文本1 */ |
|||
padding: auto; |
|||
font-size: 1.125rem; |
|||
font-weight: 700; |
|||
letter-spacing: 0px; |
|||
line-height: 26.06px; |
|||
color: rgba(255, 255, 255, 1); |
|||
} |
|||
|
|||
} |
|||
|
|||
.work-list{ |
|||
margin-top: 12%; |
|||
} |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
</style> |
Write
Preview
Loading…
Cancel
Save
Reference in new issue