Merge branch 'develop' of http://gitlab.dongwu-inc.com:10080/BOE/fe-stu into develop

This commit is contained in:
dongruihua
2022-12-14 15:37:53 +08:00
27 changed files with 3658 additions and 2026 deletions

1883
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -2,7 +2,7 @@
* @Author: lixg lixg@dongwu-inc.com
* @Date: 2022-11-21 17:28:10
* @LastEditors: lixg lixg@dongwu-inc.com
* @LastEditTime: 2022-11-22 12:54:09
* @LastEditTime: 2022-12-13 22:10:22
* @FilePath: /fe-stu/src/App.vue
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
-->
@@ -34,12 +34,17 @@ export default defineComponent({
const router = useRouter();
const route = useRoute();
console.log("router", router.getRoutes(), route);
console.log(import.meta.env.DEV);
const routes = computed(() => {
return router.getRoutes().filter((e) => e.meta?.isLink);
});
const currentRouteName = computed(() => route.name);
// localStorage.setItem(
// "token",
// "eyJ0eXBlIjoidG9rZW4iLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOlwvXC91LmJvZS5jb20iLCJpYXQiOjE2NzA3NjExNzIsImV4cCI6MTY3MDc2ODM3MiwiR2l2ZW5OYW1lIjoiYm9ldSIsInVzZXJJZCI6IjZCMDQ5RkFGLUMzMTQtN0NDRi0wRDI4LTBEMjNGNEM0MjUzMSIsInVJZCI6Ijk2NTM0MjAyNzQ5NzYwNzE2OCIsInBlcm1pc3Npb24iOiIifQ==.9e8c4d3933c3a6d9b660e0b849940c813e1c245b3d17646ff7a793100640bc42"
// );
return {
routes,
name: currentRouteName,
@@ -97,7 +102,7 @@ export default defineComponent({
main {
flex: 1;
width: 100%;
padding: 30px;
// padding: 30px;
box-sizing: border-box;
}
}

5
src/api/ThirdApi.js Normal file
View File

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

View File

@@ -1,29 +1,55 @@
export const BASE = 'http://localhost:3000'
/*
* @Author: lixg lixg@dongwu-inc.com
* @Date: 2022-12-11 16:57:58
* @LastEditors: lixg lixg@dongwu-inc.com
* @LastEditTime: 2022-12-12 17:05:42
* @FilePath: /fe-stu/src/api/api.js
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
export const BASE = import.meta.env.DEV ? '' : '/manageApi'
export const BASE_URL = import.meta.env.DEV ? '' : 'https://u-pre.boe.com/fe-student'
export const LOGIN = '/admin/CheckUser/userLogin post'
// export const FILE_UPLOAD = 'http://111.231.196.214:30001/file/upload'
export const FILE_UPLOAD = '/file/upload'
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'
export const ROUTER_PROCESS = '/stu/router/process'
export const ROUTER_UNCOMPLETE_LIST = '/stu/router/unCompleteTaskList'
export const TAS_ACTIVITY_DETAIL = '/stu/task/activity/detail'
export const TASK_ACTIVITY_SIGN = '/stu/task/activity/sign'
export const PROJECT_PROCESS = '/stu/project/process'
export const ROUTER_UNCOMPLETE_LIST = '/stu/router/unCompleteTaskList post'
export const TAS_ACTIVITY_DETAIL = '/activity'
export const TASK_ACTIVITY_SIGN = '/activitySubmit/updateActivitySignInStatus post'
export const TASK_BROADCAST_COMMIT = '/stu/task/broadcast/commit'
export const TASK_BROADCAST_DETAIL = '/stu/task/broadcast/detail'
export const TASK_BROADCAST_DETAIL = '/liveBroadcast'
export const TASK_BROADCAST_SIGN = '/stu/task/broadcast/sign'
export const TASK_VOTE_COMMIT = '/stu/task/vote/commit'
export const TASK_VOTE_DETAIL = '/stu/task/vote/detail'
export const TASK_WORK_COMMIT = '/stu/task/work/commit'
export const TASK_WORK_DETAIL = '/stu/task/work/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 VOTE_DETAIL = '/queryVoteSubmitDetailById'
export const TASK_VOTE_LIST = '/queryVoteSubmitDetailListByTaskId'
export const STU_OFFCOURSE_DETAIL = '/stu/offcourse/detail'
export const STU_OFFCOURSE_DETAIL = '/stu/offcourse/detail post'
export const WORK_QUERYWORKDETAILBYID = '/work/queryWorkDetailById'
export const WORK_HISTROY = '/workSubmit/queryWorkDetailListByStuId'
export const EXAMINATION_QUERYEXAMINATIONDETAILBYID = '/examination/queryExaminationDetailById'
export const DISCUSS_COLLECTION = '/discussSubmit/clickDiscussCollectionCountOr POST'
export const DISCUSS_LIKE = '/discussSubmit/clickDiscussLikeCountOr POST'
export const DISCUSS_LIST = '/discussSubmit/queryDiscussSubmitDetailByDiscussId'
export const DISCUSS_DETAIL = '/discuss/getDiscussDetail'
export const EXAMINATION_QUERY = examinationId => `/examination/queryExaminationDetailById?examinationId=${examinationId} post`
export const DISCUSS_LIKE = '/discussSubmit/clickDiscussLikeCountOr post'
export const DISCUSS_LIST = '/discussSubmit/taskList'
export const DISCUSS_DETAIL = '/discussSubmit/detail'
export const DISCUSS_SUBMIT_REVIEW_LIST = '/discussSubmit/queryDiscussSubmitAndReview'
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 COMMENT_COLLECTION = '/comment/collection post'
export const ASSESSMENT_SUBMIT_QUERY = assessmentId => `/assessmentSubmit/queryAssessmentSubmitDetailById?assessmentSubmitId=${assessmentId} post`
export const ASSESSMENT_QUERY = assessmentId => `/assessment/queryAssessmentDetailById?assessmentId=${assessmentId} post`
export const ASSESSMENT_SUBMIT = '/assessmentSubmit/submitAssessmentDetail'
export const ACTIVITY = '/activity'

View File

@@ -1,28 +1,66 @@
import router from "@/router";
import {ref, watch} from "vue";
import {reactive, ref, toRefs, watch} from "vue";
import axios from 'axios';
import {getCookie} from "@/api/utils";
import {BASE} from "@/api/api";
export function usePage(_url, param) {
const state = reactive({
data: {},
loading: false,
total: 0,
size: 10,
current: 1,
params: {pageNo: 1, pageSize: 10, ...param}
})
watch(param, () => {
state.params = {...state.params, ...param}
fetchData()
})
function fetchData() {
state.loading = true
request(_url, state.params).then(r => {
state.params.pageNo === 1 ? (state.data = (r.data.records || r.data.rows)) : (state.data = [...state.data, ...(r.data.records || r.data.rows)])
state.size = r.data.size
state.total = r.data.total
state.current = r.data.current
state.loading = false
})
}
fetchData()
return {
...toRefs(state),
fetchData,
};
}
export function useRequest(_url, params = {}) {
const data = ref({})
const loading = ref(false)
const state = reactive({
data: {},
loading: false,
})
watch(params, () => {
fetchData()
})
function fetchData() {
loading.value = true
state.loading = true
request(_url, params).then(r => {
data.value = r.data
loading.value = false
state.data = r.data
state.loading = false
})
}
fetchData()
return {
data,
loading,
...toRefs(state),
fetchData,
};
}
@@ -30,7 +68,7 @@ export function useRequest(_url, params = {}) {
export async function request(_url, params) {
const s = _url.split(' ')
let url = s[0]
const method = s[1] || 'get'
const method = s[1]?.toLowerCase() || 'get'
if (method === 'get') {
let paramsArray = [];
//拼接参数
@@ -51,20 +89,21 @@ export async function request(_url, params) {
'X-Token': localStorage.getItem('token'),
...method !== 'get' ? {'Content-Type': 'application/json'} : {}
},
baseURL: '',
baseURL: BASE,
...method !== 'get' ? {data: JSON.stringify(body)} : {}
}).then(resp=>resp.data).then(response => {
}).then(resp => resp.data).then(response => {
if (response.code !== 200 && response.code !== 0) {
if (response.code === 3 || response.code === 4 || response.code === 100) {
// router.push({path: '/login'})
return
console.log(1111111111)
console.log(response.code)
if (import.meta.env.DEV && response.code === 1000) {
router.push({path: '/login'})
} else {
// response.showMsg && notification.open({
// message: response.showMsg,
// duration: 2,
// });
return
// response.showMsg && notification.open({
// message: response.showMsg,
// duration: 2,
// });
}
throw new Error('接口异常')
}
return response
}).catch(e => {
@@ -72,4 +111,39 @@ export async function request(_url, params) {
console.log(e)
// router.push({path: '/login'})
})
}
export async function boeRequest(_url, params) {
const s = _url.split(' ')
let url = s[0]
const method = s[1]?.toLowerCase() || 'get'
if (method === 'get') {
let paramsArray = [];
//拼接参数
if (params) {
Object.keys(params).forEach(key => paramsArray.push(key + '=' + params[key]))
if (url.search(/\?/) === -1) {
url += '?' + paramsArray.join('&')
} else {
url += '&' + paramsArray.join('&')
}
}
}
const body = method !== 'get' ? params || {} : {}
return axios({
url,
method,
headers: {
token: getCookie('token'),
...method !== 'get' ? {'Content-Type': 'application/json'} : {}
},
baseURL: '',
...method !== 'get' ? {data: JSON.stringify(body)} : {}
}).then(resp => resp.data).then(response => {
return response
}).catch(e => {
console.log(2222)
console.log(e)
// router.push({path: '/login'})
})
}

View File

@@ -1,3 +1,30 @@
export function useImage(src){
import {watch, ref} from "vue";
import {boeRequest} from "@/api/request";
import {BASE, GET_USER_LIST} from "@/api/ThirdApi";
const BASE_AVATAR = import.meta.env.DEV ? `${BASE}/upload` : ''
export function useImage(src) {
return new URL(`../assets/image/${src}`, import.meta.url).href
}
export function setCookie(name, value, perpetual) {
const d = new Date()
d.setDate(perpetual * 24 * 60 * 60 * 1000)
document.cookie = `${name}=${value};expires=${d.toGMTString()};path=/`
}
export function getCookie(name) {
return document.cookie?.split(";").find(e => e.includes(name)).replace(`${name}=`, '') || ''
}
export function useUserInfo(id) {
const userInfo = ref({})
watch(id, () => {
id.value && boeRequest(GET_USER_LIST, {id: id.value}).then(res => {
userInfo.value = res.result.userInfoList[0]
userInfo.value.avatar = BASE_AVATAR + userInfo.value.avatar
})
})
return userInfo
}

View File

@@ -1,13 +1,14 @@
html,
body {
height: 100vh;
margin: 0;
padding: 0;
// overflow-y: auto;
height: 100vh;
margin: 0;
padding: 0;
// overflow-y: auto;
}
//标签tag样式-----------------------------------------------------------------
// 必修
.tag1{
.tag1 {
width: 80px;
height: 26px;
border: 1px solid #51C6E6;
@@ -19,8 +20,9 @@ body {
font-weight: bold;
color: #51C6E6;
}
// 选修
.tag2{
.tag2 {
width: 80px;
height: 26px;
border: 1px solid #CD7FED;
@@ -32,8 +34,9 @@ body {
font-weight: bold;
color: #CD7FED;
}
// 在线 面授 测评 外部链接 作业 辩论等
.tag3{
.tag3 {
height: 26px;
border: 1px solid #7F96ED;
border-radius: 4px;
@@ -43,12 +46,13 @@ body {
font-size: 14px;
font-weight: bold;
color: #7F96ED;
padding-left:25px ;
padding-left: 25px;
padding-right: 25px;
}
// 标签
.tag4{
padding-left:15px ;
.tag4 {
padding-left: 15px;
padding-right: 12px;
height: 24px;
border: 1px solid rgba(255, 185, 109, 1);
@@ -63,18 +67,39 @@ body {
//标签tag样式-----------------------------------------------------------------
//进度条样式
.progress10{
background-color:rgba(238, 112, 108, 1) !important;
.progress10 {
background-color: rgba(238, 112, 108, 1) !important;
}
.progress30{
background-color:rgba(255, 151, 38, 1) !important;
.progress30 {
background-color: rgba(255, 151, 38, 1) !important;
}
.progress50{
background-color:rgba(39, 122, 255, 1) !important;
.progress50 {
background-color: rgba(39, 122, 255, 1) !important;
}
.progress80{
background-color:rgba(59, 94, 251, 1) !important;
.progress80 {
background-color: rgba(59, 94, 251, 1) !important;
}
.progress100{
background-color:rgba(57, 219, 183, 1) !important;
.progress100 {
background-color: rgba(57, 219, 183, 1) !important;
}
//提交按钮
.submitbtn {
width: 146px;
height: 46px;
background: #2478ff;
box-shadow: 0px 1px 8px 0px rgba(56, 125, 247, 0.7);
border-radius: 4px;
// width: 66px;
font-size: 16px;
font-weight: 800;
color: #ffffff;
line-height: 24px;
border: 0;
cursor: pointer;
}

View File

@@ -14,9 +14,12 @@ import zip from '@/assets/image/file/zip.png'
import book from '@/assets/image/file/book.png'
import {defineProps, ref} from "vue";
const {modelValue = [],style} = defineProps({
const {modelValue = [], style} = defineProps({
modelValue: String,
style: Object
style: {
type: Object,
default: {}
}
})
const filePath = ref(modelValue)
</script>

View File

@@ -1,4 +1,3 @@
import './mock/index'
import {createApp} from 'vue'
import App from './App.vue'
import router from './router'

View File

@@ -6,7 +6,7 @@
* @FilePath: /fe-stu/src/router/index.js
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
import { createRouter, createWebHashHistory } from 'vue-router';
import {createRouter, createWebHashHistory, createWebHistory} from 'vue-router';
import routesConfig from './config';
// console.log('routesConfig', routesConfig)
@@ -20,7 +20,7 @@ const routes = [
]
const router = createRouter({
history: createWebHashHistory("/fe-student"),
history: createWebHistory("/fe-student"),
routes
})

View File

@@ -1,5 +1,5 @@
<template>
<div class="moreactive">
<div class="moreactive" style="padding: 30px">
<!-- 面包屑导航 -->
<div class="crumb">
<div>混合制项目</div>
@@ -16,7 +16,7 @@
</div>
</div>
<!-- 面包屑导航 -->
<div class="debateTitle">投票管理者进阶腾飞班 - 授课方式</div>
<div class="debateTitle">投票{{ dataInfo?.voteName }}</div>
<!-- 详细信息 -->
<div class="detailinfo">
<div class="detail">
@@ -24,9 +24,8 @@
<div class="left">
<div class="title">
<img
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>
@@ -34,64 +33,97 @@
<!-- <div style="display: flex; align-items: center"></div> -->
<div class="all">
<div class="item allbox1">
<div class="item1" style="color: #089dff">{{ data.accessCnt }}</div>
<div class="item1" style="color: #089dff">
{{
dataInfo.numberOfInvolved || dataInfo.numberOfInvolved == 0
? dataInfo.numberOfInvolved
: "-"
}}
</div>
<div class="item2">参与数</div>
</div>
<div class="item allbox2">
<div class="item1" style="color: #387df7">{{ data.voteCnt }}</div>
<div class="item1" style="color: #387df7">
{{
dataInfo.votesTotal || dataInfo.votesTotal == 0
? dataInfo.votesTotal
: "-"
}}
</div>
<div class="item2">总票数</div>
</div>
<div class="item allbox3">
<div class="item1" style="color: #00c6ff">{{ data.viewCnt }}</div>
<div class="item1" style="color: #00c6ff">
{{
dataInfo.numberOfBrowse || dataInfo.numberOfBrowse == 0
? dataInfo.numberOfBrowse
: "-"
}}
</div>
<div class="item2">浏览数</div>
</div>
</div>
<div class="title">
<img
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="join">
<div class="imgcontent">
<div class="imgone" style="margin-right: 10px"></div>
<div class="imgone"></div>
</div>
<!-- todo #投票任务 参与投票下面这段文字是固定的么-->
<div class="ontitle">
通过对各级人员的软件平台培训使其能够了解如何运用乾元坤和智能信息管理系统来提升企业管理水平最大限度发挥软件产品在企业中的作用;
<br/>
<br/>
培训目标
<br/>
<br/>
1.使企业不同部门人员掌握便捷有效的系统平台操作方法;
<br/>
<br/>
2.通过系统平台的培训提高员工对企业的管理理念认识与提升
<br/>
<br/>
3.通过系统平台培训加强沟通统一部署协同工作提高效率
<br/>
<br/>
培训对象
<br/>
<br/>
集团领导各相关部门领导总经理车间主管车间操作员等;
<div
v-for="(item, index) in dataInfo.ballotVo?.voteStemVoList"
:key="index"
style="margin-bottom: 41px"
>
<div class="stem">
<div>{{ item.orderNumber }}</div>
<div>{{ item.voteStemName }}</div>
</div>
<div class="options">
<div
v-for="(value, key) in item.optionDetailList"
:key="key"
style="
width: 140px;
margin-right: 114px;
margin-bottom: 25px;
"
>
<img
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>
<div class="opt-text">{{ value.optionName }}</div>
</label>
</div>
</div>
</div>
</div>
</div>
<div
style="
width: 100%;
display: flex;
justify-content: center;
margin-top: 30px;
"
>
<button class="submitbtn btn01" @click="submitVote">提交</button>
</div>
</div>
<div class="right">
<div class="righttitle">
<img
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>
@@ -99,30 +131,42 @@
<div class="timebox clearfix">
<div class="innertime">
{{
data.detail?.voteStartTime
}}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{{ data.detail?.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(data.detail?.voteEndTime).diff(dayjs(), 'minute') / 60) }}</span>&nbsp;&nbsp;
小时&nbsp;&nbsp;<span
class="te">{{ dayjs(data.detail?.voteEndTime).diff(dayjs(), 'minute') % 60 }}</span>&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>
</div>
</div>
<div class="righttitle">
<img
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="data.detail?.voteExplain"></div>
<div
class="explaincontent"
v-html="
dataInfo?.voteExplain ? dataInfo?.voteExplain : '暂无说明'
"
></div>
</div>
</div>
</div>
@@ -133,16 +177,29 @@
</template>
<script setup>
import {useRequest} from "@/api/request";
import {ROUTER_CHAPTER_LIST, ROUTER_LIST, TASK_VOTE_DETAIL} from "@/api/api";
import { useRequest } from "@/api/request";
import {
ROUTER_CHAPTER_LIST,
ROUTER_LIST,
TASK_VOTE_DETAIL,
VOTE_DETAIL2,
} 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 },
} = useRoute();
//获取基本信息
const { data: dataInfo } = useRequest(VOTE_DETAIL2(courseId));
const {data} = useRequest(TASK_VOTE_DETAIL, {})
const handleClick = (tab, event) => {
console.log(tab, event);
};
const submitVote = () => {};
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
@@ -342,26 +399,26 @@ const handleClick = (tab, event) => {
.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%
);
}
@@ -394,7 +451,62 @@ const handleClick = (tab, event) => {
// 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;

View File

@@ -23,17 +23,22 @@
<div class="detail">
<!-- 左侧 -->
<div
style="margin-left: 48px; margin-right: 48px; background-color: pink"
style="margin-left: 48px; margin-right: 48px; background-color: pink"
>
<div class="title">
<img width="20px" height="20px" src="../../assets/image/yuan.png"/>
<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">
<div class="item allbox1">
<div class="item1" style="color: #089dff">{{ data.accessCnt }}</div>
<div class="item1" style="color: #089dff">
{{ data.accessCnt }}
</div>
<div class="item2">参与数</div>
</div>
<div class="item allbox2">
@@ -47,12 +52,11 @@
</div>
<!-- todo #提交投票 提交投票时投票列表如何来的-->
<div class="vsbox">
<div class="yes">
</div>
<div class="yes"></div>
<div class="vs clearfix">
<img
style="margin-top: 20px; margin-left: 85px"
src="../../assets/image/VS.png"
style="margin-top: 20px; margin-left: 85px"
src="../../assets/image/VS.png"
/>
<div class="count">
<span style="color: #fe6a64">576</span>
@@ -64,9 +68,7 @@
<button class="btn btn2">投票</button>
</div>
</div>
<div class="no">
</div>
<div class="no"></div>
</div>
</div>
<!-- 左侧 -->
@@ -77,23 +79,23 @@
</template>
<script setup>
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 { 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";
const {query: {id: voteSubmitId}} = useRoute()
const {data} = useRequest(TASK_VOTE_DETAIL, {voteSubmitId})
const {data:voteDetail} = useRequest(VOTE_DETAIL, {voteSubmitId})
const {
query: { id: voteSubmitId },
} = useRoute();
const { data } = useRequest(TASK_VOTE_DETAIL, { voteSubmitId });
const { data: voteDetail } = useRequest(VOTE_DETAIL, { voteSubmitId });
const state = reactive({
activeName: "first",
});
const {activeName} = toRefs(state)
const { activeName } = toRefs(state);
const handleClick = (id) => {
};
const handleClick = (id) => {};
</script>
<style scoped lang="scss">
@@ -191,26 +193,26 @@ const handleClick = (id) => {
.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%
);
}
@@ -289,9 +291,9 @@ const handleClick = (id) => {
width: 435px;
// height: 763px;
background: linear-gradient(
0deg,
rgba(226, 104, 119, 0) 0%,
rgba(226, 104, 119, 0.1) 100%
0deg,
rgba(226, 104, 119, 0) 0%,
rgba(226, 104, 119, 0.1) 100%
);
border-radius: 8px;
@@ -477,9 +479,9 @@ const handleClick = (id) => {
width: 435px;
// height: 763px;
background: linear-gradient(
0deg,
rgba(88, 164, 232, 0) 0%,
rgba(88, 164, 232, 0.1) 100%
0deg,
rgba(88, 164, 232, 0) 0%,
rgba(88, 164, 232, 0.1) 100%
);
border-radius: 8px;

View File

@@ -1,8 +1,8 @@
<template>
<div class="surveydetail">
<div class="surveydetail" style="padding: 30px">
<!-- 面包屑导航 -->
<div
style="display: flex; align-items: center; justify-content: space-between"
style="display: flex; align-items: center; justify-content: space-between"
>
<div class="crumb">
<div>混合制项目</div>
@@ -14,66 +14,88 @@
<div class="prevnext">
<div class="prev">
<img
style="width: 23px; height: 23px"
src="../../assets/image/prev.png"
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"
style="width: 23px; height: 23px"
src="../../assets/image/next.png"
/>
</div>
</div>
</div>
<!-- 面包屑导航 -->
<!-- 标题 -->
<div class="title">调研管理者进阶腾飞班 - 班内成员讨论</div>
<div class="title">{{ info.name }}</div>
<!-- 标题 -->
<!-- 详细内容 -->
<div class="bascinfo clearfix">
<!-- 中间部分 -->
<div class="middletitle">
<div class="title">
{{ disDetail.discussName }}
{{ info.name }}
</div>
<button class="btn">发表帖子</button>
<!-- <button class="btn">发表帖子</button>-->
</div>
<div class="line clearfix">
<div class="linetitle">{{ disDetail.discussExplain }}</div>
<div class="radi"></div>
<div class="intime">进行中</div>
</div>
<div class="allbtn">
<button :class="`btnone ${param.searchType==1?'active':''}`" @click="param.searchType=1">最新</button>
<button :class="`btntwo ${param.searchType==2?'active':''}`" @click="param.searchType=2"
style="margin-left: 20px">最热
</button>
</div>
<div class="discusslist" v-for="(d,i) in data.rows">
<div class="itemtitle">{{ d.discussSubmitTitle }}</div>
<div class="itemdiscuss">
{{ d.discussSubmitContent }}
<div>
<div class="line clearfix">
<div class="linetitle">{{ info.sName }}</div>
<div class="radi"></div>
<div class="intime">进行中</div>
</div>
<div class="allstar clearfix">
<div @click="comment(i)" style="display: flex;cursor: pointer">
<span class="iconfont icon-pinglun" style="color:#b3bdc4"></span>
<div class="count"> {{ d.discussReviewCount }}</div>
</div>
<div @click="like(i)" style="display: flex;cursor: pointer">
<span class="iconfont icon-dianzan" :style="{color:d.isLike?'red':'#b3bdc4',marginLeft: '19px'}"></span>
<div class="count"> {{ d.discussLikeCount }}</div>
</div>
<div @click="collection(i)" style="display: flex;cursor: pointer">
<span class="iconfont icon-shoucang"
:style="{color:d.isCollection?'red':'#b3bdc4',marginLeft: '19px'}"></span>
<div class="count"> {{ d.discussCollectionCount }}</div>
</div>
<div class="allbtn">
<button :class="`btnone ${param.searchType == 1 ? 'active' : ''}`">
最新
</button>
<button
:class="`btntwo ${param.searchType == 2 ? 'active' : ''}`"
style="margin-left: 20px"
>
最热
</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>
<div class="allstar clearfix">
<div @click="comment(d)" style="display: flex; cursor: pointer">
<span class="iconfont icon-pinglun" style="color: #b3bdc4"></span>
<div class="count">{{ d.commentNum || 0 }}</div>
</div>
<div @click="like(d)" style="display: flex; cursor: pointer">
<span
class="iconfont icon-dianzan"
:style="{
color: d.praised ? 'red' : '#b3bdc4',
marginLeft: '19px',
}"
></span>
<div class="count">{{ 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',
marginLeft: '19px',
}"
></span>
<div class="count">{{ d.collectionNum || 0 }}</div>
</div>
</div>
<div class="thinline"></div>
</div>
<div class="thinline"></div>
</div>
</div>
<!-- 详细内容 -->
@@ -81,42 +103,40 @@
</template>
<script setup>
import {request, useRequest} from "@/api/request";
import {DISCUSS_COLLECTION, DISCUSS_DETAIL, DISCUSS_LIKE, DISCUSS_LIST, TASK_VOTE_DETAIL} from "@/api/api";
import {reactive, ref, toRefs} from "vue";
import {useRoute, useRouter} from "vue-router";
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";
const router = useRouter()
const {query: {id: discussId}} = useRoute()
const router = useRouter();
const {
query: { id, type },
} = useRoute();
const param = ref({
searchType: 1,
discussId
})
const {data} = useRequest(DISCUSS_LIST, param.value)
const {data: disDetail} = useRequest(DISCUSS_DETAIL, {discussId})
type,
id,
});
const { data: info } = useRequest(DISCUSS_LIST, param.value);
const state = reactive({
activeName: "first",
});
function comment(i) {
const id = data.value.rows[i].discussId
router.push({path: 'discussdetail', query: {id}})
function comment({ discussId: id }) {
router.push({ path: "discussdetail", query: { id, type } });
}
//todo 帖子点赞收藏 是否已经点赞收藏
function like(i) {
data.value.rows[i].isLike ? (data.value.rows[i].discussLikeCount -= 1) : (data.value.rows[i].discussLikeCount += 1)
data.value.rows[i].isLike = !data.value.rows[i].isLike
const discussSubmitId = data.value.rows[i].discussSubmitId
request(DISCUSS_LIKE, {discussSubmitId})
function like(d) {
d.praised ? (d.praiseNum -= 1) : (d.praiseNum += 1);
d.praised = !d.praised;
request(COMMENT_PRAISE, { targetId: d.discussId, type: 3 });
}
function collection(i) {
data.value.rows[i].isCollection ? (data.value.rows[i].discussCollectionCount -= 1) : (data.value.rows[i].discussCollectionCount += 1)
data.value.rows[i].isCollection = !data.value.rows[i].isCollection
const discussSubmitId = data.value.rows[i].discussSubmitId
request(DISCUSS_COLLECTION, {discussSubmitId})
function collection(d) {
d.collected ? (d.collectionNum -= 1) : (d.collectionNum += 1);
d.collected = !d.collected;
request(COMMENT_COLLECTION, { targetId: d.discussId, type: 4 });
}
</script>
@@ -169,9 +189,7 @@ function collection(i) {
background: #ffffff;
border-radius: 8px;
margin-top: 24px;
// display: flex;
// flex-direction: column;
// align-items: center;
display: block;
.middletitle {
display: flex;
margin-top: 64px;
@@ -211,7 +229,7 @@ function collection(i) {
.line {
display: flex;
margin: 47px 45px 0 75px;
max-width: 1810px;
//max-width: 1810px;
// height: 50px;
background: #f9f9f9;
position: relative;

View File

@@ -1,8 +1,8 @@
<template>
<div class="surveydetailpage">
<div class="surveydetailpage" style="padding: 30px">
<!-- 面包屑导航 -->
<div
style="display: flex; align-items: center; justify-content: space-between"
style="display: flex; align-items: center; justify-content: space-between"
>
<div class="crumb">
<div>混合制项目</div>
@@ -14,16 +14,16 @@
<div class="prevnext">
<div class="prev">
<img
style="width: 23px; height: 23px"
src="../../assets/image/prev.png"
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"
style="width: 23px; height: 23px"
src="../../assets/image/next.png"
/>
</div>
</div>
@@ -37,35 +37,58 @@
<!-- 中间部分 -->
<div class="middletitle">
<div class="title">
{{ disDetail.discussName }}
{{ disDetail.projectName }}
</div>
<button class="btn">回复</button>
<!-- <button class="btn">回复</button>-->
</div>
<div class="line clearfix">
<div class="linetitle">{{ disDetail.discussExplain }}</div>
<div class="linetitle">{{ disDetail.stageName }}</div>
<div class="radi"></div>
<div class="intime">进行中</div>
</div>
<div class="discusscontent clearfix">
<div class="contenttop clearfix">
<div class="contenttitle">{{ data.discussSubmitTitle }}</div>
<div @click="like(data.discussId)"
style="display: flex;cursor: pointer;align-items: baseline;margin-left: 20px">
<span class="iconfont icon-dianzan" :style="{color:data.isLike?'red':'#b3bdc4',marginLeft: '19px'}"></span>
<div class="count"> {{ data.discussLikeCount }}</div>
<div class="contenttitle">{{ disDetail.discussName }}</div>
<div
@click="like()"
style="
display: flex;
cursor: pointer;
align-items: baseline;
margin-left: 20px;
"
>
<span
class="iconfont icon-dianzan"
:style="{
color: disDetail.praised ? 'red' : '#b3bdc4',
marginLeft: '19px',
}"
></span>
<div class="count">{{ disDetail.praiseNum || 0 }}</div>
</div>
<div @click="collection(data.discussId)"
style="display: flex;cursor: pointer;align-items: baseline;margin-left: 20px">
<span class="iconfont icon-shoucang"
:style="{color:data.isCollection?'red':'#b3bdc4',marginLeft: '19px'}"></span>
<div class="count"> {{ data.discussCollectionCount }}</div>
<div
@click="collection()"
style="
display: flex;
cursor: pointer;
align-items: baseline;
margin-left: 20px;
"
>
<span
class="iconfont icon-shoucang"
:style="{
color: disDetail.collected ? 'red' : '#b3bdc4',
marginLeft: '19px',
}"
></span>
<div class="count">{{ disDetail.collectionNum || 0 }}</div>
</div>
</div>
<div class="contentmid">
{{ data.discussSubmitTitle }}
{{ disDetail.discussExplain }}
</div>
</div>
</div>
@@ -73,124 +96,180 @@
<div class="bascinfor">
<div class="inputone">
<el-input
v-model="textarea1"
:autosize="{ minRows: 5, maxRows: 5 }"
resize="none"
maxlength="100"
type="textarea"
placeholder="写评论~"
@input="textareaInput"
v-model="disComment.content"
:autosize="{ minRows: 5, maxRows: 5 }"
resize="none"
maxlength="100"
type="textarea"
placeholder="写评论~"
/>
<div class="words">{{ textarealength }}/100</div>
<div class="words">{{ disComment.content.length }}/100</div>
<div class="upload">
<div style="display: flex">
<div class="allimg" v-for="(img,i) in commentSubmitFileList">
<div class="imgone" :style="{backgroundImage: `url('${img.url}')`,marginLeft:'15px'}"></div>
<div
class="allimg"
v-for="(img, i) in commentSubmitFileList"
:key="i"
>
<div
class="imgone"
:style="{
backgroundImage: `url('${img.url}')`,
marginLeft: '15px',
}"
></div>
<div class="cha" @click="removeCommentImg(i)"></div>
</div>
</div>
<datagrid class="uploadAnd">
<UploadImg v-model="commentSubmitFileList">
<button class="btnone clearfix">
<img class="image" src="../../assets/image/uploadimg.png"/>
<div class="shangchuan">上传图片</div>
</button>
</UploadImg>
<div class="uploadAnd">
<div class="btnone clearfix">
<UploadImg v-model="commentSubmitFileList">
<button class="btwwo">
<img class="image" src="../../assets/image/uploadimg.png" />
<div class="shangchuan">上传图片</div>
</button>
</UploadImg>
</div>
<button class="btntwo" @click="submitComment">发表</button>
</datagrid>
</div>
</div>
<div class="thinline"></div>
<div class="bottom">
<div v-for="(row,i) in data.submitReviewVoList">
<div v-for="(row, i) in commontList" :key="i">
<div class="header">
<div class="avator"></div>
<div class="id">{{ row.stuName }}</div>
<div class="id">{{ row.userName }}</div>
<div class="showCareer">(显示事业)</div>
<div class="idThink">理性思考崇尚科学</div>
</div>
<div class="discuss clearfix">
<div class="discussmain clearfix">
<div class="talkmain">
{{ row.discussReviewContent }}
{{ row.content }}
</div>
</div>
<div class="intime">{{ row.createTime }}</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.discussLikeCount }}</div>
<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-shoucang"
:style="{color:data.submitReviewVoList[i].isLike?'red':'#b3bdc4'}"></span>
<div class="count"> {{ row.discussLikeCount }}</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 ? 'red' : '#b3bdc4' }"
></span>
<div class="count">{{ row.praiseNum || 0 }}</div>
</div>
</div>
<div v-for="(replay,j) in row.submitReplyVoList">
<div v-for="(replay, j) in row.children" :key="j">
<div class="reply">
<div class="sameava avaone"></div>
<div class="sameuser">{{ replay.stuName }}</div>
<div class="sameuser">{{ replay.userName }}</div>
<div class="centerreply">回复</div>
<div class="sameava avatwo"></div>
<div class="sameuser">{{ row.stuName }}</div>
<div class="replytime">{{ replay.createTime }}</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.replyContent }}
{{ 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.discussLikeCount }}</div>
<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 @click="commentLike(replay)"
style="display: flex;cursor: pointer;align-items: baseline;margin-left: 19px">
<span class="iconfont icon-shoucang"
:style="{color:replay.isLike?'red':'#b3bdc4'}"></span>
<div class="count"> {{ replay.discussLikeCount }}</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 class="discuss clearfix">
<div
class="discuss clearfix"
v-if="commontList && commontList.length"
>
<div class="inreply">
<el-input
v-model="textarea2"
:autosize="{ minRows: 5, maxRows: 5 }"
resize="none"
maxlength="100"
type="textarea"
@input="textareaInputdown"
:placeholder="placeholder"
v-model="replayComment.content"
:autosize="{ minRows: 5, maxRows: 5 }"
resize="none"
maxlength="100"
type="textarea"
:placeholder="replayComment.placeholder"
/>
<div class="words">{{ textarealength2 }}/100</div>
<div class="words">{{ replayComment.content.length }}/100</div>
<div class="upload">
<div style="display: flex">
<div class="allimg" v-for="(img,i) in fileList">
<div class="imgone" :style="{backgroundImage: `url('${img.url}')`,marginLeft:'15px'}"></div>
<div class="allimg" v-for="(img, i) in fileList" :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">
<UploadImg v-model="fileList">
<button class="btnone clearfix">
<img class="image" src="../../assets/image/uploadimg.png"/>
<img
class="image"
src="../../assets/image/uploadimg.png"
/>
<div class="shangchuan">上传图片</div>
</button>
</UploadImg>
<button class="btntwo">发表</button>
<button class="btntwo" @click="submitReplayComment">
发表
</button>
</datagrid>
</div>
</div>
@@ -201,92 +280,97 @@
<!-- 详细内容 -->
</div>
</template>
<!--todo #评论详情 发表和回复共功能-->
<script setup>
import {reactive, ref, toRefs} from "vue";
import {useRoute} from "vue-router/dist/vue-router";
import {request, useRequest} from "@/api/request";
import { reactive, ref, toRefs } from "vue";
import { useRoute } from "vue-router/dist/vue-router";
import { request, usePage, useRequest } from "@/api/request";
import {
DISCUSS_COLLECTION,
COMMENT_ADD,
COMMENT_COLLECTION,
COMMENT_LIST,
COMMENT_PRAISE,
DISCUSS_DETAIL,
DISCUSS_LIKE,
DISCUSS_LIST,
DISCUSS_SUBMIT_REVIEW_LIST,
FILE_UPLOAD
FILE_UPLOAD,
} from "@/api/api";
import UploadImg from '@/components/img/UploadImg.vue'
import UploadImg from "@/components/img/UploadImg.vue";
const {query: {id: discussSubmitId, discussId}} = useRoute()
const {data} = useRequest(DISCUSS_SUBMIT_REVIEW_LIST, {discussSubmitId})
const {data: disDetail} = useRequest(DISCUSS_DETAIL, {discussId})
const fileList = ref([])
const commentSubmitFileList = ref([])
const state = reactive({
textarea1: "",
textarealength: 0,
textarea2: "",
textarealength2: 0,
placeholder: '',
rId:''
});
const {
textarea1,
textarealength,
textarea2,
textarealength2,
placeholder
} = toRefs(state)
query: { id, discussSubmitId, type },
} = useRoute();
const textareaInput = (e) => {
state.textarea1 = e;
state.textarealength = e.length;
};
const textareaInputdown = (e) => {
state.textarea2 = e;
state.textarealength2 = e.length;
};
const { data: commontList, fetchData: commonFetch } = usePage(COMMENT_LIST, {
id,
type: 1,
});
const { data: disDetail } = useRequest(DISCUSS_DETAIL, { id, type });
const fileList = ref([]);
const commentSubmitFileList = ref([]);
const disComment = ref({
content: "",
});
const replayComment = ref({
placeholder: "",
content: "",
pid: "",
});
function removeImg(i) {
fileList.value.splice(i, 1)
fileList.value.splice(i, 1);
}
function removeCommentImg() {
commentSubmitFileList.value.splice(i, 1)
commentSubmitFileList.value.splice(i, 1);
}
//todo 帖子是否点赞收藏
function like(discussSubmitId) {
data.value.isLike ? (data.value.discussLikeCount -= 1) : (data.value.discussLikeCount += 1)
data.value.isLike = !data.value.isLike
request(DISCUSS_LIKE, {discussSubmitId})
//todo 帖子和评论 返回是否点赞和收藏
function like() {
disDetail.value.praised
? (disDetail.value.praiseNum -= 1)
: (disDetail.value.praiseNum += 1);
disDetail.value.praised = !disDetail.value.praised;
request(COMMENT_PRAISE, { targetId: disDetail.value.discussId, type: 5 });
}
function collection(discussSubmitId) {
data.value.isCollection ? (data.value.discussCollectionCount -= 1) : (data.value.discussCollectionCount += 1)
data.value.isCollection = !data.value.isCollection
request(DISCUSS_COLLECTION, {discussSubmitId})
function collection() {
disDetail.value.collected
? (disDetail.value.collectionNum -= 1)
: (disDetail.value.collectionNum += 1);
disDetail.value.collected = !disDetail.value.collected;
request(COMMENT_COLLECTION, { targetId: disDetail.value.discussId, type: 6 });
}
function commentLike(obj) {
obj.isLike ? (obj.discussLikeCount -= 1) : (obj.discussLikeCount += 1)
obj.isLike = !obj.isLike
const discussSubmitId = obj.discussSubmitId
request(DISCUSS_LIKE, {discussSubmitId})
obj.praised ? (obj.praiseNum -= 1) : (obj.praiseNum += 1);
obj.praised = !obj.praised;
request(COMMENT_PRAISE, { targetId: obj.id, type: 5 });
}
function commentComment(obj) {
state.placeholder = '@ '+obj.stuName
state.rId = obj.discussSubmitId
replayComment.value.placeholder = "@ " + obj.userName;
replayComment.value.pid = obj.id;
}
function submitComment() {
request(COMMENT_ADD, {
targetId: disDetail.value.discussId,
content: disComment.value.content,
type: 1,
}).then(() => {
commonFetch();
});
}
function submitReplayComment() {
request(COMMENT_ADD, {
targetId: disDetail.value.discussId,
content: replayComment.value.content,
type: 2,
pid: replayComment.value.pid,
}).then(() => {
commonFetch();
});
}
</script>
@@ -374,7 +458,6 @@ function submitComment() {
.line {
display: flex;
margin: 47px 45px 0 75px;
max-width: 1810px;
height: 50px;
background: #f9f9f9;
position: relative;
@@ -537,6 +620,35 @@ function submitComment() {
.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;
@@ -586,7 +698,7 @@ function submitComment() {
}
.thinline {
margin-top: 26px;
margin-top: 66px;
// width: 1635px;
border-top: 1px solid #878b92;
margin-left: -50px;

View File

@@ -1,5 +1,5 @@
<template>
<div class="surveydetail">
<div class="surveydetail" style="padding: 30px">
<!-- 面包屑导航 -->
<div
style="display: flex; align-items: center; justify-content: space-between"
@@ -37,20 +37,26 @@
<!-- 中间盒子 -->
<div class="centercontent">
<div class="righttitle">
<img width="20px" height="20px" src="../../assets/image/yuan.png" />
<img
style="width: 20px; height: 20px"
src="../../assets/image/yuan.png"
/>
<div class="text">考试测试</div>
<div class="text">{{ data.examinationName }}</div>
<div class="box"></div>
</div>
<!-- 考试测试的盒子 -->
<div class="test clearfix">
<div class="detail">
<span style="margin-right: 43px">考试时间30分钟</span>
<span>及格线60</span>
<span style="margin-right: 43px"
>考试时间{{ data.examinationDuration }}分钟</span
>
<span>及格线{{ data.passLine || 60 }}</span>
</div>
<div class="testtime clearfix">
<div class="timedetail">
考试时间2022-7-20 00:00 2022-8-29 23:59:59
考试时间{{ data.examinationStartTime }}
{{ data.examinationEndTime }}
</div>
</div>
</div>
@@ -60,7 +66,10 @@
<button class="starttest" style="cursor: pointer">开始考试</button>
<!-- 开始考试按钮 -->
<div class="righttitleE">
<img width="20px" height="20px" src="../../assets/image/yuan.png" />
<img
style="width: 20px; height: 20px"
src="../../assets/image/yuan.png"
/>
<div class="text">历史纪录</div>
<div class="box"></div>
@@ -101,12 +110,19 @@
</div>
<!-- 详细内容 -->
</div>
<!-- todo #考试接口 暂时没有-->
</template>
<script>
export default {
name: "ExamPage",
};
<script setup>
import { useRoute } from "vue-router/dist/vue-router";
import { usePage, useRequest } from "@/api/request";
import { COMMENT_LIST, DISCUSS_DETAIL, EXAMINATION_QUERY } from "@/api/api";
const {
query: { id, discussSubmitId },
} = useRoute();
const { data } = useRequest(EXAMINATION_QUERY(159), {});
</script>
<style scoped lang="scss">
@@ -117,18 +133,21 @@ export default {
font-size: 14px;
line-height: 24px;
}
.prevnext {
display: flex;
align-items: center;
font-size: 14px;
font-weight: 500;
color: #ffffff;
.prev {
display: flex;
align-items: center;
cursor: pointer;
}
}
.title {
font-size: 20px;
font-weight: 800;
@@ -137,6 +156,7 @@ export default {
margin-top: 17px;
margin-left: -11px;
}
.bascinfo {
min-height: 800px;
width: 100%;
@@ -146,24 +166,29 @@ export default {
display: flex;
flex-direction: column;
align-items: center;
.clearfix:before,
.clearfix:after {
content: "";
display: table;
clear: both;
}
.centercontent {
position: relative;
.righttitle {
display: flex;
padding-top: 30px;
position: relative;
.text {
margin-left: 8px;
font-size: 16px;
color: rgba(51, 51, 51, 1);
font-weight: 800;
}
.box {
width: 75px;
height: 10px;
@@ -173,6 +198,7 @@ export default {
top: 44px;
}
}
.test {
margin-top: 16px;
margin-bottom: 26px;
@@ -180,6 +206,7 @@ export default {
height: 158px;
background: #f2f5f7;
border-radius: 8px;
.detail {
margin-top: 29px;
margin-left: 44px;
@@ -188,6 +215,7 @@ export default {
font-weight: 500;
color: #56a3f9;
}
.testtime {
margin-top: 20px;
margin-left: 10px;
@@ -195,6 +223,7 @@ export default {
height: 81px;
background: #ffffff;
border-radius: 0px 8px 0px 8px;
.timedetail {
font-size: 14px;
font-weight: 500;
@@ -204,6 +233,7 @@ export default {
}
}
}
.starttest {
position: absolute;
width: 146px;
@@ -218,17 +248,20 @@ export default {
left: calc(50% - 73px);
cursor: pointer;
}
.righttitleE {
display: flex;
margin-top: 110px;
// padding-top: 30px;
position: relative;
.text {
margin-left: 8px;
font-size: 16px;
color: rgba(51, 51, 51, 1);
font-weight: 800;
}
.box {
width: 75px;
height: 10px;
@@ -238,6 +271,7 @@ export default {
top: 14px;
}
}
.history {
position: relative;
margin-top: 32px;
@@ -245,38 +279,46 @@ export default {
height: 200px;
border: 1px solid #d7e5fd;
border-radius: 8px;
.clearfix:before,
.clearfix:after {
content: "";
display: table;
clear: both;
}
.fenge {
width: 841px;
border-top: 1px solid #d7e5fd;
}
.tongyi {
display: flex;
}
.content1 {
margin-top: 14px;
margin-left: 77px;
}
.content2 {
position: absolute;
margin-top: 14px;
left: 328px;
}
.content3 {
position: absolute;
margin-top: 14px;
left: 512px;
}
.content4 {
position: absolute;
margin-top: 14px;
left: 700px;
}
.contentbtn {
position: absolute;
margin-top: 14px;
@@ -290,6 +332,7 @@ export default {
border: 0;
cursor: pointer;
}
.historycontent {
width: 59px;
height: 14px;
@@ -299,12 +342,14 @@ export default {
color: #333330;
line-height: 38px;
}
.historytitle {
width: 842px;
height: 50px;
background: #f2f5f7;
border-radius: 8px 8px 0px 0px;
}
.historytitle2 {
width: 842px;
height: 48px;

View File

@@ -1,5 +1,5 @@
<template>
<div class="faceteach">
<div class="faceteach" style="padding: 30px">
<!-- 面包屑导航 -->
<div class="crumb">
<div>课程列表</div>
@@ -11,21 +11,27 @@
<!-- 基本信息 -->
<div class="bascinfo">
<div style="margin-left: 46px">
<div class="title">其他活动{{ data.offCourseInfo?.name }}</div>
<div class="title">面授课{{ data.planDto?.name }}</div>
<div class="time" style="margin-top: 26px">
<img width="15px" height="17px" src="../../assets/image/time.png"/>
<div style="margin-left: 8px">{{ data.offCoursePlanInfo?.beginTime }}</div>
<img
style="width: 15px; height: 17px"
src="../../assets/image/time.png"
/>
<div style="margin-left: 8px">
{{ data.offcourseDto?.publishTime }}
</div>
</div>
<div class="time" style="margin-top: 23px">
<img
width="16px"
height="18px"
src="../../assets/image/position.png"
style="width: 16px; height: 18px"
src="../../assets/image/position.png"
/>
<div style="margin-left: 8px">{{ data.offCoursePlanInfo?.address }}</div>
<div style="margin-left: 8px">{{ data.planDto?.address }}</div>
</div>
</div>
<div class="btn" v-if="data.offCoursePlanInfo?.evalFlag && !data.evalFlag">评估</div>
<div class="btn" @click="toSurvery" v-if="data.planDto?.evalFlag">
评估
</div>
</div>
<!-- 基本信息 -->
@@ -36,15 +42,14 @@
<div class="" style="margin-left: 48px; margin-right: 48px">
<div class="title">
<img
width="20px"
height="20px"
src="../../assets/image/course.png"
style="width: 20px; height: 20px"
src="../../assets/image/course.png"
/>
<div class="text">课程详情</div>
<div class="box"></div>
</div>
<div style="display: flex; align-items: center">
<div class="content" v-html="data.offCourseInfo?.intro"></div>
<div class="content" v-html="data.planDto?.description"></div>
</div>
</div>
</div>
@@ -52,25 +57,27 @@
<el-tabs v-model="activeName" @tab-click="handleClick">
<el-tab-pane label="课程附件" name="first">
<div
v-for="(el, index) in data.offCoursePlanInfo?.attach.split(',')"
:key="index"
class="enclosure"
:style="{
'border-bottom':
index === enclosure.length - 1
? null
: '1px solid rgba(56, 125, 247, 0.2)',
}"
v-for="(el, index) in data.planDto?.attach.split(',')"
:key="index"
v-if="data.planDto"
class="enclosure"
:style="{ borderBottom: '1px solid rgba(56, 125, 247, 0.2)' }"
>
<div class="enclosureL">
<FileTypeImg v-model="data.offCoursePlanInfo.attach.split(',')[index]"
:style="{width:'22px',height:'26px',marginLeft:'10px'}"></FileTypeImg>
<FileTypeImg
v-model="data.planDto.attach.split(',')[index]"
:style="{
width: '22px',
height: '26px',
marginLeft: '10px',
}"
></FileTypeImg>
<div style="margin-left: 20px">{{ el }}</div>
</div>
<div class="download">
<img
style="width: 16px; height: 15px"
src="../../assets/image/download.png"
style="width: 16px; height: 15px"
src="../../assets/image/download.png"
/>
<div style="margin-left: 5px" @click="download(el)">下载</div>
</div>
@@ -79,27 +86,36 @@
<el-tab-pane label="课程作业" name="second">
<div class="work">
<div>
<div class="question">{{ data.workItem?.name }}</div>
<div class="question">{{ data.workDto?.workName }}</div>
<div style="margin-top: 16px; display: flex">
<div class="tag1">必修</div>
<div class="tag1" v-if="data.workDto?.workFlag">必修</div>
<div class="tag3" style="margin-left: 11px">作业</div>
</div>
</div>
<div class="submit" @click="toWork(data.workItem)" v-if="!data.workFlag">提交</div>
<div class="submit" @click="toWork" v-if="data.workDto?.workId">
提交
</div>
</div>
</el-tab-pane>
<el-tab-pane label="课程考试" name="third">
<div class="work">
<div>
<div class="question">
{{ data.examItem?.name }}
{{ data.examinationDto?.examinationTestName }}
</div>
<div style="margin-top: 16px; display: flex">
<div class="tag1">必修</div>
<div
class="tag1"
v-if="data.examinationDto?.examinationFlag"
>
必修
</div>
<div class="tag3" style="margin-left: 11px">考试</div>
</div>
</div>
<div class="submit" @click="toExamItem(data.examItem)" v-if="!data.examFlag">去考试</div>
<!-- <div class="submit" @click="toExamItem(data.examinationDto)">-->
<!-- 去考试-->
<!-- </div>-->
</div>
</el-tab-pane>
</el-tabs>
@@ -108,32 +124,22 @@
<div class="teacher">
<div class="title">
<img
style="width: 21px; height: 23px"
src="../../assets/image/livelecturer.png"
style="width: 21px; height: 23px"
src="../../assets/image/livelecturer.png"
/>
<div class="text">直播讲师</div>
<div class="box"></div>
</div>
<!-- todo #面授课接口 讲师缺少img和介绍-->
<div
v-for="(el, index) in teacher"
:key="el.id"
class="teacheritem"
:style="{
'border-bottom':
index === teacher.length - 1
? null
: '1px solid rgba(56, 125, 247, 0.2)',
}"
>
<img class="peopleimg" :src="el.peopleimg"/>
<div class="teacheritem">
<img class="peopleimg" :src="userAvatar" />
<div style="margin-left: 17px; width: 190px">
<div class="teacherName" style="margin-right: 5px">
{{ el.name }}
{{ data.planDto?.teacher }}
</div>
<div class="introduce">{{ el.introduce }}</div>
<div class="introduce">{{ data.planDto?.bandDesc }}</div>
</div>
<div class="follow">+ 关注</div>
<!-- <div class="follow">+ 关注</div>-->
</div>
</div>
</div>
@@ -142,33 +148,56 @@
</template>
<script setup>
import {reactive, toRefs, watch} from "vue";
import { computed, reactive, toRefs, watch } from "vue";
import FileTypeImg from "@/components/FileTypeImg.vue";
import {request, useRequest} from "@/api/request";
import {STU_OFFCOURSE_DETAIL} from "@/api/api";
import {useRouter} from "vue-router";
import { request, useRequest } from "@/api/request";
import { STU_OFFCOURSE_DETAIL } from "@/api/api";
import { useRoute, useRouter } from "vue-router";
import { useUserInfo } from "@/api/utils";
const router = useRouter()
const router = useRouter();
const {
query: { courseId, type },
} = useRoute();
const { data } = useRequest(STU_OFFCOURSE_DETAIL, { courseId });
const { avatar: userAvatar } = useUserInfo(
computed(() => data.value?.planDto?.teacherId)
);
const {data} = useRequest(STU_OFFCOURSE_DETAIL, {})
const state = reactive({
activeName: "first",
enclosure: ''
})
const {activeName, enclosure} = toRefs(state)
enclosure: "",
});
const { activeName, enclosure } = toRefs(state);
const handleClick = (tab, event) => {
console.log(tab, event);
};
const download = (url) => {
window.open(url)
window.open(url);
};
function toSurvery() {
router.push({
path: "/surveydetail",
query: { courseId: data.value.planDto.evaluateId },
});
}
function toWork(obj) {
router.push({path: '/homeworkpage', query: {id: obj.courseId}})
function toWork() {
router.push({
path: "/homeworkpage",
query: {
courseId: data.value.workDto.workId,
id: data.value.offcourseDto.categoryId,
type,
},
});
}
function toExamItem(obj) {
router.push({path: '/starttest', query: {id: obj.courseId}})
router.push({ path: "/starttest", query: { id: obj.courseId } });
}
</script>

View File

@@ -1,5 +1,5 @@
<template>
<div class="homework">
<div class="homework" style="padding: 30px">
<!-- 面包屑导航 -->
<div class="crumb">
<div>混合制项目</div>
@@ -24,7 +24,7 @@
<div class="detail">
<div class="detailT">
<div
style="
style="
margin-left: 45px;
margin-right: 42px;
position: relative;
@@ -33,9 +33,8 @@
>
<div class="title">
<img
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>
@@ -43,65 +42,79 @@
<div class="shapan">
<div style="flex: 1; width: 0">
<div class="shapanexplain">
{{ data.detail?.workName }}
{{ data?.workName }}
</div>
</div>
</div>
<UploadImg v-model="fileList" ref="uploadRef">
<button
class="shangchuan"
style="cursor: pointer"
@mousemove='showFileList=1'
@mouseout='showFileList=0'
class="shangchuan"
style="cursor: pointer"
@mousemove="showFileList = 1"
@mouseout="showFileList = 0"
>
上传
</button>
</UploadImg>
<div
class="uploadDetail"
:style="{ display: showFileList ? 'block' : 'none' }"
@mousemove='showFileList=1'
@mouseout='showFileList=0'
style="padding-top: 60px"
class="uploadDetail"
:style="{ display: showFileList ? 'block' : 'none' }"
@mousemove="showFileList = 1"
@mouseout="showFileList = 0"
style="padding-top: 60px"
>
<div class="triangle"></div>
<div class="square clearfix">
<div class="squarecontent1" v-for="(file,i) in fileList">
<FileTypeImg v-model="file.name" :style="{margin:'12px 15px 0 27px'}"></FileTypeImg>
<div
class="squarecontent1"
v-for="(file, i) in fileList"
:key="i"
>
<FileTypeImg
v-model="file.name"
:style="{ margin: '12px 15px 0 27px' }"
></FileTypeImg>
<div class="rarDetail">
<span class="detail1" style="margin-right: 130px">
{{ file.name }}
</span>
<span class="detail2" style="margin-right: 10px">{{ file.percentage }}%</span>
<span class="detail2" style="margin-right: 10px"
>{{ file.percentage }}%</span
>
<span class="detail1">{{
{
ready: '正在上传',
abort: '暂停',
uploading: '正在上传',
fail: '上传失败',
success: '上传成功'
}[file.status]
}}</span>
{
ready: "正在上传",
abort: "暂停",
uploading: "正在上传",
fail: "上传失败",
success: "上传成功",
}[file.status]
}}</span>
<div class="progress">
<div class="progressinner" :style="{width:`${291*file.percentage/100}px`}"></div>
<div
class="progressinner"
:style="{ width: `${(291 * file.percentage) / 100}px` }"
></div>
</div>
</div>
<button class="btn btndetail" @click="reUpload(i)">{{
<button class="btn btndetail" @click="reUpload(i)">
{{
{
ready: '暂停',
uploading: '暂停',
abort: '开始',
fail: '重传',
ready: "暂停",
uploading: "暂停",
abort: "开始",
fail: "重传",
}[file.status]
}}
</button>
<button class="btn" @click="remove">{{
<button class="btn" @click="remove">
{{
{
ready: '取消',
abort: '取消',
uploading: '取消',
fail: '取消',
success: '删除'
ready: "取消",
abort: "取消",
uploading: "取消",
fail: "取消",
success: "删除",
}[file.status]
}}
</button>
@@ -111,8 +124,8 @@
<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>
@@ -120,11 +133,11 @@
<div class="join">
<el-input
v-model="textarea1"
:autosize="{ minRows: 12.5, maxRows: 12.5 }"
resize="none"
type="textarea"
@input="textareaInput"
v-model="textarea1"
:autosize="{ minRows: 12.5, maxRows: 12.5 }"
resize="none"
type="textarea"
@input="textareaInput"
/>
</div>
<div style="display: flex; justify-content: center">
@@ -135,9 +148,8 @@
<div class="title" style="margin-top: 0px">
<img
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>
@@ -149,12 +161,12 @@
<div class="content2">作业内容</div>
</div>
<div
v-for="(value, index) in data.workSubmitList"
:key="index"
class="historytitle2"
:style="{
v-for="(value, index) in submitList"
:key="index"
class="historytitle2"
:style="{
'border-bottom':
index === data.workSubmitList.length - 1
index === submitList.length - 1
? '1px solid rgba(215, 229, 253, 0)'
: '1px solid rgba(215, 229, 253, 1)',
}"
@@ -162,7 +174,7 @@
<div class="content1">{{ value.createTime }}</div>
<div class="content2">
<div
style="
style="
width: 95%;
overflow: hidden;
text-overflow: ellipsis;
@@ -179,36 +191,52 @@
</div>
<div class="right">
<div class="righttitle">
<img width="20px" height="20px" src="../../assets/image/yuan.png"/>
<img
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">
{{
data.detail?.submitStartTime
}}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{{ data.detail?.submitEndTime }}
data?.submitStartTime
}}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{{
data?.submitEndTime
}}
</div>
<div class="endtime clearfix">
<div class="endtimetext">
距离结束还有&nbsp;&nbsp;
<span class="te">{{ parseInt(dayjs(data.detail?.submitEndTime).diff(dayjs(), 'minute') / 60) }}</span>&nbsp;&nbsp;
小时&nbsp;&nbsp;<span
class="te"
>{{ dayjs(data.detail?.submitEndTime).diff(dayjs(), 'minute') % 60 }}</span
>&nbsp;&nbsp;分钟
<span class="te">{{
parseInt(
dayjs(data?.submitEndTime).diff(dayjs(), "minute") / 60
)
}}</span
>&nbsp;&nbsp; 小时&nbsp;&nbsp;<span class="te">{{
dayjs(data?.submitEndTime).diff(dayjs(), "minute") % 60
}}</span
>&nbsp;&nbsp;分钟
</div>
</div>
</div>
<div class="righttitle">
<img width="20px" height="20px" src="../../assets/image/yuan.png"/>
<img
style="width: 20px; height: 20px"
src="../../assets/image/yuan.png"
/>
<div class="text">作业说明</div>
<div class="box"></div>
</div>
<div class="explain clearfix">
<!-- todo #作业任务详情 作业说明是作业要求字段么-->
<div class="explain1" style="margin-top: 26px" v-html="data.detail?.workRequirement"></div>
<!-- todo #作业任务详情 作业说明是作业要求字段么-->
<div
class="explain1"
style="margin-top: 26px"
v-html="data?.workRequirement"
></div>
</div>
</div>
</div>
@@ -217,44 +245,57 @@
</template>
<script setup>
import {reactive, ref, toRefs} from "vue";
import {request, useRequest} from "@/api/request";
import {TASK_WORK_COMMIT, TASK_WORK_DETAIL, WORK_HISTROY} from "@/api/api";
import { reactive, ref, toRefs } from "vue";
import { request, useRequest } from "@/api/request";
import {
TASK_WORK_COMMIT,
TASK_WORK_DETAIL,
TASK_WORK_SUBMIT_LIST,
WORK_HISTROY,
} from "@/api/api";
import dayjs from "dayjs";
import {useRouter} from "vue-router";
import UploadImg from '@/components/img/UploadImg.vue'
import { useRouter } from "vue-router";
import UploadImg from "@/components/img/UploadImg.vue";
import FileTypeImg from "@/components/FileTypeImg.vue";
import {useRoute} from "vue-router/dist/vue-router";
import { useRoute } from "vue-router/dist/vue-router";
const fileList = ref([])
const uploadRef = ref()
const showFileList = ref(0)
const fileList = ref([]);
const uploadRef = ref();
const showFileList = ref(0);
const state = reactive({
textarea1: "",
})
const {textarea1} = toRefs(state);
const router = useRouter()
});
const { textarea1 } = toRefs(state);
const router = useRouter();
const {query: {id: workId}} = useRoute()
const {
query: { courseId: workId, type, id: taskId },
} = useRoute();
const {data} = useRequest(TASK_WORK_DETAIL, {workId})
const { data } = useRequest(TASK_WORK_DETAIL, { workId, taskId });
const { data: submitList } = useRequest(TASK_WORK_SUBMIT_LIST, { workId });
const handleClick = () => {
request(TASK_WORK_COMMIT, {workSubmitDto: {workId,workUploadContent: state.textarea1}}).then(() => {
router.back()
})
request(TASK_WORK_COMMIT, {
projectOrRouterLogo: type,
workUploadContent: textarea1.value,
workId,
taskId,
}).then((res) => {
submitList.value.unshift(res.data);
});
textarea1.value = "";
};
const textareaInput = (e) => {
state.textarea1 = e;
};
function remove(i) {
uploadRef.value.remove(i)
uploadRef.value.remove(i);
}
function reUpload(i) {
uploadRef.value.reUpload(i)
uploadRef.value.reUpload(i);
}
</script>
@@ -660,25 +701,25 @@ function reUpload(i) {
.allbox1 {
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 {
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%
);
}

View File

@@ -1,5 +1,5 @@
<template>
<div class="moreactive">
<div class="moreactive" style="padding: 30px">
<!-- 面包屑导航 -->
<div class="crumb">
<div>混合制项目</div>
@@ -20,25 +20,40 @@
<!-- 基本信息 -->
<div class="bascinfo">
<div style="margin-left: 46px">
<div class="title">直播{{ data.detail?.liveName }}</div>
<div class="title">直播{{ data?.liveName }}</div>
<div class="time" style="margin-top: 26px">
<img width="15px" height="17px" src="../../assets/image/time.png"/>
<div style="margin-left: 8px">{{ data.detail?.liveStartTime }}</div>
<img
style="width: 15px; height: 17px"
src="../../assets/image/time.png"
/>
<div style="margin-left: 8px">{{ data?.liveStartTime }}</div>
</div>
<div class="time" style="margin-top: 23px">
<img
width="16px"
height="18px"
src="../../assets/image/position.png"
style="width: 16px; height: 18px"
src="../../assets/image/position.png"
/>
<!-- todo #直播详情 没有位置字段-->
<div style="margin-left: 8px">大族广场</div>
</div>
</div>
<div class="threeBtn">
<botton class="btn" style="background: rgb(59, 191, 252)" @click="commitClick">观看</botton>
<botton class="btn" style="background: rgb(57, 146, 249)" @click="signClick" v-if="!data.signFlag">签到</botton>
<botton class="btn" @click="commitClick" v-if="!data.evalFlag">评估</botton>
<botton
class="btn"
style="background: rgb(59, 191, 252)"
@click="showClick"
>观看
</botton>
<botton
class="btn"
style="background: rgb(57, 146, 249)"
@click="signClick"
v-if="!data.signFlag"
>签到
</botton>
<botton class="btn" @click="commitClick" v-if="!data.evalFlag"
>评估
</botton>
</div>
</div>
<!-- 基本信息 -->
@@ -50,43 +65,41 @@
<div class="" style="margin-left: 48px; margin-right: 48px">
<div class="title">
<img
width="20px"
height="20px"
src="../../assets/image/course.png"
style="width: 20px; height: 20px"
src="../../assets/image/course.png"
/>
<div class="text">课前预习</div>
<div class="box"></div>
</div>
<div style="display: flex; align-items: center">
<!-- todo 没有课前预习字段-->
<!-- todo #直播 没有课前预习字段-->
<div class="content">
通过对各级人员的软件平台培训使其能够了解如何运用乾元坤和智能信息管理系统来提升企业管理水平最大限度发挥软件产品在企业中的作用;<br/>
通过对各级人员的软件平台培训使其能够了解如何运用乾元坤和智能信息管理系统来提升企业管理水平最大限度发挥软件产品在企业中的作用;<br />
培训目标
<br/>1.使企业不同部门人员掌握便捷有效的系统平台操作方法;<br/>
2.通过系统平台的培训提高员工对企业的管理理念认识与提升<br/>
<br />1.使企业不同部门人员掌握便捷有效的系统平台操作方法;<br />
2.通过系统平台的培训提高员工对企业的管理理念认识与提升<br />
3.通过系统平台培训加强沟通统一部署协同工作提高效率
<br/>
培训对象<br/>
集团领导各相关部门领导总经理车间主管车间操作员等;<br/>
<br />
培训对象<br />
集团领导各相关部门领导总经理车间主管车间操作员等;<br />
</div>
</div>
<div class="title">
<img
width="20px"
height="20px"
src="../../assets/image/write.png"
style="width: 20px; height: 20px"
src="../../assets/image/write.png"
/>
<!-- todo 课后作业-->
<!-- todo #直播 课后作业-->
<div class="text">课后作业</div>
<div class="box"></div>
</div>
<div style="display: flex; align-items: center">
<div class="content">
<span style="font-weight: 600"
>网易有道词典现有功能结构拆解+问题分析</span
><br/>
查找资料介绍一种国外日本美国欧洲道路公路铁路城市道路地铁设计规范的演变过程可以一种或几种主要技术指标为例并说明其原因<br/>
>网易有道词典现有功能结构拆解+问题分析</span
><br />
查找资料介绍一种国外日本美国欧洲道路公路铁路城市道路地铁设计规范的演变过程可以一种或几种主要技术指标为例并说明其原因<br />
</div>
</div>
</div>
@@ -96,43 +109,36 @@
<div class="tell">
<div class="title">
<img
style="width: 21px; height: 23px"
src="../../assets/image/tv.png"
style="width: 21px; height: 23px"
src="../../assets/image/tv.png"
/>
<div class="text">直播公告</div>
<div class="box"></div>
</div>
<div class="content" v-html="data.detail?.liveExplain"></div>
<div class="content" v-html="data?.liveExplain"></div>
</div>
<div class="teacher">
<div class="title">
<img
style="width: 21px; height: 23px"
src="../../assets/image/livelecturer.png"
style="width: 21px; height: 23px"
src="../../assets/image/livelecturer.png"
/>
<!-- todo #直播详情 没有直播讲师-->
<div class="text">直播讲师</div>
<div class="box"></div>
</div>
<div
v-for="(el, index) in teacher"
:key="el.id"
class="teacheritem"
:style="{
'border-bottom':
index === teacher.length - 1
? null
: '1px solid rgba(56, 125, 247, 0.2)',
}"
class="teacheritem"
:style="{ 'border-bottom': '1px solid rgba(56, 125, 247, 0.2)' }"
>
<img class="peopleimg" :src="el.peopleimg"/>
<img class="peopleimg" :src="userAvatar" />
<div style="margin-left: 17px; width: 190px">
<div class="teacherName" style="margin-right: 5px">
{{ el.name }}
{{ data.userInfoBo?.userName }}
</div>
<div class="introduce">{{ el.introduce }}</div>
<div class="introduce">{{ data.userInfoBo?.bandDesc }}</div>
</div>
<div class="follow">+ 关注</div>
<!-- <div class="follow">+ 关注</div>-->
</div>
</div>
</div>
@@ -142,13 +148,25 @@
</template>
<script setup>
import {reactive, toRefs} from "vue";
import img from '@/assets/image/uploadimg.png'
import {request, useRequest} from "@/api/request";
import {TASK_BROADCAST_COMMIT, TASK_BROADCAST_DETAIL, TASK_BROADCAST_SIGN} from "@/api/api";
import { computed, reactive, toRefs } from "vue";
import img from "@/assets/image/uploadimg.png";
import { request, useRequest } from "@/api/request";
import { TASK_BROADCAST_DETAIL, TASK_BROADCAST_SIGN } from "@/api/api";
import { useRoute } from "vue-router/dist/vue-router";
import { useRouter } from "vue-router";
import { useUserInfo } from "@/api/utils";
const {
query: { courseId: liveId },
} = useRoute();
const router = useRouter();
const { data } = useRequest(TASK_BROADCAST_DETAIL, { liveId });
const { avatar: userAvatar } = useUserInfo(
computed(() => data.value.userInfoBo?.userId)
);
const {data} = useRequest(TASK_BROADCAST_DETAIL, {})
const state = reactive({
activeName: "first",
teacher: [
@@ -156,32 +174,25 @@ const state = reactive({
id: 1,
name: "王星天(显示事业)",
introduce:
"教师是学生的镜子,学生是老师的影子。教师是学生的镜子,学生是老师的影子。教师是学生的镜子,学生是老师的影子。",
peopleimg: img,
},
{
id: 2,
name: "王星天(显示事业)",
introduce: "教师是学生的镜子,学生是老师的影子。",
"教师是学生的镜子,学生是老师的影子。教师是学生的镜子,学生是老师的影子。教师是学生的镜子,学生是老师的影子。",
peopleimg: img,
},
],
});
const {activeName, teacher} = toRefs(state)
const signClick = (id) => {
request(TASK_BROADCAST_SIGN, {id}).then(() => {
console.log(data.value)
data.value.signFlag = 1
})
const { activeName, teacher } = toRefs(state);
const signClick = () => {
data.value.signFlag = 1;
request(TASK_BROADCAST_SIGN, { courseId: liveId });
};
const commitClick = (id) => {
request(TASK_BROADCAST_COMMIT, {id}).then(() => {
data.value.evalFlag = 1
})
const commitClick = () => {
router.push({
path: "/surveydetail",
query: { courseId: data.value.assessmentId },
});
};
function showClick() {
window.open(data.value.liveLink);
}
</script>
@@ -469,9 +480,9 @@ function showClick() {
background-color: rgba(255, 255, 255, 1);
border-radius: 8px;
background: linear-gradient(
180deg,
rgba(36, 120, 255, 0.15) 0%,
rgba(255, 255, 255) 50%
180deg,
rgba(36, 120, 255, 0.15) 0%,
rgba(255, 255, 255) 50%
);
.title {

62
src/views/login/login.vue Normal file
View File

@@ -0,0 +1,62 @@
<template>
<div
:style="{
margin: 'auto',
background:
'url(http://img.gz2c.com/FoTcLY8ww-ISCFlwyCoYuLim1BMt) no-repeat',
backgroundSize: '100% 100%',
width: '100%',
height: '100vh',
display: 'flex',
}"
>
<div
:style="{
width: '300px',
height: '300px',
margin: '10% auto',
padding: '20px 30px',
textAlign: 'center',
borderRadius: '10px',
background: '#e0e0e0',
boxShadow: '20px 20px 60px #bebebe,-20px -20px 60px #ffffff',
}"
>
<div :style="{ fontSize: '24px', paddingBottom: '30px' }">用户登录</div>
<div>
<input placeholder="用户名" v-model="form.account"/>
<input
placeholder="密码"
v-model="form.password"
:style="{ marginTop: '30px' }"
type="password"
/>
<button :style="{ marginTop: '30px' }" @click="loginUser">
登录
</button>
</div>
</div>
</div>
</template>
<script setup>
import {useRouter} from "vue-router";
import {ref} from "vue";
import {LOGIN} from "@/api/api";
import {setCookie} from "@/api/utils";
import {request} from "@/api/request";
const router = useRouter();
const form = ref({
account: "10181457",
password: "1234567890Aa",
});
async function loginUser() {
const {data:token} = await request(LOGIN, form.value);
setCookie("token", token, 10);
await router.push({path: "/learnpath"});
// location.reload();
}
</script>

View File

@@ -1,5 +1,5 @@
<template>
<div class="moreactive">
<div class="moreactive" style="padding: 30px">
<!-- 面包屑导航 -->
<div class="crumb">
<div>混合制项目</div>
@@ -21,21 +21,25 @@
<div class="bascinfo">
<div style="margin-left: 46px">
<!-- <div class="title">其他活动管理者进阶腾飞班 - 专属线下活动</div>-->
<div class="title">{{ data.detail?.workName }}</div>
<div class="title">{{ data?.activityName }}</div>
<div class="time" style="margin-top: 26px">
<img width="15px" height="17px" src="../../assets/image/time.png"/>
<div style="margin-left: 8px">{{ data.detail?.createTime }}</div>
<img
style="width: 15px; height: 17px"
src="../../assets/image/time.png"
/>
<div style="margin-left: 8px">
{{ data?.activityStartTime + "-" + data?.activityEndTime }}
</div>
</div>
<div class="time" style="margin-top: 23px">
<img
width="16px"
height="18px"
src="../../assets/image/position.png"
style="width: 16px; height: 18px"
src="../../assets/image/position.png"
/>
<div style="margin-left: 8px">{{ data.detail?.workEnclosureAddress }}</div>
<div style="margin-left: 8px">{{ data?.activityAddress }}</div>
</div>
</div>
<div class="btn" v-if="!data.signFlag" @click="signClick">签到</div>
<div class="btn" v-if="!data.activityFlag" @click="signClick">签到</div>
</div>
<!-- 基本信息 -->
@@ -46,15 +50,58 @@
<div style="margin-left: 48px; margin-right: 48px">
<div class="title">
<img
width="20px"
height="20px"
src="../../assets/image/book.png"
style="width: 20px; height: 20px"
src="../../assets/image/book.png"
/>
<div class="text">课程详情</div>
<div class="text">活动详情</div>
<div class="box"></div>
</div>
<div style="display: flex; align-items: center">
<div class="content" v-html="data.detail?.workRequirement"></div>
<div class="activedetail">
<div>
<div>活动时长</div>
<div class="content">
{{
data?.activityDuration
? data?.activityDuration + "分钟"
: "-"
}}
</div>
</div>
<div>
<div>活动地点</div>
<div class="content">
{{ data?.activityAddress ? data?.activityAddress : "-" }}
</div>
</div>
<div>
<div>活动考勤</div>
<div class="content">
{{
data?.beforeSignIn
? "开始前" + data?.beforeSignIn + "分钟开始签到"
: "-"
}}
</div>
<div class="content">
{{
data?.afterSignIn
? "开始后" + data?.afterSignIn + "分钟结束签到"
: "-"
}}
</div>
</div>
<div>
<div>活动完成标准</div>
<div class="content">
{{ data?.standardSettings ? "仅签到" : "-" }}
</div>
</div>
<div>
<div>活动说明</div>
<div class="content">
{{ data?.activityExplain ? data?.activityExplain : "-" }}
</div>
</div>
</div>
</div>
</div>
@@ -62,25 +109,15 @@
<div class="teacher">
<div class="title">
<img
style="width: 24px; height: 20px"
src="../../assets/image/call.png"
style="width: 24px; height: 20px"
src="../../assets/image/call.png"
/>
<div class="text">活动公告</div>
<div class="box"></div>
</div>
<!-- todo #活动任务详情 活动公告没有-->
<div class="content">
为拓宽人民群众的表达途径畅听民意及时了解
和解决人民群众反映强烈的公共法律服务问题
局将在浈江区公共法律服务中心开展领导干部接待
活动现将2022年8月的活动安排公告如下<br/>
接待时间 <br/>
工作日上午9:00-12:00<br/>
接待地点<br/>
浈江区公共法律服务中心浈江区新韶镇乐土路3号
曲仁田螺冲党群服务中心一楼<br/>
接待受理范围 <br/>听取人民群众对公共法律服务工作的批评和
意见建议 <br/>解答或接收公共法律服务相关业务咨询<br/>
{{ data.activityNotice }}
</div>
</div>
</div>
@@ -89,17 +126,22 @@
</template>
<script setup>
import { TAS_ACTIVITY_DETAIL, TASK_ACTIVITY_SIGN, ACTIVITY } from "@/api/api";
import { request, useRequest } from "@/api/request";
import { useRoute } from "vue-router/dist/vue-router";
const {
query: { courseId: activityId },
} = useRoute();
import {TAS_ACTIVITY_DETAIL, TASK_ACTIVITY_SIGN} from "@/api/api";
import {request, useRequest} from "@/api/request";
const {data} = useRequest(TAS_ACTIVITY_DETAIL, {})
const { data } = useRequest(ACTIVITY, { activityId });
console.log("data", data);
const signClick = (tab, event) => {
request(TASK_ACTIVITY_SIGN, {}).then(res => {
console.log(22)
data.value.signFlag = 1
})
request(TASK_ACTIVITY_SIGN, {
activitySubmitId: data.activityId,
signInStatus: 1,
}).then((res) => {
data.value.activityFlag = 1;
});
};
</script>
@@ -227,14 +269,15 @@ const signClick = (tab, event) => {
left: 23px;
top: 53px;
}
.content {
margin-left: 8px;
font-size: 14px;
color: rgba(51, 51, 48, 1);
font-weight: 500;
line-height: 35px;
.activedetail {
margin-top: 30px;
font-size: 14px;
font-weight: 500;
color: #333330;
line-height: 36px;
.content {
color: #677d86;
}
}
}
@@ -369,9 +412,9 @@ const signClick = (tab, event) => {
background-color: rgba(255, 255, 255, 1);
border-radius: 8px;
background: linear-gradient(
180deg,
rgba(36, 120, 255, 0.15) 0%,
rgba(255, 255, 255) 50%
180deg,
rgba(36, 120, 255, 0.15) 0%,
rgba(255, 255, 255) 50%
);
.title {

View File

@@ -0,0 +1,846 @@
<template>
<div class="pathdetails" style="padding: 30px">
<!-- 面包屑导航 -->
<div class="crumb">
<div>产品经理学习路径图</div>
<div style="margin-left: 6px; margin-right: 6px">/</div>
<div style="font-weight: 700">路径图详情</div>
</div>
<!-- 面包屑导航 -->
<div class="pdname">中级产品经理</div>
<!-- 详细信息 -->
<div class="detailinfo">
<div class="detailL">
<div v-for="(i, k) in data.stageProcessList" :key="k">
<div class="title">
<div class="titleL">{{ i.stageName }}</div>
<div class="titleR" :style="{ display: 'flex' }">
<img src="../../assets/image/pathdetails/circle.png" />
<div class="titleRT">进行中</div>
</div>
<div
class="titleR"
:style="{ display: i.status === 2 ? 'flex' : 'none' }"
>
<img src="../../assets/image/pathdetails/circle2.png" />
<div class="titleRT" style="color: rgba(102, 102, 102, 1)">
未开始
</div>
</div>
</div>
<div
class="course"
v-for="(value, index) in i.taskProcessList"
:key="index"
>
<div>
<div class="coursename">{{ value.name }}</div>
<div class="coursetag">
<div class="tag1" style="margin-right: 11px; margin-top: 16px">
必修
</div>
<div class="tag3" style="margin-right: 11px; margin-top: 16px">
{{ types.typeName[value.type] || "" }}
</div>
<!-- <div-->
<!-- v-for="(item, key) in value.flag"-->
<!-- :key="key"-->
<!-- :class="{1:'tag1',2:'tag2',3:'tag3',4:'tag4'}[item.type]"-->
<!-- style="margin-right: 11px; margin-top: 16px"-->
<!-- >-->
<!-- {{ item.name }}-->
<!-- </div>-->
</div>
<div
class="progressBox"
:style="{ display: value.status === 1 ? 'block' : 'none' }"
>
<div>当前进度</div>
<div class="progress">
<div style="width: 291px">
<el-progress
:percentage="value.currentRatio"
:show-text="false"
:stroke-width="8"
:color="
{
0: 'rgba(238, 112, 108, 1)',
1: 'rgba(255, 151, 38, 1)',
2: 'rgba(39, 122, 255, 1)',
3: 'rgba(59, 94, 251, 1)',
4: 'rgba(57, 219, 183, 1)',
5: 'rgba(57, 219, 183, 1)',
}[parseInt(value.currentRatio / 20)]
"
/>
</div>
<div
style="
font-size: 14px;
font-weight: 500;
color: #277aff;
margin-left: 10px;
"
:style="{
color: {
0: 'rgba(238, 112, 108, 1)',
1: 'rgba(255, 151, 38, 1)',
2: 'rgba(39, 122, 255, 1)',
3: 'rgba(59, 94, 251, 1)',
4: 'rgba(57, 219, 183, 1)',
5: 'rgba(57, 219, 183, 1)',
}[parseInt(value.currentRatio / 20)],
}"
>
{{ value.currentRatio }}%
</div>
</div>
</div>
</div>
<div class="goclass" @click="toFinish(value)">
{{ types.toName[value.type] || "" }}
</div>
<!-- <div :style="{ display: value.status === 1 ? 'block' : 'none' }">-->
<!-- <div-->
<!-- class="goclass"-->
<!-- :style="{ display: value.currentRatio === 0 ? 'none' : 'flex' }">去上课-->
<!-- </div>-->
<!-- <img-->
<!-- style="width: 76px; height: 76px; margin-right: 61px"-->
<!-- :style="{ display: value.currentRatio === 0 ? 'flex' : 'none' }"-->
<!-- src="../../assets/image/pathdetails/notstarted.png"-->
<!-- />-->
<!-- </div>-->
</div>
</div>
<!-- <div class="tag1">必修</div>
<div class="tag2">选修</div>
<div class="tag3">测评</div>
<div class="tag4">#通用力</div> -->
</div>
<div class="detailR">
<!-- todo #路径详情 课程公告及共享文档缺失-->
<!-- 课程公告及共享文档 -->
<div class="detailRT">
<el-tabs v-model="activeName" @tab-click="handleClick">
<el-tab-pane label="课程公告" name="first">
<div class="notice">
请各位选课的同学提前阅读本课程的
教学大纲与计划课程考核要求学习要求
并按给定的中学化学教学主题分好小组 <br />
每位同学在网上学习的活动轨迹都会自动被系统记录将作为大家个人线上参与的评价依据<br />
请大家务必在规定的时间内提交作业否则会被系统自动记录为迟交未交则会影响线上参与的平时成
<br />
</div>
</el-tab-pane>
<el-tab-pane label="共享文档" name="second">
<div style="padding: 19px 30px 17px 28px">
<div
v-for="(value, index) in sharedoc"
:key="index"
style="
display: flex;
align-items: center;
margin-bottom: 15px;
"
>
<img :src="value.img" style="width: 22px; height: 26px" />
<div class="sharedocname">{{ value.name }}</div>
<div class="download">
<img
src="../../assets/image/download.png"
style="width: 16px; height: 15px"
/>
<div style="margin-left: 7px">下载</div>
</div>
</div>
</div>
</el-tab-pane>
</el-tabs>
</div>
<!-- 课程公告及共享文档 -->
<!-- 个人信息及学习进度 -->
<div class="detailRB">
<div class="info">
<div class="title">
<img
style="width: 21px; height: 20px"
src="../../assets/image/pathdetails/info.png"
/>
<div class="text" style="margin-left: 7px">个人信息</div>
<div class="box"></div>
</div>
<!-- todo #路径详情 个人信息缺少img和介绍-->
<div
class="teacheritem"
:style="{ 'border-bottom': '1px solid rgba(56, 125, 247, 0.2)' }"
>
<img class="peopleimg" :src="data.userInfoBo?.peopleimg" />
<div style="margin-left: 17px">
<div class="teacherName">
<div style="margin-right: 5px">
{{ data.userInfoBo?.userName }}
</div>
<div v-for="(item, key) in data.userInfoBo?.medal" :key="key">
<img class="teacherMedal" :src="item" />
</div>
</div>
<div class="introduce">{{ data.userInfoBo?.introduce }}</div>
</div>
</div>
</div>
<div class="info" style="padding-top: 20px">
<div class="title">
<img
style="width: 18px; height: 17px"
src="../../assets/image/pathdetails/study.png"
/>
<div class="text" style="margin-left: 9px">学习进度</div>
<div class="box"></div>
</div>
<div class="rate">
<div class="ratetext">上次学到启航班-领导寄语</div>
<div class="ratebtn">继续学习</div>
</div>
<div style="margin-top: 16px">
<div class="progressBox">
<div>总进度</div>
<div class="progress">
<div style="width: 291px">
<el-progress
:percentage="data.totalChapterCnt"
:show-text="false"
:stroke-width="8"
:color="
{
0: 'rgba(238, 112, 108, 1)',
1: 'rgba(255, 151, 38, 1)',
2: 'rgba(39, 122, 255, 1)',
3: 'rgba(59, 94, 251, 1)',
4: 'rgba(57, 219, 183, 1)',
5: 'rgba(57, 219, 183, 1)',
}[parseInt(data.totalChapterCnt / 20)]
"
/>
</div>
<div
style="font-size: 14px; font-weight: 500; margin-left: 10px"
:style="{
color: {
0: 'rgba(238, 112, 108, 1)',
1: 'rgba(255, 151, 38, 1)',
2: 'rgba(39, 122, 255, 1)',
3: 'rgba(59, 94, 251, 1)',
4: 'rgba(57, 219, 183, 1)',
5: 'rgba(57, 219, 183, 1)',
}[parseInt(data.totalChapterCnt / 20)],
}"
>
{{ data.totalChapterCnt }}%
</div>
</div>
</div>
</div>
<div style="margin-top: 31px">
<div class="progressBox">
<div>必修进度</div>
<div class="progress">
<div style="width: 291px">
<el-progress
:percentage="data.currentChapterCnt"
:show-text="false"
:stroke-width="8"
:color="
{
0: 'rgba(238, 112, 108, 1)',
1: 'rgba(255, 151, 38, 1)',
2: 'rgba(39, 122, 255, 1)',
3: 'rgba(59, 94, 251, 1)',
4: 'rgba(57, 219, 183, 1)',
5: 'rgba(57, 219, 183, 1)',
}[parseInt(data.currentChapterCnt / 20)]
"
/>
</div>
<div
style="
font-size: 14px;
font-weight: 500;
color: #277aff;
margin-left: 10px;
"
:style="{
color: {
0: 'rgba(238, 112, 108, 1)',
1: 'rgba(255, 151, 38, 1)',
2: 'rgba(39, 122, 255, 1)',
3: 'rgba(59, 94, 251, 1)',
4: 'rgba(57, 219, 183, 1)',
5: 'rgba(57, 219, 183, 1)',
}[parseInt(data.currentChapterCnt / 20)],
}"
>
{{ data.currentChapterCnt }}%
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 个人信息及学习进度 -->
</div>
</div>
<!-- 详细信息 -->
</div>
</template>
<script setup>
import { reactive, ref } from "vue";
import word from "@/assets/image/file/word.png";
import ppt from "@/assets/image/file/ppt.png";
import pdf from "@/assets/image/file/pdf.png";
import zip from "@/assets/image/file/zip.png";
import md from "@/assets/image/file/md.png";
import medal1 from "@/assets/image/medal/medal1.png";
import medal2 from "@/assets/image/medal/medal2.png";
import medal3 from "@/assets/image/medal/medal3.png";
import img from "@/assets/image/uploadimg.png";
import { useRequest } from "@/api/request";
import { PROJECT_PROCESS, ROUTER_PROCESS } from "@/api/api";
import { useRoute, useRouter } from "vue-router";
const {
query: { projectId },
} = useRoute();
const router = useRouter();
const { data } = useRequest(PROJECT_PROCESS, { projectId });
const state = reactive({
course: [
{
state: 1, //1进行中 2未开始
title: "序:产品经理从初级到中级",
courseItem: [
{
id: 1,
name: "人工智能启蒙就讲解(上)",
tag: [
{
classify: 1, //1必修 2选修 3在线、测评等 4标签
name: "必修",
},
{
classify: 3,
name: "在线",
},
{
classify: 4,
name: "#通用力",
},
{
classify: 4,
name: "#前沿趋势",
},
],
progress: 90,
},
{
id: 1,
name: "人工智能启蒙就讲解(下)",
tag: [
{
classify: 2,
name: "选修",
},
{
classify: 3,
name: "测评",
},
{
classify: 4,
name: "#通用力",
},
{
classify: 4,
name: "#前沿趋势",
},
],
progress: 0,
},
],
},
{
state: 2, //1进行中 2未开始
title: "第一讲:中级产品经理的思考逻辑",
courseItem: [
{
id: 1,
name: "趣味课前小测 - MBTI测试你适合做哪个方向",
tag: [
{
classify: 1, //1必修 2选修 3在线、测评等 4标签
name: "必修",
},
{
classify: 3,
name: "测评",
},
],
progress: 48,
},
{
id: 1,
name: "趣味课前小测 - MBTI测试你适合做哪个方向",
tag: [
{
classify: 2,
name: "选修",
},
{
classify: 3,
name: "外部链接",
},
],
progress: 0,
},
],
},
{
state: 2, //1进行中 2未开始
title: "第二讲:模块化产品展示",
courseItem: [
{
id: 1,
name: "模块化产品展示相关案例与展示:如何自由组合你的思考?",
tag: [
{
classify: 1, //1必修 2选修 3在线、测评等 4标签
name: "必修",
},
{
classify: 3,
name: "测评",
},
],
progress: 48,
},
{
id: 1,
name: "社交产品如何做好模块化处理?",
tag: [
{
classify: 2,
name: "选修",
},
{
classify: 3,
name: "作业",
},
],
progress: 0,
},
{
id: 1,
name: "微信与Telegram哪个平台的功能模块化做的最好",
tag: [
{
classify: 2,
name: "选修",
},
{
classify: 3,
name: "辩论",
},
],
progress: 0,
},
],
},
],
sharedoc: [
{
id: 1,
name: "项目参考文档.doc",
img: word,
},
{
id: 2,
name: "人工智能启蒙讲解讲义.pptx",
img: ppt,
},
{
id: 3,
name: "中级产品经理必备工具.pdf",
img: pdf,
},
{
id: 4,
name: "Python学习入门讲义.zip",
img: zip,
},
{
id: 5,
name: "Axure RP10更新内容.md",
img: md,
},
],
teacher: [
{
id: 1,
name: "王星天(显示事业)",
introduce: "教师是学生的镜子,学生是老师的影子。",
peopleimg: img,
medal: [medal1, medal2, medal3],
},
],
});
const activeName = ref("first");
const totalprogress = ref(30);
const compulsoryprogress = ref(10);
const handleClick = (tab, event) => {
console.log(tab, event);
};
const path = { 1: "path" };
const types = ref({
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: "去上课",
2: "/faceteach",
3: "案例",
4: "/homeworkpage",
5: "去完成",
6: "/livebroadcast",
7: "外链",
8: "/discusspage",
9: "/moreactive",
10: "/starttest",
11: "/surveydetail",
12: "/ballotpage",
13: "去完成",
},
});
function toFinish(d) {
router.push({
path: types.value.path[d.type],
query: { id: d.projectTaskId, type: 2, courseId: d.courseId },
});
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style lang="scss">
.pathdetails {
.crumb {
color: #fff;
display: flex;
font-size: 14px;
line-height: 24px;
}
.pdname {
font-size: 20px;
font-weight: 800;
color: #ffffff;
margin-top: 17px;
}
.detailinfo {
width: 100%;
margin-top: 24px;
display: flex;
.detailL {
flex: 1;
margin-right: 20px;
background: #ffffff;
border-radius: 8px;
padding-left: 45px;
padding-right: 45px;
padding-top: 23px;
.title {
height: 50px;
display: flex;
justify-content: space-between;
align-items: center;
background-color: rgba(249, 249, 249, 1);
margin-top: 27px;
margin-bottom: 19px;
.titleL {
font-size: 16px;
font-weight: 800;
color: #333333;
margin-left: 27px;
}
.titleR {
display: flex;
align-items: center;
}
.titleR .titleRT {
font-size: 16px;
font-weight: 800;
color: #0060ff;
margin-right: 73px;
margin-left: 2px;
}
}
.course {
display: flex;
align-items: center;
justify-content: space-between;
flex-wrap: wrap;
margin-bottom: 32px;
margin-left: 26px;
.coursename {
font-size: 14px;
font-weight: 500;
color: #333330;
line-height: 24px;
}
.coursetag {
display: flex;
flex-wrap: wrap;
}
.progressBox {
font-size: 14px;
font-weight: 500;
color: #677d86;
margin-top: 24px;
.progress {
display: flex;
align-items: center;
}
.progress .el-progress-bar__outer {
background-color: rgba(232, 241, 254, 1);
}
}
.goclass {
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;
display: flex;
align-items: center;
justify-content: center;
margin-right: 37px;
cursor: pointer;
}
}
}
.detailR {
width: 434px;
.detailRT {
min-height: 298px;
background: #ffffff;
border-radius: 8px;
.el-tabs__item {
height: 56px;
padding: 10px 33px 0px 27px;
font-size: 14px;
font-weight: 500;
}
.el-tabs__nav-wrap::after {
background-color: rgba(56, 125, 247, 0.2);
}
.notice {
padding: 15px 43px 30px 47px;
font-size: 14px;
font-weight: 500;
color: #333330;
line-height: 24px;
}
.sharedocname {
width: 259px;
font-size: 14px;
font-weight: 400;
color: #677d86;
margin-left: 20px;
line-height: 24px;
}
.download {
display: flex;
align-items: center;
margin-left: 20px;
cursor: pointer;
font-size: 16px;
font-weight: 400;
color: #2478ff;
}
}
.detailRB {
min-height: 459px;
background: #ffffff;
border-radius: 8px;
margin-top: 17px;
.info .title {
display: flex;
align-items: center;
padding-top: 39px;
position: relative;
margin-left: 48px;
}
.info .title .text {
margin-left: 8px;
font-size: 16px;
color: rgba(51, 51, 51, 1);
font-weight: 800;
}
.info .title .box {
width: 75px;
height: 10px;
background-color: rgba(36, 120, 255, 0.15);
position: absolute;
left: 23px;
top: 53px;
}
.info .teacheritem {
margin-left: 48px;
margin-right: 48px;
margin-top: 30px;
display: flex;
// align-items: center;
}
.info .teacheritem .peopleimg {
width: 60px;
height: 60px;
border-radius: 30px;
}
.info .teacheritem .teacherName {
font-size: 14px;
font-weight: bold;
color: #394145;
display: flex;
align-items: center;
width: 260px;
}
.info .teacheritem .teacherName .teacherMedal {
width: 17px;
height: 19px;
margin-right: 4px;
display: flex;
align-items: center;
}
.info .teacheritem .introduce {
width: 260px;
font-size: 14px;
font-weight: 500;
color: #394145;
margin-top: 14px;
line-height: 24px;
}
.info .rate {
display: flex;
align-items: center;
justify-content: space-between;
margin-top: 29px;
margin-left: 48px;
margin-right: 26px;
}
.info .rate .ratetext {
width: 259px;
font-size: 14px;
font-weight: 500;
color: #677d86;
line-height: 24px;
}
.info .rate .ratebtn {
width: 86px;
height: 36px;
border: 1px solid #2478ff;
border-radius: 4px;
font-size: 14px;
font-weight: 500;
color: #2478ff;
line-height: 24px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
}
.info .progressBox {
font-size: 14px;
font-weight: 500;
color: #677d86;
margin-top: 16px;
margin-left: 44px;
.progress {
display: flex;
align-items: center;
}
.progress .el-progress-bar__outer {
background-color: rgba(232, 241, 254, 1);
}
}
}
}
}
}
</style>

View File

@@ -4,53 +4,58 @@
<div class="title">
<div class="titleL">
<div @click="returnfun" class="text">学习路径图</div>
<div class="info" style="margin-right: 14px">
<img style="width: 20px; height: 18px; margin-right: 10px"
src="../../assets/image/pm.png"
<div class="info" style="margin-right: 14px" v-if="useInfo.jobName">
<img
style="width: 20px; height: 18px; margin-right: 10px"
src="../../assets/image/pm.png"
/>
<div style="margin-top: 1px">产品经理</div>
<div style="margin-top: 1px">{{ useInfo.jobName }}</div>
</div>
<div class="info">
<img style="width: 18px; height: 17px; margin-right: 11px"
src="../../assets/image/band.png"
<div class="info" v-if="useInfo.bandDesc">
<img
style="width: 18px; height: 17px; margin-right: 11px"
src="../../assets/image/band.png"
/>
<div style="margin-top: 2px">Band8</div>
<div style="margin-top: 2px">{{ useInfo.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>
<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>-->
<!-- todo #学习路径 只会有一个未完成任务么?是否是直接跳到任务详情-->
<!-- <div class="titleR">进入未完成任务</div>-->
<!-- </template>-->
<!-- </el-popover>-->
</div>
<div
:style="{ display: showmapdetail ? 'flex' : 'none' }"
@@ -63,7 +68,7 @@
<!-- 路径列表-->
<div :style="{ display: !showmapdetail ? 'flex' : 'none' }" class="head">
<div style="min-width: 770px; width: 100%">
<el-table :data="data.rows" style="width: 100%" @row-click="gofun">
<el-table :data="data" style="width: 100%" @row-click="gofun">
<el-table-column
prop="img"
label="缩略图"
@@ -71,7 +76,10 @@
align="center"
width="255"
>
<img :src="scope.row.picUrl" style="width: 230px; height: 155px"/>
<img
:src="scope.row.picUrl"
style="width: 230px; height: 155px"
/>
</el-table-column>
<el-table-column align="center" prop="name" label="路径名称"/>
<el-table-column
@@ -83,7 +91,6 @@
<el-popover
placement="top-start"
title="路径介绍"
:width="350"
trigger="hover"
:content="scope.row.remark"
>
@@ -93,16 +100,23 @@
</el-popover>
</el-table-column>
<el-table-column align="center" prop="target" label="目标人群"/>
<el-table-column
align="center"
prop="organizationName"
label="归属组织"
/>
<el-table-column
#default="scope"
align="center"
width="110"
:width="150"
prop="state"
label="状态"
>
<img :src="{0:nostarted,1:completed,2:ongoing}[scope.row.status]"
style="width: 99px; height: 99px"
<img
:src="
{ 0: nostarted, 1: completed, 2: ongoing }[scope.row.status]
"
style="width: 99px; height: 99px"
/>
</el-table-column>
</el-table>
@@ -114,52 +128,74 @@
:style="{ display: showmapdetail ? 'flex' : 'none' }"
class="mapdetail"
>
<div v-for="(item,i) in detail?.rows">
<img :src="useImage(`222_0${i+2}.png`)">
<div v-for="(item, i) in detail?.rows" :key="i">
<img :src="useImage(`222_0${i + 2}.png`)"/>
</div>
<!-- <div class="modal"-->
<!-- style="width: calc(100% - 168px); height: 525px;background-image: url('../../src/assets/image/mapdetail.png');background-size: 100%;background-repeat: no-repeat;">-->
<!-- </div>-->
<!-- <div class="modal"-->
<!-- style="width: calc(100% - 168px); height: 525px;background-image: url('../../src/assets/image/mapdetail.png');background-size: 100%;background-repeat: no-repeat;">-->
<!-- </div>-->
</div>
<!-- 路径详情图 -->
</div>
</div>
</template>
<script setup>
import {reactive, toRefs, ref} from "vue";
import nostarted from '../../assets/image/nostarted.png'
import completed from '../../assets/image/completed.png'
import ongoing from '../../assets/image/ongoing.png'
import {request, useRequest} from "@/api/request";
import {ROUTER_CHAPTER_LIST, ROUTER_LIST, ROUTER_UNCOMPLETE_LIST} from "@/api/api";
import {reactive, toRefs, ref, onMounted} from "vue";
import nostarted from "../../assets/image/nostarted.png";
import completed from "../../assets/image/completed.png";
import ongoing from "../../assets/image/ongoing.png";
import {boeRequest, request, usePage, useRequest} from "@/api/request";
import {
BASE_URL,
ROUTER_CHAPTER_LIST,
ROUTER_LIST,
ROUTER_UNCOMPLETE_LIST,
} from "@/api/api";
import {useImage} from "@/api/utils";
import {useRouter} from "vue-router";
import {GET_USER_INFO} from "@/api/ThirdApi";
const detail = ref();
const useInfo = ref({});
const {data} = usePage(ROUTER_LIST, {});
const router = useRouter();
// const {unCompleteTaskList} = useRequest(ROUTER_UNCOMPLETE_LIST, {});
onMounted(()=>{
boeRequest(GET_USER_INFO).then(res=>{
useInfo.value=res.result
})
})
const detail = ref()
const {data} = useRequest(ROUTER_LIST, {})
const {unCompleteTaskList} = useRequest(ROUTER_UNCOMPLETE_LIST, {})
const state = reactive({
showmapdetail: false,
});
const {showmapdetail} = toRefs(state)
const {showmapdetail} = toRefs(state);
const returnfun = () => {
state.showmapdetail = false;
};
async function gofun(routerId) {
const data = await request(ROUTER_CHAPTER_LIST, {stuChapterListVo: {routerId}})
detail.value = data.data
state.showmapdetail = true;
async function gofun({routerId}) {
// console.log(routerId)
// const data = await request(ROUTER_CHAPTER_LIST, {stuChapterListVo: {routerId}})
// detail.value = data.data
// state.showmapdetail = true;
// router.push({path: "/pathdetails", query: {routerId}});
import.meta.env.DEV ? router.push({
path: "/pathdetails",
query: {routerId}
}) : window.parent.location.href = `http://u-pre.boe.com/pc/forward?to=/fe-student/pathdetails&params=${encodeURIComponent(`routerId=${routerId}`)}`
}
function toUnTask() {
}
</script>
<style lang="scss">
.modal {
.modal {
}
.modal:after {
@@ -168,8 +204,8 @@ function toUnTask() {
.learnpath {
width: 100%;
min-height: 734px;
border-radius: 8px;
min-height: 800px;
//border-radius: 8px;
background-color: rgba(255, 255, 255, 1);
display: flex;

View File

@@ -1,5 +1,5 @@
<template>
<div class="pathdetails">
<div class="pathdetails" style="padding: 30px">
<!-- 面包屑导航 -->
<div class="crumb">
<div>产品经理学习路径图</div>
@@ -16,7 +16,7 @@
<div class="titleL">{{ i.chapterName }}</div>
<div
class="titleR"
:style="{ display: i.status === 1 ? 'flex' : 'none' }"
:style="{ display: 'flex' }"
>
<img src="../../assets/image/pathdetails/circle.png"/>
<div class="titleRT">进行中</div>
@@ -39,15 +39,21 @@
<div>
<div class="coursename">{{ value.name }}</div>
<div class="coursetag">
<!-- todo #路径详情 缺少标签-->
<!-- <div-->
<!-- v-for="(item, key) in value.flag"-->
<!-- :key="key"-->
<!-- :class="{1:'tag1',2:'tag2',3:'tag3',4:'tag4'}[item.type]"-->
<!-- style="margin-right: 11px; margin-top: 16px"-->
<!-- >-->
<!-- {{ item.name }}-->
<!-- </div>-->
<div class="tag1" style="margin-right: 11px; margin-top: 16px" v-if="value.flag">必修</div>
<div class="tag2" style="margin-right: 11px; margin-top: 16px" v-if="!value.flag">选修</div>
<div class="tag3" style="margin-right: 11px; margin-top: 16px">{{
types.typeName[value.type] || ''
}}
</div>
<!-- <div-->
<!-- v-for="(item, key) in value.flag"-->
<!-- :key="key"-->
<!-- :class="{1:'tag1',2:'tag2',3:'tag3',4:'tag4'}[item.type]"-->
<!-- style="margin-right: 11px; margin-top: 16px"-->
<!-- >-->
<!-- {{ item.name }}-->
<!-- </div>-->
</div>
<div
class="progressBox"
@@ -96,19 +102,23 @@
</div>
</div>
</div>
<div :style="{ display: value.status === 1 ? 'block' : 'none' }">
<div
class="goclass"
:style="{ display: value.currentRatio === 0 ? 'none' : 'flex' }"
>
去上课
</div>
<img
style="width: 76px; height: 76px; margin-right: 61px"
:style="{ display: value.currentRatio === 0 ? 'flex' : 'none' }"
src="../../assets/image/pathdetails/notstarted.png"
/>
<div class="goclass" :style="{background:`${types.path[value.type]?'#2478ff':'#999'}`}"
@click="toFinish(value)">
{{
types.path[value.type] ? types.toName[value.type] : '未开放'
}}
</div>
<!-- <div :style="{ display: value.status === 1 ? 'block' : 'none' }">-->
<!-- <div-->
<!-- class="goclass"-->
<!-- :style="{ display: value.currentRatio === 0 ? 'none' : 'flex' }">去上课-->
<!-- </div>-->
<!-- <img-->
<!-- style="width: 76px; height: 76px; margin-right: 61px"-->
<!-- :style="{ display: value.currentRatio === 0 ? 'flex' : 'none' }"-->
<!-- src="../../assets/image/pathdetails/notstarted.png"-->
<!-- />-->
<!-- </div>-->
</div>
</div>
<!-- <div class="tag1">必修</div>
@@ -117,7 +127,7 @@
<div class="tag4">#通用力</div> -->
</div>
<div class="detailR">
<!-- todo #路径详情 课程公告及共享文档缺失-->
<!-- todo #路径详情 课程公告及共享文档缺失-->
<!-- 课程公告及共享文档 -->
<div class="detailRT">
<el-tabs v-model="activeName" @tab-click="handleClick">
@@ -168,27 +178,20 @@
<div class="text" style="margin-left: 7px">个人信息</div>
<div class="box"></div>
</div>
<!-- todo #路径详情 个人信息缺少img和介绍-->
<!-- todo #路径详情 个人信息缺少img和介绍-->
<div
v-for="(el, index) in [data.userInfoBo]"
:key="el.id"
class="teacheritem"
:style="{
'border-bottom':
index === teacher.length - 1
? null
: '1px solid rgba(56, 125, 247, 0.2)',
}"
:style="{'border-bottom': '1px solid rgba(56, 125, 247, 0.2)'}"
>
<img class="peopleimg" :src="el.peopleimg"/>
<img class="peopleimg" :src="userAvatar"/>
<div style="margin-left: 17px">
<div class="teacherName">
<div style="margin-right: 5px">{{ el.userName }}</div>
<div v-for="(item, key) in el.medal" :key="key">
<div style="margin-right: 5px">{{ data.userInfoBo?.userName }}</div>
<div v-for="(item, key) in data.userInfoBo?.medal" :key="key">
<img class="teacherMedal" :src="item"/>
</div>
</div>
<div class="introduce">{{ el.introduce }}</div>
<div class="introduce">{{ data.userInfoBo?.introduce }}</div>
</div>
</div>
</div>
@@ -211,7 +214,7 @@
<div class="progress">
<div style="width: 291px">
<el-progress
:percentage="data.totalChapterCnt"
:percentage="parseInt(data.currentChapterCnt/data.totalChapterCnt * 100)"
:show-text="false"
:stroke-width="8"
:color="
@@ -222,7 +225,7 @@
3:'rgba(59, 94, 251, 1)',
4:'rgba(57, 219, 183, 1)',
5:'rgba(57, 219, 183, 1)'
}[parseInt(data.totalChapterCnt/20)]
}[parseInt(data.currentChapterCnt/data.totalChapterCnt)]
"
/>
</div>
@@ -240,10 +243,10 @@
3:'rgba(59, 94, 251, 1)',
4:'rgba(57, 219, 183, 1)',
5:'rgba(57, 219, 183, 1)'
}[parseInt(data.totalChapterCnt/20)]
}[parseInt(data.currentChapterCnt/data.totalChapterCnt)]
}"
>
{{ data.totalChapterCnt }}%
{{ parseInt(data.currentChapterCnt / data.totalChapterCnt * 100) }}%
</div>
</div>
</div>
@@ -254,7 +257,7 @@
<div class="progress">
<div style="width: 291px">
<el-progress
:percentage="data.currentChapterCnt"
:percentage="parseInt(data.currentReqCnt/data.totalReqCnt * 100)"
:show-text="false"
:stroke-width="8"
:color="
@@ -265,7 +268,7 @@
3:'rgba(59, 94, 251, 1)',
4:'rgba(57, 219, 183, 1)',
5:'rgba(57, 219, 183, 1)'
}[parseInt(data.currentChapterCnt/20)]
}[parseInt(data.currentReqCnt/data.totalReqCnt)]
"
/>
</div>
@@ -285,10 +288,10 @@
3:'rgba(59, 94, 251, 1)',
4:'rgba(57, 219, 183, 1)',
5:'rgba(57, 219, 183, 1)'
}[parseInt(data.currentChapterCnt/20)]
}[parseInt(data.currentReqCnt/data.totalReqCnt)]
}"
>
{{ data.currentChapterCnt }}%
{{ parseInt(data.currentReqCnt / data.totalReqCnt * 100) }}%
</div>
</div>
</div>
@@ -302,8 +305,8 @@
</div>
</template>
<script>
import {reactive, toRefs} from "vue";
<script setup>
import {computed, reactive, ref, watch} from "vue";
import word from '@/assets/image/file/word.png'
import ppt from '@/assets/image/file/ppt.png'
import pdf from '@/assets/image/file/pdf.png'
@@ -313,209 +316,265 @@ import medal1 from '@/assets/image/medal/medal1.png'
import medal2 from '@/assets/image/medal/medal2.png'
import medal3 from '@/assets/image/medal/medal3.png'
import img from '@/assets/image/uploadimg.png'
import {useRequest} from "@/api/request";
import {ROUTER_PROCESS} from "@/api/api";
import {boeRequest, useRequest} from "@/api/request";
import {BASE_URL, ROUTER_PROCESS} from "@/api/api";
import {useRoute, useRouter} from "vue-router";
import {ElMessage} from 'element-plus'
import {useUserInfo} from "@/api/utils";
export default {
name: "PathDetails",
setup() {
const {data} = useRequest(ROUTER_PROCESS, {})
const state = reactive({
activeName: "first",
course: [
{
state: 1, //1进行中 2未开始
title: "序:产品经理从初级到中级",
courseItem: [
{
id: 1,
name: "人工智能启蒙就讲解(上)",
tag: [
{
classify: 1, //1必修 2选修 3在线、测评等 4标签
name: "必修",
},
{
classify: 3,
name: "在线",
},
{
classify: 4,
name: "#通用力",
},
{
classify: 4,
name: "#前沿趋势",
},
],
progress: 90,
},
{
id: 1,
name: "人工智能启蒙就讲解(下)",
tag: [
{
classify: 2,
name: "选修",
},
{
classify: 3,
name: "测评",
},
{
classify: 4,
name: "#通用力",
},
{
classify: 4,
name: "#前沿趋势",
},
],
progress: 0,
},
],
},
{
state: 2, //1进行中 2未开始
title: "第一讲:中级产品经理的思考逻辑",
courseItem: [
{
id: 1,
name: "趣味课前小测 - MBTI测试你适合做哪个方向",
tag: [
{
classify: 1, //1必修 2选修 3在线、测评等 4标签
name: "必修",
},
{
classify: 3,
name: "测评",
},
],
progress: 48,
},
{
id: 1,
name: "趣味课前小测 - MBTI测试你适合做哪个方向",
tag: [
{
classify: 2,
name: "选修",
},
{
classify: 3,
name: "外部链接",
},
],
progress: 0,
},
],
},
{
state: 2, //1进行中 2未开始
title: "第二讲:模块化产品展示",
courseItem: [
{
id: 1,
name: "模块化产品展示相关案例与展示:如何自由组合你的思考?",
tag: [
{
classify: 1, //1必修 2选修 3在线、测评等 4标签
name: "必修",
},
{
classify: 3,
name: "测评",
},
],
progress: 48,
},
{
id: 1,
name: "社交产品如何做好模块化处理?",
tag: [
{
classify: 2,
name: "选修",
},
{
classify: 3,
name: "作业",
},
],
progress: 0,
},
{
id: 1,
name: "微信与Telegram哪个平台的功能模块化做的最好",
tag: [
{
classify: 2,
name: "选修",
},
{
classify: 3,
name: "辩论",
},
],
progress: 0,
},
],
},
],
sharedoc: [
const {query: {routerId}} = useRoute()
const router = useRouter()
const {data} = useRequest(ROUTER_PROCESS, {routerId})
const {avatar: userAvatar} = useUserInfo(computed(() => data.value?.userInfoBo?.userId))
const state = reactive({
course: [
{
state: 1, //1进行中 2未开始
title: "序:产品经理从初级到中级",
courseItem: [
{
id: 1,
name: "项目参考文档.doc",
img: word,
name: "人工智能启蒙就讲解(上)",
tag: [
{
classify: 1, //1必修 2选修 3在线、测评等 4标签
name: "必修",
},
{
classify: 3,
name: "在线",
},
{
classify: 4,
name: "#通用力",
},
{
classify: 4,
name: "#前沿趋势",
},
],
progress: 90,
},
{
id: 2,
name: "人工智能启蒙讲解讲义.pptx",
img: ppt,
},
{
id: 3,
name: "中级产品经理必备工具.pdf",
img: pdf,
},
{
id: 4,
name: "Python学习入门讲义.zip",
img: zip,
},
{
id: 5,
name: "Axure RP10更新内容.md",
img: md,
},
],
teacher: [
{
id: 1,
name: "王星天(显示事业",
introduce: "教师是学生的镜子,学生是老师的影子。",
peopleimg: img,
medal: [
medal1,
medal2,
medal3,
name: "人工智能启蒙就讲解(下",
tag: [
{
classify: 2,
name: "选修",
},
{
classify: 3,
name: "测评",
},
{
classify: 4,
name: "#通用力",
},
{
classify: 4,
name: "#前沿趋势",
},
],
progress: 0,
},
],
totalprogress: 30, //总进度
compulsoryprogress: 10, //必修进度
});
const handleClick = (tab, event) => {
console.log(tab, event);
};
return {
...toRefs(state),
handleClick,
data,
};
},
},
{
state: 2, //1进行中 2未开始
title: "第一讲:中级产品经理的思考逻辑",
courseItem: [
{
id: 1,
name: "趣味课前小测 - MBTI测试你适合做哪个方向",
tag: [
{
classify: 1, //1必修 2选修 3在线、测评等 4标签
name: "必修",
},
{
classify: 3,
name: "测评",
},
],
progress: 48,
},
{
id: 1,
name: "趣味课前小测 - MBTI测试你适合做哪个方向",
tag: [
{
classify: 2,
name: "选修",
},
{
classify: 3,
name: "外部链接",
},
],
progress: 0,
},
],
},
{
state: 2, //1进行中 2未开始
title: "第二讲:模块化产品展示",
courseItem: [
{
id: 1,
name: "模块化产品展示相关案例与展示:如何自由组合你的思考?",
tag: [
{
classify: 1, //1必修 2选修 3在线、测评等 4标签
name: "必修",
},
{
classify: 3,
name: "测评",
},
],
progress: 48,
},
{
id: 1,
name: "社交产品如何做好模块化处理?",
tag: [
{
classify: 2,
name: "选修",
},
{
classify: 3,
name: "作业",
},
],
progress: 0,
},
{
id: 1,
name: "微信与Telegram哪个平台的功能模块化做的最好",
tag: [
{
classify: 2,
name: "选修",
},
{
classify: 3,
name: "辩论",
},
],
progress: 0,
},
],
},
],
sharedoc: [
{
id: 1,
name: "项目参考文档.doc",
img: word,
},
{
id: 2,
name: "人工智能启蒙讲解讲义.pptx",
img: ppt,
},
{
id: 3,
name: "中级产品经理必备工具.pdf",
img: pdf,
},
{
id: 4,
name: "Python学习入门讲义.zip",
img: zip,
},
{
id: 5,
name: "Axure RP10更新内容.md",
img: md,
},
],
teacher: [
{
id: 1,
name: "王星天(显示事业)",
introduce: "教师是学生的镜子,学生是老师的影子。",
peopleimg: img,
medal: [
medal1,
medal2,
medal3,
],
},
],
});
const activeName = ref('first')
const totalprogress = ref(30)
const compulsoryprogress = ref(10)
const handleClick = (tab, event) => {
console.log(tab, event);
};
const path = {1: 'path'}
const types = ref({
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: '',
2: '/faceteach',
3: '',
4: '/homeworkpage',
5: '',
6: '/livebroadcast',
7: '',
8: '/discusspage',
9: '/moreactive',
10: '/surveydetail',
11: '/surveydetail',
12: '/ballotpage',
13: '去完成'
}
})
function toFinish(d) {
if (!types.value.path[d.type]) {
ElMessage.error('暂时未开放')
return
}
router.push({path: types.value.path[d.type], query: {id: d.routerTaskId, type: 1, courseId: d.courseId}})
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->

View File

@@ -1,5 +1,5 @@
<template>
<div class="surveydetail">
<div class="surveydetail" style="padding: 30px">
<!-- 标题 -->
<div class="title">考试模式</div>
<!-- 标题 -->
@@ -8,7 +8,10 @@
<!-- 中间盒子 -->
<div class="middle clearfix">
<div class="righttitle">
<img width="20px" height="20px" src="../../assets/image/yuan.png" />
<img
style="width: 20px; height: 20px"
src="../../assets/image/yuan.png"
/>
<div class="text">阶段性考试</div>
<div class="box"></div>

View File

@@ -1,5 +1,5 @@
<template>
<div class="surveydetail">
<div class="surveydetail" style="padding: 30px">
<!-- 面包屑导航 -->
<div
style="display: flex; align-items: center; justify-content: space-between"
@@ -37,17 +37,20 @@
<div>
<div
class="question"
v-for="(value, index) in question"
v-for="(value, index) in data.scoringQuestionVoList"
:key="index"
:style="{ 'margin-top': index === 0 ? '57px' : '41px' }"
>
<div class="text">{{ value.text }}</div>
<div class="text">{{ value.assessmentScTitle }}</div>
<div class="answer">
<div class="answerL">完全没用</div>
<div class="answerC">
<div
class="answerCitem"
v-for="(item, key) in select"
v-for="(item, key) in Array.from(
{ length: value.assessmentMaxScore },
(k, i) => i
)"
:key="key"
:style="{
'margin-left': key === 0 ? '15px' : '10px',
@@ -60,140 +63,124 @@
? '#fff'
: 'rgba(86, 163, 249, 1)',
}"
@click="score(value, item)"
@click="
() => {
value.selectAnswer = item;
}
"
>
<div>{{ item }}</div>
<div>{{ item + 1 }}</div>
</div>
</div>
<div class="answerR">非常有帮助/启发</div>
</div>
</div>
<div class="question" style="margin-top: 41px">
<div class="text">4.类似相应的课程您认为适合哪些人观看</div>
<div
class="question"
style="margin-top: 41px"
v-for="(item, i) in data.singleStemVoList"
:key="i"
>
<div class="text">{{ item.singleStemName }}</div>
<div
v-for="(value, index) in viewpeople"
v-for="(value, index) in item.assessmentSingleChoiceVoList"
:key="index"
style="display: flex; align-items: center"
:style="{ 'margin-top': index === 0 ? '29px' : '22px' }"
@click="selectPeople(value)"
:style="{
'margin-top': index === 0 ? '29px' : '22px',
cursor: 'pointer',
}"
@click="
() => {
item.assessmentSingleChoiceVoList.forEach((e) => {
e.select = false;
});
value.select = true;
}
"
>
<img
style="width: 19px; height: 18px; cursor: pointer"
:src="
value.select
? checkbox
: checkbox2
"
:src="value.select ? checkbox : checkbox2"
/>
<div class="people">{{ value.text }}</div>
<div class="people">{{ value.singleOptionName }}</div>
</div>
</div>
<div class="question" style="margin-top: 41px">
<div class="text">5.您的其他意见</div>
<div
class="question"
style="margin-top: 41px"
v-for="(item, i) in data.multipleStemVoList"
:key="i"
>
<div class="text">{{ item.multipleStemName }}</div>
<div
v-for="(value, index) in item.multipleChoiceVoList"
:key="index"
style="display: flex; align-items: center"
:style="{
'margin-top': index === 0 ? '29px' : '22px',
cursor: 'pointer',
}"
@click="() => (value.select = !value.select)"
>
<img
style="width: 19px; height: 18px; cursor: pointer"
:src="value.select ? checkbox : checkbox2"
/>
<div class="people">{{ value.multipleOptionName }}</div>
</div>
</div>
<div
class="question"
style="margin-top: 41px"
v-for="(item, i) in data.essayQuestionVoList"
:key="i"
>
<div class="text">{{ item.assessmentQaTitle }}</div>
<div style="width: 713px; margin-top: 31px; position: relative">
<el-input
v-model="textarea1"
v-model="item.content"
:autosize="{ minRows: 5, maxRows: 5 }"
resize="none"
maxlength="200"
type="textarea"
@input="textareaInput"
/>
<div class="words">{{ textarealength }}/200</div>
<div class="words">{{ item.content?.length || 0 }}/200</div>
</div>
</div>
<div style="display: flex; justify-content: center">
<div class="submit">提交</div>
<div class="submit" @click="submit">提交</div>
</div>
</div>
</div>
<!-- 基本信息 -->
<!-- todo 测评页面 没有接口-->
</div>
</template>
<script>
import { reactive, toRefs } from "vue";
import checkbox from '@/assets/image/checkbox.png'
import checkbox2 from '@/assets/image/checkbox2.png'
export default {
name: "SurveyDetail",
setup() {
const state = reactive({
question: [
{
id: 1,
text: "1.您觉得课程对您是否有用?",
selectAnswer: 0,
},
{
id: 2,
text: "2.您是否会推荐课程给其他同事?",
selectAnswer: 0,
},
{
id: 3,
text: "3.后续该讲师有其他课程是否会参与?",
selectAnswer: 0,
},
],
select: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
viewpeople: [
{
id: 1,
text: "基础员工",
select: false,
},
{
id: 2,
text: "中层管理",
select: false,
},
{
id: 3,
text: "专业人员",
select: false,
},
{
id: 4,
text: "高级管理",
select: false,
},
],
textarea1: "",
textarealength: 0,
});
const score = (value, item) => {
let arr = state.question;
arr.map((i) => {
if (i.id === value.id) {
i.selectAnswer = item;
}
});
state.question = arr;
};
const selectPeople = (value) => {
let arr = state.viewpeople;
arr.map((i) => {
if (i.id === value.id) {
i.select = !i.select;
}
});
state.viewpeople = arr;
};
const textareaInput = (e) => {
// console.log("eee", e);
state.textarea1 = e;
state.textarealength = e.length;
};
return {
...toRefs(state),
score,
selectPeople,
textareaInput,
checkbox,
checkbox2
};
},
};
<script setup>
import checkbox from "@/assets/image/checkbox.png";
import checkbox2 from "@/assets/image/checkbox2.png";
import { useRoute } from "vue-router/dist/vue-router";
import { request, usePage, useRequest } from "@/api/request";
import {
ASSESSMENT_QUERY,
ASSESSMENT_SUBMIT,
COMMENT_LIST,
DISCUSS_DETAIL,
} from "@/api/api";
const {
query: { courseId },
} = useRoute();
const { data } = useRequest(ASSESSMENT_QUERY(courseId), {});
function submit() {
request(ASSESSMENT_SUBMIT, data).then(() => {
console.log("提交成功");
});
}
</script>
<style lang="scss">
.surveydetail {
@@ -203,18 +190,21 @@ export default {
font-size: 14px;
line-height: 24px;
}
.prevnext {
display: flex;
align-items: center;
font-size: 14px;
font-weight: 500;
color: #ffffff;
.prev {
display: flex;
align-items: center;
cursor: pointer;
}
}
.title {
font-size: 20px;
font-weight: 800;
@@ -223,6 +213,7 @@ export default {
margin-top: 17px;
margin-left: -11px;
}
.bascinfo {
width: 100%;
min-height: 1032px;
@@ -238,6 +229,7 @@ export default {
font-weight: 500;
color: #333330;
}
.question .answer {
margin-top: 30px;
display: flex;
@@ -246,6 +238,7 @@ export default {
font-weight: 500;
color: #56a3f9;
}
.question .answer .answerC {
width: 540px;
height: 73px;
@@ -271,12 +264,14 @@ export default {
cursor: pointer;
}
}
.question .people {
font-size: 14px;
font-weight: 500;
color: #333330;
margin-left: 15px;
}
.question .words {
position: absolute;
right: 15px;
@@ -285,10 +280,12 @@ export default {
font-weight: 500;
color: #333330;
}
.question .el-textarea__inner {
border-radius: 8px;
background-color: rgba(245, 246, 247, 1);
}
.submit {
width: 126px;
height: 46px;

View File

@@ -1,5 +1,5 @@
<template>
<div class="surveydetail">
<div class="surveydetail" style="padding: 30px">
<!-- 标题 -->
<div class="title">考试模式</div>
<!-- 标题 -->

View File

@@ -2,7 +2,7 @@
* @Author: lixg lixg@dongwu-inc.com
* @Date: 2022-11-21 17:28:10
* @LastEditors: lixg lixg@dongwu-inc.com
* @LastEditTime: 2022-11-22 12:45:57
* @LastEditTime: 2022-12-13 20:49:00
* @FilePath: /fe-stu/vite.config.js
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
@@ -13,7 +13,8 @@ import { viteMockServe } from 'vite-plugin-mock'
import topLevelAwait from "vite-plugin-top-level-await";
const path = require('path')
// const url = 'http://localhost:30001'
const url = 'http://111.231.196.214:12013/manageApi'
export default defineConfig(({ command }) =>
({
base: '/fe-student',
@@ -26,21 +27,71 @@ export default defineConfig(({ command }) =>
promiseExportName: '__tla',
promiseImportName: i => `__tla_${i}`
}),
viteMockServe({
mockPath: './src/mock/mocks',
})
// viteMockServe({
// mockPath: './src/mock/mocks',
// })
],
resolve: {
alias: [
{ find: '@', replacement: path.resolve(__dirname, 'src') }
]
}, server: {
},
server: {
proxy: {
'/file/upload': {
target: 'http://u-pre.boe.com/manageApi',
changeOrigin: true,
}
},
'/stu': {
target: url,
changeOrigin: true,
},
'/queryVoteSubmitDetailById': {
target: url,
changeOrigin: true,
},
'/work': {
target: url,
changeOrigin: true,
},
'/discuss': {
target: url,
changeOrigin: true,
},
'/discussSubmit': {
target: url,
changeOrigin: true,
},
'/comment': {
target: url,
changeOrigin: true,
},
'/vote': {
target: url,
changeOrigin: true,
},
'/admin': {
target: url,
changeOrigin: true,
}, '/activity': {
target: url,
changeOrigin: true,
}, '/liveBroadcast': {
target: url,
changeOrigin: true,
}, '/examination': {
target: url,
changeOrigin: true,
}, '/assessment': {
target: url,
changeOrigin: true,
}, '/workSubmit': {
target: url,
changeOrigin: true,
}, '/userbasic': {
target: 'https://u-pre.boe.com',
changeOrigin: true,
},
}
}
})