Compare commits

...

6 Commits

Author SHA1 Message Date
zhaowenkang 5bf5a76272 bug修改 10 months ago
zhaowenkang 536506069e bug修改 10 months ago
zhaowenkang 9de048d82e bug修改 10 months ago
zhaowenkang 9e6782bf14 导出数据匹配修改 10 months ago
zhaowenkang 6d9bf01ffb 局域网内访问 10 months ago
zhaowenkang 4ac5d919ed 修改俱乐部的绑定 10 months ago
  1. 2
      work/package.json
  2. 4
      work/src/api/LoginApi.js
  3. 19
      work/src/api/index.js
  4. 26
      work/src/router/index.js
  5. 89
      work/src/views/AddWork.vue
  6. 366
      work/src/views/DoHomeworkView.vue
  7. 35
      work/src/views/HomeWork.vue
  8. 16
      work/src/views/Login.vue
  9. 403
      work/src/views/UpdateWork.vue
  10. 17
      work/src/views/WorkDetail.vue
  11. 563
      work/src/views/WorksShowView.vue
  12. 2
      work/vite.config.js

2
work/package.json

@ -4,7 +4,7 @@
"private": true, "private": true,
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "vite",
"dev": "vite --host 0.0.0.0",
"build": "vite build", "build": "vite build",
"preview": "vite preview" "preview": "vite preview"
}, },

4
work/src/api/LoginApi.js

@ -5,8 +5,8 @@ const LoginApi={
return service.post("/api/login",username,password) return service.post("/api/login",username,password)
}, },
//退出登录 //退出登录
logout(token){
return service.post("/api/logout",token)
logout(){
return service.post("/api/logout")
} }
} }
export default LoginApi; export default LoginApi;

19
work/src/api/index.js

