合并冲突

This commit is contained in:
wyx
2023-03-05 08:33:00 +08:00
52 changed files with 37651 additions and 31385 deletions

19
.env
View File

@@ -1,18 +1,19 @@
VITE_BASE=/fe-student
VITE_BASE_H5=/fe-student-h5
VITE_BASE_API=
VITE_OUTPUT_DIR=./dist
VITE_FILE_PATH=/upload/
VITE_BASE_LOGIN_URL=https://u-pre.boe.com/web/
VITE_PROXY_URL=http://localhost:30001
VITE_BASE_LOGIN_URL=//u-pre.boe.com/web/
VITE_PROXY_URL=http://43.143.139.204/manageApi
VITE_BOE_ONLINE_CLASS_URL=https://u-pre.boe.com/pc/course/studyindex?id=
VITE_BOE_CASS_DETAIL_URL=https://u-pre.boe.com/pc/case/detail?id=
VITE_BOE_TEST_DETAIL_URL=https://u-pre.boe.com/web/quizsummary?detailId=
VITE_BOE_TEST_OUT_DETAIL_URL=https://u-pre.boe.com/api/b1/tale/do-quiz?quizKid=
VITE_BOE_EXAM_DETAIL_URL=https://u-pre.boe.com/pc/exam/test?id=
VITE_BOE_PATH_DETAIL_URL=https://u-pre.boe.com/pc/forward?to=/fe-student
VITE_BOE_ONLINE_CLASS_URL=//u-pre.boe.com/pc/course/studyindex?id=
VITE_BOE_CASS_DETAIL_URL=//u-pre.boe.com/pc/case/detail?id=
VITE_BOE_TEST_DETAIL_URL=//u-pre.boe.com/web/quizsummary?detailId=
VITE_BOE_TEST_OUT_DETAIL_URL=//u-pre.boe.com/api/b1/tale/do-quiz?quizKid=
VITE_BOE_EXAM_DETAIL_URL=//u-pre.boe.com/pc/exam/test?id=
VITE_BOE_PATH_DETAIL_URL=//u-pre.boe.com/pc/forward?to=/fe-student
VITE_BOE_API_URL=https://u-pre.boe.com
VITE_TASK_WHITE_TYPE=-8-,-12-,-13-
VITE_TASK_WHITE_TYPE=-22-

View File

@@ -1,10 +1,10 @@
VITE_BASE=/fe-student
VITE_BASE_API=/manageApi
VITE_BOE_ONLINE_CLASS_URL=https://u-pre.boe.com/pc/course/studyindex?id=
VITE_BOE_CASS_DETAIL_URL=https://u-pre.boe.com/pc/case/detail?id=
VITE_BOE_TEST_DETAIL_URL=https://u-pre.boe.com/web/quizsummary?detailId=
VITE_BOE_TEST_OUT_DETAIL_URL=https://u-pre.boe.com/api/b1/tale/do-quiz?quizKid=
VITE_BOE_EXAM_DETAIL_URL=https://u-pre.boe.com/pc/exam/test?id=
VITE_BOE_ONLINE_CLASS_URL=//u-pre.boe.com/pc/course/studyindex?id=
VITE_BOE_CASS_DETAIL_URL=//u-pre.boe.com/pc/case/detail?id=
VITE_BOE_TEST_DETAIL_URL=//u-pre.boe.com/web/quizsummary?detailId=
VITE_BOE_TEST_OUT_DETAIL_URL=//u-pre.boe.com/api/b1/tale/do-quiz?quizKid=
VITE_BOE_EXAM_DETAIL_URL=//u-pre.boe.com/pc/exam/test?id=
VITE_BOE_API_URL=https://u-pre.boe.com

View File

@@ -1,15 +1,15 @@
VITE_BASE=/fe-student
VITE_BASE_API=/manageApi
VITE_BASE_LOGIN_URL=https://u.boe.com/web/
VITE_BASE_LOGIN_URL=//u.boe.com/web/
VITE_BOE_ONLINE_CLASS_URL=https://u.boe.com/pc/course/studyindex?id=
VITE_BOE_CASS_DETAIL_URL=https://u.boe.com/pc/case/detail?id=
VITE_BOE_TEST_DETAIL_URL=https://u.boe.com/web/quizsummary?detailId=
VITE_BOE_TEST_OUT_DETAIL_URL=https://u.boe.com/api/b1/tale/do-quiz?quizKid=
VITE_BOE_EXAM_DETAIL_URL=https://u.boe.com/pc/exam/test?id=
VITE_BOE_PATH_DETAIL_URL=https://u.boe.com/pc/forward?to=/fe-student
VITE_BOE_ONLINE_CLASS_URL=//u.boe.com/pc/course/studyindex?id=
VITE_BOE_CASS_DETAIL_URL=//u.boe.com/pc/case/detail?id=
VITE_BOE_TEST_DETAIL_URL=//u.boe.com/web/quizsummary?detailId=
VITE_BOE_TEST_OUT_DETAIL_URL=//u.boe.com/api/b1/tale/do-quiz?quizKid=
VITE_BOE_EXAM_DETAIL_URL=//u.boe.com/pc/exam/test?id=
VITE_BOE_PATH_DETAIL_URL=//u.boe.com/pc/forward?to=/fe-student
VITE_BOE_API_URL=https://u.boe.com
VITE_TASK_WHITE_TYPE=-8-,-12-,-13-
VITE_TASK_WHITE_TYPE==-22-

View File

@@ -1,12 +1,12 @@
VITE_BASE=/fe-student-release
VITE_BASE_API=/manageApi-release
VITE_BASE_LOGIN_URL=https://u.boe.com/web/
VITE_BASE_LOGIN_URL=//u.boe.com/web/
VITE_BOE_ONLINE_CLASS_URL=https://u.boe.com/pc-release/course/studyindex?id=
VITE_BOE_CASS_DETAIL_URL=https://u.boe.com/pc-release/case/detail?id=
VITE_BOE_TEST_DETAIL_URL=https://u.boe.com/web/quizsummary?detailId=
VITE_BOE_TEST_OUT_DETAIL_URL=https://u.boe.com/api/b1/tale/do-quiz?quizKid=
VITE_BOE_EXAM_DETAIL_URL=https://u.boe.com/pc-release/exam/test?id=
VITE_BOE_PATH_DETAIL_URL=https://u.boe.com/pc-release/forward?to=/fe-student-release
VITE_BOE_ONLINE_CLASS_URL=//u.boe.com/pc-release/course/studyindex?id=
VITE_BOE_CASS_DETAIL_URL=//u.boe.com/pc-release/case/detail?id=
VITE_BOE_TEST_DETAIL_URL=//u.boe.com/web/quizsummary?detailId=
VITE_BOE_TEST_OUT_DETAIL_URL=//u.boe.com/api/b1/tale/do-quiz?quizKid=
VITE_BOE_EXAM_DETAIL_URL=//u.boe.com/pc-release/exam/test?id=
VITE_BOE_PATH_DETAIL_URL=//u.boe.com/pc-release/forward?to=/fe-student-release
VITE_BOE_API_URL=https://u.boe.com

44957
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,67 +1,69 @@
{
"name": "jdfstudy",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "vite",
"server": "vite build --mode boe && vite preview ",
"build": "vite build --mode release",
"build:boe": "vite build --mode boe",
"build:prod": "vite build --mode prod",
"build:release": "vite build --mode release",
"build:test": "vite build --mode test"
"name": "jdfstudy",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "vite",
"server": "vite build --mode boe && vite preview ",
"build": "vite build --mode release",
"build:boe": "vite build --mode boe",
"build:prod": "vite build --mode prod",
"build:release": "vite build --mode release",
"build:test": "vite build --mode test"
},
"dependencies": {
"@wangeditor/editor": "^5.1.23",
"@wangeditor/editor-for-vue": "^5.1.12",
"ant-design-vue": "^3.2.15",
"axios": "^1.1.3",
"core-js": "^3.26.0",
"dayjs": "^1.11.6",
"element-plus": "^2.2.27",
"json-bigint": "^1.0.0",
"vue": "^3.2.45",
"vue-router": "^4.1.6",
"vuex": "^4.1.0"
},
"devDependencies": {
"@babel/core": "^7.20.2",
"@babel/eslint-parser": "^7.19.1",
"@vitejs/plugin-legacy": "^2.3.1",
"@vitejs/plugin-vue": "^3.2.0",
"@vue/cli-plugin-babel": "~5.0.8",
"@vue/cli-plugin-eslint": "~5.0.8",
"@vue/cli-plugin-router": "~5.0.8",
"@vue/cli-plugin-vuex": "~5.0.8",
"@vue/cli-service": "~5.0.8",
"ajv": "^8",
"eslint": "^8.27.0",
"eslint-plugin-vue": "^9.7.0",
"mockjs": "^1.1.0",
"sass": "^1.56.1",
"sass-loader": "^13.2.0",
"vite": "^3.2.3",
"vite-plugin-imp": "^2.3.1",
"vite-plugin-mock": "^2.9.6",
"vite-plugin-style-import": "^2.0.0",
"vite-plugin-top-level-await": "^1.2.1"
},
"eslintConfig": {
"root": true,
"env": {
"node": true
},
"dependencies": {
"ant-design-vue": "^3.2.15",
"axios": "^1.1.3",
"core-js": "^3.26.0",
"dayjs": "^1.11.6",
"element-plus": "^2.2.27",
"json-bigint": "^1.0.0",
"vue": "^3.2.45",
"vue-router": "^4.1.6",
"vuex": "^4.1.0"
"extends": [
"plugin:vue/vue3-essential",
"eslint:recommended"
],
"parserOptions": {
"parser": "@babel/eslint-parser"
},
"devDependencies": {
"@babel/core": "^7.20.2",
"@babel/eslint-parser": "^7.19.1",
"@vitejs/plugin-legacy": "^2.3.1",
"@vitejs/plugin-vue": "^3.2.0",
"@vue/cli-plugin-babel": "~5.0.8",
"@vue/cli-plugin-eslint": "~5.0.8",
"@vue/cli-plugin-router": "~5.0.8",
"@vue/cli-plugin-vuex": "~5.0.8",
"@vue/cli-service": "~5.0.8",
"ajv": "^8",
"eslint": "^8.27.0",
"eslint-plugin-vue": "^9.7.0",
"mockjs": "^1.1.0",
"sass": "^1.56.1",
"sass-loader": "^13.2.0",
"vite": "^3.2.3",
"vite-plugin-imp": "^2.3.1",
"vite-plugin-mock": "^2.9.6",
"vite-plugin-style-import": "^2.0.0",
"vite-plugin-top-level-await": "^1.2.1"
},
"eslintConfig": {
"root": true,
"env": {
"node": true
},
"extends": [
"plugin:vue/vue3-essential",
"eslint:recommended"
],
"parserOptions": {
"parser": "@babel/eslint-parser"
},
"rules": {}
},
"browserslist": [
"> 1%",
"last 2 versions",
"not dead",
"not ie 11"
]
"rules": {}
},
"browserslist": [
"> 1%",
"last 2 versions",
"not dead",
"not ie 11"
]
}

10890
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -7,11 +7,11 @@
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
-->
<template>
<!--
<!--
-->
<div id="container">
<div id="container">
<!-- <div id="nav">
<!-- <div id="nav">
<router-link
v-for="item in routes"
:key="item.path"
@@ -24,34 +24,42 @@
{{ item.name }}
</router-link>
</div> -->
<main style="z-index: 2">
<router-view />
</main>
</div>
<main style="z-index: 2">
<router-view/>
</main>
</div>
</template>
<script setup>
import {boeRequest, request} from "@/api/request";
import { GET_USER_INFO } from "@/api/ThirdApi";
import { useStore } from "vuex";
import { onMounted } from "vue";
import {GET_USER_INFO} from "@/api/ThirdApi";
import {useStore} from "vuex";
import {onMounted} from "vue";
import {useRoute} from "vue-router/dist/vue-router";
import {USER_INFO} from "@/api/api";
import {IsPhone} from "@/api/utils";
console.log("版本1.2.2------------");
const store = useStore();
const {path} = useRoute();
const { path } = useRoute();
onMounted(() => {
path === '/login' || getUserInfo();
path === "/login" || getUserInfo();
if (IsPhone()) {
if (import.meta.env.MODE === "development") {
window.location.href = window.location.href.replace(import.meta.env.VITE_BASE, import.meta.env.VITE_BASE_H5).replace('5173','5174');
} else {
window.location.href = window.location.href.replace(import.meta.env.VITE_BASE, import.meta.env.VITE_BASE_H5)
}
}
});
function getUserInfo() {
if(import.meta.env.MODE ==='development' || import.meta.env.MODE ==='test'){
request(USER_INFO,{}).then(res=>{
if (import.meta.env.MODE === "development" || import.meta.env.MODE === "test") {
request(USER_INFO, {}).then(res => {
store.commit("SET_USER", res.data);
})
}else{
});
} else {
boeRequest(GET_USER_INFO).then((res) => {
res.result.avatar = res.result.avatar || '/800e23f7-b58c-4192-820d-0c6a2b7544cc.png'
res.result.avatar = res.result.avatar || "/800e23f7-b58c-4192-820d-0c6a2b7544cc.png";
store.commit("SET_USER", res.result);
});
}
@@ -59,58 +67,67 @@ function getUserInfo() {
</script>
<style lang="scss">
#app {
// font-family: MicrosoftYaHei, Microsoft YaHei, Avenir, Helvetica, Arial,
// sans-serif;
font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB,
Microsoft YaHei, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
color: #2c3e50;
height: 100%;
// font-family: MicrosoftYaHei, Microsoft YaHei, Avenir, Helvetica, Arial,
// sans-serif;
font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB,
Microsoft YaHei, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
color: #2c3e50;
height: 100%;
}
.return {
right: 0 !important;
}
.preNext {
right: 115px !important;
margin-top: 4px;
}
#container {
display: flex;
width: 100%;
min-height: 100%;
background-color: rgba(242, 245, 247, 1);
display: flex;
width: 100%;
min-height: 100%;
background-color: rgba(242, 245, 247, 1);
// background-color: #ccc;
#nav {
width: 220px;
height: 100%;
display: flex;
flex-direction: column;
gap: 20px;
padding: 30px 0;
box-sizing: border-box;
background: #f1f1f1;
box-shadow: 0 5px 15px 8px rgba(1, 22, 54, 0.795);
// background-color: #ccc;
#nav {
width: 220px;
height: 100%;
display: flex;
flex-direction: column;
gap: 20px;
padding: 30px 0;
box-sizing: border-box;
background: #f1f1f1;
box-shadow: 0 5px 15px 8px rgba(1, 22, 54, 0.795);
.link {
text-decoration: none;
color: rgb(0, 0, 0);
padding: 10px;
transition: all 0.4s;
text-align: center;
.link {
text-decoration: none;
color: rgb(0, 0, 0);
padding: 10px;
transition: all 0.4s;
text-align: center;
&:hover {
background: rgba(4, 37, 223, 0.274);
color: #f1f1f1;
}
&:hover {
background: rgba(4, 37, 223, 0.274);
color: #f1f1f1;
}
&.active {
color: #f1f1f1;
background: rgba(17, 120, 255, 0.74);
}
}
}
&.active {
color: #f1f1f1;
background: rgba(17, 120, 255, 0.74);
}
}
}
main {
flex: 1;
width: 100%;
// padding: 30px;
box-sizing: border-box;
}
main {
flex: 1;
width: 100%;
// padding: 30px;
box-sizing: border-box;
}
}
</style>

View File

@@ -1,3 +1,56 @@
export const PROJECT = 1;
export const ROUTER = 2;
export const COURSE = 3;
export const TASK_TYPES = {
typeName: {
1: "在线",
2: "面授",
3: "案例",
4: "作业",
5: "考试",
6: "直播",
7: "外链",
8: "讨论",
9: "活动",
10: "测评",
11: "评估",
12: "投票",
13: "项目",
},
toName: {
1: "去上课",
2: "去上课",
3: "去阅读",
4: "去完成",
5: "去完成",
6: "去观看",
7: "去查看",
8: "去讨论",
9: "去签到",
10: "去完成",
11: "去完成",
12: "去投票",
13: "去完成",
},
path: {
1: ({courseId}) => window.open(window.location.protocol + import.meta.env.VITE_BOE_ONLINE_CLASS_URL + courseId), //在线
2: ({courseId}) => window.open(`${location.protocol}//${location.host}${import.meta.env.VITE_BASE_API}/stu/project/redirectDetail?courseId=${courseId}`, '_top'),
3: ({courseId}) => window.open(window.location.protocol + import.meta.env.VITE_BOE_CASS_DETAIL_URL + courseId), //案例
4: "/homeworkpage",
5: ({examType}) => examType === 2 ? '/externalexamination' : (window.location.protocol + import.meta.env.VITE_BOE_EXAM_DETAIL_URL), //考试
6: "/livebroadcast",
7: '/outerchain', //外联
8: "/discusspage",
9: "/moreactive",
10: ({evaType, targetId}) =>
window.open(
evaType == 0
? window.location.protocol + import.meta.env.VITE_BOE_TEST_DETAIL_URL + targetId
: window.location.protocol + import.meta.env.VITE_BOE_TEST_OUT_DETAIL_URL + targetId + `&quizTaskKid=${routerId}&channelCode=learningpath`
, '_top'), //测评
11: "/surveydetail",
12: "/ballotpage",
13: "/projectdetails",
},
}

View File

@@ -1,4 +1,4 @@
export const BASE = 'https://u-pre.boe.com'
export const BASE = window.location.protocol + '//u-pre.boe.com'
export const GET_USER_LIST = `/userbasic/user/list post`
export const GET_USER_INFO = `/userbasic/user/info post`

View File

@@ -2,15 +2,16 @@
* @Author: lixg lixg@dongwu-inc.com
* @Date: 2022-12-11 16:57:58
* @LastEditors: lixg lixg@dongwu-inc.com
* @LastEditTime: 2022-12-18 18:37:26
* @LastEditTime: 2023-01-29 10:46:54
* @FilePath: /fe-stu/src/api/api.js
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
export const LOGIN = '/admin/CheckUser/userLogin post'
export const USER_INFO = '/admin/CheckUser/userInfo'
// export const FILE_UPLOAD = 'http://111.231.196.214:30001/file/upload'
// export const FILE_UPLOAD = 'http://143.143.139.204:30001/file/upload'
export const FILE_UPLOAD = import.meta.env.VITE_BASE_API + '/file/uploadFile'
export const FILE_UPLOAD_ANNEX = import.meta.env.VITE_BASE_API + '/file/stuUploadAnnex'
export const FILE_UPLOAD_ANNEX = import.meta.env.VITE_BASE_API + '/file/upload'
export const FILE_UPLOAD_IMG = import.meta.env.VITE_BASE_API + '/file/img'
export const COMMON_TOKEN = 'https://upload-z2.qiniup.com'
export const ROUTER_CHAPTER_LIST = '/stu/router/chapterList'
export const ROUTER_LIST = '/stu/router/list post'
@@ -31,6 +32,9 @@ export const TASK_VOTE_DETAIL = '/stu/task/vote/detail'
export const TASK_WORK_COMMIT = '/workSubmit/submitStudentWorkDetail post'
export const TASK_WORK_DETAIL = '/workSubmit/getWorkDetailByTaskId'
export const TASK_WORK_SUBMIT_LIST = '/workSubmit/queryWorkSubmitDetailById'
// 查询学员端是否导入了作业成绩
export const WhetherImportHomeWorkScore = '/admin/student/whetherImportHomeWorkScore post'
export const VOTE_DETAIL = '/queryVoteSubmitDetailById'
export const TASK_VOTE_LIST = '/queryVoteSubmitDetailListByTaskId'
@@ -47,9 +51,13 @@ export const DISCUSS_SUBMIT_REVIEW_LIST = '/discussSubmit/queryDiscussSubmitAndR
export const COMMENT_LIST = '/comment/list'
export const VOTE_DETAIL2 = voteId => `/vote/queryVoteAndVoteStemDetailByVoteId?voteId=${voteId} post`
export const COMMENT_ADD = '/comment post'
export const COMMENT_PRAISE = '/comment/praise post'
export const VOTE_DETAIL2 = `/voteSubmit/queryVoteTaskDetailById post`
export const VOTE_DETAIL3 = voteId => `/vote/queryVoteById?voteId=${voteId}`
// 投票详情接口
export const VOTE_DETAIL_SUBMIT = `/voteSubmit/vote/commit post`
export const COMMENT_ADD = '/comment/add post'
export const COMMENT_PRAISE = '/comment/praise'
export const COMMENT_COLLECTION = '/comment/collection post'
export const ASSESSMENT_SUBMIT_QUERY = assessmentId => `/assessmentSubmit/queryAssessmentSubmitDetailById?assessmentSubmitId=${assessmentId} post`
@@ -62,3 +70,61 @@ export const STUDY_RECORD = '/stu/task/thirdTask/submit post'
export const PROJECT_LIST = '/stu/project/list post'
export const FACETEACH_SIGNUP = `/stu/project/stuFaceTeachSignUp`
export const UPDATE_CURRENT_TASK = `/admin/student/updateCurrentTask post`
// 外部考试详情接口
export const EXTERNALEXAM = `/external/exam/queryExternalExam`
// 外链详情接口
export const LINKGETONE = `/link/getOne`
// 讨论模块
// -- 根据讨论的Id查询讨论发表的帖子
export const QueryDiscussSubmitDetailByDiscussId = '/discussSubmit/queryDiscussSubmitDetailByDiscussId post'
// 测评任务去学习
export const EvaluationToLearn = '/evaluation/evaluationToLearn post'
// 个人/小组完成度排行
export const CompletionList = `/stu/project/rank_list/completion_list`
// 积分排行榜
export const PointList = `/stu/project/rank_list/point_list`
// 根据ID获取测评信息详情
export const QueryEvaluationDetailById = evaluationId => `/evaluation/queryEvaluationDetailById?evaluationId=${evaluationId} post`
// 外部考试点击去完成调用
export const SubmitExternalExam = `/stu/externalExam/submitExternalExam post`
// 发表帖子
export const PostAdd = `/statement/add post`
// 帖子收藏
export const PostCollection = `/statement/collection post`
// 帖子删除
export const PostDelete = postId => `/statement/delete?id=${postId} post`
// 贴子点赞
export const PostPraise = `/statement/praise`
// 帖子更新
export const PostUpdate = `/statement/update post`
// 帖子详情查询
export const PostDetails = `/statement/info`
// 查询帖子的评论
export const GetComments = `/statement/getComments`
// 查询某个评论下更多的回复
export const GetMoreComments = `/statement/getMoreComments`
// 查询讨论下的帖子
export const PostList = `/statement/list`
// 查询单个测评的状态
export const QueryEvaluationTaskStatusOne = `/evaluation/queryEvaluationTaskStatusOne`
// 投票浏览和参与数目
export const EditVoteInvolvedAndBrowse = `/vote/editVoteInvolvedAndBrowse post`

