yujialong 5 months ago
parent d11e9ed59b
commit 8068572935
  1. 2
      public/index.html
  2. 2
      src/api/index.js
  3. 103
      src/components/quill/index.vue
  4. 16
      src/pages/achievement/info/project.vue
  5. 57
      src/pages/achievement/list/course.vue
  6. 14
      src/pages/achievement/show/index.vue
  7. 278
      src/pages/assessment/add/index.vue
  8. 808
      src/pages/product/show/index.vue
  9. 5
      src/pages/project/add/index.vue
  10. 224
      src/pages/project/list/index.vue
  11. 137
      src/pages/screen/index.vue
  12. 1
      src/pages/station/preview/index.vue
  13. 47
      src/plugins/requests/index.js
  14. 1
      src/setting.js
  15. 64
      src/store/modules/project.js
  16. 7
      src/styles/page/screen.scss

@ -10,7 +10,7 @@
var _hmt = _hmt || [];
(function() {
var hm = document.createElement('script');
hm.src = 'https://hm.baidu.com/hm.js?e4d7deeca2d6ea71d2bd5fa2365bc654';
hm.src = 'https://hm.baidu.com/hm.js?72fbad6ebf1d6c705117fe8fe0686a0e';
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(hm, s);
})();

@ -126,6 +126,7 @@ export default {
exportDetailsOfStudentAssessmentResults: `${host}occupationlab/occupationlab/achievement/exportDetailsOfStudentAssessmentResults`,
exportProductPracticeResults: `${host}occupationlab/occupationlab/achievement/exportProductPracticeResults`,
exportProductAssessResults: `${host}occupationlab/occupationlab/achievement/exportProductAssessResults`,
exportMultipleExperimentalReports: `${host}occupationlab/occupationlab/achievement/exportMultipleExperimentalReports`,
// 项目管理
getSystemIdBySchool: `occupationlab/occupationlab/projectManage/getSystemIdBySchool`, // 获取学校下拥有的系统
@ -422,6 +423,7 @@ export default {
courseRankings: `occupationlab/occupationlab/data/kanban/courseRankings`,
platformLoginStatistics: `users/users/user/platformLoginStatistics`,
activityRanking: `occupationlab/occupationlab/data/kanban/activityRanking`,
productsWithExperimentalResults: `occupationlab/occupationlab/data/kanban/productsWithExperimentalResults`,
// 产品中心
productCategoryList: `nakadai/productClassification/productCategoryList`,

@ -1,39 +1,21 @@
<template>
<div>
<el-radio-group v-if="!readonly && radio"
class="type-radio"
v-model="editorType"
@change="typeChange">
<el-radio-group v-if="!readonly && radio" class="type-radio" v-model="editorType" @change="typeChange">
<el-radio label="0">富文本</el-radio>
<el-radio label="1">markdown</el-radio>
</el-radio-group>
<div v-show="editorType == 0"
class="quill"
ref="quill"
:class="classes">
<div ref="editor"
:style="styles"
v-loading="loading"></div>
<div v-show="editorType == 0" class="quill" ref="quill" :class="classes">
<div ref="editor" :style="styles" v-loading="loading"></div>
<Upload :max-size="1000"
:limit="100"
@beforeUpload="beforeUpload"
@onSuccess="editorUploadSuccess"
style="display: none">
<Upload :max-size="1000" :limit="100" @beforeUpload="beforeUpload" @onSuccess="editorUploadSuccess"
style="display: none">
<div slot="trigger">
<el-button :id="'editorUpload' + index"
type="primary">点击上传</el-button>
<el-button :id="'editorUpload' + index" type="primary">点击上传</el-button>
</div>
</Upload>
</div>
<mavon-editor class="md"
v-model="mdVal"
v-show="editorType == 1"
ref="md"
:ishljs="true"
:subfield="false"
@change="mdChange"
@imgAdd="imgAdd" />
<mavon-editor class="md" v-model="mdVal" v-show="editorType == 1" ref="md" :ishljs="true" :subfield="false"
@change="mdChange" @imgAdd="imgAdd" />
</div>
</template>
@ -303,40 +285,63 @@ export default {
</script>
<style lang="scss" scoped>
.type-radio {
margin-bottom: 20px;
margin-bottom: 20px;
}
.quill-no-border {
.ql-toolbar.ql-snow {
border: none;
border-bottom: 1px solid #e8eaec;
}
.ql-toolbar.ql-snow {
border: none;
border-bottom: 1px solid #e8eaec;
}
.ql-container.ql-snow {
border: none;
}
.ql-container.ql-snow {
border: none;
}
}
.else {
.ql-toolbar.ql-snow {
height: 0;
overflow: hidden;
padding: 0;
border-top: 0;
}
.ql-toolbar.ql-snow {
height: 0;
overflow: hidden;
padding: 0;
border-top: 0;
}
}
/deep/.ql-snow {
position: relative;
.ql-tooltip {
position: absolute !important;
top: 10px !important;
left: 10px !important;
transform: translateY(10px);
}
position: relative;
.ql-tooltip {
position: absolute !important;
top: 10px !important;
left: 10px !important;
transform: translateY(10px);
}
}
.md {
max-height: 300px;
max-height: 300px;
}
/deep/.v-note-wrapper .v-note-panel {
min-height: 200px;
min-height: 200px;
}
/deep/.markdown-body {
ul {
list-style: disc;
li {
list-style: inherit;
}
}
ol {
list-style: decimal;
li {
list-style: inherit;
}
}
}
</style>

@ -263,8 +263,10 @@ export default {
const res = this.permissions ?
await this.$post(`${this.api.getAssessmentDetail}?pageNum=${this.page}&pageSize=${this.pageSize}&assessmentId=${this.id}&classId=${this.classId}&keyword=${this.keyword}&mallId=${this.mallId}`) :
await this.$post(`${this.api.getPracticeDetail}?pageNum=${this.page}&pageSize=${this.pageSize}&projectId=${this.id}&keyWord=${this.keyword}&classId=${this.classId}&mallId=${this.mallId}`)
this.listData = res.page.records
this.total = res.page.total
//
const isArr = res.page instanceof Array
this.listData = isArr ? res.page : res.page.records
this.total = isArr ? res.total : res.page.total
this.avgScore = (+res.avgScore).toFixed(2)
this.examCount = res.examCount
this.peopleNum = res.peopleNum
@ -339,6 +341,16 @@ export default {
list = res.page.records
}
const res = await axios.post(this.api.exportMultipleExperimentalReports, list.map(e => e.reportId), {
headers: {
token: this.token
},
responseType: 'blob'
})
const name = res.headers['content-disposition']
util.downloadFileDirect(name ? decodeURI(name) : '成绩报告.xlsx', new Blob([res.data]))
this.exporting = false
return
list.forEach(async e => {
if (e.reportId) {
try {

@ -1,67 +1,39 @@
<template>
<div class="page"
v-loading="loading">
<div class="page" v-loading="loading">
<h6 class="p-title">筛选</h6>
<div class="tool mul">
<ul class="filter">
<li>
<el-input placeholder="请输入课程名称"
prefix-icon="el-icon-search"
v-model="keyword"
clearable></el-input>
<el-input placeholder="请输入课程名称" prefix-icon="el-icon-search" v-model="keyword" clearable></el-input>
</li>
</ul>
</div>
<el-table :data="list"
class="table"
ref="table"
stripe
header-align="center"
row-key="id">
<el-table-column type="index"
width="60"
label="序号"
align="center">
<el-table :data="list" class="table" ref="table" stripe header-align="center" row-key="id">
<el-table-column type="index" width="60" label="序号" align="center">
<template slot-scope="scope">
{{ scope.$index + (page - 1) * pageSize + 1 }}
</template>
</el-table-column>
<el-table-column prop="curriculumName"
label="课程"
align="center"
min-width="200"></el-table-column>
<el-table-column prop="curriculumName" label="课程" align="center" min-width="200"></el-table-column>
<!-- <el-table-column prop="className"
label="班级"
align="center"
min-width="130"></el-table-column> -->
<el-table-column prop="numberOfPracticeItems"
label="练习项目数"
align="center"
min-width="100"></el-table-column>
<el-table-column prop="numberOfAssessmentItems"
label="考核项目数"
align="center"
min-width="100"></el-table-column>
<el-table-column prop="numberOfPracticeItems" label="练习项目数" align="center" min-width="100"></el-table-column>
<el-table-column prop="numberOfAssessmentItems" label="考核项目数" align="center" min-width="100"></el-table-column>
<!-- <el-table-column prop="classSize"
label="班级人数"
align="center"
min-width="100"></el-table-column> -->
<el-table-column label="操作"
align="center"
width="100">
<el-table-column label="操作" align="center" width="100">
<template slot-scope="scope">
<el-button v-auth="'练习成绩管理'"
type="text"
@click="entry(scope.row)">成绩管理</el-button>
<el-button v-auth="'练习成绩管理'" type="text" @click="entry(scope.row)">成绩管理</el-button>
</template>
</el-table-column>
</el-table>
<div class="pagination">
<el-pagination background
layout="total, prev, pager, next"
:total="total"
@current-change="handleCurrentChange"
:current-page="page"></el-pagination>
<el-pagination background layout="total, prev, pager, next" :total="total" @current-change="handleCurrentChange"
:current-page="page"></el-pagination>
</div>
</div>
</template>
@ -253,10 +225,11 @@ export default {
</script>
<style lang="scss" scoped>
.el-radio.is-bordered + .el-radio.is-bordered {
margin-left: 0;
.el-radio.is-bordered+.el-radio.is-bordered {
margin-left: 0;
}
.el-radio-group {
white-space: nowrap;
white-space: nowrap;
}
</style>

@ -218,9 +218,14 @@ export default {
index++
}
})
e.lcStudentAnswer.map((n, i) => {
e.answer += `${i + 1}.${n.userAnswer || '未填写'};`
})
// lcStudentAnswerlcRuleRecords
if (e.lcStudentAnswer) {
e.lcStudentAnswer.map((n, i) => {
e.answer += `${i + 1}.${n.userAnswer || '未填写'};`
})
} else {
e.lcStudentAnswer = e.lcRuleRecords
}
})
} else { // pythonuserScores
list.forEach(e => {
@ -234,7 +239,7 @@ export default {
this.expData = list
this.loading = false
},
exportPage () {
async exportPage () {
const form = Object.assign(this.form, this.infoData)
const list = JSON.parse(JSON.stringify(this.expData))
list.map((e, i) => {
@ -387,6 +392,7 @@ samp {
padding: 10px 16px;
font-size: 14px;
color: #333;
white-space: pre-wrap;
&.edit {
color: #abb3c6;

@ -1,33 +1,24 @@
<template>
<div>
<el-form :disabled="isDetail">
<el-card shadow="hover"
class="m-b-20">
<el-card shadow="hover" class="m-b-20">
<div class="flex-between">
<el-page-header @back="goBack"
:content="isDetail ? '查看' : (form.id ? '更新' : '创建') + '教学实验'"></el-page-header>
<el-page-header @back="goBack" :content="isDetail ? '查看' : (form.id ? '更新' : '创建') + '教学实验'"></el-page-header>
<div>
<el-button type="primary"
@click="save(0)"
v-show="!isDetail">{{ form.id ? "更新" : "创建" }}</el-button>
<el-button type="primary" @click="save(0)" v-show="!isDetail">{{ form.id ? "更新" : "创建" }}</el-button>
</div>
</div>
</el-card>
<el-card shadow="hover"
class="mgr20 m-b-20">
<el-card shadow="hover" class="mgr20 m-b-20">
<div>
<p class="m-b-20">考核名称</p>
<el-input placeholder="请输入考核名称"
v-model.trim="form.experimentalName"
clearable
maxlength="15"
class="inline-input"></el-input>
<el-input placeholder="请输入考核名称" v-model.trim="form.experimentalName" clearable maxlength="15"
class="inline-input"></el-input>
</div>
</el-card>
<el-card shadow="hover"
class="m-b-20">
<el-card shadow="hover" class="m-b-20">
<div>
<p class="m-b-20">发布方式</p>
<el-radio-group v-model="form.type">
@ -37,55 +28,34 @@
</div>
</el-card>
<!-- 根据发布方式判断时间的显示 -->
<el-card shadow="hover"
class="m-b-20">
<el-card shadow="hover" class="m-b-20">
<div>
<p class="m-b-20">实验时间</p>
<!-- 手动发布显示 -->
<div class="date-inputs"
v-if="form.type==1">
<div class="date-inputs" v-if="form.type == 1">
实验时长
<el-input type="number"
min="0"
v-model.trim="duration.day"
placeholder></el-input>
<el-input type="number" min="0" v-model.trim="duration.day" placeholder></el-input>
<el-input type="number"
min="0"
v-model.trim="duration.hour"
placeholder></el-input>
<el-input type="number" min="0" v-model.trim="duration.hour" placeholder></el-input>
小时
<el-input type="number"
min="0"
v-model.trim="duration.minute"
placeholder></el-input>
<el-input type="number" min="0" v-model.trim="duration.minute" placeholder></el-input>
</div>
<!-- 定时发布显示 -->
<div v-if="form.type==2"
class="addAssess">
<div v-if="form.type == 2" class="addAssess">
<span class="mgr10">开始时间:</span>
<el-date-picker size="small"
v-model="date"
type="datetimerange"
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
:picker-options="pickerOptions"></el-date-picker>
<el-date-picker size="small" v-model="date" type="datetimerange" range-separator="-"
start-placeholder="开始日期" end-placeholder="结束日期" :picker-options="pickerOptions"></el-date-picker>
</div>
</div>
</el-card>
<el-card shadow="hover"
class="mgr20 m-b-20">
<el-card shadow="hover" class="mgr20 m-b-20">
<div>
<p class="m-b-20">课程</p>
<div class="inline-input">
<el-select v-model="form.mallId"
@change="initData">
<el-option v-for="item in curriculumList"
:key="item.mallId"
:label="item.curriculumName"
:value="item.mallId">
<el-select v-model="form.mallId" @change="initData">
<el-option v-for="item in curriculumList" :key="item.mallId" :label="item.curriculumName"
:value="item.mallId">
</el-option>
</el-select>
<!-- <el-select v-model="form.curriculumId" @change="initData">
@ -100,76 +70,49 @@
</div>
</el-card>
<!-- 实训项目模块 -->
<el-card shadow="hover"
class="m-b-20">
<el-card shadow="hover" class="m-b-20">
<div class="flex-between m-b-20">
<span>实训项目</span>
<div style="display: inline-flex;">
<div>
<el-input placeholder="请输入项目名称"
prefix-icon="el-icon-search"
v-model.trim="keyword"
clearable></el-input>
<el-input placeholder="请输入项目名称" prefix-icon="el-icon-search" v-model.trim="keyword" clearable></el-input>
</div>
<el-button style="margin-left: 5px"
type="primary"
round
@click="toProject">自定义实验项目</el-button>
<el-button style="margin-left: 5px" type="primary" round @click="toProject">自定义实验项目</el-button>
</div>
</div>
<!-- 实训项目表格 -->
<el-table :data="projectData"
class="table"
stripe
header-align="center">
<el-table :data="projectData" class="table" stripe header-align="center">
<!-- 单选实训项目ID -->
<el-table-column width="60"
label="选择"
align="center">
<el-table-column width="60" label="选择" align="center">
<template slot-scope="scope">
<el-radio v-model="form.projectId"
:label="scope.row.projectId">&nbsp;</el-radio>
<el-radio v-model="form.projectId" :label="scope.row.projectId">&nbsp;</el-radio>
</template>
</el-table-column>
<el-table-column prop="projectName"
label="项目名称"
align="center"></el-table-column>
<el-table-column prop="auth"
label="项目权限"
align="center">
<el-table-column prop="projectName" label="项目名称" align="center"></el-table-column>
<el-table-column prop="auth" label="项目权限" align="center">
<template slot-scope="scope">
{{ permissionsKeys[scope.row.permissions] }}
</template>
</el-table-column>
<!-- <el-table-column prop="createUser" label="创建人" align="center"></el-table-column> -->
<el-table-column prop="founder"
label="创建人"
align="center">
<el-table-column prop="founder" label="创建人" align="center">
<template slot-scope="scope">
{{ scope.row.createUser }}
</template>
</el-table-column>
<el-table-column prop="createTime"
label="创建时间"
align="center"></el-table-column>
<el-table-column label="操作"
align="center">
<el-table-column prop="createTime" label="创建时间" align="center"></el-table-column>
<el-table-column label="操作" align="center">
<template slot-scope="scope">
<el-button type="text"
@click="showProject(scope.row)">查看</el-button>
<el-button type="text" @click="showProject(scope.row)">查看</el-button>
</template>
</el-table-column>
</el-table>
<div class="pagination">
<el-pagination background
:page-size="pageSize"
@current-change="handleCurrentChange"
layout="total,prev, pager, next"
:total="total"></el-pagination>
<el-pagination background :page-size="pageSize" @current-change="handleCurrentChange"
layout="total,prev, pager, next" :total="total"></el-pagination>
</div>
</el-card>
<el-card shadow="hover"
class="mgr20 m-b-20">
<el-card shadow="hover" class="mgr20 m-b-20">
<div>
<p class="m-b-20">考核发布</p>
<el-radio-group v-model="form.isSpecify">
@ -177,46 +120,28 @@
<el-radio :label="0">无指定范围</el-radio>
</el-radio-group>
</div>
<div v-show="form.isSpecify == 1"
style="padding-top: 24px;">
<div v-show="form.isSpecify == 1" style="padding-top: 24px;">
<p class="m-b-20">班级名称</p>
<el-input placeholder="请输入班级名称"
v-model.trim="filterClassName"
class="inline-input m-b-20"
clearable>
<el-button slot="append"
icon="el-icon-search"></el-button>
<el-input placeholder="请输入班级名称" v-model.trim="filterClassName" class="inline-input m-b-20" clearable>
<el-button slot="append" icon="el-icon-search"></el-button>
</el-input>
<div v-show="tagList.length"
class="m-b-20">
<el-tag v-for="(tag, index) in tagList"
:key="index"
closable
@close="handleCloseTag(tag)"
style="margin-right: 10px">
<div v-show="tagList.length" class="m-b-20">
<el-tag v-for="(tag, index) in tagList" :key="index" closable @close="handleCloseTag(tag)"
style="margin-right: 10px">
{{ tag.organizationName }}
</el-tag>
</div>
<div class="tree-con">
<student-tree ref="tree"
node-key="id"
show-checkbox
highlight-current
default-expand-all
lazy
:load="loadTree"
:default-checked-keys="defaultCheckedKeys"
:props="{children: 'children', label: 'organizationName', isLeaf: 'leaf'}"
:filter-node-method="filterNode"
@check="handleCheck">
<student-tree ref="tree" node-key="id" show-checkbox highlight-current default-expand-all lazy
:load="loadTree" :default-checked-keys="defaultCheckedKeys"
:props="{ children: 'children', label: 'organizationName', isLeaf: 'leaf' }"
:filter-node-method="filterNode" @check="handleCheck">
</student-tree>
</div>
</div>
</el-card>
<!-- 邀请码 -->
<el-card v-if="form.isSpecify == 0"
shadow="hover"
class="m-b-20">
<el-card v-if="form.isSpecify == 0" shadow="hover" class="m-b-20">
<div style="margin-bottom: 10px">
<p class="m-b-20">设置邀请码</p>
<el-radio-group v-model="form.isEnableCode">
@ -225,13 +150,9 @@
</el-radio-group>
</div>
<div v-if="form.isEnableCode == 1">
<el-input style="display: inline-block;width: auto;margin-right: 10px"
type="number"
v-model.trim="form.invitationCode"
maxlength="6"
placeholder="请设置6个数字"></el-input>
<el-button type="text"
@click="createInv">随机</el-button>
<el-input style="display: inline-block;width: auto;margin-right: 10px" type="number"
v-model.trim="form.invitationCode" maxlength="6" placeholder="请设置6个数字"></el-input>
<el-button type="text" @click="createInv">随机</el-button>
</div>
</el-card>
</el-form>
@ -597,16 +518,16 @@ export default {
expNameRepeat: this.expNameRepeat, //
allCheckedNodes: this.allCheckedNodes //
};
this.setAss(data);
this.isToProject = true;
this.setAss(data)
this.isToProject = true
},
toProject () {
this.handleCacheData();
this.$router.push("/project/list?show=1");
this.handleCacheData()
this.$router.push("/project/list?show=1")
},
showProject (row) {
this.handleCacheData();
this.$router.push(`/project/add?projectId=${row.projectId}&show=1`);
this.handleCacheData()
this.$router.push(`/project/add?projectId=${row.projectId}&show=1&ass=1`)
},
createInv () {
let result = "";
@ -646,51 +567,60 @@ export default {
<style lang="scss" scoped>
.inline-input {
width: 500px;
width: 500px;
}
.date-inputs {
.el-input {
width: 100px;
}
.el-input {
width: 100px;
}
}
.tree-con {
height: 400px;
max-height: 400px;
width: 100%;
border: 1px solid #dcdfe6;
border-radius: 4px;
padding: 10px 10px 10px 40px;
overflow: auto;
/deep/ .el-tree-node__content {
height: 30px;
.el-tree-node__expand-icon {
padding: 2px;
color: #fff;
background-color: #9278ff;
border-radius: 30px;
margin: 0 10px;
}
.el-tree-node__expand-icon.is-leaf {
background-color: transparent;
}
.el-icon-caret-right:before {
font-size: 14px;
}
.el-checkbox__inner {
width: 18px;
height: 18px;
border: 1px solid #9278ff;
border-radius: 20px;
}
.el-checkbox__inner::after {
position: absolute;
top: 3px;
left: 6px;
}
.el-checkbox__input.is-indeterminate .el-checkbox__inner::before {
position: absolute;
top: 7px;
}
height: 400px;
max-height: 400px;
width: 100%;
border: 1px solid #dcdfe6;
border-radius: 4px;
padding: 10px 10px 10px 40px;
overflow: auto;
/deep/ .el-tree-node__content {
height: 30px;
.el-tree-node__expand-icon {
padding: 2px;
color: #fff;
background-color: #9278ff;
border-radius: 30px;
margin: 0 10px;
}
.el-tree-node__expand-icon.is-leaf {
background-color: transparent;
}
.el-icon-caret-right:before {
font-size: 14px;
}
.el-checkbox__inner {
width: 18px;
height: 18px;
border: 1px solid #9278ff;
border-radius: 20px;
}
.el-checkbox__inner::after {
position: absolute;
top: 3px;
left: 6px;
}
.el-checkbox__input.is-indeterminate .el-checkbox__inner::before {
position: absolute;
top: 7px;
}
}
}
</style>

@ -1,141 +1,87 @@
<template>
<div class="wrap">
<el-card shadow="hover"
class="m-b-20">
<el-card shadow="hover" class="m-b-20">
<div class="flex-between">
<el-page-header @back="$router.push('list')"
:content="form.mall.productName"></el-page-header>
<el-page-header @back="$router.push('list')" :content="form.mall.productName"></el-page-header>
</div>
</el-card>
<div class="inner">
<div class="top">
<el-carousel class="pics"
:interval="6000"
height="278px"
:arrow="form.pics.length > 1 ? 'hover' : 'never'"
:indicator-position="form.pics.length > 1 ? '' : 'none'">
<el-carousel-item v-for="(item, i) in form.pics"
:key="i">
<img class="pic"
:src="item" />
<el-carousel class="pics" :interval="6000" height="278px" :arrow="form.pics.length > 1 ? 'hover' : 'never'"
:indicator-position="form.pics.length > 1 ? '' : 'none'">
<el-carousel-item v-for="(item, i) in form.pics" :key="i">
<img class="pic" :src="item" />
</el-carousel-item>
</el-carousel>
<div class="right"
id="fields">
<div class="right" id="fields">
<h6>{{ form.mall.productName }}</h6>
<div v-if="isCourse"
class="meta">
<div v-if="isCourse" class="meta">
<span class="val">{{ form.numberOfExperimentalItems }}</span> 个实验项目&emsp;&emsp;
已有 <span class="val">{{ form.goodsRes.learningCount }}</span>人学过
</div>
<div class="des"
v-html="form.mall.productIntroduction"></div>
<div class="des" v-html="form.mall.productIntroduction"></div>
<div class="fields">
<div class="field">
<img src="@/assets/img/product/1.png"
alt=""> 适用专业
<el-tooltip class="text"
effect="dark"
:visible-arrow="false"
:content="form.goodsRes.professionalName"
placement="bottom">
<img src="@/assets/img/product/1.png" alt=""> 适用专业
<el-tooltip class="text" effect="dark" :visible-arrow="false" :content="form.goodsRes.professionalName"
placement="bottom">
<div>
{{ form.goodsRes.professionalName }}
</div>
</el-tooltip>
</div>
<div v-if="form.mall.applicationScenario"
class="field">
<img src="@/assets/img/product/2.png"
alt=""> 适用场景
<div v-if="form.mall.applicationScenario" class="field">
<img src="@/assets/img/product/2.png" alt=""> 适用场景
<div class="text">{{ form.mall.applicationScenario }}</div>
</div>
<div v-if="form.mall.matchingCourse"
class="field">
<img src="@/assets/img/product/3.png"
alt=""> 匹配课程
<el-tooltip class="text"
effect="dark"
:visible-arrow="false"
:content="form.mall.matchingCourse"
placement="bottom">
<div v-if="form.mall.matchingCourse" class="field">
<img src="@/assets/img/product/3.png" alt=""> 匹配课程
<el-tooltip class="text" effect="dark" :visible-arrow="false" :content="form.mall.matchingCourse"
placement="bottom">
<div class="text">
{{ form.mall.matchingCourse }}
</div>
</el-tooltip>
</div>
<div v-if="form.mall.courseHours"
class="field">
<img src="@/assets/img/product/4.png"
alt=""> 预计课时
<div v-if="form.mall.courseHours" class="field">
<img src="@/assets/img/product/4.png" alt=""> 预计课时
<div class="text">{{ form.mall.courseHours }}</div>
</div>
<div v-if="form.goodsRes.typeName"
class="field">
<img src="@/assets/img/product/5.png"
alt=""> 产品类型
<div v-if="form.goodsRes.typeName" class="field">
<img src="@/assets/img/product/5.png" alt=""> 产品类型
<div class="text">{{ form.goodsRes.typeName }}</div>
</div>
</div>
<button v-if="!form.goodsRes.logoOfOurSchool"
class="btn"
@click="toTrail">试用体验</button>
<button v-else-if="isCourse || withLink"
class="btn entry"
@click="toStation">进入{{ isDataforward ? '系统' : '实验' }}</button>
<button v-else-if="isValueModule"
class="btn entry"
@click="toSystem">进入系统</button>
<button v-if="!form.goodsRes.logoOfOurSchool" class="btn" @click="toTrail">试用体验</button>
<button v-else-if="isCourse || withLink" class="btn entry" @click="toStation">进入{{ isDataforward ? '系统' : '实验'
}}</button>
<button v-else-if="isValueModule" class="btn entry" @click="toSystem">进入系统</button>
</div>
</div>
<div class="course"
id="part0">
<div class="course" id="part0">
<div class="detail">
<ul class="tab">
<li v-for="(tab, i) in tabs"
:key="i"
:class="{active: curTab === tab.id}"
@click="tabChange(tab)">{{ tab.name }}</li>
<li v-for="(tab, i) in tabs" :key="i" :class="{ active: curTab === tab.id }" @click="tabChange(tab)">{{
tab.name }}</li>
</ul>
<div class="courses">
<div class="des"
v-html="form.mall.detailedIntroduction"></div>
<div v-if="isCourse"
class="chapter"
id="part1"
v-for="(item, i) in chapterList"
:key="i">
<div class="des" v-html="form.mall.detailedIntroduction"></div>
<div v-if="isCourse" class="chapter" id="part1" v-for="(item, i) in chapterList" :key="i">
<div class="chapterName">{{ item.name }}</div>
<div class="section"
v-if="item.subsectionList.length">
<div v-for="(section, j) in item.subsectionList"
:key="j"
@click="toPreview(i, j)">
<div class="sectionName"
:title="section.name">
<div class="section" v-if="item.subsectionList.length">
<div v-for="(section, j) in item.subsectionList" :key="j" @click="toPreview(i, j)">
<div class="sectionName" :title="section.name">
<div class="val">
<img v-if="section.fileType === 'pptx'"
src="@/assets/img/exts/ppt.png"
alt="">
<img v-else-if="section.fileType === 'mp4'"
src="@/assets/img/exts/video.png"
alt="">
<img v-if="section.fileType === 'pptx'" src="@/assets/img/exts/ppt.png" alt="">
<img v-else-if="section.fileType === 'mp4'" src="@/assets/img/exts/video.png" alt="">
<img v-else-if="section.fileType === 'doc' || section.fileType === 'docx'"
src="@/assets/img/exts/word.png"
alt="">
<img v-else-if="section.fileType === 'txt'"
src="@/assets/img/exts/txt.png"
alt="">
<img v-else-if="section.fileType === 'pdf'"
src="@/assets/img/exts/pdf.png"
alt="">
<img v-else
src="@/assets/img/exts/pic.png"
alt="">
src="@/assets/img/exts/word.png" alt="">
<img v-else-if="section.fileType === 'txt'" src="@/assets/img/exts/txt.png" alt="">
<img v-else-if="section.fileType === 'pdf'" src="@/assets/img/exts/pdf.png" alt="">
<img v-else src="@/assets/img/exts/pic.png" alt="">
{{ section.name }}
</div>
<i v-if="!form.goodsRes.logoOfOurSchool && j"
class="icon el-icon-lock"></i>
<i v-if="!form.goodsRes.logoOfOurSchool && j" class="icon el-icon-lock"></i>
</div>
</div>
</div>
@ -145,33 +91,20 @@
<div class="products">
<h6>热门产品推荐</h6>
<ul class="product">
<li v-for="(item, i) in hots"
:key="i"
@click="toDetail(item.mallId)">
<img :src="item.coverDrawing"
alt="" />
<img v-if="item.logoOfOurSchool"
class="my-school"
src="@/assets/img/my-school.png"
alt="">
<li v-for="(item, i) in hots" :key="i" @click="toDetail(item.mallId)">
<img :src="item.coverDrawing" alt="" />
<img v-if="item.logoOfOurSchool" class="my-school" src="@/assets/img/my-school.png" alt="">
<div class="texts">
<div class="title">{{ item.productName }}</div>
<div :class="['desc', {'not-tag': !item.tagsName}]"
v-html="item.productIntroduction"></div>
<div v-if="item.tagsName"
class="tags">
<el-tag v-for="(tag, i) in item.tagsName.split(',')"
:key="i"
class="tag">{{ tag }}</el-tag>
<div :class="['desc', { 'not-tag': !item.tagsName }]" v-html="item.productIntroduction"></div>
<div v-if="item.tagsName" class="tags">
<el-tag v-for="(tag, i) in item.tagsName.split(',')" :key="i" class="tag">{{ tag }}</el-tag>
</div>
<div class="metas">
<el-tag v-if="item.selected"
type="danger"
effect="dark">
<el-tag v-if="item.selected" type="danger" effect="dark">
官方精选
</el-tag>
<div v-if="item.isCourse"
class="meta">{{ item.learningCount }}人学过</div>
<div v-if="item.isCourse" class="meta">{{ item.learningCount }}人学过</div>
</div>
</div>
</li>
@ -181,20 +114,11 @@
</div>
<!-- 选择链接 -->
<el-dialog title="请选择链接"
:visible.sync="linkVisible"
width="420px"
center
:close-on-click-modal="false">
<div v-if="withLink"
class="buy">
<div v-for="(link, i) in form.mallNonAssociatedLinks"
:key="i"
class="link-line">
<el-dialog title="请选择链接" :visible.sync="linkVisible" width="420px" center :close-on-click-modal="false">
<div v-if="withLink" class="buy">
<div v-for="(link, i) in form.mallNonAssociatedLinks" :key="i" class="link-line">
{{ link.urlName }}
<a class="url"
:href="link.url"
target="_blank">{{ link.url }}</a>
<a class="url" :href="link.url" target="_blank">{{ link.url }}</a>
</div>
</div>
</el-dialog>
@ -334,13 +258,18 @@ export default {
window.open('https://www.wjx.top/vm/wFCPCFp.aspx')
},
//
toStation () {
async toStation () {
if (this.isCourse) { //
this.$post(`${this.api.addLearningRecord}?mallId=${this.id}`).then(res => {
this.$router.push('/station/preview?courseId=' + this.form.mall.associatedProduct + '&curriculumName=' + this.form.mall.productName + '&mallId=' + this.id + '&admin=1')
}).catch(res => { })
await this.$post(`${this.api.addLearningRecord}?mallId=${this.id}`)
this.$router.push('/station/preview?courseId=' + this.form.mall.associatedProduct + '&curriculumName=' + this.form.mall.productName + '&mallId=' + this.id + '&admin=1')
} else if (this.withLink) { //
this.linkVisible = true
const links = this.form.mallNonAssociatedLinks
//
if (links.length === 1) {
window.open(links[0].url)
} else {
this.linkVisible = true
}
}
},
//
@ -379,295 +308,350 @@ export default {
<style lang="scss" scoped>
.wrap {
padding: 24px;
margin: -24px;
background: url(../../../assets/img/product/bg1.png) 0 373px no-repeat, url(../../../assets/img/product/bg2.png) bottom right no-repeat;
background-color: #f3f6fa;
.inner {
width: 1146px;
margin: 0 auto;
}
.top {
display: flex;
padding: 24px;
margin: -24px;
background: url(../../../assets/img/product/bg1.png) 0 373px no-repeat, url(../../../assets/img/product/bg2.png) bottom right no-repeat;
background-color: #f3f6fa;
.inner {
width: 1146px;
margin: 0 auto;
background-color: #fff;
border-radius: 10px;
.pics {
width: 484px;
margin-right: 20px;
.pic {
width: 100%;
height: 100%;
border-radius: 8px;
}
}
.top {
display: flex;
padding: 24px;
background-color: #fff;
border-radius: 10px;
.pics {
width: 484px;
margin-right: 20px;
.pic {
width: 100%;
height: 100%;
border-radius: 8px;
}
}
.right {
width: 592px;
overflow: hidden;
}
h6 {
font-size: 24px;
font-weight: 600;
color: #2e2d31;
}
.meta {
margin: 10px 0;
font-size: 12px;
color: #2e2d31;
.val {
color: #007eff;
}
}
.des {
margin-bottom: 15px;
font-size: 14px;
color: #666;
line-height: 20px;
@include mul-ellipsis(3);
}
.field {
display: inline-flex;
align-items: center;
margin: 0 20px 10px 0;
font-size: 14px;
color: #2e2d31;
&:last-child {
margin-right: 0;
}
.label {
color: #333;
}
.text {
max-width: 160px;
@include ellipsis;
}
img {
margin-right: 5px;
}
}
.fields {
display: flex;
// justify-content: space-between;
flex-wrap: wrap;
height: 60px;
margin: 10px 0 10px;
overflow: hidden;
}
.btn {
width: 119px;
height: 46px;
color: #fff;
background: #64c25a;
border-radius: 6px;
border: 0;
cursor: pointer;
&:hover {
opacity: 0.9;
}
&:first-child {
margin-left: 11px;
}
}
.entry {
background: #007eff;
}
.right {
width: 592px;
overflow: hidden;
}
.tab {
z-index: 100;
position: sticky;
top: 0;
display: flex;
padding: 10px 10px 20px;
background-color: #fff;
li {
position: relative;
margin-right: 20px;
font-size: 18px;
line-height: 25px;
color: #0b1d30;
cursor: pointer;
&:after {
content: '';
position: absolute;
bottom: -10px;
left: 50%;
width: 53px;
height: 4px;
transform: translateX(-50%);
}
&.active:after {
background-color: #007eff;
}
}
h6 {
font-size: 24px;
font-weight: 600;
color: #2e2d31;
}
.course {
display: flex;
margin-top: 20px;
.detail {
width: calc(100% - 294px);
padding: 20px 24px;
background-color: #fff;
border-radius: 10px;
}
.meta {
margin: 10px 0;
font-size: 12px;
color: #2e2d31;
.val {
color: #007eff;
}
}
.des {
margin-bottom: 15px;
font-size: 14px;
color: #666;
line-height: 20px;
@include mul-ellipsis(3);
}
.courses {
padding-top: 10px;
.field {
display: inline-flex;
align-items: center;
margin: 0 20px 10px 0;
font-size: 14px;
color: #2e2d31;
&:last-child {
margin-right: 0;
}
.label {
color: #333;
}
.text {
max-width: 160px;
@include ellipsis;
}
img {
margin-right: 5px;
}
}
.fields {
display: flex;
// justify-content: space-between;
flex-wrap: wrap;
height: 60px;
margin: 10px 0 10px;
overflow: hidden;
}
.btn {
width: 119px;
height: 46px;
color: #fff;
background: #64c25a;
border-radius: 6px;
border: 0;
cursor: pointer;
&:hover {
opacity: 0.9;
}
&:first-child {
margin-left: 11px;
}
}
.entry {
background: #007eff;
}
}
.tab {
z-index: 100;
position: sticky;
top: 0;
display: flex;
padding: 10px 10px 20px;
background-color: #fff;
li {
position: relative;
margin-right: 20px;
font-size: 18px;
line-height: 25px;
color: #0b1d30;
cursor: pointer;
&:after {
content: '';
position: absolute;
bottom: -10px;
left: 50%;
width: 53px;
height: 4px;
transform: translateX(-50%);
}
&.active:after {
background-color: #007eff;
}
}
}
.course {
display: flex;
margin-top: 20px;
.detail {
width: calc(100% - 294px);
padding: 20px 24px;
background-color: #fff;
border-radius: 10px;
}
}
.courses {
padding-top: 10px;
overflow: hidden;
/deep/.des {
div,
p,
span {
font-family: PingFang SC !important;
}
}
.chapters {
margin-top: 16px;
max-height: calc(100% - 53px);
overflow: auto;
}
.chapter {
padding-top: 60px;
margin-bottom: 20px;
}
.chapterName {
padding: 0 12px;
margin-bottom: 15px;
color: #333;
font-size: 14px;
font-weight: 600;
}
.sectionName {
position: relative;
display: flex;
justify-content: space-between;
padding: 12px;
font-size: 14px;
color: #666;
cursor: pointer;
border-radius: 8px;
@include ellipsis;
img {
margin-right: 8px;
}
&:hover {
color: #007eff;
background: #f6fbff;
}
.val {
display: inline-flex;
align-items: center;
}
.icon {
font-size: 18px;
color: #666;
}
}
}
.products {
width: 270px;
margin-left: 24px;
&>h6 {
font-size: 14px;
color: #0b1d30;
}
}
.product {
margin-top: 11px;
li {
position: relative;
margin-bottom: 15px;
cursor: pointer;
border-radius: 10px;
background-color: #fff;
transition: all 0.3s;
overflow: hidden;
img {
width: 100%;
height: 155px;
transition: 0.3s;
}
.my-school {
position: absolute;
top: 0;
right: 0;
width: 57px;
height: 22px;
}
.texts {
padding: 10px;
}
.title {
margin-bottom: 10px;
color: #0b1d30;
font-size: 14px;
font-weight: 600;
word-wrap: break-word;
word-break: break-all;
overflow: hidden;
/deep/.des {
div,
p,
span {
font-family: PingFang SC !important;
}
}
.chapters {
margin-top: 16px;
max-height: calc(100% - 53px);
overflow: auto;
}
.chapter {
padding-top: 60px;
margin-bottom: 20px;
}
.chapterName {
padding: 0 12px;
margin-bottom: 15px;
color: #333;
font-size: 14px;
font-weight: 600;
}
.sectionName {
position: relative;
display: flex;
justify-content: space-between;
padding: 12px;
font-size: 14px;
color: #666;
cursor: pointer;
border-radius: 8px;
@include ellipsis;
img {
margin-right: 8px;
}
&:hover {
color: #007eff;
background: #f6fbff;
}
.val {
display: inline-flex;
align-items: center;
}
.icon {
font-size: 18px;
color: #666;
}
text-overflow: ellipsis;
white-space: nowrap;
}
.desc {
min-height: 34px;
color: #757f92;
font-size: 12px;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
&.not-tag {
-webkit-line-clamp: 3;
}
}
.products {
width: 270px;
margin-left: 24px;
& > h6 {
font-size: 14px;
color: #0b1d30;
}
.tags {
margin-top: 10px;
}
.tag {
margin-right: 8px;
color: #007eff;
background-color: #f9f9f9;
border: 0;
}
.type {
display: inline-block;
padding: 4px 11px;
font-size: 12px;
color: #666;
border: 1px solid #dadada;
border-radius: 20px;
}
.metas {
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 10px;
}
.meta {
display: inline-flex;
align-items: center;
color: #b5bfd5;
font-size: 12px;
.icon {
width: 14px;
max-height: 14px;
margin-right: 3px;
}
}
.product {
margin-top: 11px;
li {
position: relative;
margin-bottom: 15px;
cursor: pointer;
border-radius: 10px;
background-color: #fff;
transition: all 0.3s;
overflow: hidden;
img {
width: 100%;
height: 155px;
transition: 0.3s;
}
.my-school {
position: absolute;
top: 0;
right: 0;
width: 57px;
height: 22px;
}
.texts {
padding: 10px;
}
.title {
margin-bottom: 10px;
color: #0b1d30;
font-size: 14px;
font-weight: 600;
word-wrap: break-word;
word-break: break-all;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.desc {
min-height: 34px;
color: #757f92;
font-size: 12px;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
&.not-tag {
-webkit-line-clamp: 3;
}
}
.tags {
margin-top: 10px;
}
.tag {
margin-right: 8px;
color: #007eff;
background-color: #f9f9f9;
border: 0;
}
.type {
display: inline-block;
padding: 4px 11px;
font-size: 12px;
color: #666;
border: 1px solid #dadada;
border-radius: 20px;
}
.metas {
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 10px;
}
.meta {
display: inline-flex;
align-items: center;
color: #b5bfd5;
font-size: 12px;
.icon {
width: 14px;
max-height: 14px;
margin-right: 3px;
}
}
&:hover {
box-shadow: 0px 5px 12px 4px rgba(142, 123, 253, 0.09), 0px 3px 6px 0px rgba(142, 123, 253, 0.12),
0px 1px 2px -2px rgba(142, 123, 253, 0.16);
img {
transform: scale(1.05);
}
}
}
&:hover {
box-shadow: 0px 5px 12px 4px rgba(142, 123, 253, 0.09), 0px 3px 6px 0px rgba(142, 123, 253, 0.12),
0px 1px 2px -2px rgba(142, 123, 253, 0.16);
img {
transform: scale(1.05);
}
}
}
}
}
.link-line {
margin: 5px 0;
.url {
color: #007eff;
text-decoration: underline;
}
margin: 5px 0;
.url {
color: #007eff;
text-decoration: underline;
}
}
</style>

@ -193,6 +193,7 @@ export default {
return {
projectId: this.$route.query.projectId,
founder: this.$route.query.founder,
fromAss: this.$route.query.ass, //
systemList: [],
mallIds: [],
curs: [],
@ -400,7 +401,6 @@ export default {
this.setSystemId(this.projectManage.systemId);
}).catch(() => {
this.projectManage.systemId = this.lastSystemId;
// console.log(this.lastSystemId, "this.lastSystemId");
});
}
},
@ -759,8 +759,7 @@ export default {
}
},
backPage () {
const { params } = this.$store.state.project
this.$router.push(`/project?${qs.stringify(params.form)}&page=${params.page}`)
this.fromAss ? this.$router.back() : this.$router.push(this.$store.state.achievement.referrer || '/project')
},
}
};

@ -1,10 +1,7 @@
<template>
<div>
<el-card v-if="showBack"
shadow="hover"
class="m-b-20">
<el-page-header content="实验项目管理"
@back="goBack"></el-page-header>
<el-card v-if="fromAss" shadow="hover" class="m-b-20">
<el-page-header content="实验项目管理" @back="goBack"></el-page-header>
</el-card>
<div class="page">
<h6 class="p-title">筛选</h6>
@ -12,196 +9,114 @@
<ul class="filter">
<li>
<label>创建人</label>
<el-select v-model="form.founder"
placeholder="请选择创建人"
@change="founderChange">
<el-option v-for="(item,index) in founderList"
:key="index"
:label="item.label"
:value="item.value"></el-option>
<el-select v-model="form.founder" placeholder="请选择创建人" @change="founderChange">
<el-option v-for="(item, index) in founderList" :key="index" :label="item.label"
:value="item.value"></el-option>
</el-select>
</li>
<li>
<label>状态</label>
<el-select v-model="form.state"
clearable
placeholder="请选择状态"
@change="initData">
<el-option v-for="(item,index) in stateList"
:key="index"
:label="item.label"
:value="item.value"></el-option>
<el-select v-model="form.state" clearable placeholder="请选择状态" @change="initData">
<el-option v-for="(item, index) in stateList" :key="index" :label="item.label"
:value="item.value"></el-option>
</el-select>
</li>
<li>
<label>用途</label>
<el-select v-model="form.permissions"
placeholder="请选择"
@change="initData">
<el-option v-for="item in permissionsList"
:key="item.value"
:label="item.label"
:value="item.value"></el-option>
<el-select v-model="form.permissions" placeholder="请选择" @change="initData">
<el-option v-for="item in permissionsList" :key="item.value" :label="item.label"
:value="item.value"></el-option>
</el-select>
</li>
<li>
<label>课程</label>
<el-cascader v-model="cid"
:options="curs"
:props="{ checkStrictly: true, value: 'id' }"
popper-class="course-cas"
@expand-change="curChange"
@change="curChange"></el-cascader>
<el-cascader v-model="cid" :options="curs" :props="{ checkStrictly: true, value: 'id' }"
popper-class="course-cas" @expand-change="curChange" @change="curChange"></el-cascader>
</li>
<li>
<el-input placeholder="请输入项目名称"
prefix-icon="el-icon-search"
v-model="form.projectName"
clearable></el-input>
<el-input placeholder="请输入项目名称" prefix-icon="el-icon-search" v-model="form.projectName"
clearable></el-input>
</li>
</ul>
<div>
<el-button v-auth
type="info"
@click="add">新增项目</el-button>
<el-button v-auth
type="primary"
@click="delAllData">批量删除</el-button>
<el-button v-auth type="info" @click="add">新增项目</el-button>
<el-button v-auth type="primary" @click="delAllData">批量删除</el-button>
</div>
</div>
<el-table :data="listData"
class="table"
ref="table"
stripe
header-align="center"
@selection-change="handleSelectionChange">
<el-table-column type="selection"
width="55"
align="center"
:selectable="disabledSelection"></el-table-column>
<el-table-column type="index"
width="100"
label="序号"
align="center">
<el-table :data="listData" class="table" ref="table" stripe header-align="center"
@selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" :selectable="disabledSelection"></el-table-column>
<el-table-column type="index" width="100" label="序号" align="center">
<template slot-scope="scope">{{ scope.$index + (page - 1) * pageSize + 1 }}</template>
</el-table-column>
<el-table-column prop="projectName"
label="实验项目名称"
min-width="400"
align="center"
show-overflow-tooltip></el-table-column>
<el-table-column prop="founder"
label="创建人"
min-width="150"
align="center">
<el-table-column prop="projectName" label="实验项目名称" min-width="400" align="center"
show-overflow-tooltip></el-table-column>
<el-table-column prop="founder" label="创建人" min-width="150" align="center">
<template slot-scope="scope">
{{ founderKeys[scope.row.founder] }}
</template>
</el-table-column>
<el-table-column label="用途"
min-width="120"
align="center">
<el-table-column label="用途" min-width="120" align="center">
<template slot-scope="scope">
{{ permissionsKeys[scope.row.permissions] }}
</template>
</el-table-column>
<el-table-column prop="createTime"
label="创建时间"
min-width="150"
align="center"></el-table-column>
<el-table-column prop="status"
label="状态"
min-width="100"
align="center">
<el-table-column prop="createTime" label="创建时间" min-width="150" align="center"></el-table-column>
<el-table-column prop="status" label="状态" min-width="100" align="center">
<template slot-scope="scope">
{{ stateKeys[scope.row.state] }}
</template>
</el-table-column>
<el-table-column label="实验提示"
width="120"
align="center">
<el-table-column label="实验提示" width="120" align="center">
<template slot-scope="scope">
<template v-if="scope.row.state">
<!-- 老师 -->
<el-switch v-if="scope.row.founder"
v-model="scope.row.hintOpen"
:active-text="scope.row.hintOpen ? '关闭' : '启用'"
:active-value="0"
:inactive-value="1"
style="margin: 0 10px 0 10px"
@change="switchOffTips(scope.row, scope.row.hintOpen)"></el-switch>
<el-switch v-if="scope.row.founder" v-model="scope.row.hintOpen"
:active-text="scope.row.hintOpen ? '关闭' : '启用'" :active-value="0" :inactive-value="1"
style="margin: 0 10px 0 10px" @change="switchOffTips(scope.row, scope.row.hintOpen)"></el-switch>
<!-- 系统 -->
<el-switch v-else
v-model="scope.row.hintOpenBySchool"
:active-text="scope.row.hintOpenBySchool ? '关闭' : '启用'"
:active-value="0"
:inactive-value="1"
style="margin: 0 10px 0 10px"
@change="switchOffTips(scope.row, scope.row.hintOpenBySchool)"></el-switch>
<el-switch v-else v-model="scope.row.hintOpenBySchool"
:active-text="scope.row.hintOpenBySchool ? '关闭' : '启用'" :active-value="0" :inactive-value="1"
style="margin: 0 10px 0 10px"
@change="switchOffTips(scope.row, scope.row.hintOpenBySchool)"></el-switch>
</template>
</template>
</el-table-column>
<el-table-column label="操作"
width="300"
align="center">
<el-table-column label="操作" width="300" align="center">
<template slot-scope="scope">
<el-button type="text"
@click="edit(scope.row, 1)">查看</el-button>
<el-button v-if="scope.row.founder && (roleName.includes('超级') || roleName === scope.row.roleName || (roleName === '管理员' && !scope.row.roleName.includes('超级')))"
type="text"
@click="edit(scope.row)">编辑</el-button>
<el-button v-if="scope.row.founder && (roleName.includes('超级') || roleName === scope.row.roleName || (roleName === '管理员' && !scope.row.roleName.includes('超级')))"
type="text"
@click="handleDelete(scope.row.projectId)">删除</el-button>
<el-button v-auth
type="text"
@click="copyData(scope.row.projectId)">复制</el-button>
<el-switch v-auth="'禁用'"
v-if="scope.row.state"
v-model="scope.row.ccupationlabOpen"
:active-text="scope.row.ccupationlabOpen ? '关闭' : '启用'"
:active-value="0"
:inactive-value="1"
style="margin: 0 10px 0 10px"
@change="switchOff(scope.row)"></el-switch>
<el-button type="text" @click="edit(scope.row, 1)">查看</el-button>
<el-button
v-if="scope.row.founder && (roleName.includes('超级') || roleName === scope.row.roleName || (roleName === '管理员' && !scope.row.roleName.includes('超级')))"
type="text" @click="edit(scope.row)">编辑</el-button>
<el-button
v-if="scope.row.founder && (roleName.includes('超级') || roleName === scope.row.roleName || (roleName === '管理员' && !scope.row.roleName.includes('超级')))"
type="text" @click="handleDelete(scope.row.projectId)">删除</el-button>
<el-button v-auth type="text" @click="copyData(scope.row.projectId)">复制</el-button>
<el-switch v-auth="'禁用'" v-if="scope.row.state" v-model="scope.row.ccupationlabOpen"
:active-text="scope.row.ccupationlabOpen ? '关闭' : '启用'" :active-value="0" :inactive-value="1"
style="margin: 0 10px 0 10px" @change="switchOff(scope.row)"></el-switch>
</template>
</el-table-column>
</el-table>
<div class="pagination">
<el-pagination background
@current-change="handleCurrentChange"
:current-page="page"
layout="total, prev, pager, next"
:total="total"></el-pagination>
<el-pagination background @current-change="handleCurrentChange" :current-page="page"
layout="total, prev, pager, next" :total="total"></el-pagination>
</div>
<el-dialog title="复制"
:visible.sync="copyVisible"
width="24%"
center
:close-on-click-modal="false">
<el-dialog title="复制" :visible.sync="copyVisible" width="24%" center :close-on-click-modal="false">
<el-form label-width="70px">
<el-form-item label="项目名称">
<el-input placeholder="请输入项目名称"
v-model="copyForm.projectName"></el-input>
<el-input placeholder="请输入项目名称" v-model="copyForm.projectName"></el-input>
</el-form-item>
<el-form-item v-if="!curRow.projectManage.founder"
label="课程">
<el-cascader v-model="copyMallId"
:options="copyCurs"
:props="{ checkStrictly: true, value: 'id' }"
popper-class="course-cas"
@expand-change="copySystemChange"
@change="copySystemChange"></el-cascader>
<el-form-item v-if="!curRow.projectManage.founder" label="课程">
<el-cascader v-model="copyMallId" :options="copyCurs" :props="{ checkStrictly: true, value: 'id' }"
popper-class="course-cas" @expand-change="copySystemChange" @change="copySystemChange"></el-cascader>
</el-form-item>
</el-form>
<span slot="footer"
class="dialog-footer">
<span slot="footer" class="dialog-footer">
<el-button @click="copyVisible = false"> </el-button>
<el-button type="primary"
:loading="submiting"
@click="copySubmit"> </el-button>
<el-button type="primary" :loading="submiting" @click="copySubmit"> </el-button>
</span>
</el-dialog>
</div>
@ -209,12 +124,13 @@
</template>
<script>
import { mapState, mapActions, mapMutations } from "vuex";
import { mapState } from "vuex";
import util from "@/libs/util";
import qs from 'qs'
export default {
data () {
return {
showBack: Boolean(this.$route.query.show),
fromAss: Boolean(this.$route.query.show), //
lc: [11, 12, 19],
cid: [this.$route.query.mallId ? +this.$route.query.mallId : '', this.$route.query.cid ? +this.$route.query.cid : ''],
curs: [],
@ -308,10 +224,6 @@ export default {
...mapState("user", [
"userId", "roleId", 'roleName'
]),
...mapState("project", [
"lastSystemId",
"assFields",
])
},
watch: {
'form.projectName': function (val) {
@ -331,11 +243,7 @@ export default {
this.getSystemData()
},
methods: {
...mapActions("project", [
"setSystemId"
]),
getData () {
this.setSystemId(this.form.systemId);
let data = {
...this.form,
pageNum: this.page,
@ -398,20 +306,15 @@ export default {
},
//
setCache () {
this.$store.commit('project/setParams', {
form: this.form,
page: this.page,
})
this.$store.commit('achievement/setReferrer', `${this.$route.path}?${qs.stringify(this.form)}&page=${this.page}`)
},
add () { //
this.setCache()
this.setSystemId(this.form.systemId);
this.$router.push(`/project/add?founder=${this.form.founder}`);
this.$router.push(`/project/add?founder=${this.form.founder}${this.fromAss ? '&ass=1' : ''}`);
},
edit (row, show) { //
this.setCache()
this.setSystemId(row.systemId);
this.$router.push(`/project/add?projectId=${row.projectId}&founder=${this.form.founder}${show ? `&show=1` : ''}`);
this.$router.push(`/project/add?projectId=${row.projectId}&founder=${this.form.founder}${show ? `&show=1` : ''}${this.fromAss ? '&ass=1' : ''}`);
},
handleSelectionChange (val) { //
this.multipleSelection = val;
@ -544,5 +447,4 @@ export default {
};
</script>
<style lang="scss" scoped>
</style>
<style lang="scss" scoped></style>

@ -1,10 +1,7 @@
<template>
<div class="wrap">
<!-- 全屏 -->
<img class="full"
src="@/assets/img/screen/full.png"
alt=""
@click="fullScreen">
<img class="full" src="@/assets/img/screen/full.png" alt="" @click="fullScreen">
<!--header-->
<div class="header">
<div class="bg_header">
@ -37,18 +34,15 @@
<i class="b_r_line"></i>
</div>
<div class="main_title">
<img src="@/assets/img/screen/t_1.png"
alt="">
<img src="@/assets/img/screen/t_1.png" alt="">
平台考试数据统计
</div>
<ul class="time-switch">
<li v-for="(item, i) in times"
:key="i"
:class="{active: item.id === time}"
@click="switchTime(item.id)">{{ item.name }}</li>
<li v-for="(item, i) in times" :key="i" :class="{ active: item.id === time }" @click="switchTime(item.id)">
{{
item.name }}</li>
</ul>
<div id="chart1"
class="chart"></div>
<div id="chart1" class="chart"></div>
</div>
<div class="item">
<div class="t_line_box">
@ -68,12 +62,10 @@
<i class="b_r_line"></i>
</div>
<div class="main_title">
<img src="@/assets/img/screen/t_2.png"
alt="">
<img src="@/assets/img/screen/t_2.png" alt="">
学生成绩分布分析
</div>
<div id="chart2"
class="chart t_btn9"></div>
<div id="chart2" class="chart t_btn9"></div>
</div>
<div class="item">
<div class="t_line_box">
@ -93,12 +85,10 @@
<i class="b_r_line"></i>
</div>
<div class="main_title">
<img src="@/assets/img/screen/t_7.png"
alt="">
<img src="@/assets/img/screen/t_7.png" alt="">
月人均在线学习时长情况
</div>
<div id="chart3"
class="chart t_btn9"></div>
<div id="chart3" class="chart t_btn9"></div>
</div>
<div class="item">
<div class="t_line_box">
@ -118,17 +108,14 @@
<i class="b_r_line"></i>
</div>
<div class="main_title">
<img src="@/assets/img/screen/t_7.png"
alt="">
<img src="@/assets/img/screen/t_7.png" alt="">
平台登录人数
</div>
<div id="chart4"
class="chart t_btn9"></div>
<div id="chart4" class="chart t_btn9"></div>
</div>
</div>
<div class="middle">
<div class="item"
style="height: 620px">
<div class="item" style="height: 620px">
<!--左上边框-->
<div class="t_line_box">
<i class="t_l_line"></i>
@ -149,15 +136,8 @@
<i class="r_b_line"></i>
<i class="b_r_line"></i>
</div>
<video class="video"
ref="video"
width="100%"
height="100%"
autoplay
muted
loop>
<source src="@/assets/videos/screen.mp4"
type="video/mp4">
<video class="video" ref="video" width="100%" height="100%" autoplay muted loop>
<source src="@/assets/videos/screen.mp4" type="video/mp4">
您的浏览器不支持 video 标签
</video>
<div class="stat-mask"></div>
@ -173,8 +153,7 @@
<p class="name">当前活跃人数</p>
</div>
</div>
<div class="item"
style="height: 440px;">
<div class="item" style="height: 440px;">
<!--左上边框-->
<div class="t_line_box">
<i class="t_l_line"></i>
@ -196,18 +175,14 @@
<i class="b_r_line"></i>
</div>
<div class="main_title">
<img src="@/assets/img/screen/t_3.png"
alt="">
<img src="@/assets/img/screen/t_3.png" alt="">
学生实验课程考核成绩趋势图
</div>
<div class="chart"
id="chart5"
style="height: 420px"></div>
<div class="chart" id="chart5" style="height: 420px"></div>
</div>
</div>
<div class="right">
<div class="item"
style="height: 160px">
<div class="item" style="height: 160px">
<!--左上边框-->
<div class="t_line_box">
<i class="t_l_line"></i>
@ -229,23 +204,18 @@
<i class="b_r_line"></i>
</div>
<div class="main_title">
<img src="@/assets/img/screen/t_4.png"
alt="">
<img src="@/assets/img/screen/t_4.png" alt="">
本月综合学习积极性最高的实验课程
</div>
<ul class="list">
<li v-for="(item, i) in courses"
:key="i">
<li v-for="(item, i) in courses" :key="i">
<span class="index">{{ i + 1 }}</span>
<p class="text">{{ item.goodsName }}</p>
<img class="icon"
src="@/assets/img/screen/medal.png"
alt="">
<img class="icon" src="@/assets/img/screen/medal.png" alt="">
</li>
</ul>
</div>
<div class="item"
style="height: 240px">
<div class="item" style="height: 240px">
<!--左上边框-->
<div class="t_line_box">
<i class="t_l_line"></i>
@ -267,23 +237,20 @@
<i class="b_r_line"></i>
</div>
<div class="main_title">
<img src="@/assets/img/screen/t_5.png"
alt="">
<img src="@/assets/img/screen/t_5.png" alt="">
热门理论课程排行榜
</div>
<div class="popular-wrap"
ref="popularCourses">
<div class="popular-wrap" ref="popularCourses">
<ul class="list popular">
<li v-for="(item, i) in popularCourses"
:key="i">
<li v-for="(item, i) in popularCourses" :key="i">
<span class="index">{{ i + 1 }}</span>
<p class="text">{{ item }}</p>
<p class="text">{{ item.courseName }}</p>
<span class="num">{{ item.viewCount }}</span>
</li>
</ul>
</div>
</div>
<div class="item"
style="height: 300px">
<div class="item" style="height: 300px">
<div class="t_line_box">
<i class="t_l_line"></i>
<i class="l_t_line"></i>
@ -301,8 +268,7 @@
<i class="b_r_line"></i>
</div>
<div class="main_title">
<img src="@/assets/img/screen/t_7.png"
alt="">
<img src="@/assets/img/screen/t_7.png" alt="">
学霸排行榜
</div>
<div class="main_table">
@ -318,13 +284,10 @@
</thead>
</table>
</div>
<div class="main_table"
ref="ach"
style="max-height: 222px;margin-top: 0;overflow: hidden">
<div class="main_table" ref="ach" style="max-height: 222px;margin-top: 0;overflow: hidden">
<table>
<tbody>
<tr v-for="(item, i) in achs"
:key="i">
<tr v-for="(item, i) in achs" :key="i">
<td width="20%">{{ i + 1 }}</td>
<td width="20%">{{ item.userName }}</td>
<td width="20%">{{ token ? item.className : item.schoolName }}</td>
@ -335,8 +298,7 @@
</table>
</div>
</div>
<div class="item"
style="height: 300px">
<div class="item" style="height: 300px">
<div class="t_line_box">
<i class="t_l_line"></i>
<i class="l_t_line"></i>
@ -354,8 +316,7 @@
<i class="b_r_line"></i>
</div>
<div class="main_title">
<img src="@/assets/img/screen/t_7.png"
alt="">
<img src="@/assets/img/screen/t_7.png" alt="">
活跃度排行榜
</div>
<div class="main_table">
@ -369,13 +330,10 @@
</thead>
</table>
</div>
<div class="main_table"
ref="active"
style="max-height: 230px;margin-top: 0;overflow: hidden">
<div class="main_table" ref="active" style="max-height: 230px;margin-top: 0;overflow: hidden">
<table>
<tbody>
<tr v-for="(item, i) in actives"
:key="i">
<tr v-for="(item, i) in actives" :key="i">
<td width="20%">{{ i + 1 }}</td>
<td width="20%">{{ token ? item.className : item.schoolName }}</td>
<td width="20%">{{ item.activityIndex }}</td>
@ -462,8 +420,8 @@ export default {
}).catch(res => { })
//
this.$post(this.api.courseRankings).then(({ data }) => {
this.popularCourses = data
this.$post(this.api.courseRankings).then(({ list }) => {
this.popularCourses = list
}).catch(res => { })
//
@ -769,9 +727,9 @@ export default {
color2: 'rgba(150, 20, 144, 0.4)'
},
]
1
const cousrseRes = await this.$post(this.api.websiteProductList, {
const cousrseRes = await this.$post(this.api.productsWithExperimentalResults, {
pageNum: 1,
pageSize: 1000,
sort: 0,
@ -780,7 +738,7 @@ export default {
purchaseStatus: this.token ? 1 : ''
})
if (cousrseRes) {
const courseList = cousrseRes.page.records
const courseList = cousrseRes.list
const ids = courseList.map(e => e.mallId)
times.map(e => {
e.mallId = ids
@ -1137,15 +1095,16 @@ export default {
const dom = this.$refs.popularCourses
const dom1 = this.$refs.ach
const dom2 = this.$refs.active
const unit = window.innerWidth > 1920 ? 2 : 1
setInterval(() => {
dom.scrollTop += 1
if (dom.clientHeight + dom.scrollTop === dom.scrollHeight) dom.scrollTop = 0
dom.scrollTop += unit
if (dom.clientHeight + dom.scrollTop >= dom.scrollHeight) dom.scrollTop = 0
dom1.scrollTop += 1
if (dom1.clientHeight + dom1.scrollTop === dom1.scrollHeight) dom1.scrollTop = 0
dom1.scrollTop += unit
if (dom1.clientHeight + dom1.scrollTop >= dom1.scrollHeight) dom1.scrollTop = 0
dom2.scrollTop += 1
if (dom2.clientHeight + dom2.scrollTop === dom2.scrollHeight) dom2.scrollTop = 0
dom2.scrollTop += unit
if (dom2.clientHeight + dom2.scrollTop >= dom2.scrollHeight) dom2.scrollTop = 0
}, 30)
}
}

@ -858,6 +858,7 @@ export default {
util.cookies.set('competitionId', '', -1)
util.cookies.set('language', '', -1)
util.cookies.set('className', '', -1)
util.cookies.set('loaded', '', -1)
// 8pythoncookiesystemId
location.href = process.env.NODE_ENV === 'development' ?
`http://${location.hostname}:8085/#/` :

@ -1,5 +1,5 @@
import axios from "axios";
import util from "@/libs/util";
import Util from "@/libs/util";
import router from "@/router/index";
import Setting from "@/setting";
import store from '@/store'
@ -13,11 +13,11 @@ service.defaults.headers.post["Content-Type"] = "application/json;charset=UTF-8"
// 请求拦截器
service.interceptors.request.use(config => {
let token = util.local.get(Setting.tokenKey);
let token = Util.local.get(Setting.tokenKey);
if (token) config.headers.token = token;
return config;
}, err => {
util.errorMsg({
Util.errorMsg({
message: "退出登陆",
onClose: function () {
store.dispatch('user/logout')
@ -33,10 +33,22 @@ service.interceptors.response.use(
const res = response.data;
if (res.status == 200 || res.status == 10000 || res.status == 30001) {
return Promise.resolve(res).catch(e => { });
} else if (res.code === 401) {
// 账号互踢
if (!logouted) {
Util.local.remove(Setting.storeKey)
Util.local.remove(Setting.tokenKey)
Util.errorMsg(res.msg.includes('顶') ? '您的账号已在其他设备登录,您已被迫下线!' : '登录过期,请重新登录!')
setTimeout(() => {
store.dispatch('user/logout')
logouted = 0
}, 2000)
logouted = 1
}
} else if (!res.status) {
return Promise.resolve(res).catch(e => { });
} else {
util.errorMsg(res.message);
Util.errorMsg(res.message);
return Promise.reject(res)
// return Promise.resolve(res).catch(e => {});
}
@ -50,9 +62,9 @@ service.interceptors.response.use(
// 在登录成功后返回当前页面,这一步需要在登录页操作。
case 401:
if (!logouted) {
util.local.remove(Setting.storeKey);
util.local.remove(Setting.tokenKey);
util.errorMsg("登录过期,请重新登录");
Util.local.remove(Setting.storeKey);
Util.local.remove(Setting.tokenKey);
Util.errorMsg("登录过期,请重新登录");
setTimeout(() => {
store.dispatch('user/logout')
}, 1000);
@ -60,30 +72,15 @@ service.interceptors.response.use(
}
break;
case 500:
util.errorMsg("网络错误");
break;
// 403 token过期
// 登录过期对用户进行提示
// 清除本地token和清空vuex中token对象
// 跳转登录页面
case 403:
util.local.remove(Setting.storeKey);
util.local.remove(Setting.tokenKey);
util.errorMsg("登录过期,请重新登录");
// 清除token
// store.commit('loginSuccess', null);
// 跳转登录页面,并将要浏览的页面fullPath传过去,登录成功后跳转需要访问的页面
setTimeout(() => {
store.dispatch('user/logout')
}, 1000);
Util.errorMsg("网络错误");
break;
// 404请求不存在
case 404:
util.errorMsg("网络请求不存在!");
Util.errorMsg("网络请求不存在!");
break;
// 其他错误,直接抛出错误提示
default:
util.errorMsg(error.response.data.message);
Util.errorMsg(error.response.data.message);
Promise.reject(res);
}
return Promise.reject(error.response);

@ -32,6 +32,7 @@ if (isPro) {
host = 'https://www.occupationlab.com/' // 正式服
// host = "http://192.168.31.51:9000/";
host = localStorage.getItem('localIp') == 1 ? 'http://192.168.31.51:9000/' : 'http://192.168.31.217:9000/'
// host = 'http://192.168.31.51:9000/'
} else if (isSq) {
zcPath = `10.20.100.204:8883`
}

@ -2,37 +2,41 @@
* 项目系统相关
* */
export default {
namespaced: true,
state: {
params: null,
lastSystemId: "",
projectFields: {},
assFields: {},
queryDataStatus: null
namespaced: true,
state: {
params: null,
lastSystemId: "",
projectFields: {},
assFields: {},
queryDataStatus: null,
referrer: '',
},
mutations: {
setParams: (state, val) => {
state.params = val
},
mutations: {
setParams: (state, val) => {
state.params = val
},
SET_SYSTEM_ID: (state, systemId) => {
state.lastSystemId = systemId;
},
SET_PROJECT: (state, projectFields) => {
state.projectFields = projectFields;
},
SET_ASS: (state, assFields) => {
state.assFields = assFields;
},
SET_SYSTEM_ID: (state, systemId) => {
state.lastSystemId = systemId;
},
actions: {
setSystemId({ state, commit }, systemId) {
commit("SET_SYSTEM_ID", systemId);
},
setProject({ state, commit }, projectFields) {
commit("SET_PROJECT", projectFields);
},
setAss({ state, commit }, assFields) {
commit("SET_ASS", assFields);
}
SET_PROJECT: (state, projectFields) => {
state.projectFields = projectFields;
},
SET_ASS: (state, assFields) => {
state.assFields = assFields;
},
setReferrer: (state, val) => {
state.referrer = val
},
},
actions: {
setSystemId ({ state, commit }, systemId) {
commit("SET_SYSTEM_ID", systemId);
},
setProject ({ state, commit }, projectFields) {
commit("SET_PROJECT", projectFields);
},
setAss ({ state, commit }, assFields) {
commit("SET_ASS", assFields);
}
}
};

@ -381,6 +381,13 @@ $height: 250px;
background-color: #072951;
box-shadow:-10px 0px 15px #2C58A6 inset, 10px 0px 15px #2C58A6 inset;
}
.num {
position: absolute;
top: 10px;
right: 10%;
font-size: 12px;
color: #fff;
}
}
.index {
position: absolute;

Loading…
Cancel
Save