@ -18,6 +18,7 @@
import axios from "axios"; import axios from "axios";
import { useTokenStore } from "../stores/token"; import { useTokenStore } from "../stores/token";
const service = axios.create({ const service = axios.create({
// baseURL: 'http://192.168.8.191:8080', // baseURL: 'http://192.168.8.191:8080',
// baseURL: 'http://localhost:8080', // baseURL: 'http://localhost:8080',
@ -27,9 +28,9 @@ const service = axios.create({
// Axios的请求拦截器,在这里添加token到请求头 // Axios的请求拦截器,在这里添加token到请求头
axios.interceptors.request.use(config => { axios.interceptors.request.use(config => {
const token = useTokenStore();
if (token) {
config.headers.token = `${token}`;
const tokenStore = useTokenStore();
if (tokenStore.token) {
config.headers.token = tokenStore.token;
} }
return config; return config;
}, error => { }, error => {
@ -37,10 +38,10 @@ axios.interceptors.request.use(config => {
}); });
service.interceptors.request.use(config => { service.interceptors.request.use(config => {
const token = useTokenStore();
if (token) {
const tokenStore = useTokenStore();
if (tokenStore.token) {
// 一般后端会约定一个请求头的字段名来接收token,常见的如 'Authorization',并要求按照一定格式传递,比如 'Bearer <token>',这里按照此格式添加,你需要根据后端实际要求调整 // 一般后端会约定一个请求头的字段名来接收token,常见的如 'Authorization',并要求按照一定格式传递,比如 'Bearer <token>',这里按照此格式添加,你需要根据后端实际要求调整
config.headers.token = `${token}`;
config.headers.token =tokenStore.token;
} }
return config; return config;
}, error => { }, error => {
@ -58,14 +59,14 @@ service.interceptors.request.use(config => {
service.interceptors.response.use(response => { service.interceptors.response.use(response => {
return response.data; return response.data;
}, error =>{ }, error =>{
if(error.code == "500"){
if(error.code === "500"){
ElMessage.error("服务器错误!"); ElMessage.error("服务器错误!");
} }
const response = error.response; const response = error.response;
if(error.response && error.response.status == 403){
if(error.response && error.response.status === 403){
//提示一下权限不足 //提示一下权限不足
ElMessage.warning(response.data.message); ElMessage.warning(response.data.message);
} else if(response && response.status == 401){
} else if(response && response.code === 401){
//提示一下未登录 //提示一下未登录
ElMessage.warning(response.data.message); ElMessage.warning(response.data.message);
//跳转登录页面 //跳转登录页面

26
work/src/router/index.js

@ -1,11 +1,10 @@
import { createRouter, createWebHistory } from 'vue-router'; import { createRouter, createWebHistory } from 'vue-router';
import HomeWork from '../views/HomeWork.vue'; import HomeWork from '../views/HomeWork.vue';
import Login from '../views/Login.vue'; import Login from '../views/Login.vue';
import WorksShowView from '../views/WorksShowView.vue';
import DoHomeworkView from "@/views/DoHomeworkView.vue";
import AddWork from '../views/AddWork.vue'; import AddWork from '../views/AddWork.vue';
import WorkDetail from '../views/WorkDetail.vue'; import WorkDetail from '../views/WorkDetail.vue';
import UpdateWork from '../views/UpdateWork.vue'; import UpdateWork from '../views/UpdateWork.vue';
import { useTokenStore } from '../stores/token';
const router = createRouter({ const router = createRouter({
history: createWebHistory(), history: createWebHistory(),
@ -26,16 +25,6 @@ const router = createRouter({
component: AddWork component: AddWork
}, },
{ {
path: '/show',
name: 'workshow',
component: WorksShowView
},
{
path:'/doWork/:id?/:sub?',
name:'doWork',
component: DoHomeworkView
},
{
path:'/workdetail/:id', path:'/workdetail/:id',
name:'workdetail', name:'workdetail',
component: WorkDetail component: WorkDetail
@ -48,4 +37,17 @@ const router = createRouter({
] ]
}) })
// 添加全局前置守卫
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 export default router

89
work/src/views/AddWork.vue

@ -29,11 +29,11 @@
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="关联文章"> <el-form-item label="关联文章">
<el-autocomplete v-model="articleTitle" :fetch-suggestions="queryArticleList" placeholder="请输入"
@select="handleSelectArticle" clearable @change="handleArticleChange"/>
<el-autocomplete v-model="articleTitle" :fetch-suggestions="queryArticleList" placeholder="请输入文章关键词"
@select="handleSelectArticle" clearable @clear="handleArticleClear"/>
</el-form-item> </el-form-item>
<el-form-item label="关联直播"> <el-form-item label="关联直播">
<el-select v-model="form.LiveId" placeholder="请选择" style="width: 100%" clearable @change="handleLiveChange">
<el-select v-model="form.LiveId" placeholder="请选择(可选择昨日、今日以及未来7日已创建的直播)" style="width: 100%" clearable @change="handleLiveChange">
<el-option v-for="item in live" :key="item.id" :label="item.name" :value="item.id" /> <el-option v-for="item in live" :key="item.id" :label="item.name" :value="item.id" />
</el-select> </el-select>
</el-form-item> </el-form-item>
@ -41,7 +41,7 @@
<div> <div>
<el-button type="primary" @click="addSingleChoice">添加单选</el-button> <el-button type="primary" @click="addSingleChoice">添加单选</el-button>
<el-button type="primary" @click="addMultipleChoice">添加多选</el-button> <el-button type="primary" @click="addMultipleChoice">添加多选</el-button>
<el-button type="primary" @click="addBlank">添加单选填空</el-button>
<el-button type="primary" @click="addBlank">添加简答题</el-button>
</div> </div>
</el-form-item> </el-form-item>
<div class="question-container" v-for="(question, index) in questions" :key="index" <div class="question-container" v-for="(question, index) in questions" :key="index"
@ -53,7 +53,8 @@
<div style="width: 600px;"> <div style="width: 600px;">
<el-input v-model="question.description" /> <el-input v-model="question.description" />
</div> </div>
<div class="add" v-if="question.type !== 'blank'">
<div class="add">
<div v-if="question.type !== 3">
<div class="question-option"> <div class="question-option">
<span>设置选项:</span> <span>设置选项:</span>
<el-button type="primary" text @click="addOption(index)">添加</el-button> <el-button type="primary" text @click="addOption(index)">添加</el-button>
@ -70,6 +71,7 @@
</div> </div>
</div> </div>
</div> </div>
</div>
<div class="delete" style="margin-left: 50px;"> <div class="delete" style="margin-left: 50px;">
<el-button type="info" plain @click="removeQuestion(index)">删除</el-button> <el-button type="info" plain @click="removeQuestion(index)">删除</el-button>
</div> </div>
@ -87,7 +89,7 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { ref, onMounted, computed } from 'vue'
import { ref, onMounted, computed,reactive } from 'vue'
import AddWorkApi from '../api/AddWorkApi'; import AddWorkApi from '../api/AddWorkApi';
import _ from 'lodash'; import _ from 'lodash';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
@ -100,6 +102,7 @@ import { useUserStore } from '../stores/user';
const router = useRouter(); const router = useRouter();
const options = ref([ const options = ref([
{ id: 1, name: '牧民俱乐部' }, { id: 1, name: '牧民俱乐部' },
{ id: 2, name: '博古论坛' }, { id: 2, name: '博古论坛' },
@ -127,7 +130,18 @@ const form = ref({
const articleTitle = ref(''); const articleTitle = ref('');
// //
const questions = ref([]); const questions = ref([]);
const onSubmit = () => { const onSubmit = () => {
let hasEmptyDescription = false;
questions.value.forEach(question => {
if (question.description === '') {
hasEmptyDescription = true;
}
});
if (hasEmptyDescription) {
ElMessage.error('存在题目未填写描述内容,请填写完整后再提交!');
return;
}
// picker // picker
if (form.value.picker && form.value.picker.length === 2) { if (form.value.picker && form.value.picker.length === 2) {
const startDate = dayjs(form.value.picker[0]).format('YYYY-MM-DD HH:mm:00'); const startDate = dayjs(form.value.picker[0]).format('YYYY-MM-DD HH:mm:00');
@ -137,13 +151,34 @@ const onSubmit = () => {
} }
form.value.Questions = questions.value; form.value.Questions = questions.value;
AddWorkApi.addWork(form.value) AddWorkApi.addWork(form.value)
.then(res => {
const code = res['code'];
const message=res['message']
if (code !== 200) {
ElMessage.error(message);
}else{
console.log(questions.value+'--------------') console.log(questions.value+'--------------')
ElMessage.success('添加成功');
router.push('/list')
}
});
} }
const back = () => { const back = () => {
window.history.back() window.history.back()
} }
const handleArticleClear=()=>{
articleTitle.value='';
form.value.ArticleId = '';
}
// const handleInputLimit = () => {
// if (form.value.Name.length > 22) {
// form.value.Name = form.value.Name.slice(0, 22);
// ElMessage.warning('22');
// }
// };
// //
const articleSearchResults = ref([]); const articleSearchResults = ref([]);
@ -152,7 +187,7 @@ const queryArticleList = async (queryString: string) => {
if (form.value.LiveId) { if (form.value.LiveId) {
ElMessage.warning('您已关联直播,暂无法关联文章'); ElMessage.warning('您已关联直播,暂无法关联文章');
articleTitle.value = ''; // articleTitle.value = ''; //
form.value.LiveId = '';
//form.value.LiveId = '';
return []; return [];
} }
try { try {
@ -165,6 +200,8 @@ const queryArticleList = async (queryString: string) => {
return formattedResults; return formattedResults;
} catch (error) { } catch (error) {
console.error('查询关联文章失败', error); console.error('查询关联文章失败', error);
ElMessage.error('请输入正确的文章关联词');
articleTitle.value = '';
return []; return [];
} }
}; };
@ -182,8 +219,8 @@ const handleLiveChange = () => {
if (form.value.ArticleId) { if (form.value.ArticleId) {
ElMessage.warning('您已关联文章,暂无法关联直播'); ElMessage.warning('您已关联文章,暂无法关联直播');
form.value.LiveId = ''; // form.value.LiveId = ''; //
form.value.ArticleId = '';
articleTitle.value = '';
//form.value.ArticleId = '';
//articleTitle.value = '';
} }
}; };
@ -231,27 +268,22 @@ const addMultipleChoice = () => {
}); });
}; };
//const hasAddedBlank=ref(false);
const addBlank = () => { const addBlank = () => {
// hasAddedBlanktrue
//if (!hasAddedBlank.value) {
questions.value.push({ questions.value.push({
type: 3, // 3 type: 3, // 3
description: '', description: '',
content: [{ "id": "", "text": "" }] content: [{ "id": "", "text": "" }]
}); });
// hasAddedBlank.value = true;
// }else {
// ElMessage.warning('');
// }
}; };
// 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 addOption = (questionIndex) => {
const currentQuestion = questions.value[questionIndex]; const currentQuestion = questions.value[questionIndex];
// content // content
@ -262,6 +294,21 @@ const addOption = (questionIndex) => {
}; };
const removeOption = (questionIndex, optionIndex) => { const removeOption = (questionIndex, optionIndex) => {
const currentQuestion = questions.value[questionIndex]; const currentQuestion = questions.value[questionIndex];
//
if (currentQuestion.type === 1) {
// 2
if (currentQuestion.content.length <= 1) {
ElMessage.warning('单选题至少需要保留一个选项,不能继续删除');
return;
}
}
if (currentQuestion.type === 2) {
// 2
if (currentQuestion.content.length <= 2) {
ElMessage.warning('多选题至少需要保留两个选项,不能继续删除');
return;
}
}
currentQuestion.content.splice(optionIndex, 1); currentQuestion.content.splice(optionIndex, 1);
}; };
const removeQuestion = (questionIndex) => { const removeQuestion = (questionIndex) => {

366
work/src/views/DoHomeworkView.vue

@ -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>

35
work/src/views/HomeWork.vue

@ -21,15 +21,15 @@
<el-table-column prop="name" label="作业名称"></el-table-column> <el-table-column prop="name" label="作业名称"></el-table-column>
<el-table-column label="内容归属"> <el-table-column label="内容归属">
<template v-slot="scope"> <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>财富的游戏</span>
<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> </template>
</el-table-column> </el-table-column>
<el-table-column prop="article" label="关联文章"> <el-table-column prop="article" label="关联文章">
@ -58,7 +58,7 @@
</el-table-column> </el-table-column>
<el-table-column prop="status" label="状态"> <el-table-column prop="status" label="状态">
<template #default="{ row }"> <template #default="{ row }">
<span v-if="row.status === 0">上架</span>
<span v-if="row.status === 0">发布</span>
<span v-else-if="row.status === 1">发布中</span> <span v-else-if="row.status === 1">发布中</span>
<span v-else-if="row.status === 2">已下架</span> <span v-else-if="row.status === 2">已下架</span>
</template> </template>
@ -130,6 +130,11 @@ const getAssignments = (PageNo, PageSize) => {
//mounted //mounted
onMounted(() => { onMounted(() => {
getAssignments(PageNo.value, PageSize.value); getAssignments(PageNo.value, PageSize.value);
const token = useTokenStore();
console.log(token);
console.log(token.value);
console.log(token.token)
console.log("=============");
}); });
const newAssignment = () => { const newAssignment = () => {
@ -188,15 +193,17 @@ const editAssignment = async (row) => {
// } // }
//退 //退
function logout(){
const logout=async()=>{
try {
await LoginApi.logout()
} catch (error) {
console.log(error)
}
// //
const tokenStore = useTokenStore(); const tokenStore = useTokenStore();
const userStore = useUserStore(); const userStore = useUserStore();
tokenStore.clear(); tokenStore.clear();
userStore.clear(); userStore.clear();
LoginApi.logout().then(res => {
console.log(res)
})
router.push('/') router.push('/')
} }
</script> </script>

16
work/src/views/Login.vue

@ -28,6 +28,7 @@ import LoginApi from '../api/LoginApi';
import { ElMessage } from 'element-plus'; import { ElMessage } from 'element-plus';
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
import axios from 'axios'; import axios from 'axios';
import { useTokenStore } from '../stores/token';
// 使ref // 使ref
const username = ref(''); const username = ref('');
const password = ref(''); const password = ref('');
@ -50,18 +51,14 @@ const login = async () => {
if (response.code === 200) { if (response.code === 200) {
// token // token
token.value = response.data.token; token.value = response.data.token;
// tokenlocalStorage'token'
localStorage.setItem('token', token.value);
// axiostoken
axios.interceptors.request.use(config => {
//config.headers.token = `${token.value}`;
config.headers['token'] = token.value;
return config;
});
const tokenStore=useTokenStore();
tokenStore.changeToken(token.value);
// const userStore=useUserStore();
// userStore.changeUser(response.data.user);
console.log(token.value); console.log(token.value);
console.log("=--------");
// //
ElMessage.success('登录成功'); ElMessage.success('登录成功');
// //
router.push('/list'); router.push('/list');
} else { } else {
@ -72,7 +69,6 @@ const login = async () => {
// //
ElMessage.error('网络异常,请检查网络连接后重试'); ElMessage.error('网络异常,请检查网络连接后重试');
console.error(error); console.error(error);
} }
}; };
</script> </script>

403
work/src/views/UpdateWork.vue

@ -3,119 +3,192 @@
<el-container> <el-container>
<el-header class="header"> <el-header class="header">
<el-text class="header-text">抢点班作业后台管理</el-text> <el-text class="header-text">抢点班作业后台管理</el-text>
<el-button class="header-button" type="primary" text style="float: right;" @click="logout">退出登录</el-button>
<el-button
class="header-button"
type="primary"
text
style="float: right"
@click="logout"
>退出登录</el-button
>
</el-header> </el-header>
<el-main class="main"> <el-main class="main">
<div class="main-title"> <div class="main-title">
<div class="main-title-text" style="float: left;">
编辑作业
</div>
<div class="main-title-text" style="float: left">编辑作业</div>
<div> <div>
<el-button class="main-button" @click="back">返回上一页</el-button> <el-button class="main-button" @click="back">返回上一页</el-button>
</div> </div>
</div> </div>
<div class="main-back"> <div class="main-back">
<el-form :model="form" label-width="auto" style="max-width: 700px" size="large">
<el-form
:model="form"
label-width="auto"
style="max-width: 700px"
size="large"
>
<el-form-item label="作业名称"> <el-form-item label="作业名称">
<el-input v-model="form.Name" placeholder="请输入"></el-input> <el-input v-model="form.Name" placeholder="请输入"></el-input>
</el-form-item> </el-form-item>
<el-form-item label="提交时间" style="width: 70%"> <el-form-item label="提交时间" style="width: 70%">
<el-date-picker v-model="form.picker" type="daterange" range-separator="" start-placeholder="开始日期"
end-placeholder="结束日期" />
<el-date-picker
v-model="form.picker"
type="daterange"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
/>
</el-form-item> </el-form-item>
<el-form-item label="作业归属"> <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
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-select>
</el-form-item> </el-form-item>
<el-form-item label="关联文章"> <el-form-item label="关联文章">
<el-autocomplete v-model="articleTitle" :fetch-suggestions="queryArticleList" placeholder="请输入"
@select="handleSelectArticle" clearable />
<el-autocomplete
v-model="articleTitle"
:fetch-suggestions="queryArticleList"
placeholder="请输入文章关键词"
@select="handleSelectArticle"
clearable
/>
</el-form-item> </el-form-item>
<el-form-item label="关联直播"> <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
v-model="form.LiveId"
placeholder="请选择(可选择昨日、今日以及未来7日已创建的直播)"
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-select>
</el-form-item> </el-form-item>
<el-form-item label="选择类型"> <el-form-item label="选择类型">
<div> <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>
<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> </div>
</el-form-item> </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-container"
v-for="(question, index) in questions"
:key="index"
:class="{ 'bg-change': isHovered[index] }"
@mouseenter="handleMouseEnter(index)"
@mouseleave="handleMouseLeave(index)"
>
<div class="question-title"> <div class="question-title">
{{ questionPrefix(index) }} {{ getQuestionTypeText(question.type) }}
{{ questionPrefix(index) }}
{{ getQuestionTypeText(question.type) }}
</div> </div>
<div style="width: 600px;">
<div style="width: 600px">
<el-input v-model="question.description" /> <el-input v-model="question.description" />
</div> </div>
<div class="add" v-if="question.type !== 'blank'">
<div class="add">
<div v-if="question.type !== 3">
<div class="question-option"> <div class="question-option">
<span>设置选项:</span> <span>设置选项:</span>
<el-button type="primary" text @click="addOption(index)">添加</el-button>
<el-button type="primary" text @click="addOption(index)"
>添加</el-button
>
</div> </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
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>
<div> <div>
<el-button type="primary" text @click="removeOption(index, optionIndex)">删除</el-button>
<el-button
type="primary"
text
@click="removeOption(index, optionIndex)"
>删除</el-button
>
</div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div class="delete" style="margin-left: 50px;">
<el-button type="info" plain @click="removeQuestion(index)">删除</el-button>
<div class="delete" style="margin-left: 50px">
<el-button type="info" plain @click="removeQuestion(index)"
>删除</el-button
>
</div> </div>
</div> </div>
</div> </div>
<div class="submit"> <div class="submit">
<el-button type="primary" :disabled="!form.Name || !form.picker" @click="onSubmit">确认</el-button>
<el-button
type="primary"
:disabled="!form.Name || !form.picker"
@click="onSubmit"
>确认</el-button
>
</div> </div>
</el-form> </el-form>
</div> </div>
</el-main> </el-main>
</el-container> </el-container>
</div> </div>
</template> </template>
<script lang="ts" setup> <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';
import { ref, onMounted, computed, reactive } 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";
import { ar } from "date-fns/locale";
import { el } from "element-plus/es/locale";
const router = useRouter(); const router = useRouter();
const options = ref([ 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: '财富的游戏' },
{ 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 route = useRoute();
const id = ref(route.params.id)
console.log(id.value + '============')
const id = ref(route.params.id);
console.log(id.value + "============");
// //
const homeworkData = ref<{ const homeworkData = ref<{
@ -133,22 +206,21 @@ const homeworkData = ref<{
}; };
status: number; status: number;
form: FormItemType[]; form: FormItemType[];
}>({ }>({
name: '',
startDate: '',
endDate: '',
clubType: '',
name: "",
startDate: "",
endDate: "",
clubType: "",
article: { article: {
id: '',
title: '',
id: "",
title: "",
}, },
live: { live: {
id: '',
name: ''
id: "",
name: "",
}, },
status: 0, status: 0,
form: []
form: [],
}); });
// form // form
@ -165,17 +237,16 @@ interface FormItemType {
updatedAt: string; updatedAt: string;
} }
const form = ref({ const form = ref({
id: '',
Name: '',
ClubType: '',
ArticleId: '',
LiveId: '',
id: "",
Name: "",
ClubType: "",
ArticleId: "",
LiveId: "",
picker: [], picker: [],
StartDate: '',
EndDate: '',
Questions: []
StartDate: "",
EndDate: "",
Questions: [],
}); });
// false // false
@ -184,13 +255,13 @@ onMounted(async () => {
try { try {
const response = await ClassListApi.getClassListOne(id.value); const response = await ClassListApi.getClassListOne(id.value);
homeworkData.value = response.data; homeworkData.value = response.data;
console.log(homeworkData.value)
console.log(homeworkData.value);
form.value.Name = homeworkData.value.name; form.value.Name = homeworkData.value.name;
// //
isPublished.value = homeworkData.value.status; 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');
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]; form.value.picker = [start, end];
if (homeworkData.value.article && homeworkData.value.article.title) { if (homeworkData.value.article && homeworkData.value.article.title) {
@ -203,7 +274,10 @@ onMounted(async () => {
const newQuestions = []; const newQuestions = [];
homeworkData.value.form.forEach((formItem: FormItemType) => { homeworkData.value.form.forEach((formItem: FormItemType) => {
// contentJSON // contentJSON
const contentArray = JSON.parse(formItem.content) as { id: string, text: string }[];
const contentArray = JSON.parse(formItem.content) as {
id: string;
text: string;
}[];
// questions // questions
const question = { const question = {
id: formItem.id, id: formItem.id,
@ -223,89 +297,120 @@ onMounted(async () => {
}; };
questions.value = processFormData(); questions.value = processFormData();
} catch (error) { } catch (error) {
console.error('接口请求出现错误:', error);
console.error("接口请求出现错误:", error);
} }
}); });
const articleTitle = ref('');
const articleTitle = ref("");
// //
const questions = ref([]); const questions = ref([]);
const onSubmit = () => { const onSubmit = () => {
let hasEmptyDescription = false;
questions.value.forEach(question => {
if (question.description === '') {
hasEmptyDescription = true;
}
});
if (hasEmptyDescription) {
ElMessage.error('存在题目未填写描述内容,请填写完整后再提交!');
return;
}
// picker // picker
if (form.value.picker && form.value.picker.length === 2) { 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');
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.StartDate = startDate;
form.value.EndDate = endDate; form.value.EndDate = endDate;
} }
form.value.Questions = questions.value; form.value.Questions = questions.value;
if (
isLiveChange.value === false &&
homeworkData.value.live &&
homeworkData.value.live.id
) {
form.value.LiveId = homeworkData.value.live.id;
}
if (form.value.LiveId) { if (form.value.LiveId) {
// form.value.liveid使liveidArticleIdliveid // form.value.liveid使liveidArticleIdliveid
form.value.ArticleId = '';
form.value.ArticleId = "";
articleTitle.value = "";
} else if (form.value.ArticleId) { } else if (form.value.ArticleId) {
// 使idform.value.ArticleId // 使idform.value.ArticleId
} else if (homeworkData.value.article && homeworkData.value.article.id) { } else if (homeworkData.value.article && homeworkData.value.article.id) {
// 使idhomeworkData.value.article.id // 使idhomeworkData.value.article.id
form.value.ArticleId = homeworkData.value.article.id; form.value.ArticleId = homeworkData.value.article.id;
} }
if (typeof id.value === 'string') {
if (typeof id.value === "string") {
form.value.id = id.value; form.value.id = id.value;
} }
ClassListApi.editWork(form.value)
.then((response) => {
if (!form.value.ArticleId && !form.value.LiveId) {
ElMessage.error("编辑失败,请选择关联文章或关联直播");
} else {
ClassListApi.editWork(form.value).then((response) => {
const code = response["code"];
const message = response["message"];
if (code !== 200) {
ElMessage.error(message);
} else {
console.log(response); console.log(response);
ElMessage.success('编辑成功');
router.push('/list')
})
.catch((error) => {
console.error('编辑失败', error);
ElMessage.error('编辑失败');
ElMessage.success("编辑成功");
router.push("/list");
}
}); });
console.log(id.value + '--------------')
console.log(form.value)
} }
console.log(id.value + "--------------");
console.log(form.value);
};
const back = () => { const back = () => {
window.history.back()
}
window.history.back();
};
// //
const articleSearchResults = ref([]); const articleSearchResults = ref([]);
// //
const queryArticleList = async (queryString: string) => { const queryArticleList = async (queryString: string) => {
if (form.value.LiveId) { if (form.value.LiveId) {
ElMessage.warning('您已关联直播,暂无法关联文章');
articleTitle.value = ''; //
form.value.LiveId = '';
ElMessage.warning("您已关联直播,暂无法关联文章");
articleTitle.value = ""; //
//form.value.LiveId = ''; //()
return []; return [];
} }
try { try {
const response = await AddWorkApi.getArticleList(queryString); const response = await AddWorkApi.getArticleList(queryString);
const formattedResults = response.data.map(article => ({
const formattedResults = response.data.map((article) => ({
value: article.title, value: article.title,
label: article.id
label: article.id,
})); }));
articleSearchResults.value = formattedResults; articleSearchResults.value = formattedResults;
return formattedResults; return formattedResults;
} catch (error) { } catch (error) {
console.error('查询关联文章失败', error);
console.error("查询关联文章失败", error);
ElMessage.error("请输入正确的文章关联词");
articleTitle.value = "";
return []; return [];
} }
}; };
//
const isLiveChange = ref(false);
const handleLiveChange = () => { const handleLiveChange = () => {
if (form.value.ArticleId) {
ElMessage.warning('您已关联文章,暂无法关联直播');
form.value.LiveId = ''; //
form.value.ArticleId = '';
articleTitle.value = '';
isLiveChange.value = true;
if (articleTitle.value) {
ElMessage.warning("您已关联文章,暂无法关联直播");
form.value.LiveId = ""; //
form.value.ArticleId = "";
//articleTitle.value = ''; ()
} }
}; };
// //
const handleSelectArticle = (article: { label: string }) => { const handleSelectArticle = (article: { label: string }) => {
// idarticle.label使 // idarticle.label使
console.log('选中的文章id', article.label);
console.log("选中的文章id", article.label);
form.value.ArticleId = article.label; // id form.value.ArticleId = article.label; // id
const selectedArticle = articleSearchResults.value.find(a => a.label === article.label);
const selectedArticle = articleSearchResults.value.find(
(a) => a.label === article.label
);
if (selectedArticle) { if (selectedArticle) {
articleTitle.value = selectedArticle.value; // articleTitle.value = selectedArticle.value; //
} }
@ -315,13 +420,13 @@ const handleSelectArticle = (article: { label: string }) => {
const live = ref([]); const live = ref([]);
function getLive() { function getLive() {
AddWorkApi.getLiveList() AddWorkApi.getLiveList()
.then(res => {
.then((res) => {
live.value = res.data; live.value = res.data;
console.log(live.value); console.log(live.value);
}) })
.catch(error => {
console.error('获取直播列表失败', error)
})
.catch((error) => {
console.error("获取直播列表失败", error);
});
} }
getLive(); getLive();
@ -329,52 +434,59 @@ getLive();
const getQuestionTypeText = (type) => { const getQuestionTypeText = (type) => {
switch (type) { switch (type) {
case 1: case 1:
return '作业题目(单选)';
return "作业题目(单选)";
case 2: case 2:
return '作业题目(多选)';
return "作业题目(多选)";
case 3: case 3:
return '作业题目(简答题)';
return "作业题目(简答题)";
default: default:
return '未知类型题目';
return "未知类型题目";
} }
}; };
const addSingleChoice = () => { const addSingleChoice = () => {
if (isPublished.value === 1) { if (isPublished.value === 1) {
ElMessage.warning('处于发布中,不能添加新题目');
ElMessage.warning("处于发布中,不能添加新题目");
} else { } else {
questions.value.push({ questions.value.push({
type: 1, // 1 type: 1, // 1
description: '',
content: [{ "id": "", "text": "" }, { "id": "", "text": "" }]
description: "",
content: [
{ id: "", text: "" },
{ id: "", text: "" },
],
}); });
} }
}; };
const addMultipleChoice = () => { const addMultipleChoice = () => {
if (isPublished.value === 1) { if (isPublished.value === 1) {
ElMessage.warning('处于发布中,不能添加新题目');
ElMessage.warning("处于发布中,不能添加新题目");
} else { } else {
questions.value.push({ questions.value.push({
type: 2, // 2 type: 2, // 2
description: '',
content: [{ "id": "", "text": "" }, { "id": "", "text": "" }]
description: "",
content: [
{ id: "", text: "" },
{ id: "", text: "" },
],
}); });
} }
}; };
//const hasAddedBlank=ref(false);
const addBlank = () => { const addBlank = () => {
if (isPublished.value === 1) {
ElMessage.warning('处于发布中,不能添加新题目');
} else {
// hasAddedBlanktrue
//if (!hasAddedBlank.value) {
questions.value.push({ questions.value.push({
type: 3, // 3 type: 3, // 3
description: '', description: '',
content: [{ "id": "", "text": "" }] content: [{ "id": "", "text": "" }]
}); });
}
// hasAddedBlank.value = true;
// }else {
// ElMessage.warning('');
// }
}; };
const addOption = (questionIndex) => { const addOption = (questionIndex) => {
@ -387,12 +499,26 @@ const addOption = (questionIndex) => {
}; };
const removeOption = (questionIndex, optionIndex) => { const removeOption = (questionIndex, optionIndex) => {
const currentQuestion = questions.value[questionIndex]; const currentQuestion = questions.value[questionIndex];
//
if (currentQuestion.type === 1) {
if (currentQuestion.content.length <= 1) {
ElMessage.warning("单选题至少需要保留一个选项,不能继续删除");
return;
}
}
if (currentQuestion.type === 2) {
// 2
if (currentQuestion.content.length <= 2) {
ElMessage.warning("多选题至少需要保留两个选项,不能继续删除");
return;
}
}
currentQuestion.content.splice(optionIndex, 1); currentQuestion.content.splice(optionIndex, 1);
}; };
const removeQuestion = (questionIndex) => { const removeQuestion = (questionIndex) => {
if (isPublished.value === 1) { if (isPublished.value === 1) {
ElMessage.warning('处于发布中,不能删除题目');
ElMessage.warning("处于发布中,不能删除题目");
} else { } else {
questions.value.splice(questionIndex, 1); questions.value.splice(questionIndex, 1);
} }
@ -403,7 +529,7 @@ const questionPrefix = computed(() => {
return (index) => { return (index) => {
return `${index + 1}`; return `${index + 1}`;
}; };
})
});
// false // false
const isHovered = ref(Array(questions.value.length).fill(false)); const isHovered = ref(Array(questions.value.length).fill(false));
@ -420,7 +546,6 @@ onMounted(() => {
isHovered.value = Array(questions.value.length).fill(false); isHovered.value = Array(questions.value.length).fill(false);
}); });
//退 //退
function logout() { function logout() {
// //
@ -428,10 +553,10 @@ function logout() {
const userStore = useUserStore(); const userStore = useUserStore();
tokenStore.clear(); tokenStore.clear();
userStore.clear(); userStore.clear();
LoginApi.logout().then(res => {
console.log(res)
})
router.push('/')
LoginApi.logout().then((res) => {
console.log(res);
});
router.push("/");
} }
</script> </script>
@ -496,7 +621,7 @@ function logout() {
.main { .main {
padding: 30px 212px; padding: 30px 212px;
background-color: #F8F8F8;
background-color: #f8f8f8;
} }
.main-title { .main-title {

17
work/src/views/WorkDetail.vue

@ -18,7 +18,7 @@
<div class="table-container"> <div class="table-container">
<div class="search-bar" :v-model="form"> <div class="search-bar" :v-model="form">
<el-input v-model="form.jwcode" type="text" placeholder="请输入精网号" style="width: 180px;" <el-input v-model="form.jwcode" type="text" placeholder="请输入精网号" style="width: 180px;"
size="large" />
size="large" clearable />
<el-select v-model="form.deptId" placeholder="选择分店门部" size="large" <el-select v-model="form.deptId" placeholder="选择分店门部" size="large"
style="width: 180px; margin-left: 15px;" clearable @change="handleDeptSelect"> style="width: 180px; margin-left: 15px;" clearable @change="handleDeptSelect">
<el-option v-for="item in dept" :key="item.id" :label="item.deptName" <el-option v-for="item in dept" :key="item.id" :label="item.deptName"
@ -51,13 +51,13 @@
</el-table-column> </el-table-column>
<el-table-column label="作业详情"> <el-table-column label="作业详情">
<template v-slot="{ $index }"> <template v-slot="{ $index }">
<el-popover placement="bottom" title="详情" :width="500" trigger="click">
<el-popover placement="bottom" title="作业详情" :width="500" trigger="click">
<template #reference> <template #reference>
<el-button link type="primary">查看</el-button> <el-button link type="primary">查看</el-button>
</template> </template>
<div v-for="(r, subIndex) in getContent($index).replies" :key="subIndex"> <div v-for="(r, subIndex) in getContent($index).replies" :key="subIndex">
<div>{{ r.formTitle }}</div>
<div>{{ r.contentTitle }}</div>
<div><h3>{{ r.formTitle }}</h3></div>
<div><h1>{{ r.contentTitle }}</h1></div>
<div>{{ r.content }}</div> <div>{{ r.content }}</div>
<div style="margin-bottom: 10px;"></div> <div style="margin-bottom: 10px;"></div>
</div> </div>
@ -146,9 +146,9 @@ const searchData = async () => {
} catch (error) { } catch (error) {
console.error('搜索失败', error); console.error('搜索失败', error);
} }
form.value.jwcode = "";
form.value.deptId = "";
form.value.shopId = "";
// form.value.jwcode = "";
// form.value.deptId = "";
// form.value.shopId = "";
} }
// //
const dept = ref([]); const dept = ref([]);
@ -209,6 +209,9 @@ const getContent = (index) => {
}; };
}; };
const exportData = async () => { const exportData = async () => {
if(!workdetailData.value){
ElMessage.warning('暂无数据可导出');
}
try { try {
const params = { const params = {
// form.valueid.value // form.valueid.value

563
work/src/views/WorksShowView.vue

@ -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">
<span class="write" @click="writeWorks(work.groupId,work.submit)">写作业</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>

2
work/vite.config.js

@ -16,7 +16,7 @@ export default defineConfig({
server: { server: {
proxy: { proxy: {
'/api': { '/api': {
target: 'http://192.168.8.191:8080',
target: 'http://192.168.9.19:8080',
changeOrigin: true, changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, '') rewrite: (path) => path.replace(/^\/api/, '')
}, },

Loading…
Cancel
Save