View File

@@ -30,7 +30,7 @@ export function usePage(_url, param, callback) {
state.total = r.data.total
state.current = r.data.current
state.loading = false
callback(r)
callback && callback(r)
})
}
@@ -41,7 +41,7 @@ export function usePage(_url, param, callback) {
};
}
export function useRequest(_url, params = {}) {
export function useRequest(_url, params = {}, callback) {
const state = reactive({
data: {},
@@ -58,6 +58,7 @@ export function useRequest(_url, params = {}) {
request(_url, params).then(r => {
state.data = r.data
state.loading = false
callback&&callback(r)
})
}
@@ -97,7 +98,7 @@ export async function request(_url, params) {
}).then(resp => resp.data).then(response => {
if (response.code !== 200 && response.code !== 0) {
if (response.code === 1000) {
(import.meta.env.MODE === 'development' || import.meta.env.MODE === 'test') ? router.push({path: '/login'}) : window.open(import.meta.env.VITE_BASE_LOGIN_URL, '_top')
(import.meta.env.MODE === 'development' || import.meta.env.MODE === 'test') ? router.push({path: '/login'}) : window.open(window.location.protocol + import.meta.env.VITE_BASE_LOGIN_URL, '_top')
}
if (response.code === 2001) {
router.push({path: '/FaceTeachSignUp', query: {courseId: router.currentRoute.value.query.courseId,type:3}})
@@ -149,3 +150,13 @@ export async function boeRequest(_url, params) {
return JSONBigIntStr.parse(res)
})
}
const httpupload = axios.create({
baseURL: process.env.VUE_APP_BASE_API,
timeout: 1000 * 15,
headers: { "Content-Type": "multipart/form-data" },
});
export const fileUp = (data) => httpupload.post( import.meta.env.VITE_BASE_API+"/file/upload", data, {
headers: { "Content-Type": "multipart/form-data" },
});

53
src/api/useCommon.js Normal file
View File

@@ -0,0 +1,53 @@
import {useRoute, useRouter} from "vue-router/dist/vue-router";
import {useStore} from "vuex";
import {TASK_TYPES} from "@/api/CONST";
import {computed, watchEffect} from "vue";
export function useTaskPage() {
const router = useRouter()
const {query: {id: taskId, type, infoId}} = useRoute()
const {state, dispatch} = useStore()
const info = computed(() => type == 1 ? state.projectInfo : state.routerInfo)
const taskList = computed(() => type == 1 ? info.value.stageProcessList.flatMap(t => t.taskProcessList.map(s => ({
...s,
stageId: t.id,
stageName: t.name
}))) : info.value.taskBoList)
const index = computed(() => taskList.value?.findIndex(t => t.id == taskId))
const hasPrev = computed(() => index.value - 1 > 0)
const hasNext = computed(() => taskList.value.length > index.value)
type == 1 ? dispatch('getProjectInfo', {projectId: infoId}) : dispatch('getRouterInfo', {routerId: infoId})
function nextPage() {
toPage(taskList.value[index.value + 1])
}
function prevPage() {
toPage(taskList.value[index.value - 1])
}
function toPage(d) {
if (typeof TASK_TYPES.path[d.type] === "string") {
TASK_TYPES.path[d.type] && TASK_TYPES.path[d.type].startsWith("http") && window.open(TASK_TYPES.path[d.type] + d.targetId, '_top');
TASK_TYPES.path[d.type] && TASK_TYPES.path[d.type].startsWith("/") && router.push({
path: TASK_TYPES.path[d.type],
query: {
id: d.id,
type: type,
infoId: info.id,
courseId: d.courseId,
pName: info.name,
sName: d.stageName,
chapterOrStageId: d.stageId,
btype: type
},
});
} else if (typeof TASK_TYPES.path[d.type] === "function") {
TASK_TYPES.path[d.type](d);
}
}
return {hasPrev, hasNext, nextPage, prevPage}
}

View File

@@ -21,8 +21,12 @@ export function useUserInfo(id) {
watch(id, () => {
id.value && boeRequest(GET_USER_LIST, {id: id.value}).then(res => {
userInfo.value = res.result.userInfoList[0]
userInfo.value.avatar = userInfo.value.avatar?userInfo.value.avatar:'/800e23f7-b58c-4192-820d-0c6a2b7544cc.png'
userInfo.value.avatar = userInfo.value.avatar?userInfo.value.avatar.includes('upload')?userInfo.value.avatar:'/upload'+userInfo.value.avatar:'/800e23f7-b58c-4192-820d-0c6a2b7544cc.png'
})
})
return userInfo
}
export function IsPhone() {
return /mobile/i.test(navigator.userAgent);
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

View File

Before

Width:  |  Height:  |  Size: 65 KiB

After

Width:  |  Height:  |  Size: 65 KiB

View File

Before

Width:  |  Height:  |  Size: 5.4 KiB

After

Width:  |  Height:  |  Size: 5.4 KiB

View File

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

BIN
src/assets/image/rank1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

BIN
src/assets/image/rank2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

BIN
src/assets/image/rank3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

BIN
src/assets/image/rankme.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@@ -1,21 +1,39 @@
<template>
<div class="pathDetail" v-if="visiable" :style="{background:`url('${back}') no-repeat`}">
<div v-for="(item,i) in detail.chapterDtoList" :key="i" class="cha"
<div
class="pathDetail"
v-if="visiable"
:style="{
background:`url('${imgAttr.backurl}') no-repeat`,
backgroundSize: 'contain'
}">
<div v-if="detail.chapterDtoList" v-for="(item,i) in detail.chapterDtoList.slice(0,8)" :key="i" class="cha"
:style="{top:`${imgAttr.positions[i]?.top - (current===i?5:0)}px`,left:`${imgAttr.positions[i]?.left - (current===i?10:0)}px`}">
<div @click="toDetail(i)"
class="nameClass"
:title="item.name"
:style="{background: `url('${current===i?currentBack:nameBack}')`,backgroundSize:'100%',width:`${current===i?107:93}px`,height:`${current===i?80:70}px`,lineHeight:'50px',color:'#FFF'}">
:style="{
background: `url('${current===i?imgAttr.currentBack:imgAttr.nameBack}')`,
backgroundSize:'100%',
width:`${current===i?107:93}px`,
height:`${current===i?imgAttr.cheightC:imgAttr.cheight}px`,
lineHeight:'50px',color: current===i?imgAttr.ccolors:imgAttr.colors}">
{{ item.name }}
</div>
</div>
</div>
</template>
<script setup>
import {computed, defineProps, ref, watch} from "vue";
import back from '@/assets/image/pathdetails/组 21.png'
import nameBack from '@/assets/image/pathdetails/组 23.png'
import currentBack from '@/assets/image/pathdetails/组 23(1).png'
import {computed, defineProps, ref} from "vue";
import {ElMessage} from "element-plus";
import back from '@/assets/image/pathdetails/pathDetailBack.png'
import nameBack from '@/assets/image/pathdetails/pathDetailImg.png'
import currentBack from '@/assets/image/pathdetails/pathDetailImgSelect.png'
import back1 from '@/assets/image/pathdetails/back1.png'
import nameBack1 from '@/assets/image/pathdetails/nameBack1.png'
import currentBack1 from '@/assets/image/pathdetails/currentBack1.png'
import back2 from '@/assets/image/pathdetails/back2.png'
import nameBack2 from '@/assets/image/pathdetails/nameBack2.png'
import currentBack2 from '@/assets/image/pathdetails/currentBack2.png'
import {useRouter} from "vue-router/dist/vue-router";
const props = defineProps({
@@ -29,40 +47,125 @@ const props = defineProps({
const router = useRouter();
const visiable = ref(true)
const imageAttrs = {
'路径图背景-1671015331292.png': {
'路径图背景': {
width: 1437,
height: 594,
cheight:70,
cheightC:80,
backurl: back,
currentBack: currentBack,
nameBack: nameBack,
ccolors: '#FFF',
colors: '#FFF',
positions: [
{left: 63, top: 503},
{left: 828, top: 455},
{left: 268, top: 325},
{left: 1087, top: 183},
{left: 647, top: 84},
{left: 1180, top: 40},
{left: 50, top: 425},
{left: 440, top: 425},
{left: 400, top: 315},
{left: 515, top: 220},
{left: 800, top: 200},
{left: 660, top: 115},
{left: 760, top: 35},
{left: 1000, top: 25},
]
},
'路径图2': {
width: 1437,
height: 594,
cheight:100,
cheightC:106,
backurl: back2,
currentBack: currentBack2,
nameBack: nameBack2,
ccolors: '#FFF3E5',
colors: '#FFF',
positions: [
{left: 40, top: 380},
{left: 160, top: 290},
{left: 330, top: 270},
{left: 440, top: 200},
{left: 610, top: 170},
{left: 780, top: 130},
{left: 890, top: 60},
{left: 1060, top: 30},
]
},
'路径图3': {
width: 1437,
height: 594,
cheight:70,
cheightC:80,
backurl: back1,
currentBack: currentBack1,
nameBack: nameBack1,
ccolors: '#FFF',
colors: '#A06438',
positions: [
{left: 20, top: 390},
{left: 210, top: 380},
{left: 320, top: 275},
{left: 485, top: 265},
{left: 645, top: 220},
{left: 820, top: 180},
{left: 960, top: 150},
{left: 1050, top:60},
]
}
}
const imgAttr = computed(() => imageAttrs[Object.keys(imageAttrs).find(e => props.img.includes(e))] || {})
const current = computed(() => props.detail.chapterDtoList.findIndex(e => e.chapterId === props.detail.currentStageId))
const imgAttr = computed(() => imageAttrs[Object.keys(imageAttrs).find(e => props.img&&props.img.includes(e))] || {})
console.log(imgAttr)
const current = computed(() => props.detail.chapterDtoList.findIndex(e => e.id === props.detail.currentStageId))
function show() {
visiable.value = true
}
function toDetail(i) {
if (current.value !== i) {
return
// 预览和学习设置
let previewSetting = props.detail.previewSetting;
let studySetting = props.detail.studySetting;
let isStudy = false;
let chapterId = props.detail.chapterDtoList[i].id
console.log(studySetting)
if(previewSetting==null){
// 如果未设置预览 则只可以看当前关卡 其余关卡不让点击
if (current.value !== i) {
ElMessage.warning("当前关卡不可预览");
return
}
isStudy = true;
}else{
if (current.value !== i) {
let lookArr = [];
lookArr = previewSetting.split(',')
if((i+1)>=lookArr[0] && (i+1)<=lookArr[1]){
if(studySetting!==null){
let studyArr = [];
studyArr = studySetting.split(',')
if((i+1)>=studyArr[0] && (i+1)<=studyArr[1]){
isStudy = true;
}else{
isStudy = false;
}
}else{
isStudy = false;
}
}else{
ElMessage.warning("当前关卡不可预览");
return
}
}else{
isStudy = true;
}
}
(import.meta.env.MODE === "development" || import.meta.env.MODE === "test")
? router.push({
path: "/pathdetails",
query: {routerId: props.detail.routerId, routerName: props.detail.routerName},
query: {routerId: props.detail.id, routerName: props.detail.name, isStudy, chapterId},
})
: window.open(
`${import.meta.env.VITE_BOE_PATH_DETAIL_URL}/pathdetails&params=${encodeURIComponent(
`routerId=${props.detail.routerId}&routerName=${props.detail.routerName}`
`${window.location.protocol + import.meta.env.VITE_BOE_PATH_DETAIL_URL}/pathdetails&params=${encodeURIComponent(
`routerId=${props.detail.id}&routerName=${props.detail.name}&chapterId=${chapterId}&studySetting=${studySetting}`
)}`
,'_top');
}
@@ -73,8 +176,9 @@ function close() {
</script>
<style lang="scss">
.pathDetail {
width: 100%;
width: 1232px;
height: 1011px;
min-width: 1232px;
position: relative;
}

View File

@@ -0,0 +1,94 @@
<template>
<el-upload
ref="imageRef"
:file-list="files"
:show-file-list="false"
:limit="max"
:action="FILE_UPLOAD_ANNEX"
:auto-upload="false"
:on-exceed="exceed"
:on-change="handleChange">
<template #trigger>
<div>
<slot></slot>
</div>
</template>
</el-upload>
</template>
<script setup>
import { defineProps, ref, watch } from "vue";
import { ElMessage } from "element-plus";
import { computed } from "vue";
import { useStore } from "vuex";
import { FILE_UPLOAD_ANNEX } from "@/api/api";
const store = useStore();
const userInfo = computed(() => store.state.userInfo);
const props = defineProps({
value: [],
max: {
type: Number,
default: 1
}
})
const emit = defineEmits()
const files = ref([])
const imageRef = ref()
watch(props.value, () => {
props.value.length || (files.value = props.value)
})
function exceed() {
ElMessage.error(`只能上传${props.max}个附件`);
}
function handleChange(file) {
let fileName = userInfo.value.realName + '-' + userInfo.value.userNo + '-' + file.name;
let f = new File([file.raw],fileName);
f.uid = file.uid;
file.raw = f;
console.log(file.raw)
imageRef.value.submit();
if (file.response && file.response.code === 200) {
file.url = file.response.data
}
const index = files.value.findIndex(f => f.uid === file.uid)
if (index === -1) {
files.value.unshift(file)
} else {
files.value[index] = file
}
emit('update:value', files.value)
}
function remove(i) {
files.value.splice(i, 1)
console.log(imageRef)
}
function clearFiles() {
imageRef.value.clearFiles();
}
function reUpload(i) {
if (files.value[i].status === 'ready' || files.value[i].status === 'uploading') {
imageRef.value.abort(files.value[i].raw)
files.value[i].status = 'abort';
} else if (files.value[i].status === 'fail' || files.value[i].status === 'abort') {
imageRef.value.handleStart(files.value[i].raw)
imageRef.value.submit()
}
}
function abort(i) {
imageRef.value.abort(files.value[i].raw)
}
defineExpose({ reUpload, remove, clearFiles })
</script>

View File

@@ -0,0 +1,81 @@
<!-- 上传评论图片 -->
<template>
<el-upload :file-list="files" :action="FILE_UPLOAD_IMG" method="POST" :show-file-list="false" :on-change="handleChange"
:limit="max" ref="imageRef" :on-exceed="exceed">
<template #trigger>
<div>
<slot></slot>
</div>
</template>
</el-upload>
</template>
<script setup>
import { FILE_UPLOAD_IMG } from "@/api/api";
import { defineProps, ref, watch } from "vue";
import { ElMessage } from "element-plus";
const props = defineProps({
value: [],
max: {
type: Number,
default: 10
}
})
const emit = defineEmits()
const files = ref([])
const imageRef = ref()
watch(props.value, () => {
props.value.length || (files.value = props.value)
})
function exceed() {
ElMessage.error(`只能上传${props.max}个附件`);
}
function handleChange(e) {
if (e.response && e.response.code === 200) {
e.url = e.response.data
// console.log(e)
emit('fileUploadValue', e)
}
const index = files.value.findIndex(f => f.uid === e.uid)
if (index === -1) {
files.value.unshift(e)
} else {
files.value[index] = e
}
emit('update:value', files.value)
}
function remove(i) {
files.value.splice(i, 1)
console.log(imageRef)
}
function clearFiles() {
imageRef.value.clearFiles();
}
function reUpload(i) {
console.log(i)
if (files.value[i].status === 'ready' || files.value[i].status === 'uploading') {
imageRef.value.abort(files.value[i].raw)
files.value[i].status = 'abort';
} else if (files.value[i].status === 'fail' || files.value[i].status === 'abort') {
imageRef.value.handleStart(files.value[i].raw)
imageRef.value.submit()
}
}
function abort(i) {
imageRef.value.abort(files.value[i].raw)
}
defineExpose({ reUpload, remove, clearFiles })
</script>

View File

@@ -1,15 +1,89 @@
import {createStore} from 'vuex'
import {createStore} from "vuex";
import {PROJECT_PROCESS, ROUTER_PROCESS} from "@/api/api";
import {request} from "@/api/request";
import {TASK_TYPES} from "@/api/CONST";
export default createStore({
state: {
userInfo: {}
state: {
userInfo: {},
projectInfo: {},
routerInfo: {}
},
getters: {},
mutations: {
SET_USER(state, userInfo) {
state.userInfo = userInfo;
},
getters: {},
mutations: {
SET_USER(state, userInfo) {
state.userInfo = userInfo
},
SET_PROJECT_INFO(state, info) {
state.projectInfo = info;
},
actions: {},
modules: {}
})
INIT_PROJECT_INFO(state) {
if (state.projectInfo.status === -1) {
state.projectInfo.stageProcessList.forEach((t) => {
t.statusName = "已结束";
t.taskProcessList?.forEach((s) => s.statusName = "已结束");
});
return;
}
if (state.projectInfo.unlockMode === 1) {
state.projectInfo.stageProcessList.forEach((t) => {
t.statusName = "进行中";
t.taskProcessList?.forEach((s) => s.statusName = (s.status === 1) ? "已完成" : TASK_TYPES.toName[s.type]);
t.taskProcessList?.every((s) => s.status === 1) && (t.statusName = "已完成");
});
return;
}
state.projectInfo.stageProcessList?.some((t) => {
t.statusName = "已完成";
const stageState = t.taskProcessList?.some((s) => {
s.unlock = true;
s.statusName = "已完成";
s.status === 2 ? (s.statusName = "进行中") : (!s.status && (s.statusName = TASK_TYPES.toName[s.type]));
return state.projectInfo.unlockMode === 2 ? s.status !== 1 : (s.status !== 1 && s.flag);
});
stageState && (t.statusName = "进行中");
return stageState;
});
},
SET_ROUTER_INFO(state, info) {
state.routerInfo = info;
},
INIT_ROUTER_INFO(state) {
// state.routerInfo.unlockMode 1自由模式 2闯关模式 3 闯关模式 必修 flag true
if (state.routerInfo.status === -1) {
state.routerInfo.statusName = "已结束";
state.routerInfo.taskBoList.forEach((t) => t.statusName = "已结束");
return;
}
state.routerInfo.statusName = "进行中";
if (state.routerInfo.unlockMode === 1) {
state.routerInfo.taskBoList?.forEach((s) => s.statusName = (s.status === 1) ? "已完成" : TASK_TYPES.toName[s.type]);
state.routerInfo.taskBoList?.every((s) => s.status === 1) && (state.routerInfo.statusName = "已完成");
return;
}
state.routerInfo.statusName = "已完成";
state.routerInfo.taskBoList?.some((s) => {
s.unlock = true;
s.statusName = "已完成";
s.status === 2 ? (s.statusName = "进行中") : (!s.status && (s.statusName = TASK_TYPES.toName[s.type]));
// s.status !== 1 && (s.statusName = TASK_TYPES.toName[s.type]);
return state.routerInfo.unlockMode === 2 ? s.status !== 1 : (s.status !== 1 && s.flag);
}) && (state.routerInfo.statusName = "进行中");
},
},
actions: {
getProjectInfo(content, { projectId }) {
request(PROJECT_PROCESS, { projectId, type: 1 }).then(res => {
content.commit("SET_PROJECT_INFO", res.data);
content.commit("INIT_PROJECT_INFO");
});
},
getRouterInfo(content, { routerId, chapterId }) {
request(ROUTER_PROCESS, chapterId ? { routerId, type: 2, chapterId } : { routerId, type: 2 }).then(res => {
content.commit("SET_ROUTER_INFO", res.data);
content.commit("INIT_ROUTER_INFO");
});
},
},
modules: {}
});

View File

@@ -1,4 +1,5 @@
<template>
<div style=" background: #0078fc;height: 150px;width: 100%;position: absolute;top: 0;z-index:-9999;"></div>
<div class="moreactive" style="padding: 30px">
<!-- 面包屑导航 -->
<div class="crumb">
@@ -7,19 +8,28 @@
<div>{{ sName }}</div>
<div style="margin-left: 6px; margin-right: 6px">/</div>
<div style="font-weight: 700; font-size: 16px">投票详情</div>
<!--
<div class="preNext">
<button class="btn btn01"></button>
<span class="content" style="margin-left: 6px">上一个</span>
<span class="content" style="margin-left: 31px">一个</span>
<button class="btn btn02" style="margin-left: 6px"></button>
<span @click="prevPage" v-if="hasPrev">
<button class="btn btn01"></button>
<span class="content" style="margin-left: 6px">一个</span>
</span>
<span @click="nextPage" v-if="hasNext">
<span class="content" style="margin-left: 31px">下一个</span>
<button class="btn btn02" style="margin-left: 6px"></button>
</span>
</div>
<div class="return">
<div style="display: flex" @click="returnclick">
<el-button style="color: #0073fb">
<img
class="img2"
style="margin-right: 11px; cursor: pointer"
src="../../assets/image/return.png"
/>返回
</el-button
>
</div>
</div>
-->
<div class="return">
<div style="display: flex" @click="returnclick">
<el-button style="color:#0073FB"> <img class="img2" style="margin-right:11px;cursor: pointer;" src="../../assets/image/return.png" />返回</el-button>
</div>
</div>
</div>
<!-- 面包屑导航 -->
<div class="debateTitle">投票{{ dataInfo?.voteName }}</div>
@@ -30,8 +40,8 @@
<div class="left">
<div class="title">
<img
style="width: 20px; height: 20px"
src="../../assets/image/yuan.png"
style="width: 20px; height: 20px"
src="../../assets/image/yuan.png"
/>
<div class="text">参与情况</div>
<div class="box"></div>
@@ -40,73 +50,80 @@
<div class="all">
<div class="item allbox1">
<div class="item1" style="color: #089dff">
{{
dataInfo.numberOfInvolved || dataInfo.numberOfInvolved == 0
? dataInfo.numberOfInvolved
: "-"
}}
{{ dataInfo.numberOfInvolved || "-" }}
</div>
<div class="item2">参与数</div>
</div>
<div class="item allbox2">
<div class="item1" style="color: #387df7">
{{
dataInfo.votesTotal || dataInfo.votesTotal == 0
? dataInfo.votesTotal
: "-"
}}
{{ dataInfo.votesTotal || "-" }}
</div>
<div class="item2">总票数</div>
</div>
<div class="item allbox3">
<div class="item1" style="color: #00c6ff">
{{
dataInfo.numberOfBrowse || dataInfo.numberOfBrowse == 0
? dataInfo.numberOfBrowse
: "-"
}}
{{ dataInfo.numberOfBrowse || "-" }}
</div>
<div class="item2">浏览数</div>
</div>
</div>
<div class="title">
<img
style="width: 20px; height: 20px"
src="../../assets/image/yuan.png"
style="width: 20px; height: 20px;border-radius: 5px"
src="../../assets/image/yuan.png"
/>
<div class="text">参与投票</div>
<div class="box"></div>
</div>
<div class="join">
<div
v-for="(item, index) in dataInfo.ballotVo?.voteStemVoList"
:key="index"
style="margin-bottom: 41px"
v-for="(item, index) in dataInfo.voteStemDtoList"
:key="index"
style="margin-bottom: 10px"
>
<div class="stem">
<div>{{ item.orderNumber }}</div>
<div>{{ index + 1 }}</div>
<div>{{ item.voteStemName }}</div>
</div>
<div class="options">
<div class="options" :style="item.optionDetailList?.some(t=>t.optionPictureAddress)?'display:flex;':'display:block;'">
<div
v-for="(value, key) in item.optionDetailList"
:key="key"
style="
width: 140px;
v-for="(value, key) in item.optionDetailList"
:key="key"
style="
margin-right: 114px;
margin-bottom: 25px;
"
>
<img
style="width: 140px; height: 140px; border-radius: 8px"
:src="value.optionPictureAddress"
v-if="value.optionPictureAddress"
style="width: 140px; height: 140px; border-radius: 8px"
:src="value.optionPictureAddress"
/>
<div class="radio">
<label>
<input type="radio" name="one" value="right"/>
<div class="option"></div>
<label @click="choiceQuestion(item,value)">
<div class="radio-img">
<div
v-if="value.isAnswer"
style="
width: 10px;
height: 10px;
background: #4a9cf8;
position: relative;
left: 15px;
border-radius: 10px;
"></div>
<div
v-else
style="
width: 10px;
height: 10px;
background: #fff;
position: relative;
left: 15px;
border-radius: 10px;
"></div>
<div class="option"></div>
</div>
<div class="opt-text">{{ value.optionName }}</div>
</label>
</div>
@@ -115,97 +132,128 @@
</div>
</div>
<div
style="
style="
width: 100%;
display: flex;
justify-content: center;
margin-top: 30px;
"
>
<button class="submitbtn btn01" @click="submitVote">提交</button>
">
<button
class="submitbtn btn01"
:style="{ background: new Date().getTime() > new Date(dataInfo.voteEndTime).getTime() ||new Date().getTime() < new Date(dataInfo.voteStartTime).getTime() ? '#ccc': dataInfo.isSubmit? '#ccc': '', }" @click="submitVote(dataInfo)">
{{ dataInfo.isSubmit ? "已提交" : "提交" }}
</button>
</div>
</div>
<div class="right">
<div class="righttitle">
<img
style="width: 20px; height: 20px"
src="../../assets/image/yuan.png"
style="width: 20px; height: 20px"
src="../../assets/image/yuan.png"
/>
<div class="text">投票时间</div>
<div class="box"></div>
</div>
<div class="timebox clearfix">
<div class="innertime">
{{
dataInfo?.voteStartTime
}}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{{
dataInfo?.voteEndTime
}}
{{dataInfo?.voteStartTime }}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{{dataInfo?.voteEndTime }}
</div>
<div class="endtime clearfix">
<div class="endtimetext">
距离结束还有&nbsp;&nbsp;
<span class="te">{{
parseInt(
dayjs(dataInfo?.voteEndTime).diff(dayjs(), "minute") / 60
)
}}</span
>&nbsp;&nbsp; 小时&nbsp;&nbsp;<span class="te">{{
dayjs(dataInfo?.voteEndTime).diff(dayjs(), "minute") % 60
}}</span
>&nbsp;&nbsp;分钟
</div>
parseInt(dayjs(dataInfo?.voteEndTime).diff(dayjs(), "minute") / 60)}}</span>&nbsp;&nbsp; 小时&nbsp;&nbsp;<span class="te">{{dayjs(dataInfo?.voteEndTime).diff(dayjs(), "minute") % 60 }}</span>&nbsp;&nbsp;分钟</div>
</div>
</div>
<div class="righttitle">
<img
style="width: 20px; height: 20px"
src="../../assets/image/yuan.png"
style="width: 20px; height: 20px"
src="../../assets/image/yuan.png"
/>
<div class="text">投票说明</div>
<div class="box"></div>
</div>
<div class="explain clearfix">
<div
class="explaincontent"
v-html="
dataInfo?.voteExplain ? dataInfo?.voteExplain : '暂无说明'
"
></div>
class="explaincontent"
v-html="dataInfo?.voteExplain||'暂无说明'"></div>
</div>
</div>
</div>
</div>
</div>
<!-- 详细信息 -->
</div>
</template>
<script setup>
import {useRequest} from "@/api/request";
import {
VOTE_DETAIL2,
} from "@/api/api";
import {VOTE_DETAIL3, VOTE_DETAIL_SUBMIT, EditVoteInvolvedAndBrowse} from "@/api/api";
import dayjs from "dayjs";
import {useRoute} from "vue-router/dist/vue-router";
import {watch, reactive, toRefs} from "vue";
// const { data } = useRequest(TASK_VOTE_DETAIL, {});
// console.log("datadatadata", data);
// const state = reactive({
// votedetail: null,
// });
// let { votedetail } = toRefs(state);
const {
query: {courseId, pName, sName},
} = useRoute();
//获取基本信息
const {data: dataInfo} = useRequest(VOTE_DETAIL2(courseId));
import store from "@/store";
import {ElMessage} from "element-plus";
import {useRoute, useRouter} from "vue-router/dist/vue-router";
import {computed,watch} from "vue";
import {useTaskPage} from "@/api/useCommon";
const {
query: { courseId, pName, sName, chapterOrStageId, infoId, id, btype, type },
} = useRoute();
const { nextPage, prevPage, hasPrev, hasNext } = useTaskPage();
const router = useRouter();
const returnclick = () => {
router.back();
};
const { data: dataInfo } = useRequest(VOTE_DETAIL3(courseId), {type});
const userInfo = computed(() => store.state.userInfo);
const answerTime = dayjs(new Date()).format("YYYY-MM-DD HH:mm:ss");
// 增加浏览量
watch(dataInfo, () => {
useRequest(EditVoteInvolvedAndBrowse, {operationType:'2', voteId:dataInfo.value.id });
})
// 选择题目
const choiceQuestion = (item, value) => {
if (dataInfo.value.isSubmit) {
return;
}
item.optionDetailList?.forEach(t => t.isAnswer = false);
value.isAnswer = true;
};
// 提交投票
const submitVote = () => {
let nowTime = new Date().getTime();
let maxTime = new Date(dataInfo.value.voteEndTime).getTime();
let minTime = new Date(dataInfo.value.voteStartTime).getTime();
// 当未到开始时间
if (nowTime < minTime || nowTime > maxTime) {
ElMessage.error("未到投票开始时间");
return;
}
// 当已经提交过时候 不让提交即可
if (dataInfo.value.isSubmit) {
return;
}
if (dataInfo.value.voteStemDtoList.some(t => t.optionDetailList.every(s => !s.isAnswer))) {
ElMessage.error("请选择投票问题后进行提交");
return;
}
dataInfo.value.isSubmit = !dataInfo.value.isSubmit;
ElMessage.success("投票成功");
let obj = {
beginTime: answerTime,
chapterOrStageId: chapterOrStageId ? chapterOrStageId : 0,
result: JSON.stringify(dataInfo.value),
targetId: infoId, // 项目 路径图 id
taskId: id,
type: btype, // 1 项目 2 路径图
voteId: dataInfo.value.id,
voteName: dataInfo.value.voteName,
};
useRequest(VOTE_DETAIL_SUBMIT, obj);
// 增加参与数目
useRequest(EditVoteInvolvedAndBrowse, {operationType:'1', voteId:dataInfo.value.id });
};
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="scss">
.clearfix:before,
@@ -223,16 +271,19 @@ const submitVote = () => {
line-height: 24px;
position: relative;
}
.return{
.return {
position: absolute;
right: 10%;
.text{
.text {
text-align: center;
display: flex;
flex-direction: row;
align-items: center;
display: flex;
flex-direction: row;
align-items: center;
}
}
.preNext {
position: absolute;
right: 0px;
@@ -412,26 +463,26 @@ const submitVote = () => {
.allbox1 {
margin-right: 22px;
background: linear-gradient(
0deg,
rgba(160, 193, 230, 0) 0%,
rgba(161, 195, 231, 0.2) 100%
0deg,
rgba(160, 193, 230, 0) 0%,
rgba(161, 195, 231, 0.2) 100%
);
}
.allbox2 {
margin-right: 22px;
background: linear-gradient(
0deg,
rgba(177, 219, 229, 0) 0%,
rgba(172, 216, 227, 0.2) 100%
0deg,
rgba(177, 219, 229, 0) 0%,
rgba(172, 216, 227, 0.2) 100%
);
}
.allbox3 {
background: linear-gradient(
0deg,
rgba(195, 209, 234, 0) 0%,
rgba(191, 206, 231, 0.2) 100%
0deg,
rgba(195, 209, 234, 0) 0%,
rgba(191, 206, 231, 0.2) 100%
);
}
@@ -485,21 +536,34 @@ const submitVote = () => {
margin-top: 14px;
margin-left: -16px;
position: relative;
.radio-img{
display: flex;
align-items: center;
}
}
.radio label {
width:100%;
line-height: 20px;
position: relative;
display: flex;
align-items: center;
text-align: center;
display: grid;
grid-template-columns: 40px 1fr;
justify-content: center;
height: 35px;
font-weight: normal;
.opt-text {
justify-self: stretch;
font-size: 14px;
font-weight: bold;
color: #333330;
line-height: 18px;
margin-left: 10px;
align-self: center;
overflow: hidden;
white-space: nowrap;
cursor: pointer;
text-overflow: ellipsis;
text-align: left;
}
}
@@ -510,9 +574,8 @@ const submitVote = () => {
// top: 1px;
// // top: 32px;
// left: 0px;
background-size: cover;
background-size: 100%;
background: url(../../assets/image/noselect.png) no-repeat;
background-size: cover;
}
.radio input[type="radio"] {

View File

@@ -7,13 +7,16 @@
<div>{{ sName }}</div>
<div style="margin-left: 6px; margin-right: 6px">/</div>
<div style="font-weight: 700; font-size: 16px">辩论详情</div>
<!--
<div class="preNext">
<button class="btn btn01"></button>
<span class="content" style="margin-left: 6px">上一个</span>
<span class="content" style="margin-left: 31px">一个</span>
<button class="btn btn02" style="margin-left: 6px"></button>
</div>-->
<span @click="prevPage" v-if="hasPrev">
<button class="btn btn01"></button>
<span class="content" style="margin-left: 6px">一个</span>
</span>
<span @click="nextPage" v-if="hasNext">
<span class="content" style="margin-left: 31px">下一个</span>
<button class="btn btn02" style="margin-left: 6px"></button>
</span>
</div>
<div class="return">
<div style="display: flex" @click="returnclick">
<el-button style="color:#0073FB"> <img class="img2" style="margin-right:11px;cursor: pointer;" src="../../assets/image/return.png" />返回</el-button>
@@ -89,13 +92,14 @@ import { reactive, toRefs } from "vue";
import { useRequest } from "@/api/request";
import { TASK_VOTE_DETAIL, VOTE_DETAIL } from "@/api/api";
import { useRoute } from "vue-router/dist/vue-router";
import {useTaskPage} from "@/api/useCommon";
const {
query: { id: voteSubmitId, pName, sName },
} = useRoute();
const { data } = useRequest(TASK_VOTE_DETAIL, { voteSubmitId });
const { data: voteDetail } = useRequest(VOTE_DETAIL, { voteSubmitId });
const {nextPage,prevPage,hasPrev, hasNext} = useTaskPage()
const state = reactive({
activeName: "first",
});

View File

@@ -1,4 +1,5 @@
<template>
<div style=" background: #0078fc;height: 150px;width: 100%;position: absolute;top: 0;z-index:-9999;"></div>
<div class="surveydetail" style="padding: 30px">
<!-- 面包屑导航 -->
<div
@@ -11,23 +12,16 @@
<div style="margin-left: 6px; margin-right: 6px">/</div>
<div style="font-weight: 700; font-size: 16px">讨论详情</div>
</div>
<!--
<div class="prevnext">
<div class="prev">
<img
style="width: 23px; height: 23px"
src="../../assets/image/prev.png"
/>
<div style="margin-left: 7px">上一个</div>
</div>
<div class="prev" style="margin-left: 31px">
<div style="margin-right: 7px">下一个</div>
<img
style="width: 23px; height: 23px"
src="../../assets/image/next.png"
/>
</div>
</div>-->
<div class="preNext">
<span @click="prevPage" v-if="hasPrev">
<button class="btn btn01"></button>
<span class="content" style="margin-left: 6px">上一个</span>
</span>
<span @click="nextPage" v-if="hasNext">
<span class="content" style="margin-left: 31px">下一个</span>
<button class="btn btn02" style="margin-left: 6px"></button>
</span>
</div>
<div class="return">
<div style="display: flex" @click="returnclick">
<el-button style="color:#0073FB"> <img class="img2" style="margin-right:11px;cursor: pointer;" src="../../assets/image/return.png" />返回</el-button>
@@ -36,44 +30,40 @@
</div>
<!-- 面包屑导航 -->
<!-- 标题 -->
<div class="title">{{ info.name }}</div>
<div class="title">讨论{{ state.info.discussDtoList[0].discussName }}</div>
<!-- 标题 -->
<!-- 详细内容 -->
<div class="bascinfo clearfix">
<!-- 中间部分 -->
<div class="middletitle">
<div class="title">
{{ info.name }}
{{ state.info.discussDtoList[0].discussExplain }}
</div>
<!-- <button class="btn">发表帖子</button>-->
<button class="btn" @click="showPostModal">发表帖子</button>
</div>
<div>
<div class="line clearfix">
<div class="linetitle">{{ info.sName }}</div>
<div class="linetitle">{{ state.info.discussDtoList[0].discussName }}</div>
<div class="radi"></div>
<div class="intime">进行中</div>
</div>
<div class="allbtn">
<button :class="`btnone ${param.searchType == 1 ? 'active' : ''}`">
<button :class="`btnone ${state.searchType == 1 ? 'active' : ''}`" @click="nowPost(state.info.discussDtoList[0].id)">
最新
</button>
<button
:class="`btntwo ${param.searchType == 2 ? 'active' : ''}`"
style="margin-left: 20px"
>
:class="`btnone ${state.searchType == 2 ? 'active' : ''}`"
style="margin-left: 20px" @click="hotPost(state.info.discussDtoList[0].id)">
最热
</button>
</div>
<div
class="discusslist"
v-for="(d, j) in info?.discussDtoList"
:key="j"
>
<div class="itemtitle">{{ d.discussName }}</div>
<div class="itemdiscuss">
{{ d.discussExplain }}
</div>
v-for="(d, j) in state?.postList"
:key="j">
<div class="itemtitle" @click="comment(d)">{{ d.title }}</div>
<div class="itemdiscuss" @click="comment(d)" :v-html="d.content"></div>
<div class="allstar clearfix">
<div @click="comment(d)" style="display: flex; cursor: pointer">
<span class="iconfont icon-pinglun" style="color: #b3bdc4"></span>
@@ -83,37 +73,98 @@
<span
class="iconfont icon-dianzan"
:style="{
color: d.praised ? 'red' : '#b3bdc4',
color: d.praised ? '#2478ff' : '#b3bdc4',
marginLeft: '19px',
}"
></span>
<div class="count">{{ d.praiseNum || 0 }}</div>
<div class="count" :style="{color:d.praised ? '#2478ff' : '#b3bdc4'}">{{ d.praiseNum || 0 }}</div>
</div>
<div @click="collection(d)" style="display: flex; cursor: pointer">
<span
class="iconfont icon-shoucang"
:style="{
color: d.collected ? 'red' : '#b3bdc4',
color: d.collected ? '#2478ff' : '#b3bdc4',
marginLeft: '19px',
}"
></span>
<div class="count">{{ d.collectionNum || 0 }}</div>
<div class="count" :style="{color:d.collected ? '#2478ff' : '#b3bdc4'}">{{ d.collectionNum || 0 }}</div>
</div>
</div>
<div class="thinline"></div>
</div>
<div style="display:flex;justify-content:center;align-items:center;margin-top:36px;margin-bottom:36px;">
<!-- 分页 -->
<el-pagination
v-model:current-page="state.currentPage"
:page-size="state.pageSize"
:small="small"
layout="prev, pager, next, jumper"
:total="state.total"
@current-change="handleCurrentChange"
/>
</div>
</div>
</div>
<!-- 详细内容 -->
<!-- 富文本 -->
<el-dialog title="" top="" v-model="dialogVisible" :show-close="false" :loading="loading"
style="display:flex;justify-content:center;align-items:center;flex-direction: column;"
width="80%">
<div style="width:100%;margin-bottom: 12px;">
<el-input v-model="titleName" placeholder="请输入标题" />
</div>
<div style="border: 1px solid #ccc">
<Toolbar style="border-bottom: 1px solid #ccc" :editor="editorRef" :defaultConfig="toolbarConfig"
:mode="mode" />
<Editor style="height: 450px; overflow-y: hidden" v-model="valueHtml" :defaultConfig="editorConfig"
:mode="mode" @onCreated="handleCreated" />
</div>
<div style="width:100%;height:80px;display:flex;justify-content:center;align-items:center;margin-top:20px;">
<button
class="submitbtn btn01"
style="margin-right:40px;"
@click="cancelPost">
取消
</button>
<button
class="submitbtn btn01"
@click="postAdd">
发布
</button>
</div>
</el-dialog>
<!-- 富文本 -->
</div>
</template>
<script setup>
import { request, useRequest } from "@/api/request";
import { COMMENT_COLLECTION, COMMENT_PRAISE, DISCUSS_LIST } from "@/api/api";
import { reactive, ref, toRefs } from "vue";
import { useRoute, useRouter } from "vue-router";
import {
COMMENT_COLLECTION,
COMMENT_PRAISE,
DISCUSS_LIST,
QueryDiscussSubmitDetailByDiscussId,
FILE_UPLOAD,
PostAdd,
PostDelete,
PostUpdate,
PostList,
PostPraise,
PostCollection,
} from "@/api/api";
import "@wangeditor/editor/dist/css/style.css";
import { Editor, Toolbar } from "@wangeditor/editor-for-vue";
import { reactive, ref, toRefs, shallowRef, computed } from "vue";
import { useRoute, useRouter } from "vue-router";
import store from "@/store";
import { ElMessage } from "element-plus";
import { fileUp } from "../../api/request";
import {useTaskPage} from "@/api/useCommon";
import {ElLoading} from "element-plus";
const userInfo = computed(() => store.state.userInfo);
const router = useRouter();
const returnclick = () => {
router.back();
@@ -121,31 +172,195 @@ const returnclick = () => {
const {
query: { id, type, pName, sName },
} = useRoute();
const {nextPage,prevPage,hasPrev, hasNext} = useTaskPage()
const dialogVisible = ref(false);
const param = ref({
type,
id,
});
const { data: info } = useRequest(DISCUSS_LIST, param.value);
const titleName = ref("");
const loading = ref(false);
const state = reactive({
activeName: "first",
info:{},
pageNo:1,
pageSize:10,
searchType:1,
postList: [], //帖子列表
total:0, // 帖子总条数
currentPage: 1,
content: 1
});
function comment({ discussId: id }) {
router.push({ path: "discussdetail", query: { id, type } });
// 编辑器实例,必须用 shallowRef
const editorRef = shallowRef();
// 内容 HTML
const valueHtml = ref("");
const toolbarConfig = {
excludeKeys: ["insertVideo", "insertImage"],
};
const editorConfig = { placeholder: "请输入内容...", MENU_CONF: {} };
editorConfig.MENU_CONF["uploadImage"] = {
// 自定义上传
async customUpload(file, insertFn) {
const formData = new FormData();
console.log(1,file);
formData.append("file", file);
fileUp(formData).then((res) => {
if (res.data.code === 200) {
// 最后插入图片 url alt href
insertFn(import.meta.env.VITE_FILE_PATH+res.data.data, file.name, import.meta.env.VITE_FILE_PATH+res.data.data);
}
});
},
};
const handleCreated = (editor) => {
editorRef.value = editor; // 记录 editor 实例,重要!
};
request(DISCUSS_LIST, {
type,
id,
}).then(e=>{
state.info = e.data;
getPostList(e.data.discussDtoList[0].id);
}).catch(err=>{
console.log(err)
})
// 获取帖子
function getPostList(discussId) {
console.log('获取帖子参数', {
"pid": discussId,
"current": state.pageNo,
"order": 1
})
request(
PostList,
{
"pid": discussId,
"current": state.pageNo,
"order": state.content
}).then(e=>{
console.log('我是当前讨论下的帖子',e)
state.postList = e.data.records;
state.total = Number(e.data.total);
}).catch(err=>{
console.log(err)
})
}
// 最新
function nowPost(discussId) {
state.content = 1;
state.searchType = 1;
state.pageNo = 1;
state.currentPage = 1;
getPostList(discussId);
}
// 最热
function hotPost(discussId) {
state.content = 2;
state.searchType = 2;
state.pageNo = 1;
state.currentPage = 1;
getPostList(discussId);
}
// 分页
function handleCurrentChange(e, k) {
console.log('分页打印', e, k)
state.currentPage = e;
state.pageNo = e;
getPostList(state.info.discussDtoList[0].id);
}
// 评论点击跳转
function comment({ discussId: id, id: postID }) {
router.push({ path: "discussdetail", query: { id, type, pName, sName, postID, postName:state.info.discussDtoList[0].discussName } });
}
// 帖子点赞
function like(d) {
d.praised ? (d.praiseNum -= 1) : (d.praiseNum += 1);
d.praised ? ((d.praiseNum) = Number(d.praiseNum) - 1) : ((d.praiseNum) = Number(d.praiseNum) + 1);
d.praised = !d.praised;
request(COMMENT_PRAISE, { targetId: d.discussId, type: 3 });
console.log('我是点赞传递的参数', { targetId: d.id, type: 2 })
request(PostPraise, { targetId: d.id, type: 3 }).then(res=>{
console.log('我是点赞的操作',res)
}).catch(err=>{
console.log(err)
});
}
// 帖子收藏
function collection(d) {
d.collected ? (d.collectionNum -= 1) : (d.collectionNum += 1);
d.collected ? ((d.collectionNum) = Number(d.collectionNum) - 1) : ((d.collectionNum) = Number(d.collectionNum) + 1);
d.collected = !d.collected;
request(COMMENT_COLLECTION, { targetId: d.discussId, type: 4 });
console.log('我是收藏传递的参数', { targetId: d.id, type: 2 })
request(PostPraise, { targetId: d.id, type: 4 }).then(res=>{
console.log('我是收藏的操作',res)
}).catch(err=>{
console.log(err)
});
}
// 发表帖子弹框显示
function showPostModal() {
dialogVisible.value = true;
// 隐藏视频上传
setTimeout(() => {
let nodeChilds = document.getElementsByClassName('w-e-bar-item');
nodeChilds[31].style.display = 'none';
}, 200);
}
// 取消发布
function cancelPost() {
dialogVisible.value = false;
}
// 发表帖子发布操作
const postAdd = () => {
if(titleName.value==''){
return ElMessage.warning("评论标题为空");
}
loading.value = ElLoading.service({
lock: true,
text: "Loading",
background: "rgba(0, 0, 0, 0.7)",
});
console.log('用户信息', userInfo.value)
let obj = {
"collectionNum": 0,
"commentNum": 0,
"content": valueHtml.value,
"ctime": "",
"discussId": state.info.discussDtoList[0].id,
"id": 0,
"type": type,
"taskId": id,
"mtime": "",
"praiseNum": 0,
"status": 0,
"title": titleName.value,
"userAvatar": userInfo.value.avatar,
"userId": userInfo.value.id,
"userJobName": userInfo.value.jobName,
"userName": userInfo.value.realName,
"userOrgName": userInfo.value.orgName
}
console.log('发表帖子传递的参数', obj)
request(PostAdd,obj).then(res=>{
console.log(res)
if(res.code==200){
dialogVisible.value = false;
ElMessage.success("发帖成功");
getPostList(state.info.discussDtoList[0].id);
titleName.value = "";
valueHtml.value = "";
loading.value.close()
}
}).catch(err=>{
console.log(err)
ElMessage.error("发帖失败");
loading.value.close()
})
}
</script>
@@ -156,9 +371,39 @@ function collection(d) {
display: table;
clear: both;
}
.preNext {
position: absolute;
right: 0px;
.content {
font-size: 14px;
color: #fff;
width: 43px;
height: 14px;
display: inline-block;
position: relative;
top: -6px;
cursor: pointer;
}
.btn {
width: 23px;
height: 23px;
border-radius: 50%;
border: 0;
cursor: pointer;
}
.btn01 {
background-image: url("../../assets/image/prev.png");
}
.btn02 {
background-image: url("../../assets/image/next.png");
}
}
.active {
color: red;
color: #2478ff;
}
.surveydetail {
@@ -320,6 +565,7 @@ function collection(d) {
font-weight: 500;
color: #333333;
margin-right: 88px;
cursor: pointer;
}
.itemdiscuss {
@@ -330,6 +576,7 @@ function collection(d) {
font-weight: 500;
color: #666666;
line-height: 24px;
cursor: pointer;
}
.allstar {

View File

@@ -1,4 +1,5 @@
<template>
<div style=" background: #0078fc;height: 150px;width: 100%;position: absolute;top: 0;z-index:-9999;"></div>
<div class="surveydetailpage" style="padding: 30px">
<!-- 面包屑导航 -->
<div
@@ -37,43 +38,37 @@
</div>
<!-- 面包屑导航 -->
<!-- 标题 -->
<div class="title">调研管理者进阶腾飞班 - 班内成员讨论</div>
<div class="title">讨论{{postName}}</div>
<!-- 标题 -->
<!-- 详细内容 -->
<div class="bascinfo clearfix">
<!-- 中间部分 -->
<div class="middletitle">
<div class="title">
{{ disDetail.projectName }}
{{ postName }}
</div>
<!-- <button class="btn">回复</button>-->
<button class="btn" @click="getFocus">回复</button>
</div>
<div class="line clearfix">
<div class="linetitle">{{ disDetail.stageName }}</div>
<div class="linetitle" :title="disDetail.title">{{ disDetail.title }}</div>
<div class="radi"></div>
<div class="intime">进行中</div>
</div>
<div class="discusscontent clearfix">
<div class="contenttop clearfix">
<div class="contenttitle">{{ disDetail.discussName }}</div>
<div class="contenttitle">{{ disDetail.title }}</div>
<div
@click="like()"
style="
display: flex;
cursor: pointer;
align-items: baseline;
margin-left: 20px;
"
>
style="display: flex;cursor: pointer;align-items: baseline;margin-left: 20px;">
<span
class="iconfont icon-dianzan"
:style="{
color: disDetail.praised ? 'red' : '#b3bdc4',
color: disDetail.praised ? '#2478ff' : '#b3bdc4',
marginLeft: '19px',
}"
></span>
<div class="count">{{ disDetail.praiseNum || 0 }}</div>
<div class="count" :style="{color:disDetail.praised ? '#2478ff' : '#b3bdc4'}">{{ disDetail.praiseNum || 0 }}</div>
</div>
<div
@click="collection()"
@@ -81,21 +76,22 @@
display: flex;
cursor: pointer;
align-items: baseline;
margin-left: 20px;
"
>
margin-left: 20px;">
<span
class="iconfont icon-shoucang"
:style="{
color: disDetail.collected ? 'red' : '#b3bdc4',
color: disDetail.collected ? '#2478ff' : '#b3bdc4',
marginLeft: '19px',
}"
></span>
<div class="count">{{ disDetail.collectionNum || 0 }}</div>
<div class="count" :style="{color:disDetail.collected ? '#2478ff' : '#b3bdc4'}">{{ disDetail.collectionNum || 0 }}</div>
</div>
</div>
<div class="contentmid">
{{ disDetail.discussExplain }}
<!-- <Toolbar style="border-bottom: 1px solid #ccc" :editor="editorRef" :defaultConfig="toolbarConfig"
:mode="mode" /> -->
<Editor style="height: 450px; overflow-y: hidden" v-model="disDetail.content" :defaultConfig="editorConfig"
:mode="mode" @onCreated="handleCreated" />
</div>
</div>
</div>
@@ -103,6 +99,7 @@
<div class="bascinfor">
<div class="inputone">
<el-input
ref="refInput"
v-model="disComment.content"
:autosize="{ minRows: 5, maxRows: 5 }"
resize="none"
@@ -115,7 +112,7 @@
<div style="display: flex">
<div
class="allimg"
v-for="(img, i) in commentSubmitFileList"
v-for="(img, i) in fileListComment"
:key="i"
>
<div
@@ -130,26 +127,26 @@
</div>
<div class="uploadAnd">
<div class="btnone clearfix">
<UploadImg v-model="commentSubmitFileList">
<UploadPostImg v-model="commentSubmitFileList" @fileUploadValue="uploadBack">
<button class="btwwo">
<img class="image" src="../../assets/image/uploadimg.png" />
<div class="shangchuan">上传图片</div>
</button>
</UploadImg>
</UploadPostImg>
</div>
<button class="btntwo" @click="submitComment">发表</button>
<button class="btntwo" @click="submitComment" v-loading="submitLoading">发表</button>
</div>
</div>
<div class="thinline"></div>
<div class="bottom">
<div v-for="(row, i) in commontList" :key="i">
<div v-for="(row, i) in commontList" :key="i" style="margin-bottom: 24px;">
<div class="header">
<div class="avator"></div>
<div class="id">{{ row.userName }}</div>
<div class="showCareer">(显示事业)</div>
<div class="idThink">理性思考崇尚科学</div>
<img :src="row.studentAvatar" alt="" srcset="" class="avator">
<div class="id">{{ row.createName }}</div>
<div class="showCareer">{{row.studentJobName}}</div>
<div class="idThink"></div>
</div>
<div class="discuss clearfix">
<div class="discussmain clearfix">
@@ -157,6 +154,11 @@
{{ row.content }}
</div>
</div>
<div style="display:flex;margin-top: 12px;margin-bottom: 12px;">
<div v-if="row.img" v-for="(rowimg, index) in row.img.split(',')" :key="index" style="width:55px;height:55px;margin-right: 12px;">
<img class="image" style="width:55px;height:55px;border-radius: 4px;" :src="rowimg" />
</div>
</div>
<div class="intime">{{ row.ctime }}</div>
<div class="likeYou">
<div
@@ -171,76 +173,80 @@
</div>
<div
@click="commentLike(row)"
style="
display: flex;
cursor: pointer;
align-items: baseline;
margin-left: 19px;
"
>
style="display: flex;cursor: pointer;align-items: baseline;margin-left: 19px;">
<span
class="iconfont icon-dianzan"
:style="{ color: row.praised ? 'red' : '#b3bdc4' }"
></span>
<div class="count">{{ row.praiseNum || 0 }}</div>
:style="{ color: row.praised ? '#2478ff' : '#b3bdc4' }"></span>
<div class="count" :style="{color:row.praised ? '#2478ff' : '#b3bdc4'}">{{ row.praiseNum || 0 }}</div>
</div>
</div>
<div v-for="(replay, j) in row.children" :key="j">
<div class="reply">
<div class="sameava avaone"></div>
<div class="sameuser">{{ replay.userName }}</div>
<div class="centerreply">回复</div>
<div class="sameava avatwo"></div>
<div class="sameuser">{{ row.userName }}</div>
<div class="replytime">{{ replay.ctime }}</div>
</div>
<div class="allreplyimg">
<div class="singleimg"></div>
</div>
<div class="mainreply">
<div class="replydetail">
{{ replay.content }}
<!-- 评论下的回复 -->
<div v-if="row.children.length!==0" :style="{height:spreadReply==i ? 'auto' : 210 +'px',overflow:'hidden',position: 'relative'}">
<div v-for="(replay, j) in row.children" :key="j">
<div class="reply">
<img :src="replay.studentAvatar" alt="" srcset="" class="sameava avaone">
<div class="sameuser">{{ replay.studentName }}</div>
<div class="centerreply">回复</div>
<img :src="replay.targetStudentAvatar" alt="" srcset="" class="sameava avaone">
<div class="sameuser">{{ replay.targetStudentName }}</div>
<div class="replytime">{{ replay.createTime }}</div>
</div>
<div style="display:flex;margin-top: 12px;margin-bottom: 12px;">
<div v-if="replay.img" v-for="(rowimg, index) in replay.img.split(',')" :key="index" style="width:65px;height:65px;margin-right: 7px;">
<img class="image" style="width:65px;height:65px;border-radius: 4px;" :src="rowimg" />
</div>
</div>
<div class="mainreply">
<div class="replydetail">
{{ replay.content }}
</div>
<!-- <div class="talk"></div> -->
</div>
<div class="likeYou">
<div
@click="commentComment(replay)"
style="display: flex;cursor: pointer;align-items: baseline;">
<span
class="iconfont icon-pinglun"
:style="{ color: '#b3bdc4' }"></span>
<!-- <div class="count"> {{ replay.commentNum }}</div>-->
</div>
<div
style="display: flex; cursor: pointer; align-items: baseline;margin-left: 19px;"
@click="commentLike(replay)">
<span
class="iconfont icon-dianzan"
:style="{ color: replay.praised ? '#2478ff' : '#b3bdc4' }"></span>
<div class="count" :style="{color:replay.praised ? '#2478ff' : '#b3bdc4'}">{{ replay.praiseNum || 0 }}</div>
</div>
</div>
<!-- <div class="talk"></div> -->
</div>
<div class="likeYou">
<div
@click="commentComment(replay)"
style="
display: flex;
cursor: pointer;
align-items: baseline;
"
>
<!-- 查看更多 -->
<div style="display: flex;justify-content: center;align-items: center;position:absolute;bottom:0px;cursor: pointer;width:100%">
<span
class="iconfont icon-pinglun"
:style="{ color: '#b3bdc4' }"
></span>
<!-- <div class="count"> {{ replay.commentNum }}</div>-->
@click="lookMore(i)"
style="font-size: 14px;color: #2478ff;">{{ i==spreadReply ? '收起' : '查看更多' }}</span>
</div>
<div
@click="commentLike(replay)"
style="
display: flex;
cursor: pointer;
align-items: baseline;
margin-left: 19px;
"
>
<span
class="iconfont icon-dianzan"
:style="{ color: replay.praised ? 'red' : '#b3bdc4' }"
></span>
<div class="count">{{ replay.praiseNum || 0 }}</div>
</div>
</div>
</div>
</div>
</div>
<!-- 回复分页 -->
<div style="display:flex;justify-content:center;align-items:center;margin-top:36px;margin-bottom:36px;">
<!-- 分页 -->
<el-pagination
v-model:current-page="hfPage.currentPage"
:page-size="hfPage.pageSize"
:small="small"
layout="prev, pager, next, jumper"
:total="hfPage.total"
@current-change="handleCurrentChange"
/>
</div>
<div
class="discuss clearfix"
v-if="commontList && commontList.length"
>
v-if="commontList && commontList.length">
<div class="inreply">
<el-input
v-model="replayComment.content"
@@ -253,7 +259,7 @@
<div class="words">{{ replayComment.content.length }}/100</div>
<div class="upload">
<div style="display: flex">
<div class="allimg" v-for="(img, i) in fileList" :key="i">
<div class="allimg" v-for="(img, i) in fileListCommentRelpay" :key="i">
<div
class="imgone"
:style="{
@@ -265,7 +271,7 @@
</div>
</div>
<datagrid class="uploadAnd">
<UploadImg v-model="fileList">
<UploadPostImg v-model="fileListCommentRelpay" @fileUploadValue="uploadReplyBack">
<button class="btnone clearfix">
<img
class="image"
@@ -273,8 +279,8 @@
/>
<div class="shangchuan">上传图片</div>
</button>
</UploadImg>
<button class="btntwo" @click="submitReplayComment">
</UploadPostImg>
<button class="btntwo" @click="submitReplayComment" style="top:206px;" v-loading="submitReplayLoading">
发表
</button>
</datagrid>
@@ -282,14 +288,19 @@
</div>
</div>
</div>
</div>
</div>
<!-- 详细内容 -->
</div>
</template>
<script setup>
import { reactive, ref, toRefs } from "vue";
import { useRoute } from "vue-router/dist/vue-router";
import { reactive, ref, toRefs, shallowRef } from "vue";
import { useRoute, useRouter } from "vue-router/dist/vue-router";
import "@wangeditor/editor/dist/css/style.css";
import { Editor, Toolbar } from "@wangeditor/editor-for-vue";
import { ElMessage } from "element-plus";
import { request, usePage, useRequest } from "@/api/request";
import {
COMMENT_ADD,
@@ -298,21 +309,128 @@ import {
COMMENT_PRAISE,
DISCUSS_DETAIL,
FILE_UPLOAD,
PostAdd,
PostDelete,
PostUpdate,
PostList,
PostPraise,
PostCollection,
GetComments,
PostDetails,
GetMoreComments
} from "@/api/api";
import UploadImg from "@/components/img/UploadImg.vue";
import UploadPostImg from "@/components/img/UploadPostImg.vue";
const router = useRouter();
const refInput =ref()
const getFocus = () => {
refInput.value.focus()
}
const returnclick = () => {
router.back();
};
const {
query: { id, discussSubmitId, type, pName, sName },
query: { id, discussSubmitId, type, pName, sName, postID, postName },
} = useRoute();
const { data: commontList, fetchData: commonFetch } = usePage(COMMENT_LIST, {
id,
type: 1,
});
// 编辑器实例,必须用 shallowRef
const editorRef = shallowRef();
const { data: disDetail } = useRequest(DISCUSS_DETAIL, { id, type });
// 内容 HTML
const valueHtml = ref("");
const toolbarConfig = {
excludeKeys: ["insertVideo", "insertImage"],
};
const editorConfig = { placeholder: "", readOnly: true, MENU_CONF: {} };
editorConfig.MENU_CONF["uploadImage"] = {
// 自定义上传
async customUpload(file, insertFn) {
const formData = new FormData();
formData.append("file", file);
fileUp(formData).then((res) => {
if (res.data.code === 200) {
// 最后插入图片 url alt href
insertFn(res.data.data, file.name, res.data.data);
}
});
},
};
const handleCreated = (editor) => {
editorRef.value = editor; // 记录 editor 实例,重要!
};
const disDetail = ref({});
const commontList = ref([]);
const spreadReply = ref(-1);
// 查看更多-展开回复列表
function lookMore(i) {
i == spreadReply.value ? spreadReply.value = -1 : spreadReply.value = i;
}
// 清空回复及评论输入框
const clearText = () => {
disComment.value.content = "";
fileListComment.value = [];
fileListCommentRelpay.value = [];
replayComment.value.content = "";
}
const hfPage = ref({
currentPage: 1,
pageNo: 1,
pageSize: 10,
total: 0
})
// 回复分页
function handleCurrentChange(e, k) {
console.log('分页打印', e, k)
hfPage.value.currentPage = e;
hfPage.value.pageNo = e;
getData();
}
// 获取数据
const getData = () => {
useRequest(PostDetails, {id:postID}, (e)=>{
console.log(e)
disDetail.value = e.data
console.log('查询帖子下的评论参数',{
statementId:e.data.discussId,
pageNo:10,
pageSize:1
})
// 获取帖子下的评论
request(COMMENT_LIST, {
id: e.data.id,
type: 1,
current:hfPage.value.currentPage,
pageNo:hfPage.value.currentPage,
pageSize:10
}).then(res=>{
console.log('我是获取当前帖子的评论', res)
commontList.value = res.data.records;
hfPage.value.total = Number(res.data.total);
submitLoading.value = false;
submitReplayLoading.value = false;
clearText()
}).catch(err=>{
console.log(err)
submitLoading.value = false;
submitReplayLoading.value = false;
})
})
}
getData()
const fileList = ref([]);
const commentSubmitFileList = ref([]);
const disComment = ref({
@@ -324,61 +442,140 @@ const replayComment = ref({
pid: "",
});
function removeImg(i) {
fileList.value.splice(i, 1);
// 评论图片展示数组
const fileListComment = ref([]);
// 回复图片展示数组
const fileListCommentRelpay = ref([]);
// 上传图片成功返回的URL
const uploadBack = (e) => {
console.log('--------->', e)
fileListComment.value.push(e)
}
function removeCommentImg() {
commentSubmitFileList.value.splice(i, 1);
const uploadReplyBack = (e) => {
console.log('--------->', e)
fileListCommentRelpay.value.push(e)
}
function removeImg(i) {
fileListCommentRelpay.value.splice(i, 1);
}
function removeCommentImg(i) {
fileListComment.value.splice(i, 1);
}
function like() {
console.log(disDetail.value)
disDetail.value.praised
? (disDetail.value.praiseNum -= 1)
: (disDetail.value.praiseNum += 1);
? (disDetail.value.praiseNum = Number(disDetail.value.praiseNum) - 1)
: (disDetail.value.praiseNum = Number(disDetail.value.praiseNum) + 1);
disDetail.value.praised = !disDetail.value.praised;
request(COMMENT_PRAISE, { targetId: disDetail.value.discussId, type: 5 });
request(PostPraise, { targetId: disDetail.value.id, type: 3 });
}
function collection() {
disDetail.value.collected
? (disDetail.value.collectionNum -= 1)
: (disDetail.value.collectionNum += 1);
? (disDetail.value.collectionNum = Number(disDetail.value.collectionNum) - 1)
: (disDetail.value.collectionNum = Number(disDetail.value.collectionNum) + 1);
disDetail.value.collected = !disDetail.value.collected;
request(COMMENT_COLLECTION, { targetId: disDetail.value.discussId, type: 6 });
request(PostPraise, { targetId: disDetail.value.id, type: 4 });
}
function commentLike(obj) {
obj.praised ? (obj.praiseNum -= 1) : (obj.praiseNum += 1);
obj.praised ? (obj.praiseNum = Number(obj.praiseNum) - 1) : (obj.praiseNum = Number(obj.praiseNum) + 1);
obj.praised = !obj.praised;
request(COMMENT_PRAISE, { targetId: obj.id, type: 5 });
request(COMMENT_PRAISE, { targetId: obj.id, type: 1 });
}
function commentComment(obj) {
replayComment.value.placeholder = "@ " + obj.userName;
console.log(obj)
replayComment.value.placeholder = "@ " + obj.createName;
replayComment.value.pid = obj.id;
}
const submitLoading = ref(false);
// 提交评论
function submitComment() {
request(COMMENT_ADD, {
targetId: disDetail.value.discussId,
console.log(disDetail.value, fileListComment.value)
let imgFileUrl = []
for(let i=0;i<fileListComment.value.length;i++){
imgFileUrl.push(fileListComment.value[i].url)
}
if(disComment.value.content=="" && imgFileUrl.length==0){
ElMessage.error(`请输入评论内容`);
return
}
if(submitLoading.value){
ElMessage.error(`请勿频繁点击`)
return
}
submitLoading.value = true;
console.table('帖子评论参数',{
id: disDetail.value.id,
targetId: disDetail.value.id,
content: disComment.value.content,
type: 1,
}).then(() => {
commonFetch();
img: imgFileUrl.length!==0 ? imgFileUrl.toString() : ''
})
request(COMMENT_ADD, {
targetId: disDetail.value.id,
content: disComment.value.content,
type: 1,
img: imgFileUrl.length!==0 ? imgFileUrl.toString() : ''
}).then((res) => {
console.log(res)
getData();
}).catch(err=>{
submitLoading.value = false;
console.log(err)
});
}
const submitReplayLoading = ref(false);
// 回复评论
function submitReplayComment() {
request(COMMENT_ADD, {
targetId: disDetail.value.discussId,
let imgFileUrl = []
for(let i=0;i<fileListCommentRelpay.value.length;i++){
imgFileUrl.push(fileListCommentRelpay.value[i].url)
}
if(replayComment.value.content=="" && imgFileUrl.length==0){
ElMessage.error(`请输入回复内容`);
return
}
if(submitReplayLoading.value){
ElMessage.error(`请勿频繁点击`)
return
}
submitReplayLoading.value = true;
console.table('帖子回复评论参数',{
id: disDetail.value.id,
targetId: disDetail.value.id,
content: replayComment.value.content,
type: 2,
type: 1,
pid: replayComment.value.pid,
}).then(() => {
commonFetch();
img: imgFileUrl.length!==0 ? imgFileUrl.toString() : ''
})
request(COMMENT_ADD, {
targetId: disDetail.value.id,
content: replayComment.value.content,
type: 1,
pid: replayComment.value.pid,
img: imgFileUrl.length!==0 ? imgFileUrl.toString() : ''
}).then((res) => {
console.log(res)
getData();
}).catch(err=>{
console.log(err)
submitReplayLoading.value = false;
});
}
</script>
<style lang="scss">
@@ -483,6 +680,10 @@ function submitReplayComment() {
font-size: 16px;
font-weight: 800;
color: #333333;
width: 80%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.radi {
@@ -516,6 +717,7 @@ function submitReplayComment() {
.contenttitle {
font-size: 16px;
font-weight: 500;
width: 80%;
color: #333333;
}
@@ -605,6 +807,7 @@ function submitReplayComment() {
// }
.upload {
display: flex;
height: 100px;
// background-color: red;
.allimg {
position: relative;
@@ -733,7 +936,7 @@ function submitReplayComment() {
width: 41px;
height: 41px;
border-radius: 50%;
background-image: url(../../assets/image/px.png);
// background-image: url(../../assets/image/px.png);
background-size: 100%;
}
@@ -863,12 +1066,12 @@ function submitReplayComment() {
}
.avaone {
background-image: url(../../assets/image/px.png);
// background-image: url(../../assets/image/px.png);
background-size: 100%;
}
.avatwo {
background-image: url(../../assets/image/px.png);
// background-image: url(../../assets/image/px.png);
background-size: 100%;
}

View File

@@ -11,23 +11,16 @@
<div style="margin-left: 6px; margin-right: 6px">/</div>
<div style="font-weight: 700; font-size: 16px">考试详情</div>
</div>
<!--
<div class="prevnext">
<div class="prev">
<img
style="width: 23px; height: 23px"
src="../../assets/image/prev.png"
/>
<div style="margin-left: 7px">上一个</div>
</div>
<div class="prev" style="margin-left: 31px">
<div style="margin-right: 7px">下一个</div>
<img
style="width: 23px; height: 23px"
src="../../assets/image/next.png"
/>
</div>
</div>-->
<div class="preNext">
<span @click="prevPage" v-if="hasPrev">
<button class="btn btn01"></button>
<span class="content" style="margin-left: 6px">上一个</span>
</span>
<span @click="nextPage" v-if="hasNext">
<span class="content" style="margin-left: 31px">下一个</span>
<button class="btn btn02" style="margin-left: 6px"></button>
</span>
</div>
<div class="return">
<div style="display: flex" @click="returnclick">
<el-button style="color:#0073FB"> <img class="img2" style="margin-right:11px;cursor: pointer;" src="../../assets/image/return.png" />返回</el-button>
@@ -123,11 +116,12 @@
import { useRoute } from "vue-router/dist/vue-router";
import { usePage, useRequest } from "@/api/request";
import { COMMENT_LIST, DISCUSS_DETAIL, EXAMINATION_QUERY } from "@/api/api";
import {useTaskPage} from "@/api/useCommon";
const {
query: { id, discussSubmitId, pName, sName },
} = useRoute();
const {nextPage,prevPage,hasPrev, hasNext} = useTaskPage()
const { data } = useRequest(EXAMINATION_QUERY(159), {});
</script>

File diff suppressed because it is too large Load Diff

View File

@@ -66,13 +66,13 @@
<!-- <el-tab-pane label="课程评论" name="third" :disabed=dayjs().isBefore(dayjs(data.planDto.beginTime))>
</el-tab-pane> -->
<el-tab-pane label="材料下载" name="third" :disabed=dayjs().isBefore(dayjs(data.planDto.beginTime))>
<div v-if="!data.planDto?.attach"
<el-tab-pane label="材料下载" name="third" >
<div v-if="!data.offcourseDto?.attach"
style="font-size: 14px;font-weight: 400; line-height: 24px; cursor: pointer;margin-left: 40px; margin-top: 20px;">
此课程无附件
</div>
<div v-else>
<div v-for="(el, index) in formateArr(data.planDto.attach)" :key="index" class="enclosure"
<div v-for="(el, index) in formateArr(data.offcourseDto.attach)" :key="index" class="enclosure"
:style="{ borderBottom: '1px solid rgba(56, 125, 247, 0.2)' }">
<div class="enclosureL">
<FileTypeImg :v-model="el.slice(el.lastIndexOf('/')+1,el.indexOf('-')) + el.slice(el.lastIndexOf('.'))" :style="{
@@ -157,7 +157,8 @@ const handleClick = (tab, event) => {
console.log("附件", tab, event);
};
const download = (url) => {
window.open(url);
console.log('下载url',url)
// window.open(url);
};
const downloads = (url) => {
ElMessage.warning("未在有效时间范围内,请耐心等待!");

View File

@@ -66,13 +66,13 @@
<!-- <el-tab-pane label="课程评论" name="third" :disabed=dayjs().isBefore(dayjs(data.planDto.beginTime))>
</el-tab-pane> -->
<el-tab-pane label="材料下载" name="third" :disabed=dayjs().isBefore(dayjs(data.planDto.beginTime))>
<div v-if="!data.planDto?.attach"
<el-tab-pane label="材料下载" name="third" >
<div v-if="!data.offcourseDto?.attach"
style="font-size: 14px;font-weight: 400; line-height: 24px; cursor: pointer;margin-left: 40px; margin-top: 20px;">
此课程无附件
</div>
<div v-else>
<div v-for="(el, index) in formateArr(data.planDto.attach)" :key="index" class="enclosure"
<div v-for="(el, index) in formateArr(data.offcourseDto.attach)" :key="index" class="enclosure"
:style="{ borderBottom: '1px solid rgba(56, 125, 247, 0.2)' }">
<div class="enclosureL">
<FileTypeImg :v-model="el.slice(el.lastIndexOf('/')+1,el.indexOf('-')) + el.slice(el.lastIndexOf('.'))" :style="{

View File

@@ -63,10 +63,205 @@
<div style="padding:20px;" class="content" v-html="data.offcourseDto?.outline"></div>
</div>
</el-tab-pane>
<!-- <el-tab-pane label="课程评论" name="third" :disabed=dayjs().isBefore(dayjs(data.planDto.beginTime))>
<el-tab-pane label="课程评论" name="third" :disabed=dayjs().isBefore(dayjs(data.planDto.beginTime))>
<div class="bascinfor">
<div class="inputone">
<el-input
ref="refInput"
v-model="disComment.content"
:autosize="{ minRows: 5, maxRows: 5 }"
resize="none"
maxlength="100"
type="textarea"
placeholder="写评论~"
/>
<div class="words">{{ disComment.content.length }}/100</div>
<div class="upload">
<div style="display: flex">
<div
class="allimg"
v-for="(img, i) in fileListComment"
:key="i"
>
<div
class="imgone"
:style="{
backgroundImage: `url('${img.url}')`,
marginLeft: '15px',
}"
></div>
<div class="cha" @click="removeCommentImg(i)"></div>
</div>
</div>
<div class="uploadAnd">
<div v-if="3>5" class="btnone clearfix">
<UploadPostImg v-model="commentSubmitFileList" @fileUploadValue="uploadBack">
<button class="btwwo">
<img class="image" src="../../assets/image/uploadimg.png" />
<div class="shangchuan">上传图片</div>
</button>
</UploadPostImg>
</div>
</el-tab-pane> -->
<el-tab-pane label="材料下载" name="third" :disabed=dayjs().isBefore(dayjs(data.planDto.beginTime))>
<button class="btntwo" @click="submitComment" v-loading="submitLoading">发表评论</button>
</div>
</div>
<div class="thinline"></div>
<div class="bottom">
<div v-for="(row, i) in commontList" :key="i" style="margin-bottom: 24px;">
<div class="header">
<img :src="row.studentAvatar" alt="" srcset="" class="avator">
<div class="id">{{ row.createName }}</div>
<div class="showCareer">{{row.studentJobName}}</div>
<div class="idThink"></div>
</div>
<div class="discuss clearfix">
<div class="discussmain clearfix">
<div class="talkmain">
{{ row.content }}
</div>
</div>
<div style="display:flex;margin-top: 12px;margin-bottom: 12px;">
<div v-if="row.img" v-for="(rowimg, index) in row.img.split(',')" :key="index" style="width:55px;height:55px;margin-right: 12px;">
<img class="image" style="width:55px;height:55px;border-radius: 4px;" :src="rowimg" />
</div>
</div>
<div class="intime">{{ row.ctime }}</div>
<div class="likeYou">
<div
@click="commentComment(row)"
style="display: flex; cursor: pointer; align-items: baseline"
>
<span
class="iconfont icon-pinglun"
:style="{ color: '#b3bdc4' }"
></span>
<!-- <div class="count"> {{ row.praiseNum || 0 }}</div>-->
</div>
<div
@click="commentLike(row)"
style="display: flex;cursor: pointer;align-items: baseline;margin-left: 19px;">
<span
class="iconfont icon-dianzan"
:style="{ color: row.praised ? '#2478ff' : '#b3bdc4' }"></span>
<div class="count" :style="{color:row.praised ? '#2478ff' : '#b3bdc4'}">{{ row.praiseNum || 0 }}</div>
</div>
</div>
<!-- 评论下的回复 -->
<div v-if="row.children.length!==0" :style="{height:spreadReply==i ? 'auto' : 210 +'px',overflow:'hidden',position: 'relative'}">
<div v-for="(replay, j) in row.children" :key="j">
<div class="reply">
<img :src="replay.studentAvatar" alt="" srcset="" class="sameava avaone">
<div class="sameuser">{{ replay.studentName }}</div>
<div class="centerreply">回复</div>
<img :src="replay.targetStudentAvatar" alt="" srcset="" class="sameava avaone">
<div class="sameuser">{{ replay.targetStudentName }}</div>
<div class="replytime">{{ replay.createTime }}</div>
</div>
<div style="display:flex;margin-top: 12px;margin-bottom: 12px;">
<div v-if="replay.img" v-for="(rowimg, index) in replay.img.split(',')" :key="index" style="width:65px;height:65px;margin-right: 7px;">
<img class="image" style="width:65px;height:65px;border-radius: 4px;" :src="rowimg" />
</div>
</div>
<div class="mainreply">
<div class="replydetail">
{{ replay.content }}
</div>
<!-- <div class="talk"></div> -->
</div>
<div class="likeYou">
<div
@click="commentComment(replay)"
style="display: flex;cursor: pointer;align-items: baseline;">
<span
class="iconfont icon-pinglun"
:style="{ color: '#b3bdc4' }"></span>
<!-- <div class="count"> {{ replay.commentNum }}</div>-->
</div>
<div
style="display: flex; cursor: pointer; align-items: baseline;margin-left: 19px;"
@click="commentLike(replay)">
<span
class="iconfont icon-dianzan"
:style="{ color: replay.praised ? '#2478ff' : '#b3bdc4' }"></span>
<div class="count" :style="{color:replay.praised ? '#2478ff' : '#b3bdc4'}">{{ replay.praiseNum || 0 }}</div>
</div>
</div>
</div>
<!-- 查看更多 -->
<div style="display: flex;justify-content: center;align-items: center;position:absolute;bottom:0px;cursor: pointer;width:100%">
<span
@click="lookMore(i)"
style="font-size: 14px;color: #2478ff;">{{ i==spreadReply ? '收起' : '查看更多' }}</span>
</div>
</div>
</div>
</div>
<!-- 回复分页 -->
<div style="display:flex;justify-content:center;align-items:center;margin-top:36px;margin-bottom:36px;">
<!-- 分页 -->
<el-pagination
v-model:current-page="hfPage.currentPage"
:page-size="hfPage.pageSize"
:small="small"
layout="prev, pager, next, jumper"
:total="hfPage.total"
@current-change="handleCurrentChange"
/>
</div>
<div
class="discuss clearfix"
v-if="commontList && commontList.length">
<div class="inreply">
<el-input
v-model="replayComment.content"
:autosize="{ minRows: 5, maxRows: 5 }"
resize="none"
maxlength="100"
type="textarea"
:placeholder="replayComment.placeholder"
/>
<div class="words">{{ replayComment.content.length }}/100</div>
<div class="upload">
<div style="display: flex">
<div class="allimg" v-for="(img, i) in fileListCommentRelpay" :key="i">
<div
class="imgone"
:style="{
backgroundImage: `url('${img.url}')`,
marginLeft: '15px',
}"
></div>
<div class="cha" @click="removeImg(i)"></div>
</div>
</div>
<datagrid class="uploadAnd">
<UploadPostImg v-if="3>5" v-model="fileListCommentRelpay" @fileUploadValue="uploadReplyBack">
<button class="btnone clearfix">
<img
class="image"
src="../../assets/image/uploadimg.png"
/>
<div class="shangchuan">上传图片</div>
</button>
</UploadPostImg>
<button class="btntwo" @click="submitReplayComment" style="top:206px;" v-loading="submitReplayLoading">
回复
</button>
</datagrid>
</div>
</div>
</div>
</div>
</div>
</div>
</el-tab-pane>
<el-tab-pane label="材料下载" name="four" >
<div v-if="data.offcourseDto?.attach == ''"
style="font-size: 14px;font-weight: 400; line-height: 24px; cursor: pointer;margin-left: 40px; margin-top: 20px;">
此课程无附件
@@ -121,12 +316,18 @@
</template>
<script setup>
import {computed, reactive, toRefs, watch, onUnmounted} from "vue";
import {computed, reactive, toRefs, watch, onUnmounted, ref} from "vue";
import FileTypeImg from "@/components/FileTypeImg.vue";
import {request, useRequest} from "@/api/request";
import {
STU_OFFCOURSE_DETAIL,
FACETEACH_SIGNUP
FACETEACH_SIGNUP,
COMMENT_ADD,
COMMENT_LIST,
COMMENT_PRAISE,
PostPraise,
PostDetails,
} from "@/api/api";
import {useRoute, useRouter} from "vue-router";
import {useUserInfo} from "@/api/utils";
@@ -157,6 +358,7 @@ const handleClick = (tab, event) => {
console.log("附件", tab, event);
};
const download = (url) => {
// console.log('下载url',url)
window.open(url);
};
const downloads = (url) => {
@@ -164,6 +366,180 @@ const downloads = (url) => {
};
let timer = null;
// 查看更多-展开回复列表
function lookMore(i) {
i == spreadReply.value ? spreadReply.value = -1 : spreadReply.value = i;
}
// 获取评论数据
const hfPage = ref({
currentPage: 1,
pageNo: 1,
pageSize: 10,
total: 0
})
const disComment = ref({
content: "",
});
// 获取数据
const getData = () => {
// 获取面授课下的评论
request(COMMENT_LIST, {
id: courseId,
type: 2,
current:hfPage.value.currentPage,
pageNo:hfPage.value.currentPage,
pageSize:10
}).then(res=>{
console.log('我是获取当前帖子的评论', res)
commontList.value = res.data.records;
hfPage.value.total = Number(res.data.total);
submitLoading.value = false;
submitReplayLoading.value = false;
clearText()
}).catch(err=>{
console.log(err)
submitLoading.value = false;
submitReplayLoading.value = false;
})
}
// 回复分页
function handleCurrentChange(e, k) {
console.log('分页打印', e, k)
hfPage.value.currentPage = e;
hfPage.value.pageNo = e;
getData();
}
getData()
const disDetail = ref({});
const commontList = ref([]);
const spreadReply = ref(-1);
const replayComment = ref({
placeholder: "",
content: "",
pid: "",
});
// 清空回复及评论输入框
const clearText = () => {
disComment.value.content = "";
fileListComment.value = [];
fileListCommentRelpay.value = [];
replayComment.value.content = "";
}
// 评论图片展示数组
const fileListComment = ref([]);
// 回复图片展示数组
const fileListCommentRelpay = ref([]);
// 上传图片成功返回的URL
const uploadBack = (e) => {
console.log('--------->', e)
fileListComment.value.push(e)
}
const uploadReplyBack = (e) => {
console.log('--------->', e)
fileListCommentRelpay.value.push(e)
}
function removeImg(i) {
fileListCommentRelpay.value.splice(i, 1);
}
function removeCommentImg(i) {
fileListComment.value.splice(i, 1);
}
function commentLike(obj) {
obj.praised ? (obj.praiseNum = Number(obj.praiseNum) - 1) : (obj.praiseNum = Number(obj.praiseNum) + 1);
obj.praised = !obj.praised;
request(COMMENT_PRAISE, { targetId: obj.id, type: 1 });
}
function commentComment(obj) {
console.log(obj)
replayComment.value.placeholder = "@ " + obj.createName;
replayComment.value.pid = obj.id;
}
const submitLoading = ref(false);
// 提交评论
function submitComment() {
if(disComment.value.content==""){
ElMessage.error(`请输入评论内容`);
return
}
if(submitLoading.value){
ElMessage.error(`请勿频繁点击`)
return
}
submitLoading.value = true;
console.table('面授课评论参数',{
id: courseId,
targetId: courseId,
content: disComment.value.content,
type: 2,
})
request(COMMENT_ADD, {
id: courseId,
targetId: courseId,
content: disComment.value.content,
type: 2,
}).then((res) => {
console.log(res)
getData();
}).catch(err=>{
submitLoading.value = false;
console.log(err)
});
}
const submitReplayLoading = ref(false);
// 回复评论
function submitReplayComment() {
if(replayComment.value.content==""){
ElMessage.error(`请输入回复内容`);
return
}
if(submitReplayLoading.value){
ElMessage.error(`请勿频繁点击`)
return
}
submitReplayLoading.value = true;
console.table('帖子回复评论参数',{
id: courseId,
targetId: courseId,
content: replayComment.value.content,
type: 2,
pid: replayComment.value.pid
})
request(COMMENT_ADD, {
id: courseId,
targetId: courseId,
content: replayComment.value.content,
type: 2,
pid: replayComment.value.pid
}).then((res) => {
console.log(res)
getData();
}).catch(err=>{
console.log(err)
submitReplayLoading.value = false;
});
}
// 报名
function onLineSignUp() {
if(data.value.isSignUp){
@@ -498,4 +874,370 @@ function formateArr(strs) {
}
}
.bascinfor {
width: 100%;
background: #ffffff;
border-radius: 8px;
margin-top: 24px;
// position: relative;
.inputone {
margin-right: 44px;
position: relative;
max-width: 1069px;
// max-height: 110px;
margin-left: 88px;
margin-top: 44px;
.words {
position: absolute;
right: 15px;
// bottom: 5px;
top: 130px;
font-size: 14px;
font-weight: 500;
color: #333330;
}
.el-textarea__inner {
font-size: 14px;
font-weight: 500;
color: #666666;
margin-top: 44px;
// margin: 23px 50px;
border-radius: 8px;
background-color: rgba(245, 246, 247, 1);
padding: 11px 25px;
}
.el-textarea__inner::placeholder {
font-size: 14px;
font-weight: 500;
color: #666666;
line-height: 24px;
}
// .el-input__inner {
// &::-webkit-input-placeholder {
// /* WebKit browsers 适配谷歌 */
// color: red;
// }
// }
.upload {
display: flex;
height: 100px;
// background-color: red;
.allimg {
position: relative;
display: flex;
.imgone {
margin-top: 24px;
width: 55px;
height: 55px;
border-radius: 8px;
background-image: url(../../assets/image/px.png);
background-size: 100%;
}
.cha {
cursor: pointer;
top: 15px;
right: -9px;
// right: 0;
position: absolute;
width: 18px;
height: 18px;
border-radius: 50%;
background-image: url(../../assets/image/X.png);
background-size: 100%;
}
}
.uploadAnd {
margin-top: 21px;
.btwwo {
cursor: pointer;
.image {
padding-top: 8px;
width: 18px;
height: 17px;
// margin-top: 10px;
margin-left: -60px;
}
.shangchuan {
position: absolute;
right: 20px;
top: 7px;
display: inline-block;
margin-left: 10px;
font-size: 14px;
font-weight: 500;
color: #2478ff;
line-height: 24px;
}
width: 126px;
height: 36px;
border: none;
background-color: #fff;
}
.btnone {
cursor: pointer;
position: absolute;
right: 140px;
.image {
padding-top: 8px;
width: 18px;
height: 17px;
// margin-top: 10px;
margin-left: -60px;
}
.shangchuan {
position: absolute;
right: 20px;
top: 7px;
display: inline-block;
margin-left: 10px;
font-size: 14px;
font-weight: 500;
color: #2478ff;
line-height: 24px;
}
width: 126px;
height: 36px;
border: 1px solid #2478ff;
border-radius: 4px;
background-color: #fff;
}
.btntwo {
cursor: pointer;
position: absolute;
width: 126px;
height: 36px;
background: #2478ff;
border-radius: 4px;
font-size: 14px;
font-weight: 500;
color: #ffffff;
border: 0;
right: 0;
}
}
}
.thinline {
margin-top: 66px;
// width: 1635px;
border-top: 1px solid #878b92;
margin-left: -50px;
opacity: 0.2;
}
.bottom {
margin-top: 31px;
// width: 100px;
// height: 100px;
// background-color: #bfa;
.header {
display: flex;
.avator {
width: 41px;
height: 41px;
border-radius: 50%;
// background-image: url(../../assets/image/px.png);
background-size: 100%;
}
.id {
margin-left: 8px;
font-size: 14px;
height: 41px;
font-weight: bold;
color: #333333;
line-height: 41px;
}
.showCareer {
margin-left: 7px;
height: 41px;
font-size: 12px;
font-weight: 500;
color: #666666;
line-height: 41px;
}
.idThink {
margin-left: 17px;
height: 41px;
font-size: 14px;
font-weight: 500;
color: #666666;
line-height: 41px;
}
}
.discuss {
margin-left: 48px;
margin-top: 23px;
// width: 100px;
width: 100%;
// height: 100px;
// background-color: orange;
.discussmain {
// background-color: red;
width: 100%;
display: flex;
position: relative;
.talkmain {
margin-right: 25px;
margin-top: 2px;
font-size: 14px;
font-weight: 500;
color: #666666;
}
// .talk {
// position: absolute;
// right: 0;
// width: 23px;
// height: 23px;
// background-image: url(../../assets/image/talk.png);
// background-size: 100%;
// }
}
.intime {
margin-top: 11px;
font-size: 14px;
font-weight: 500;
color: #999999;
}
.likeYou {
margin-top: 15px;
display: flex;
.same {
width: 14px;
height: 14px;
}
.pinglun {
background-image: url(../../assets/image/pinglun.png);
background-size: 100%;
}
.dianzan {
background-image: url(../../assets/image/dianzan2.png);
background-size: 100%;
}
.count {
margin-left: 7px;
margin-top: -1px;
font-size: 14px;
font-weight: 500;
color: #b3bdc4;
}
}
.reply {
display: flex;
margin-top: 32px;
// height: 100px;
width: 100%;
// background-color: lightpink;
.sameava {
width: 29px;
height: 29px;
border-radius: 50%;
}
.sameuser {
margin-left: 14px;
line-height: 29px;
height: 29px;
font-weight: bold;
color: #333333;
font-size: 14px;
}
.centerreply {
height: 29px;
font-size: 14px;
font-weight: 500;
color: #4a9cf8;
line-height: 29px;
margin-left: 23px;
margin-right: 17px;
}
.avaone {
// background-image: url(../../assets/image/px.png);
background-size: 100%;
}
.avatwo {
// background-image: url(../../assets/image/px.png);
background-size: 100%;
}
.replytime {
margin-left: 17px;
height: 29px;
font-size: 14px;
font-weight: 500;
color: #999999;
line-height: 29px;
}
}
.allreplyimg {
display: flex;
margin-top: 21px;
.singleimg {
margin-right: 7px;
width: 65px;
height: 65px;
border-radius: 8px;
background-image: url(../../assets/image/px.png);
background-size: 100%;
}
}
.mainreply {
display: flex;
margin-top: 16px;
.replydetail {
height: 23px;
font-size: 14px;
font-weight: 500;
color: #666666;
line-height: 23px;
margin-right: 11px;
}
}
.inreply {
position: relative;
margin-top: -22px;
margin-bottom: 20px;
}
}
}
}
}
</style>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -8,13 +8,16 @@
<div>{{ sName }}</div>
<div v-if="sName" style="margin-left: 6px; margin-right: 6px">/</div>
<div style="font-weight: 700; font-size: 16px">活动详情</div>
<!--
<div class="preNext">
<button class="btn btn01"></button>
<span class="content" style="margin-left: 6px">上一个</span>
<span class="content" style="margin-left: 31px">一个</span>
<button class="btn btn02" style="margin-left: 6px"></button>
</div>-->
<span @click="prevPage" v-if="hasPrev">
<button class="btn btn01"></button>
<span class="content" style="margin-left: 6px">一个</span>
</span>
<span @click="nextPage" v-if="hasNext">
<span class="content" style="margin-left: 31px">下一个</span>
<button class="btn btn02" style="margin-left: 6px"></button>
</span>
</div>
<div class="return">
<div style="display: flex" @click="returnclick">
<el-button style="color:#0073FB"> <img class="img2" style="margin-right:11px;cursor: pointer;" src="../../assets/image/return.png" />返回</el-button>
@@ -96,20 +99,34 @@
</div>
<div>
<span>活动考勤</span>
<span class="content">
<span v-if="data?.beforeSignIn!=='0'" class="content">
{{
data?.beforeSignIn
? "活动开始前" + data?.beforeSignIn + "分钟开始签到"
: "-"
}}
</span>
<span class="content">
<span v-if="data?.beforeSignIn=='0' && data?.afterSignIn=='0'" class="content">
{{
data?.beforeSignIn
? "活动在 " + data?.activityStartTime + ""
: "-"
}}
</span>
<span v-if="data?.afterSignIn!=='0'" class="content">
{{
data?.afterSignIn
? "活动开始后" + data?.afterSignIn + "分钟结束签到"
: "-"
}}
</span>
<span v-if="data?.beforeSignIn=='0' && data?.afterSignIn=='0'" class="content">
{{
data?.afterSignIn
? " ~ " + data?.activityEndTime + " 时间段内允许签到"
: "-"
}}
</span>
</div>
<!--
<div>
@@ -156,6 +173,7 @@ import { useRouter } from "vue-router";
import { useRoute } from "vue-router/dist/vue-router";
import { ElMessage } from "element-plus";
import { reactive, onUnmounted, toRefs} from "vue";
import {useTaskPage} from "@/api/useCommon";
const router = useRouter();
const returnclick = () => {
router.back();
@@ -169,8 +187,8 @@ const state = reactive({
});
const { isAllowSign } = toRefs(state);
const { data } = useRequest(ACTIVITY, { activityId });
const {nextPage,prevPage,hasPrev, hasNext} = useTaskPage()
const { data } = useRequest(ACTIVITY, { activityId, type });
console.log('data', data)
const signClick = (tab, event) => {
if (data.value.signFlag) {
@@ -184,11 +202,19 @@ const signClick = (tab, event) => {
}
data.value.signFlag = true;
ElMessage.warning("签到成功");
request(TASK_ACTIVITY_SIGN, {
courseId: activityId,
taskId,
type,
}).then(res=>{
console.log(res)
if(res.code==200){
ElMessage.success("签到成功");
}
}).catch(err=>{
console.log(err)
ElMessage.warning("签到失败");
});
};
let timer = null;

File diff suppressed because it is too large Load Diff

View File

@@ -12,24 +12,32 @@
<div class="title">我的项目</div>
<div class="search">
<!-- <el-select v-model="value" class="m-2" placeholder="Select">
<el-option
v-for="item in projectClassify"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
<el-select v-model="value" class="m-2" placeholder="Select">
<el-option
v-for="item in studyProgress"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select> -->
<el-option
v-for="item in projectClassify"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select> -->
<div style="width: 200px; margin-right: 20px">
<el-input v-model="projectname" placeholder="请输入项目名称" />
</div>
<el-select
@change="choiceStatus"
v-model="stateValue"
class="m-2"
placeholder="请选择学习进度"
style="width: 200px; margin-right: 20px">
<el-option
v-for="item in studyProgress"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
<div style="width: 420px">
<el-date-picker v-model="searchTime" type="daterange" range-separator="至" start-placeholder="开始时间" end-placeholder="结束时间" :size="size" @change="selectTime"/>
@@ -52,7 +60,7 @@
</div>
<div v-else class="projectList" v-for="(i, k) in projectList" :key="k">
<div style="display: flex">
<img style="width: 253px; height: 144px; border-radius: 4px" :src="i.picUrl" />
<img style="width: 253px; height: 175px; border-radius: 4px" :src="i.picUrl" />
<div style="margin-left: 29px">
<div class="projectName" :title="i.name">
{{ i.name }}
@@ -70,6 +78,7 @@
</div>
</div>
<div class="studyNew" v-if="i.lastStudyTime">最新一次学习时间{{ i.lastStudyTime }}</div>
<div class="studyNew">项目起止时间{{ i.beginTime }} ~ {{ i.endTime }}</div>
</div>
</div>
<div class="tobestarted" v-if="i.status == 2" @click="goProjectDetails(i)">
@@ -131,7 +140,24 @@ import { ElLoading } from 'element-plus';
const router = useRouter();
const projectClassify = [];
const studyProgress = [];
const studyProgress = [
{
value:0,
label:"未开始"
},
{
value:1,
label:"进行中"
},
{
value:2,
label:"已完成"
},
{
value:3,
label:"已结束"
},
];
const projectList = ref([]); //项目列表
const pageSize = ref(60); //每页条数
const currentPage = ref(1); //当前页数
@@ -140,6 +166,7 @@ const projectname = ref(""); //项目名称
const searchTime = ref(""); //选择时间
const beginTime = ref(""); //结束时间
const endTime = ref(""); //开始时间
const stateValue = ref(undefined)
const dialogVisible = ref(false)
const userInfo = computed(() => store.state.userInfo);
@@ -154,12 +181,21 @@ const getProject = () => {
text: 'Loading',
background: 'rgba(0, 0, 0, 0.7)'
})
console.log('我是搜索传递的参数',{
beginTime: beginTime.value,
endTime: endTime.value,
key: projectname.value,
pageNo: currentPage.value,
pageSize: pageSize.value,
status: stateValue.value
})
request(PROJECT_LIST, {
beginTime: beginTime.value,
endTime: endTime.value,
key: projectname.value,
pageNo: currentPage.value,
pageSize: pageSize.value,
status: stateValue.value
})
.then((res) => {
console.log("获取成功", res);
@@ -205,6 +241,7 @@ const resetClick = () => {
currentPage.value = 1;
beginTime.value = "";
endTime.value = "";
stateValue.value ="";
getProject();
console.log("点击重置");
};
@@ -220,15 +257,22 @@ const goProjectDetails = (value) => {
?
router.push({
path: "/projectdetails",
query: { projectId: value.projectId },
query: { projectId: value.id },
})
:
window.open(
`${import.meta.env.VITE_BOE_PATH_DETAIL_URL}/projectdetails&params=${encodeURIComponent(
`projectId=${value.projectId}`
`${window.location.protocol + import.meta.env.VITE_BOE_PATH_DETAIL_URL}/projectdetails&params=${encodeURIComponent(
`projectId=${value.id}`
,'_top')}`
);
};
// 项目状态
const choiceStatus = (e) => {
console.log(e)
stateValue.value = e
}
</script>
<style lang="scss">
.projectManage {

View File

@@ -5,144 +5,198 @@
<div class="titleL">
<div @click="returnfun" class="text">学习路径图</div>
<div class="info" style="margin-right: 14px" v-if="userInfo.jobName">
<img style="width: 20px; height: 18px; margin-right: 10px" src="../../assets/image/pm.png"/>
<img
style="width: 20px; height: 18px; margin-right: 10px"
src="../../assets/image/pm.png"
/>
<div style="margin-top: 1px">{{ userInfo.jobName }}</div>
</div>
<div class="info" v-if="userInfo.bandDesc">
<img style="width: 18px; height: 17px; margin-right: 11px" src="../../assets/image/band.png"/>
<img
style="width: 18px; height: 17px; margin-right: 11px"
src="../../assets/image/band.png"
/>
<div style="margin-top: 2px">{{ userInfo.bandDesc }}</div>
</div>
</div>
<div :style="{ display: !showmapdetail ? 'flex' : 'none' }">
<!-- <el-popover width="475px" trigger="hover" popper-class="lppopover">-->
<!-- <div>-->
<!-- <div class="finish">-->
<!-- <img-->
<!-- src="../../assets/image/circle.png"-->
<!-- style="width: 20px; height: 20px"-->
<!-- />-->
<!-- <div class="text">未完成</div>-->
<!-- <div class="box"></div>-->
<!-- </div>-->
<!-- <div-->
<!-- v-for="(value, index) in unCompleteTaskList"-->
<!-- :key="index"-->
<!-- class="tasks"-->
<!-- :style="{-->
<!-- 'border-bottom':-->
<!-- index === unCompleteTaskList.length - 1-->
<!-- ? null-->
<!-- : '1px solid rgba(229, 228, 228, 1)',-->
<!-- }"-->
<!-- >-->
<!-- <div style="font-size: 14px; font-weight: 500; color: #677d86">-->
<!-- {{ value.name }}-->
<!-- </div>-->
<!-- <img-->
<!-- style="width: 20px; height: 20px"-->
<!-- src="../../assets/image/go.png"-->
<!-- @click="toUnTask(chapterId)"-->
<!-- />-->
<!-- </div>-->
<!-- </div>-->
<!-- <template #reference>-->
<!-- todo #学习路径 只会有一个未完成任务么?是否是直接跳到任务详情-->
<!-- <div class="titleR">进入未完成任务</div>-->
<!-- </template>-->
<!-- </el-popover>-->
<el-popover width="475px" trigger="hover" popper-class="lppopover">
<div>
<div class="finish">
<img
src="../../assets/image/circle.png"
style="width: 20px; height: 20px"
/>
<div class="text">未完成</div>
<div class="box"></div>
</div>
<div
v-for="(value, index) in unCompleteTaskList"
:key="index"
class="tasks"
:style="{
'border-bottom':
index === unCompleteTaskList.length - 1
? null
: '1px solid rgba(229, 228, 228, 1)',
}"
>
<div style="font-size: 14px; font-weight: 500; color: #677d86">
{{ value.name }}
</div>
<img
style="width: 20px; height: 20px"
src="../../assets/image/go.png"
@click="toUnTask(chapterId)"
/>
</div>
</div>
<template #reference>
<div class="titleR">进入未完成任务</div>
</template>
</el-popover>
</div>
<div :style="{ display: showmapdetail ? 'flex' : 'none' }" class="titleR" @click="returnfun">
<div
:style="{ display: showmapdetail ? 'flex' : 'none' }"
class="titleR"
@click="returnfun"
>
返回列表
</div>
</div>
<!-- 路径列表-->
<div class="routerList" v-if="isLoading" style="display:flex;color:#909399;">
</div>
<div v-else :style="{ display: !showmapdetail ? 'flex' : 'none' }" class="head">
{{ loading.close() }}
<div
class="routerList"
v-if="isLoading"
style="display: flex; color: #909399"
></div>
<div
v-else
:style="{ display: !showmapdetail ? 'flex' : 'none' }"
class="head"
>
<div style="min-width: 770px; width: 100%">
<el-table :data="data" style="width: 100%" @row-click="gofun">
<el-table-column prop="img" label="缩略图" #default="scope" align="center" width="255">
<img :src="scope.row.picUrl" style="width: 230px; height: 155px"/>
<el-table-column
prop="img"
label="缩略图"
#default="scope"
align="center"
width="255"
>
<img
:src="scope.row.picUrl"
style="width: 230px; height: 155px"
/>
</el-table-column>
<el-table-column align="center" prop="name" label="路径名称"/>
<el-table-column align="center" prop="introduce" label="路径介绍" #default="scope">
<el-popover placement="bottom-start" :width="400" title="路径介绍" trigger="hover"
:content="scope.row.remark">
<el-table-column
align="center"
prop="introduce"
label="路径介绍"
#default="scope"
>
<el-popover
placement="bottom-start"
:width="400"
title="路径介绍"
trigger="hover"
:content="scope.row.remark"
>
<template #reference>
<div>{{ scope.row.remark }}</div>
</template>
</el-popover>
</el-table-column>
<el-table-column align="center" prop="organizationName" label="归属组织"/>
<el-table-column #default="scope" align="center" :width="150" prop="state" label="状态">
<img :src="
scope.row.taskStatus === 1
? ongoing
: scope.row.taskStatus === 2
? completed
: scope.row.taskStatus === 0
? ongoing
: null
" style="width: 99px; height: 99px"/>
<el-table-column
align="center"
prop="organizationName"
label="归属组织"
/>
<el-table-column
#default="scope"
align="center"
:width="150"
prop="state"
label="状态"
>
<img
:src="{1:ongoing,2:completed,0:nostarted}[formatStatus(scope.row.process)]"
style="width: 99px; height: 99px"
/>
</el-table-column>
</el-table>
</div>
</div>
<!-- :src="{ 0: nostarted, 1: completed, 2: ongoing }[scope.row.status]"-->
<!-- 路径列表-->
<!-- 路径详情图 -->
<div :style="{ display: showmapdetail ? 'flex' : 'none' }" class="mapdetail">
<PathDetailImage img="https://u-pre.boe.com/upload/路径图背景-1671015331292.png" :detail="detail"></PathDetailImage>
<div
:style="{ display: showmapdetail ? 'flex' : 'none' }"
class="mapdetail"
>
<PathDetailImage
:img="detail?.picUrl"
:detail="detail"
></PathDetailImage>
</div>
<!-- 路径详情图 -->
</div>
</div>
</template>
<script setup>
import {computed, ref} from "vue";
import {computed, ref, watch} from "vue";
import nostarted from "../../assets/image/nostarted.png";
import completed from "../../assets/image/completed.png";
import ongoing from "../../assets/image/ongoing.png";
import completed from "@/assets/image/completed.png";
import ongoing from "@/assets/image/ongoing.png";
import {usePage} from "@/api/request";
import {ROUTER_LIST,} from "@/api/api";
import {ROUTER_LIST} from "@/api/api";
import {useRouter} from "vue-router";
import store from "@/store";
import PathDetailImage from "@/components/PathDetailImage.vue";
import { ElLoading } from 'element-plus';
import {ElLoading} from "element-plus";
import {useRequest} from "@/api/request";
import {ROUTER_UNCOMPLETE_LIST} from "@/api/api";
const detail = ref();
const showmapdetail = ref(false);
const currentStageId = ref();
const userInfo = computed(() => store.state.userInfo);
const loading = ref(false);
const isLoading = ref(true);
loading.value = ElLoading.service({
lock: true,
text: 'Loading',
background: 'rgba(0, 0, 0, 0.7)'
text: "Loading",
background: "rgba(0, 0, 0, 0.7)",
});
const {data, loading: isLoading} = usePage(ROUTER_LIST, {pageSize: 60});
watch(data, () => {
loading.value.close()
})
const {data} = usePage(ROUTER_LIST, {pageSize: 60}, (e)=>{
console.log('我请求成功了吗', e)
isLoading.value = false;
});
const router = useRouter();
const returnclick = () => {
router.back();
};
// const {unCompleteTaskList} = useRequest(ROUTER_UNCOMPLETE_LIST, {});
const {unCompleteTaskList} = useRequest(ROUTER_UNCOMPLETE_LIST, {});
const returnfun = () => {
showmapdetail.value = false;
};
function formatStatus(process) {
if (!process) {
return 0;
}
if (parseInt(process) === 1) {
return 2;
}
return 1;
}
async function gofun(e) {
detail.value = e
detail.value = e;
showmapdetail.value = true;
}

File diff suppressed because it is too large Load Diff

View File

@@ -10,22 +10,16 @@
<div v-if="sName" style="margin-left: 6px; margin-right: 6px">/</div>
<div style="font-weight: 700; font-size: 16px">评估详情</div>
</div>
<!--
<div class="prevnext">
<div class="prev">
<img
style="width: 23px; height: 23px"
src="../../assets/image/prev.png"
/>
<div style="margin-left: 7px">上一个</div>
</div>
<div class="prev" style="margin-left: 31px">
<div style="margin-right: 7px">下一个</div>
<img
style="width: 23px; height: 23px"
src="../../assets/image/next.png"
/>
</div>-->
<div class="preNext">
<span @click="prevPage" v-if="hasPrev">
<button class="btn btn01"></button>
<span class="content" style="margin-left: 6px">上一个</span>
</span>
<span @click="nextPage" v-if="hasNext">
<span class="content" style="margin-left: 31px">下一个</span>
<button class="btn btn02" style="margin-left: 6px"></button>
</span>
</div>
<div class="return">
<div style="display: flex" @click="returnclick">
<el-button style="color:#0073FB"> <img class="img2" style="margin-right:11px;cursor: pointer;"
@@ -90,23 +84,29 @@
<div class="text">
{{ value?.singleStemName }}
</div>
<div v-for="(values, indexs) in value.assessmentSingleChoiceVoList" :key="indexs"
style="display: flex; align-items: center" :style="{
'margin-top': indexs === 0 ? '29px' : '22px',
cursor: 'pointer',
}" @click="
() => {
if (data.isSubmit) {
return;
}
value.assessmentSingleChoiceVoList.forEach((e) => {
e.select = false;
});
values.select = true;
}
">
<img style="width: 19px; height: 18px; cursor: pointer" :src="values.select ? checkbox : checkbox2" />
<div class="people">{{ values.singleOptionName }}</div>
<!-- 需要遍历的选项 -->
<div style="display:flex;justify-content:flex-start;align-items:center;margin-top: 24px;">
<div
v-for="(values, indexs) in value.assessmentSingleChoiceVoList"
:key="indexs"
style="display: flex; align-items: center;cursor: pointer;flex-direction: column;"
@click="
() => {
if (data.isSubmit) {
return;
}
value.assessmentSingleChoiceVoList.forEach((e) => {
e.select = false;
});
values.select = true;}
">
<div style="display:flex">
<img style="width: 19px; height: 18px; cursor: pointer" :src="values.select ? checkbox : checkbox2" />
<div class="people">{{ values.singleOptionName }}</div>
</div>
<img v-if="values.singleOptionPictureAddress" style="width: 140px; height: 140px; border-radius: 8px;margin-left: 130px;margin-top: 12px;" :src="values.singleOptionPictureAddress ? fielPath + values.singleOptionPictureAddress : ''" />
<div v-else style="width: 140px;height: 140px;"></div>
</div>
</div>
</div>
</div>
@@ -116,20 +116,26 @@
<div class="text">
{{ value?.multipleStemName }}
</div>
<div v-for="(values, indexs) in value.multipleChoiceVoList" :key="indexs"
style="display: flex; align-items: center" :style="{
'margin-top': indexs === 0 ? '29px' : '22px',
cursor: 'pointer',
}" @click="
() => {
if (data.isSubmit) {
return;
}
values.select = !values.select;
}
">
<img style="width: 19px; height: 18px; cursor: pointer" :src="values.select ? checkbox : checkbox2" />
<div class="people">{{ values.multipleOptionName }}</div>
<!-- 需要遍历的选项 -->
<div style="display:flex;justify-content:flex-start;align-items:center;margin-top: 24px;">
<div
v-for="(values, indexs) in value.multipleChoiceVoList"
:key="indexs"
style="display: flex; align-items: center;cursor: pointer;flex-direction: column;"
@click="
() => {
if (data.isSubmit) {
return;
}
values.select = !values.select;
}">
<div style="display:flex">
<img style="width: 19px; height: 18px; cursor: pointer" :src="values.select ? checkbox : checkbox2" />
<div class="people">{{ values.multipleOptionName }}</div>
</div>
<img v-if="values.multipleOptionPictureAddress" style="width: 140px; height: 140px; border-radius: 8px;margin-left: 130px;margin-top: 12px;" :src="values.multipleOptionPictureAddress ? fielPath + values.multipleOptionPictureAddress : ''" />
<div v-else style="width: 140px;height: 140px;"></div>
</div>
</div>
</div>
</div>
@@ -332,6 +338,7 @@ import { ASSESSMENT_QUERY, ASSESSMENT_SUBMIT } from "@/api/api";
import { ElMessage } from "element-plus";
import { ref } from "vue";
import dayjs from "dayjs";
import {useTaskPage} from "@/api/useCommon";
const {
query: { courseId, id: taskId, infoId, type, pName, sName, chapterOrStageId, projectStatus, projectEndTime },
@@ -341,8 +348,10 @@ const returnclick = () => {
clearInterval(timers)
router.back();
};
const {nextPage,prevPage,hasPrev, hasNext} = useTaskPage()
const fielPath = ref(import.meta.env.VITE_FILE_PATH);
const { data } = useRequest(ASSESSMENT_QUERY(courseId), { id: courseId, type, chapterOrStageId, targetId: infoId ? infoId : 0 });
console.log(data)
console.log('我是查询评估的参数', { id: courseId, type, chapterOrStageId, targetId: infoId ? infoId : 0 })
console.log('我是需要排序得题目', data)
@@ -369,8 +378,8 @@ const questionList = ref([])
const timers = setInterval(() => {
console.log(data)
console.log(data.value.assessmentId)
if(data.value.assessmentId){
console.log(data.value.id)
if(data.value.id){
clearInterval(timers)
console.log([data.value.essayQuestionVoList, data.value.multipleStemVoList, data.value.scoringQuestionVoList, data.value.singleStemVoList])
questionList.value = formateArr([data.value.essayQuestionVoList, data.value.multipleStemVoList, data.value.scoringQuestionVoList, data.value.singleStemVoList])
@@ -470,6 +479,37 @@ function submit() {
}
</script>
<style lang="scss">
.preNext {
position: absolute;
right: 0px;
.content {
font-size: 14px;
color: #fff;
width: 43px;
height: 14px;
display: inline-block;
position: relative;
top: -6px;
cursor: pointer;
}
.btn {
width: 23px;
height: 23px;
border-radius: 50%;
border: 0;
cursor: pointer;
}
.btn01 {
background-image: url("../../assets/image/prev.png");
}
.btn02 {
background-image: url("../../assets/image/next.png");
}
}
.surveydetail {
.crumb {
color: #fff;

View File

@@ -0,0 +1,632 @@
<template>
<div class="moreactive" style="padding: 30px">
<!-- 面包屑导航 -->
<div class="crumb">
<div>{{ pName }}</div>
<div style="margin-left: 6px; margin-right: 6px">/</div>
<div>{{ sName }}</div>
<div style="margin-left: 6px; margin-right: 6px">/</div>
<div style="font-weight: 700; font-size: 16px">测评详情</div>
<div class="preNext">
<span @click="prevPage" v-if="hasPrev">
<button class="btn btn01"></button>
<span class="content" style="margin-left: 6px">上一个</span>
</span>
<span @click="nextPage" v-if="hasNext">
<span class="content" style="margin-left: 31px">下一个</span>
<button class="btn btn02" style="margin-left: 6px"></button>
</span>
</div>
<div class="return">
<div style="display: flex" @click="returnclick">
<el-button style="color:#0073FB"> <img class="img2" style="margin-right:11px;cursor: pointer;" src="../../assets/image/return.png" />返回</el-button>
</div>
</div>
</div>
<!-- 面包屑导航 -->
<!-- <div class="debateTitle">考试{{ dataInfo?.voteName }}</div> -->
<!-- 详细信息 -->
<div class="detailinfo">
<div class="detail">
<div class="detailT">
<div class="left">
<div class="debateTitle" style="color:rgba(51, 51, 51, 1);font-size:20px;margin-top:46px;">测评{{ exname }}</div>
<div style="display: flex;justify-content: space-between;align-items: center;">
<div class="title">
<img
style="width: 20px; height: 20px"
src="../../assets/image/yuan.png"
/>
<div class="text">测评时间</div>
<div class="box"></div>
</div>
<div class="">
<button class="tijiao" @click="handleClick(state.datainfo.evaluationTypeId)">查看</button>
</div>
</div>
<div class="all" style="font-size:14px;color:rgba(51, 51, 48, 1);">
{{ state.datainfo.evaluationStartTime ? state.datainfo.evaluationStartTime : "-" }} ~ {{ state.datainfo.evaluationEndTime ? state.datainfo.evaluationEndTime : "-" }}
</div>
</div>
</div>
<div class="detailT" style="margin-top:20px;height:671px;">
<div class="left">
<div class="title">
<img
style="width: 20px; height: 20px"
src="../../assets/image/yuan.png"
/>
<div class="text">测评说明</div>
<div class="box"></div>
</div>
<!-- <div style="display: flex; align-items: center"></div> -->
<div class="all" style="font-size:14px;color:rgba(51, 51, 48, 1);">
<div>
{{ state.datainfo.evaluationExplain ? state.datainfo.evaluationExplain : "暂无测评说明" }}
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 详细信息 -->
</div>
</template>
<script setup>
import {useRequest, request} from "@/api/request";
import {
LINKGETONE,
QueryEvaluationDetailById,
EvaluationToLearn
} from "@/api/api";
import {reactive,computed} from "vue";
import {useRoute,useRouter} from "vue-router/dist/vue-router";
import store from "@/store";
import {useTaskPage} from "@/api/useCommon";
const {
query: {courseId, pName, sName, chapterOrStageId, infoId, id, exname, btype, type},
} = useRoute();
const {nextPage,prevPage,hasPrev, hasNext} = useTaskPage()
const router = useRouter();
const returnclick = () => {
router.back();
};
const state = reactive({
datainfo: {}
})
//获取测评基本信息
useRequest(QueryEvaluationDetailById(courseId), {type}, (e)=>{
console.log(e)
state.datainfo = e.data
console.log('我是获取的外链基本信息12', state.dataInfo)
})
console.log('我是获取的外链基本信息4', state.dataInfo)
const userInfo = computed(() => store.state.userInfo);
// 查看测评
const handleClick = (evaluationTypeId) => {
// 调用接口 跳转页面
console.log('我是查询测评跳转链接所传递得参数',{
"businessType": btype==2 ? "learningpath" : "project",
"chapterId": chapterOrStageId,
"courseId": courseId,
"quizKid": evaluationTypeId,
"routerOrProjectId": infoId,
"studentId": userInfo.value.id,
"studentName": userInfo.value.realName
})
request(EvaluationToLearn, {
"businessType": "learningpath",
"chapterId": chapterOrStageId,
"courseId": courseId,
"quizKid": evaluationTypeId,
"routerOrProjectId": infoId,
"studentId": userInfo.value.id,
"studentName": userInfo.value.realName
}).then(res=>{
console.log(res)
if(res.code==200){
let jumpUrl = res.data.quizUrl
// 此处写跳转url
window.open( jumpUrl, '_top')
}
}).catch(err=>{
console.log(err)
})
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="scss">
.tijiao {
z-index: 999;
cursor: pointer;
margin-top: 22px;
margin-right: 40px;
width: 33px;
height: 16px;
font-size: 16px;
font-weight: 800;
color: #ffffff;
line-height: 24px;
border: 0;
background-color: #fff;
width: 162px;
height: 62px;
background-image: url("../../assets/image/tijiao.png");
}
.clearfix:before,
.clearfix:after {
content: "";
display: table;
clear: both;
}
.moreactive {
.crumb {
color: #fff;
display: flex;
font-size: 14px;
line-height: 24px;
position: relative;
}
.return{
position: absolute;
right: 10%;
.text{
text-align: center;
display: flex;
flex-direction: row;
align-items: center;
}
}
.preNext {
position: absolute;
right: 0px;
.content {
font-size: 14px;
color: #fff;
width: 43px;
height: 14px;
display: inline-block;
position: relative;
top: -6px;
cursor: pointer;
}
.btn {
width: 23px;
height: 23px;
border-radius: 50%;
border: 0;
cursor: pointer;
}
.btn01 {
background-image: url("../../assets/image/prev.png");
}
.btn02 {
background-image: url("../../assets/image/next.png");
}
}
.debateTitle {
margin-top: 15px;
font-size: 20px;
line-height: 24px;
height: 24px;
font-weight: 600;
color: #fff;
margin-left: -10px;
}
.detailinfo {
width: 100%;
margin-top: 20px;
display: flex;
.detail {
flex: 1;
// margin-right: 20px;
.detailT {
min-height: 95px;
background: #ffffff;
border-radius: 8px;
color: rgba(51, 51, 51, 1);
display: flex;
padding-bottom: 20px;
.left {
margin-left: 48px;
flex: 1;
}
.right {
width: 417px;
margin-right: 48px;
.righttitle {
display: flex;
padding-top: 39px;
position: relative;
.text {
margin-left: 8px;
font-size: 16px;
color: rgba(51, 51, 51, 1);
font-weight: 800;
}
.box {
width: 75px;
height: 10px;
background-color: rgba(36, 120, 255, 0.15);
position: absolute;
left: 23px;
top: 53px;
}
}
.timebox {
width: 417px;
height: 149px;
background: linear-gradient(90deg, #b6c6e1 0%, #89aed6 100%);
border-radius: 4px;
margin-top: 42px;
}
.innertime {
margin-top: 17px;
margin-left: 55px;
font-size: 14px;
font-weight: 500;
color: #ffffff;
line-height: 24px;
}
.endtime {
margin-left: 10px;
margin-top: 16px;
width: 397px;
height: 81px;
background: #f2f5f7;
border-radius: 0px 8px 0px 8px;
.endtimetext {
margin-top: 25px;
margin-left: 46px;
.te {
font-size: 28px;
font-weight: 800;
color: #4a9cf8;
line-height: 24px;
}
}
}
.explain {
margin-top: 30px;
width: 416px;
padding-bottom: 50px;
background: #f2f5f7;
border-radius: 8px;
}
.explaincontent {
width: 368px;
font-size: 16px;
font-weight: 500;
color: #333330;
line-height: 24px;
margin-left: 24px;
margin-top: 47px;
}
}
.title {
display: flex;
align-items: center;
padding-top: 39px;
position: relative;
}
.title .text {
margin-left: 8px;
font-size: 16px;
color: rgba(51, 51, 51, 1);
font-weight: 800;
}
.title .box {
width: 75px;
height: 10px;
background-color: rgba(36, 120, 255, 0.15);
position: absolute;
left: 23px;
top: 53px;
}
.all {
display: flex;
justify-content: space-between;
// width: 1280px;
margin-right: 48px;
margin-top: 43px;
.allbox1 {
margin-right: 22px;
background: linear-gradient(
0deg,
rgba(160, 193, 230, 0) 0%,
rgba(161, 195, 231, 0.2) 100%
);
}
.allbox2 {
margin-right: 22px;
background: linear-gradient(
0deg,
rgba(177, 219, 229, 0) 0%,
rgba(172, 216, 227, 0.2) 100%
);
}
.allbox3 {
background: linear-gradient(
0deg,
rgba(195, 209, 234, 0) 0%,
rgba(191, 206, 231, 0.2) 100%
);
}
.item {
// width: 410px;
width: calc(100% - 44px);
height: 149px;
text-align: center;
border-radius: 4px;
.item1 {
color: #089dff;
font-size: 24px;
font-weight: bold;
margin-top: 36px;
}
.item2 {
color: #333330;
font-size: 14px;
margin-top: 29px;
}
}
}
.join {
// width: 1280px;
margin-right: 48px;
// min-height: 408px;
// background: #f5f6f7;
// border-radius: 8px;
margin-top: 32px;
margin-left: 21px;
flex: 1;
.stem {
display: flex;
font-size: 16px;
font-weight: 500;
color: #333330;
line-height: 38px;
}
.options {
display: flex;
align-items: center;
flex-wrap: wrap;
}
.radio {
margin-top: 14px;
margin-left: -16px;
position: relative;
}
.radio label {
line-height: 20px;
position: relative;
display: flex;
align-items: center;
font-weight: normal;
.opt-text {
font-size: 14px;
font-weight: bold;
color: #333330;
line-height: 18px;
margin-left: 10px;
}
}
.radio .option {
width: 19px;
height: 18px;
// position: absolute;
// top: 1px;
// // top: 32px;
// left: 0px;
background-size: cover;
background: url(../../assets/image/noselect.png) no-repeat;
background-size: cover;
}
.radio input[type="radio"] {
display: inline-block;
margin-right: -3px;
opacity: 0;
}
.radio input[type="radio"]:checked + div {
background: url(../../assets/image/select.png) no-repeat;
background-size: cover;
}
.imgcontent {
display: flex;
.imgone {
width: 140px;
height: 140px;
border-radius: 8px;
background-image: url(../../assets/image/px.png);
background-size: 100% 100%;
background-position: center;
}
}
.ontitle {
margin-top: 27px;
font-size: 14px;
color: #333330;
}
}
}
.detailB {
min-height: 363px;
background: #ffffff;
border-radius: 8px;
margin-top: 20px;
.el-tabs__item {
height: 69px;
padding: 25px 7px 0px 52px;
font-size: 14px;
font-weight: 500;
}
.el-tabs__nav-wrap::after {
background-color: rgba(56, 125, 247, 0.2);
}
.enclosure {
height: 89px;
margin-left: 51px;
margin-right: 40px;
// border-bottom: 1px solid rgba(56, 125, 247, 0.2);
display: flex;
justify-content: space-between;
align-items: center;
.enclosureL {
display: flex;
align-items: center;
font-size: 14px;
font-weight: 400;
color: #677d86;
line-height: 24px;
}
.download {
display: flex;
align-items: center;
font-size: 16px;
font-weight: 400;
color: #2478ff;
line-height: 24px;
cursor: pointer;
}
}
.work {
margin-left: 51px;
margin-right: 40px;
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 37px;
}
.work .question {
font-size: 14px;
font-weight: 500;
color: #333330;
line-height: 18px;
}
.work .active {
width: 82px;
height: 28px;
background: linear-gradient(90deg, #a5d4e0 0%, #b4dce6 100%);
border-radius: 4px;
font-size: 14px;
font-weight: 500;
color: #ffffff;
line-height: 24px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
margin-right: 11px;
}
.work .unactive {
width: 80px;
height: 26px;
border: 1px solid #a5d4e0;
border-radius: 4px;
font-size: 14px;
font-weight: 500;
color: #a5d4e0;
line-height: 24px;
display: flex;
align-items: center;
justify-content: center;
margin-right: 11px;
cursor: pointer;
}
.work .btncolor {
background: linear-gradient(90deg, #84aad2 0%, #a4c5e9 100%);
}
.work .bordercolor {
border: 1px solid #85aad2;
}
.work .fontcolor {
color: rgba(133, 170, 210, 1);
}
.work .submit {
width: 126px;
height: 46px;
background: #2478ff;
box-shadow: 0px 1px 8px 0px rgba(56, 125, 247, 0.7);
border-radius: 4px;
font-size: 16px;
font-weight: 800;
color: #ffffff;
line-height: 24px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
}
}
}
}
}
</style>

View File

@@ -0,0 +1,578 @@
<template>
<div style=" background: #0078fc;height: 150px;width: 100%;position: absolute;top: 0;z-index:-9999;"></div>
<div class="moreactive" style="padding: 30px">
<!-- 面包屑导航 -->
<div class="crumb">
<div>{{ pName }}</div>
<div style="margin-left: 6px; margin-right: 6px">/</div>
<div>{{ sName }}</div>
<div style="margin-left: 6px; margin-right: 6px">/</div>
<div style="font-weight: 700; font-size: 16px">考试详情</div>
<div class="preNext">
<span @click="prevPage" v-if="hasPrev">
<button class="btn btn01"></button>
<span class="content" style="margin-left: 6px">上一个</span>
</span>
<span @click="nextPage" v-if="hasNext">
<span class="content" style="margin-left: 31px">下一个</span>
<button class="btn btn02" style="margin-left: 6px"></button>
</span>
</div>
<div class="return">
<div style="display: flex" @click="returnclick">
<el-button style="color:#0073FB"> <img class="img2" style="margin-right:11px;cursor: pointer;" src="../../assets/image/return.png" />返回</el-button>
</div>
</div>
</div>
<!-- 面包屑导航 -->
<!-- <div class="debateTitle">考试{{ dataInfo?.voteName }}</div> -->
<!-- 详细信息 -->
<div class="detailinfo">
<div class="detail">
<div class="detailT">
<div class="left">
<div class="debateTitle" style="color:rgba(51, 51, 51, 1);font-size:20px;margin-top:46px;">考试{{ exname }}</div>
<div class="title">
<img
style="width: 20px; height: 20px"
src="../../assets/image/yuan.png"
/>
<div class="text">数据来源</div>
<div class="box"></div>
</div>
<!-- <div style="display: flex; align-items: center"></div> -->
<div class="all" style="font-size:14px;color:rgba(51, 51, 48, 1);">
{{ state.datainfo.source ? state.datainfo.source : "-" }}
</div>
</div>
</div>
<div class="detailT" style="margin-top:20px;height:671px;">
<div class="left">
<div class="title">
<img
style="width: 20px; height: 20px"
src="../../assets/image/yuan.png"
/>
<div class="text">考试说明</div>
<div class="box"></div>
</div>
<!-- <div style="display: flex; align-items: center"></div> -->
<div class="all" style="font-size:14px;color:rgba(51, 51, 48, 1);">
<div>
{{ state.datainfo.externalExplain ? state.datainfo.externalExplain : "暂无考试说明" }}
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 详细信息 -->
</div>
</template>
<script setup>
import {useRequest, request} from "@/api/request";
import {
VOTE_DETAIL2,
EXTERNALEXAM
} from "@/api/api";
import {reactive} from "vue";
import {useRoute,useRouter} from "vue-router/dist/vue-router";
import {useTaskPage} from "@/api/useCommon";
const {
query: {courseId, pName, sName, chapterOrStageId, infoId, id, exname, type},
} = useRoute();
const {nextPage,prevPage,hasPrev, hasNext} = type==3 ? '' : useTaskPage()
const router = useRouter();
const returnclick = () => {
router.back();
};
const state = reactive({
datainfo: {}
})
//获取基本信息
request(EXTERNALEXAM, {externalId:courseId, type}).then(res=>{
console.log(res)
state.datainfo = res.data
}).catch(err=>{
console.log(err)
});
console.log('我是获取的考试基本信息', state.dataInfo)
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="scss">
.clearfix:before,
.clearfix:after {
content: "";
display: table;
clear: both;
}
.moreactive {
.crumb {
color: #fff;
display: flex;
font-size: 14px;
line-height: 24px;
position: relative;
}
.return{
position: absolute;
right: 10%;
.text{
text-align: center;
display: flex;
flex-direction: row;
align-items: center;
}
}
.preNext {
position: absolute;
right: 0px;
.content {
font-size: 14px;
color: #fff;
width: 43px;
height: 14px;
display: inline-block;
position: relative;
top: -6px;
cursor: pointer;
}
.btn {
width: 23px;
height: 23px;
border-radius: 50%;
border: 0;
cursor: pointer;
}
.btn01 {
background-image: url("../../assets/image/prev.png");
}
.btn02 {
background-image: url("../../assets/image/next.png");
}
}
.debateTitle {
margin-top: 15px;
font-size: 20px;
line-height: 24px;
height: 24px;
font-weight: 600;
color: #fff;
margin-left: -10px;
}
.detailinfo {
width: 100%;
margin-top: 20px;
display: flex;
.detail {
flex: 1;
// margin-right: 20px;
.detailT {
min-height: 95px;
background: #ffffff;
border-radius: 8px;
color: rgba(51, 51, 51, 1);
display: flex;
padding-bottom: 20px;
.left {
margin-left: 48px;
flex: 1;
}
.right {
width: 417px;
margin-right: 48px;
.righttitle {
display: flex;
padding-top: 39px;
position: relative;
.text {
margin-left: 8px;
font-size: 16px;
color: rgba(51, 51, 51, 1);
font-weight: 800;
}
.box {
width: 75px;
height: 10px;
background-color: rgba(36, 120, 255, 0.15);
position: absolute;
left: 23px;
top: 53px;
}
}
.timebox {
width: 417px;
height: 149px;
background: linear-gradient(90deg, #b6c6e1 0%, #89aed6 100%);
border-radius: 4px;
margin-top: 42px;
}
.innertime {
margin-top: 17px;
margin-left: 55px;
font-size: 14px;
font-weight: 500;
color: #ffffff;
line-height: 24px;
}
.endtime {
margin-left: 10px;
margin-top: 16px;
width: 397px;
height: 81px;
background: #f2f5f7;
border-radius: 0px 8px 0px 8px;
.endtimetext {
margin-top: 25px;
margin-left: 46px;
.te {
font-size: 28px;
font-weight: 800;
color: #4a9cf8;
line-height: 24px;
}
}
}
.explain {
margin-top: 30px;
width: 416px;
padding-bottom: 50px;
background: #f2f5f7;
border-radius: 8px;
}
.explaincontent {
width: 368px;
font-size: 16px;
font-weight: 500;
color: #333330;
line-height: 24px;
margin-left: 24px;
margin-top: 47px;
}
}
.title {
display: flex;
align-items: center;
padding-top: 39px;
position: relative;
}
.title .text {
margin-left: 8px;
font-size: 16px;
color: rgba(51, 51, 51, 1);
font-weight: 800;
}
.title .box {
width: 75px;
height: 10px;
background-color: rgba(36, 120, 255, 0.15);
position: absolute;
left: 23px;
top: 53px;
}
.all {
display: flex;
justify-content: space-between;
// width: 1280px;
margin-right: 48px;
margin-top: 43px;
.allbox1 {
margin-right: 22px;
background: linear-gradient(
0deg,
rgba(160, 193, 230, 0) 0%,
rgba(161, 195, 231, 0.2) 100%
);
}
.allbox2 {
margin-right: 22px;
background: linear-gradient(
0deg,
rgba(177, 219, 229, 0) 0%,
rgba(172, 216, 227, 0.2) 100%
);
}
.allbox3 {
background: linear-gradient(
0deg,
rgba(195, 209, 234, 0) 0%,
rgba(191, 206, 231, 0.2) 100%
);
}
.item {
// width: 410px;
width: calc(100% - 44px);
height: 149px;
text-align: center;
border-radius: 4px;
.item1 {
color: #089dff;
font-size: 24px;
font-weight: bold;
margin-top: 36px;
}
.item2 {
color: #333330;
font-size: 14px;
margin-top: 29px;
}
}
}
.join {
// width: 1280px;
margin-right: 48px;
// min-height: 408px;
// background: #f5f6f7;
// border-radius: 8px;
margin-top: 32px;
margin-left: 21px;
flex: 1;
.stem {
display: flex;
font-size: 16px;
font-weight: 500;
color: #333330;
line-height: 38px;
}
.options {
display: flex;
align-items: center;
flex-wrap: wrap;
}
.radio {
margin-top: 14px;
margin-left: -16px;
position: relative;
}
.radio label {
line-height: 20px;
position: relative;
display: flex;
align-items: center;
font-weight: normal;
.opt-text {
font-size: 14px;
font-weight: bold;
color: #333330;
line-height: 18px;
margin-left: 10px;
}
}
.radio .option {
width: 19px;
height: 18px;
// position: absolute;
// top: 1px;
// // top: 32px;
// left: 0px;
background-size: cover;
background: url(../../assets/image/noselect.png) no-repeat;
background-size: cover;
}
.radio input[type="radio"] {
display: inline-block;
margin-right: -3px;
opacity: 0;
}
.radio input[type="radio"]:checked + div {
background: url(../../assets/image/select.png) no-repeat;
background-size: cover;
}
.imgcontent {
display: flex;
.imgone {
width: 140px;
height: 140px;
border-radius: 8px;
background-image: url(../../assets/image/px.png);
background-size: 100% 100%;
background-position: center;
}
}
.ontitle {
margin-top: 27px;
font-size: 14px;
color: #333330;
}
}
}
.detailB {
min-height: 363px;
background: #ffffff;
border-radius: 8px;
margin-top: 20px;
.el-tabs__item {
height: 69px;
padding: 25px 7px 0px 52px;
font-size: 14px;
font-weight: 500;
}
.el-tabs__nav-wrap::after {
background-color: rgba(56, 125, 247, 0.2);
}
.enclosure {
height: 89px;
margin-left: 51px;
margin-right: 40px;
// border-bottom: 1px solid rgba(56, 125, 247, 0.2);
display: flex;
justify-content: space-between;
align-items: center;
.enclosureL {
display: flex;
align-items: center;
font-size: 14px;
font-weight: 400;
color: #677d86;
line-height: 24px;
}
.download {
display: flex;
align-items: center;
font-size: 16px;
font-weight: 400;
color: #2478ff;
line-height: 24px;
cursor: pointer;
}
}
.work {
margin-left: 51px;
margin-right: 40px;
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 37px;
}
.work .question {
font-size: 14px;
font-weight: 500;
color: #333330;
line-height: 18px;
}
.work .active {
width: 82px;
height: 28px;
background: linear-gradient(90deg, #a5d4e0 0%, #b4dce6 100%);
border-radius: 4px;
font-size: 14px;
font-weight: 500;
color: #ffffff;
line-height: 24px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
margin-right: 11px;
}
.work .unactive {
width: 80px;
height: 26px;
border: 1px solid #a5d4e0;
border-radius: 4px;
font-size: 14px;
font-weight: 500;
color: #a5d4e0;
line-height: 24px;
display: flex;
align-items: center;
justify-content: center;
margin-right: 11px;
cursor: pointer;
}
.work .btncolor {
background: linear-gradient(90deg, #84aad2 0%, #a4c5e9 100%);
}
.work .bordercolor {
border: 1px solid #85aad2;
}
.work .fontcolor {
color: rgba(133, 170, 210, 1);
}
.work .submit {
width: 126px;
height: 46px;
background: #2478ff;
box-shadow: 0px 1px 8px 0px rgba(56, 125, 247, 0.7);
border-radius: 4px;
font-size: 16px;
font-weight: 800;
color: #ffffff;
line-height: 24px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
}
}
}
}
}
</style>

View File

@@ -0,0 +1,614 @@
<template>
<div style=" background: #0078fc;height: 150px;width: 100%;position: absolute;top: 0;z-index:-9999;"></div>
<div class="moreactive" style="padding: 30px">
<!-- 面包屑导航 -->
<div class="crumb">
<div>{{ pName }}</div>
<div style="margin-left: 6px; margin-right: 6px">/</div>
<div>{{ sName }}</div>
<div style="margin-left: 6px; margin-right: 6px">/</div>
<div style="font-weight: 700; font-size: 16px">外链详情</div>
<div class="preNext">
<span @click="prevPage" v-if="hasPrev">
<button class="btn btn01"></button>
<span class="content" style="margin-left: 6px">上一个</span>
</span>
<span @click="nextPage" v-if="hasNext">
<span class="content" style="margin-left: 31px">下一个</span>
<button class="btn btn02" style="margin-left: 6px"></button>
</span>
</div>
<div class="return">
<div style="display: flex" @click="returnclick">
<el-button style="color:#0073FB"> <img class="img2" style="margin-right:11px;cursor: pointer;" src="../../assets/image/return.png" />返回</el-button>
</div>
</div>
</div>
<!-- 面包屑导航 -->
<!-- <div class="debateTitle">考试{{ dataInfo?.voteName }}</div> -->
<!-- 详细信息 -->
<div class="detailinfo">
<div class="detail">
<div class="detailT">
<div class="left">
<div class="debateTitle" style="color:rgba(51, 51, 51, 1);font-size:20px;margin-top:46px;">外链{{ exname }}</div>
<div style="display: flex;justify-content: space-between;align-items: center;">
<div class="title">
<img
style="width: 20px; height: 20px"
src="../../assets/image/yuan.png"
/>
<div class="text">链接网址</div>
<div class="box"></div>
</div>
<div class="">
<button class="tijiao" @click="handleClick(datainfo.linkAddress)">查看</button>
</div>
</div>
<div class="all" style="font-size:14px;color:rgba(51, 51, 48, 1);">
{{ datainfo.linkAddress ? datainfo.linkAddress : "-" }}
</div>
</div>
</div>
<div class="detailT" style="margin-top:20px;height:671px;">
<div class="left">
<div class="title">
<img
style="width: 20px; height: 20px"
src="../../assets/image/yuan.png"
/>
<div class="text">链接说明</div>
<div class="box"></div>
</div>
<!-- <div style="display: flex; align-items: center"></div> -->
<div class="all" style="font-size:14px;color:rgba(51, 51, 48, 1);">
<div>
{{ datainfo.linkDescription ? datainfo.linkDescription : "暂无链接说明" }}
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 详细信息 -->
</div>
</template>
<script setup>
import {useRequest, request} from "@/api/request";
import {
LINKGETONE
} from "@/api/api";
import {ref} from "vue";
import {useRoute,useRouter} from "vue-router/dist/vue-router";
import {useTaskPage} from "@/api/useCommon";
const {
query: {courseId, pName, sName, chapterOrStageId, infoId, id, exname, type},
} = useRoute();
const {nextPage,prevPage,hasPrev, hasNext} = useTaskPage()
const router = useRouter();
const returnclick = () => {
router.back();
};
const datainfo = ref({});
//获取基本信息
request(LINKGETONE, {linkId:courseId,type}).then(res=>{
console.log("我是获取的外链基本信息1",res)
datainfo.value = res.data;
console.log("我是获取的外链基本信息2",datainfo.value)
}).catch(err=>{
console.log(err)
});
// 查看外链
const handleClick = async(url) => {
console.log('我是获取的外链基本信息', datainfo.value)
// await request(UPDATE_CURRENT_TASK, { id: d.id, type: PROJECT, pid: projectId, name: d.name })
// if ( d.type == 7 ) {
// d.status !== 1 && await request(STUDY_RECORD, {
// studentId: userInfo.value.id,
// targetId: data.value.routerId,
// logo: PROJECT,
// type: PROJECT,
// stageOrChapterId: chapterOrStageId,
// taskId: d.id,
// taskType: d.type,
// });
// }
window.open(url);
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="scss">
.tijiao {
z-index: 999;
cursor: pointer;
margin-top: 22px;
margin-right: 40px;
width: 33px;
height: 16px;
font-size: 16px;
font-weight: 800;
color: #ffffff;
line-height: 24px;
border: 0;
background-color: #fff;
width: 162px;
height: 62px;
background-image: url("../../assets/image/tijiao.png");
}
.clearfix:before,
.clearfix:after {
content: "";
display: table;
clear: both;
}
.moreactive {
.crumb {
color: #fff;
display: flex;
font-size: 14px;
line-height: 24px;
position: relative;
}
.return{
position: absolute;
right: 10%;
.text{
text-align: center;
display: flex;
flex-direction: row;
align-items: center;
}
}
.preNext {
position: absolute;
right: 0px;
.content {
font-size: 14px;
color: #fff;
width: 43px;
height: 14px;
display: inline-block;
position: relative;
top: -6px;
cursor: pointer;
}
.btn {
width: 23px;
height: 23px;
border-radius: 50%;
border: 0;
cursor: pointer;
}
.btn01 {
background-image: url("../../assets/image/prev.png");
}
.btn02 {
background-image: url("../../assets/image/next.png");
}
}
.debateTitle {
margin-top: 15px;
font-size: 20px;
line-height: 24px;
height: 24px;
font-weight: 600;
color: #fff;
margin-left: -10px;
}
.detailinfo {
width: 100%;
margin-top: 20px;
display: flex;
.detail {
flex: 1;
// margin-right: 20px;
.detailT {
min-height: 95px;
background: #ffffff;
border-radius: 8px;
color: rgba(51, 51, 51, 1);
display: flex;
padding-bottom: 20px;
.left {
margin-left: 48px;
flex: 1;
}
.right {
width: 417px;
margin-right: 48px;
.righttitle {
display: flex;
padding-top: 39px;
position: relative;
.text {
margin-left: 8px;
font-size: 16px;
color: rgba(51, 51, 51, 1);
font-weight: 800;
}
.box {
width: 75px;
height: 10px;
background-color: rgba(36, 120, 255, 0.15);
position: absolute;
left: 23px;
top: 53px;
}
}
.timebox {
width: 417px;
height: 149px;
background: linear-gradient(90deg, #b6c6e1 0%, #89aed6 100%);
border-radius: 4px;
margin-top: 42px;
}
.innertime {
margin-top: 17px;
margin-left: 55px;
font-size: 14px;
font-weight: 500;
color: #ffffff;
line-height: 24px;
}
.endtime {
margin-left: 10px;
margin-top: 16px;
width: 397px;
height: 81px;
background: #f2f5f7;
border-radius: 0px 8px 0px 8px;
.endtimetext {
margin-top: 25px;
margin-left: 46px;
.te {
font-size: 28px;
font-weight: 800;
color: #4a9cf8;
line-height: 24px;
}
}
}
.explain {
margin-top: 30px;
width: 416px;
padding-bottom: 50px;
background: #f2f5f7;
border-radius: 8px;
}
.explaincontent {
width: 368px;
font-size: 16px;
font-weight: 500;
color: #333330;
line-height: 24px;
margin-left: 24px;
margin-top: 47px;
}
}
.title {
display: flex;
align-items: center;
padding-top: 39px;
position: relative;
}
.title .text {
margin-left: 8px;
font-size: 16px;
color: rgba(51, 51, 51, 1);
font-weight: 800;
}
.title .box {
width: 75px;
height: 10px;
background-color: rgba(36, 120, 255, 0.15);
position: absolute;
left: 23px;
top: 53px;
}
.all {
display: flex;
justify-content: space-between;
// width: 1280px;
margin-right: 48px;
margin-top: 43px;
.allbox1 {
margin-right: 22px;
background: linear-gradient(
0deg,
rgba(160, 193, 230, 0) 0%,
rgba(161, 195, 231, 0.2) 100%
);
}
.allbox2 {
margin-right: 22px;
background: linear-gradient(
0deg,
rgba(177, 219, 229, 0) 0%,
rgba(172, 216, 227, 0.2) 100%
);
}
.allbox3 {
background: linear-gradient(
0deg,
rgba(195, 209, 234, 0) 0%,
rgba(191, 206, 231, 0.2) 100%
);
}
.item {
// width: 410px;
width: calc(100% - 44px);
height: 149px;
text-align: center;
border-radius: 4px;
.item1 {
color: #089dff;
font-size: 24px;
font-weight: bold;
margin-top: 36px;
}
.item2 {
color: #333330;
font-size: 14px;
margin-top: 29px;
}
}
}
.join {
// width: 1280px;
margin-right: 48px;
// min-height: 408px;
// background: #f5f6f7;
// border-radius: 8px;
margin-top: 32px;
margin-left: 21px;
flex: 1;
.stem {
display: flex;
font-size: 16px;
font-weight: 500;
color: #333330;
line-height: 38px;
}
.options {
display: flex;
align-items: center;
flex-wrap: wrap;
}
.radio {
margin-top: 14px;
margin-left: -16px;
position: relative;
}
.radio label {
line-height: 20px;
position: relative;
display: flex;
align-items: center;
font-weight: normal;
.opt-text {
font-size: 14px;
font-weight: bold;
color: #333330;
line-height: 18px;
margin-left: 10px;
}
}
.radio .option {
width: 19px;
height: 18px;
// position: absolute;
// top: 1px;
// // top: 32px;
// left: 0px;
background-size: cover;
background: url(../../assets/image/noselect.png) no-repeat;
background-size: cover;
}
.radio input[type="radio"] {
display: inline-block;
margin-right: -3px;
opacity: 0;
}
.radio input[type="radio"]:checked + div {
background: url(../../assets/image/select.png) no-repeat;
background-size: cover;
}
.imgcontent {
display: flex;
.imgone {
width: 140px;
height: 140px;
border-radius: 8px;
background-image: url(../../assets/image/px.png);
background-size: 100% 100%;
background-position: center;
}
}
.ontitle {
margin-top: 27px;
font-size: 14px;
color: #333330;
}
}
}
.detailB {
min-height: 363px;
background: #ffffff;
border-radius: 8px;
margin-top: 20px;
.el-tabs__item {
height: 69px;
padding: 25px 7px 0px 52px;
font-size: 14px;
font-weight: 500;
}
.el-tabs__nav-wrap::after {
background-color: rgba(56, 125, 247, 0.2);
}
.enclosure {
height: 89px;
margin-left: 51px;
margin-right: 40px;
// border-bottom: 1px solid rgba(56, 125, 247, 0.2);
display: flex;
justify-content: space-between;
align-items: center;
.enclosureL {
display: flex;
align-items: center;
font-size: 14px;
font-weight: 400;
color: #677d86;
line-height: 24px;
}
.download {
display: flex;
align-items: center;
font-size: 16px;
font-weight: 400;
color: #2478ff;
line-height: 24px;
cursor: pointer;
}
}
.work {
margin-left: 51px;
margin-right: 40px;
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 37px;
}
.work .question {
font-size: 14px;
font-weight: 500;
color: #333330;
line-height: 18px;
}
.work .active {
width: 82px;
height: 28px;
background: linear-gradient(90deg, #a5d4e0 0%, #b4dce6 100%);
border-radius: 4px;
font-size: 14px;
font-weight: 500;
color: #ffffff;
line-height: 24px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
margin-right: 11px;
}
.work .unactive {
width: 80px;
height: 26px;
border: 1px solid #a5d4e0;
border-radius: 4px;
font-size: 14px;
font-weight: 500;
color: #a5d4e0;
line-height: 24px;
display: flex;
align-items: center;
justify-content: center;
margin-right: 11px;
cursor: pointer;
}
.work .btncolor {
background: linear-gradient(90deg, #84aad2 0%, #a4c5e9 100%);
}
.work .bordercolor {
border: 1px solid #85aad2;
}
.work .fontcolor {
color: rgba(133, 170, 210, 1);
}
.work .submit {
width: 126px;
height: 46px;
background: #2478ff;
box-shadow: 0px 1px 8px 0px rgba(56, 125, 247, 0.7);
border-radius: 4px;
font-size: 16px;
font-weight: 800;
color: #ffffff;
line-height: 24px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
}
}
}
}
}
</style>

View File

@@ -41,6 +41,14 @@ export default defineConfig(({ command, mode }) =>
target: loadEnv(mode, process.cwd()).VITE_PROXY_URL,
changeOrigin: true,
},
'/file/img': {
target: loadEnv(mode, process.cwd()).VITE_PROXY_URL,
changeOrigin: true,
},
'/file/stuUploadAnnex': {
target: loadEnv(mode, process.cwd()).VITE_PROXY_URL,
changeOrigin: true,
},
'/stu': {
target: loadEnv(mode, process.cwd()).VITE_PROXY_URL,
changeOrigin: true,
@@ -96,7 +104,70 @@ export default defineConfig(({ command, mode }) =>
}, '/onlineClasses/queryOnlineClassesStudyDetail': {
target: loadEnv(mode, process.cwd()).VITE_PROXY_URL,
changeOrigin: true,
},
},'/external/exam/queryExternalExam': {
target: loadEnv(mode, process.cwd()).VITE_PROXY_URL,
changeOrigin: true,
},'/link/getOne': {
target: loadEnv(mode, process.cwd()).VITE_PROXY_URL,
changeOrigin: true,
},'/evaluation/evaluationToLearn': {
target: loadEnv(mode, process.cwd()).VITE_PROXY_URL,
changeOrigin: true,
},'/evaluation/queryEvaluationDetailById': {
target: loadEnv(mode, process.cwd()).VITE_PROXY_URL,
changeOrigin: true,
},'/statement/add': {
target: loadEnv(mode, process.cwd()).VITE_PROXY_URL,
changeOrigin: true,
},'/statement/collection': {
target: loadEnv(mode, process.cwd()).VITE_PROXY_URL,
changeOrigin: true,
},'/statement/delete': {
target: loadEnv(mode, process.cwd()).VITE_PROXY_URL,
changeOrigin: true,
},'/statement/praise': {
target: loadEnv(mode, process.cwd()).VITE_PROXY_URL,
changeOrigin: true,
},'/statement/update': {
target: loadEnv(mode, process.cwd()).VITE_PROXY_URL,
changeOrigin: true,
},'/statement/list': {
target: loadEnv(mode, process.cwd()).VITE_PROXY_URL,
changeOrigin: true,
},'/stu/externalExam/submitExternalExam': {
target: loadEnv(mode, process.cwd()).VITE_PROXY_URL,
changeOrigin: true,
},'/comment/list': {
target: loadEnv(mode, process.cwd()).VITE_PROXY_URL,
changeOrigin: true,
},'/comment/add': {
target: loadEnv(mode, process.cwd()).VITE_PROXY_URL,
changeOrigin: true,
},'/comment/praise': {
target: loadEnv(mode, process.cwd()).VITE_PROXY_URL,
changeOrigin: true,
},'/comment/collection': {
target: loadEnv(mode, process.cwd()).VITE_PROXY_URL,
changeOrigin: true,
},'/statement/info': {
target: loadEnv(mode, process.cwd()).VITE_PROXY_URL,
changeOrigin: true,
},'/statement/getComments': {
target: loadEnv(mode, process.cwd()).VITE_PROXY_URL,
changeOrigin: true,
},'/statement/getMoreComments': {
target: loadEnv(mode, process.cwd()).VITE_PROXY_URL,
changeOrigin: true,
},'/vote/queryVoteById': {
target: loadEnv(mode, process.cwd()).VITE_PROXY_URL,
changeOrigin: true,
},'/evaluation/queryEvaluationTaskStatusOne': {
target: loadEnv(mode, process.cwd()).VITE_PROXY_URL,
changeOrigin: true,
},'/vote/editVoteInvolvedAndBrowse': {
target: loadEnv(mode, process.cwd()).VITE_PROXY_URL,
changeOrigin: true,
}
}
}
})