Browse Source

修复按钮bug

admin_zwk
lenghui 5 months ago
parent
commit
0f616c4da1
  1. 17
      work/src/api/AddWorkApi.js
  2. 20
      work/src/api/ClassListApi.js
  3. 12
      work/src/api/LoginApi.js
  4. 20
      work/src/api/UpdateWorkApi.js
  5. 83
      work/src/api/index.js
  6. 30
      work/src/router/index.js
  7. 402
      work/src/views/AddWork.vue
  8. 251
      work/src/views/HomeWork.vue
  9. 149
      work/src/views/Login.vue
  10. 532
      work/src/views/UpdateWork.vue
  11. 388
      work/src/views/WorkDetail.vue
  12. 6
      work/src/views/WorksShowView.vue

17
work/src/api/AddWorkApi.js

@ -1,17 +0,0 @@
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;

20
work/src/api/ClassListApi.js

@ -1,20 +0,0 @@
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;

12
work/src/api/LoginApi.js

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

20
work/src/api/UpdateWorkApi.js

@ -1,20 +0,0 @@
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;

83
work/src/api/index.js

@ -1,83 +1,30 @@
// 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',
});
// Axios的请求拦截器,在这里添加token到请求头
axios.interceptors.request.use(config => {
const token = useTokenStore();
// 添加请求拦截器
service.interceptors.request.use(
config => {
// 假设你的token存储在Vuex、Pinia或者本地存储中,这里直接用一个变量代替
// 请确保在实际应用中从安全的地方获取token
const token = "9ior41AF0xTIbIG2pRnnbZi0+fEeMx8pywnIlrmTwo5FbqJ9lWrSWOxp9MkpKiNtedtUafqvzIwpFKrwuMs";
if (token) {
config.headers.token = `${token}`;
config.headers['token'] = ` ${token}`;
}
return config;
}, error => {
},
error => {
return Promise.reject(error);
});
service.interceptors.request.use(config => {
const token = useTokenStore();
if (token) {
// 一般后端会约定一个请求头的字段名来接收token,常见的如 'Authorization',并要求按照一定格式传递,比如 'Bearer <token>',这里按照此格式添加,你需要根据后端实际要求调整
config.headers.token = `${token}`;
}
return config;
);
// 添加响应拦截器
service.interceptors.response.use(resp => {
return resp.data;
}, 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.status == 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;

30
work/src/router/index.js

@ -1,31 +1,11 @@
import { createRouter, createWebHistory } from 'vue-router';
import HomeWork from '../views/HomeWork.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 WorkDetail from '../views/WorkDetail.vue';
import UpdateWork from '../views/UpdateWork.vue';
const router = createRouter({
history: createWebHistory(),
routes: [
{
path: '/',
name: 'login',
component: Login,
},
{
path: '/list',
name: 'homeWorklist',
component: HomeWork,
},
{
path:'/addwork',
name:'addwork',
component: AddWork
},
{
path: '/show',
name: 'workshow',
component: WorksShowView
@ -34,16 +14,6 @@ const router = createRouter({
path:'/doWork/:id?/:sub?',
name:'doWork',
component: DoHomeworkView
},
{
path:'/workdetail/:id',
name:'workdetail',
component: WorkDetail
},
{
path:'/updatework/:id',
name:'updatework',
component: UpdateWork
}
]
})

402
work/src/views/AddWork.vue

@ -1,402 +0,0 @@
<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+'--------------')
}
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 }) => {
// idarticle.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>

251
work/src/views/HomeWork.vue

@ -1,251 +0,0 @@
<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>财富的游戏</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 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);
// // axiostoken
// // 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('/')
// }
//退
function logout(){
//
const tokenStore = useTokenStore();
const userStore = useUserStore();
tokenStore.clear();
userStore.clear();
LoginApi.logout().then(res => {
console.log(res)
})
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>

149
work/src/views/Login.vue

@ -1,149 +0,0 @@
<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';
// 使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;
// 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;
});
console.log(token.value);
//
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>

532
work/src/views/UpdateWork.vue

@ -1,532 +0,0 @@
<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; // stringJSON
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) => {
// contentJSON
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使liveidArticleIdliveid
form.value.ArticleId = '';
} else if (form.value.ArticleId) {
// 使idform.value.ArticleId
} else if (homeworkData.value.article && homeworkData.value.article.id) {
// 使idhomeworkData.value.article.id
form.value.ArticleId = homeworkData.value.article.id;
}
if (typeof id.value === 'string') {
form.value.id = id.value;
}
ClassListApi.editWork(form.value)
.then((response) => {
console.log(response);
ElMessage.success('编辑成功');
router.push('/list')
})
.catch((error) => {
console.error('编辑失败', error);
ElMessage.error('编辑失败');
});
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 (form.value.ArticleId) {
ElMessage.warning('您已关联文章,暂无法关联直播');
form.value.LiveId = ''; //
form.value.ArticleId = '';
articleTitle.value = '';
}
};
//
const handleSelectArticle = (article: { label: string }) => {
// idarticle.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>

388
work/src/views/WorkDetail.vue

@ -1,388 +0,0 @@
<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" />
<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 () => {
try {
const params = {
// form.valueid.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>

6
work/src/views/WorksShowView.vue

@ -13,7 +13,7 @@ function loadWorks() {
ShowApi.getWorks().then(result => {
works.value = result.data;
console.log(works.value);
console.log(result.data)
console.log(result.data);
works.value.forEach(work => {
let date = work.endData;
work.endData = format(new Date(date), 'yyyy-MM-dd');
@ -55,8 +55,8 @@ function writeWorks(id,sub){
<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 class="work-bottem" @click="writeWorks(work.groupId,work.submit)">
<span class="write">写作业</span>
</div>
</div>
</div>

Loading…
Cancel
Save