实验台等

master
yujialong 4 months ago
parent 2fec0e532b
commit f7f57d84dd
  1. 19
      src/App.vue
  2. 2
      src/api/index.js
  3. 77
      src/layouts/header/index.vue
  4. 30
      src/pages/product/show/index.vue
  5. 169
      src/pages/station/list/index.vue
  6. 59
      src/pages/station/preview/index.vue
  7. 6
      src/setting.js

@ -1,5 +1,10 @@
<template>
<div id="app">
<el-radio-group v-if="Setting.isDev" v-model="ip" @change="ipChange">
<el-radio :label="0">刘榕ip</el-radio>
<el-radio :label="1">陈赓ip</el-radio>
<el-radio :label="2">测试服ip</el-radio>
</el-radio-group>
<router-view></router-view>
</div>
</template>
@ -10,7 +15,13 @@ import util from "@/libs/util";
export default {
name: "App",
created() {
data () {
return {
Setting,
ip: localStorage.getItem('ip') ? +localStorage.getItem('ip') : 0,
};
},
created () {
//localStorage
if (util.local.get(Setting.storeKey)) {
this.$store.replaceState(Object.assign({}, this.$store.state, util.local.get(Setting.storeKey)));
@ -21,6 +32,12 @@ export default {
sessionStorage.removeItem('handelPermission')
util.local.get(Setting.tokenKey) && util.local.set(Setting.storeKey, this.$store.state);
});
},
methods: {
ipChange (val) {
localStorage.setItem('ip', val)
location.reload()
},
}
};
</script>

@ -34,6 +34,8 @@ export default {
updateLearningProgress: 'nakadai/nakadai/curriculum/learning/progressprogress/update',
maximumPracticeScoreList: 'occupationlab/occupationlab/achievement/maximumPracticeScoreList',
getSandTableLastCache: `product/product/bank/operation/getSandTableLastCache`,
getSchoolCourseAuthority: `nakadai/nakadai/curriculum/getSchoolCourseAuthority`,
requestRenewalNotice: `nakadai/nakadai/curriculum/requestRenewalNotice`,
// 课程笔记
addNote: `nakadai/curriculumNotes/addNote`,
curriculumNoteList: `nakadai/curriculumNotes/curriculumNoteList`,

@ -1,82 +1,46 @@
<template>
<div class="header">
<div style="line-height: 60px">
<img v-if="Setting.isSq"
class="logo"
style="max-height: 100%"
src="/images/1.png"
alt="">
<img v-else
class="logo"
:src="logoUrl" />
<img v-if="Setting.isSq" class="logo" style="max-height: 100%" src="/images/1.png" alt="">
<img v-else class="logo" :src="logoUrl" />
<span class="title">{{ title }}</span>
</div>
<el-radio-group v-if="Setting.isDev"
v-model="ip"
@change="ipChange">
<el-radio :label="0">刘榕ip</el-radio>
<el-radio :label="1">陈赓ip</el-radio>
</el-radio-group>
<div class="action">
<el-popover placement="top"
:disabled="!notices.length">
<p v-for="(item, i) in notices"
:key="i"
class="p-v-5 cursor-pointer"
@click="toComment(item)">{{ item.commentUsername }} 回复了你的评论</p>
<el-badge class="msg"
:is-dot="!!notices.length"
slot="reference">消息</el-badge>
<el-popover placement="top" :disabled="!notices.length">
<p v-for="(item, i) in notices" :key="i" class="p-v-5 cursor-pointer" @click="toComment(item)">{{
item.commentUsername }} 回复了你的评论</p>
<el-badge class="msg" :is-dot="!!notices.length" slot="reference">消息</el-badge>
</el-popover>
<el-dropdown class="user-wrap"
@command="userCommand">
<el-dropdown class="user-wrap" @command="userCommand">
<div class="user">
<el-avatar :size="40"
:src="avatar"></el-avatar>
<el-avatar :size="40" :src="avatar"></el-avatar>
<span class="m-l-10">{{ customerName || userName }}</span>
</div>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item v-if="!customerName"
command="person">个人中心</el-dropdown-item>
<el-dropdown-item v-else
command="resetPw">修改密码</el-dropdown-item>
<el-dropdown-item v-if="!customerName" command="person">个人中心</el-dropdown-item>
<el-dropdown-item v-else command="resetPw">修改密码</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
<el-divider direction="vertical"></el-divider>
<el-button type="text"
class="ml20"
@click="logout">退出</el-button>
<el-button type="text" class="ml20" @click="logout">退出</el-button>
</div>
<el-dialog title="修改密码"
:visible.sync="passwordVisible"
:close-on-click-modal="false"
:append-to-body="true"
@close="resetPassword"
width="30%">
<el-form ref="passwordForm"
label-width="82px">
<el-dialog title="修改密码" :visible.sync="passwordVisible" :close-on-click-modal="false" :append-to-body="true"
@close="resetPassword" width="30%">
<el-form ref="passwordForm" label-width="82px">
<el-form-item label="原密码">
<el-input type="password"
v-model="passwordForm.password"
placeholder="请输入原密码"></el-input>
<el-input type="password" v-model="passwordForm.password" placeholder="请输入原密码"></el-input>
</el-form-item>
<el-form-item label="新密码">
<el-input type="password"
v-model="passwordForm.newPassword"
placeholder="请输入新密码"></el-input>
<el-input type="password" v-model="passwordForm.newPassword" placeholder="请输入新密码"></el-input>
</el-form-item>
<el-form-item label="确认新密码">
<el-input type="password"
v-model="passwordForm.reNewPassword"
placeholder="请确认新密码"
<el-input type="password" v-model="passwordForm.reNewPassword" placeholder="请确认新密码"
@keyup.enter.native="submitPassword"></el-input>
</el-form-item>
</el-form>
<span slot="footer"
class="dialog-footer">
<span slot="footer" class="dialog-footer">
<el-button @click="passwordVisible = false"> </el-button>
<el-button type="primary"
@click="submitPassword"> </el-button>
<el-button type="primary" @click="submitPassword"> </el-button>
</span>
</el-dialog>
</div>
@ -261,7 +225,7 @@ export default {
.logo {
max-height: 50px;
margin: 0 40px;
margin: 0 20px 0 40px;
}
.title {
@ -278,6 +242,7 @@ export default {
display: inline-flex;
align-items: center;
cursor: pointer;
span {
font-size: 12px;
}

@ -52,7 +52,9 @@
<div class="text">{{ form.goodsRes.typeName }}</div>
</div>
</div>
<button v-if="!form.goodsRes.logoOfOurSchool" class="btn" @click="toTrail">试用体验</button>
<button v-if="!overdue" class="btn" @click="toRenew">续费</button>
<button v-else-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>
@ -148,7 +150,8 @@ export default {
chapterList: [],
hots: [],
linkVisible: false,
height: ''
height: '',
overdue: 0, //
};
},
computed: {
@ -196,6 +199,7 @@ export default {
next()
},
mounted () {
this.getStatus()
this.getData()
this.getHot()
},
@ -225,6 +229,15 @@ export default {
this.chapterList = res.chapterList
}
},
//
getStatus () {
this.$get(this.api.whetherToRenewTheFee, {
mallId: this.id
}).then(({ isRenew }) => {
// 10
this.overdue = isRenew
}).catch(res => { })
},
// tab
tabChange ({ id }) {
this.curTab = id
@ -253,6 +266,19 @@ export default {
this.getChapter()
}).catch(res => { })
},
//
async toRenew () {
try {
await this.$confirm(`<p style="margin-bottom: 10px;">确认提交续期申请吗?</p><p style="font-size: 12px;">提交后,我们将立即处理您的续期请求。请耐心等待,我们会尽快完成续期流程。</p>`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'success',
closeOnClickModal: false,
dangerouslyUseHTMLString: true,
})
await this.$post(`${this.api.requestRenewalNotice}?mallId=${this.id}`)
} catch (e) { }
},
//
toTrail () {
window.open('https://www.wjx.top/vm/wFCPCFp.aspx')

@ -3,104 +3,135 @@
<div class="wrap">
<div class="search">
<h6>创新实验智能教学</h6>
<div class="input"
v-auth="'搜索'">
<img src="@/assets/img/search.png"
alt="">
<input type="text"
placeholder="请输入关键词"
v-model="keyword">
<div class="input" v-auth="'搜索'">
<img src="@/assets/img/search.png" alt="">
<input type="text" placeholder="请输入关键词" v-model="keyword">
</div>
</div>
<div class="station">
<div class="inner">
<div class="tab">
<a class="item"
v-for="(item, i) in tabs"
:key="i"
:class="{active: item.id == active}"
@click="tabChange(item)">{{ item.name }}</a>
<a class="item" v-for="(item, i) in tabs" :key="i" :class="{ active: item.classificationId === active }"
@click="tabChange(item)">{{ item.classificationName }}</a>
</div>
<div class="curs">
<template v-if="curriculumList.length">
<template v-for="(item,i) in curriculumList">
<div class="item"
:title="item.goodsName"
@click="goPreview(item)"
:key="i"
v-if="!keyword || item.goodsName.includes(keyword)">
<div v-if="isSq"
class="cover"
:style="{backgroundImage: 'url(/images/' + i + '.png)'}"></div>
<div v-else
class="cover"
:style="{backgroundImage: 'url(' + item.coverUrl + ')'}"></div>
<template v-if="products.length">
<div v-for="(item, i) in products" class="item" :title="item.goodsName" @click="toProduct(item)" :key="i">
<div v-if="isZj || isSq" class="cover" :style="{ backgroundImage: 'url(/images/' + i + '.png)' }"></div>
<div v-else class="cover" :style="{ backgroundImage: 'url(' + item.coverUrl + ')' }"></div>
<div class="bottom">
<p class="text"><span>{{ item.goodsName || item.curriculumName }}</span></p>
<a>进入实验</a>
<a>{{ item.isInEffect ? '进入实验' : '续费' }}</a>
</div>
</div>
</template>
</template>
<div class="empty flex-1"
v-else>
<div class="empty flex-1" v-else>
<div>
<img src="@/assets/img/none.png"
alt="">
<img src="@/assets/img/none.png" alt="">
<p>暂无数据</p>
</div>
</div>
</div>
</div>
</div>
<!-- 选择链接 -->
<el-dialog title="请选择链接" :visible.sync="linkVisible" width="420px" center :close-on-click-modal="false">
<div class="buy">
<div v-for="(link, i) in links" :key="i" class="link-line">
{{ link.urlName }}
<a class="url" :href="link.url" target="_blank">{{ link.url }}</a>
</div>
</div>
</el-dialog>
</div>
</template>
<script>
import Setting from "@/setting";
import Setting from '@/setting'
export default {
name: "backstage",
data () {
return {
isZj: location.host === '10.60.32.76', //
isSq: Setting.isSq,
keyword: this.$route.query.keyword || '',
active: +this.$route.query.active || 0,
tabs: [
{
id: 0,
name: '实验课程'
},
{
id: 1,
name: '最近使用'
}
],
curriculumList: []
active: +this.$route.query.active || '',
searchTimer: null,
tabs: [],
products: [],
linkVisible: false,
links: [],
}
},
watch: {
keyword: function () {
clearTimeout(this.searchTimer)
this.searchTimer = setTimeout(this.getList, 500)
},
},
mounted () {
this.getschoolCourse();
this.getTab()
},
methods: {
getschoolCourse () { //
this.active ?
this.$post(this.api.recentUse, {
// tab
async getTab () {
const { data } = await this.$get(this.api.getSchoolCourseAuthority)
this.tabs = [
{
classificationId: '',
classificationName: '全部',
},
...data,
{
classificationId: 0,
classificationName: '最近使用',
},
]
this.getList()
},
//
async getList () {
// 使
if (this.active === 0) {
const { page } = await this.$post(this.api.recentUse, {
pageNum: 1,
pageSize: 100
}).then(({ page }) => {
pageSize: 100,
goodsName: this.keyword,
})
this.curriculumList = page.records
}).catch(err => { }) :
this.$get(this.api.schoolCourse).then(res => {
this.curriculumList = res.data;
}).catch(err => { });
} else {
const { data } = await this.$get(this.api.schoolCourse, {
authority: this.active,
goodsName: this.keyword,
})
this.products = data
}
},
goPreview (item) {
this.$router.push(`/station/preview?courseId=${item.cid}&curriculumName=${item.goodsName}&mallId=${item.mallId || ''}&keyword=${this.keyword}&active=${this.active}`);
toProduct (item) {
//
if (item.isInEffect) {
const links = item.nonAssociatedLinks
//
if (links && links.length) {
if (links.length === 1) {
window.open(links[0].url)
} else {
this.linkVisible = true
this.links = item.nonAssociatedLinks
}
} else {
this.$router.push(`/station/preview?courseId=${item.cid}&curriculumName=${item.goodsName}&mallId=${item.mallId || ''}&keyword=${this.keyword}&active=${this.active}`)
}
} else {
//
this.$router.push(`/product/show?id=${item.mallId}`)
}
},
// tab
tabChange (item) {
this.active = item.id
this.getschoolCourse()
this.active = item.classificationId
this.getList()
},
}
};
@ -110,26 +141,31 @@ export default {
.wrap {
margin: -24px;
}
.search {
position: relative;
padding: 100px 0 130px;
text-align: center;
background: url(../../../assets/img/station-bg.png) 0 0/100% 100% no-repeat;
h6 {
margin-bottom: 25px;
font-size: 26px;
color: #fff;
}
.input {
position: relative;
width: 700px;
margin: 0 auto;
}
img {
position: absolute;
top: 19px;
left: 14px;
}
input {
width: 100%;
height: 62px;
@ -147,6 +183,7 @@ export default {
display: flex;
justify-content: center;
align-items: center;
.item {
padding: 0 20px;
margin-right: 16px;
@ -156,26 +193,31 @@ export default {
line-height: 50px;
border-bottom: 3px solid transparent;
cursor: pointer;
&.active {
color: #007eff;
border-color: #007eff;
}
}
}
.station {
min-height: calc(100vh - 520px);
background: url(../../../assets/img/station1.png) (top left) / auto no-repeat,
url(../../../assets/img/station2.png) bottom right/auto no-repeat;
.inner {
width: 1072px;
margin: 0 auto;
}
.curs {
display: flex;
flex-wrap: wrap;
width: 1072px;
padding-top: 60px;
margin: 0 auto;
.item {
position: relative;
padding: 0 10px;
@ -184,9 +226,11 @@ export default {
background-color: #fff;
border-radius: 8px;
cursor: pointer;
&:hover {
opacity: 0.9;
}
.cover {
width: 215px;
height: 118px;
@ -196,12 +240,14 @@ export default {
background-position: 0 0;
background-repeat: no-repeat;
}
.bottom {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px 5px;
}
.text {
display: inline-flex;
align-items: center;
@ -211,10 +257,12 @@ export default {
font-size: 12px;
line-height: 1.6;
overflow: hidden;
span {
@include mul-ellipsis(2);
}
}
a {
padding: 0 8px;
line-height: 28px;
@ -226,15 +274,18 @@ export default {
}
}
}
.empty {
display: flex;
justify-content: center;
align-items: center;
padding: 50px 0;
text-align: center;
img {
width: 471px;
}
p {
margin-top: 40px;
font-size: 18px;

@ -303,7 +303,7 @@
</template>
<script>
import util from "@/libs/util";
import Util from "@/libs/util";
import Setting from "@/setting";
import { mapState } from "vuex";
import pdf from "vue-pdf";
@ -524,11 +524,11 @@ export default {
//
submitNote () {
const form = this.noteForm
if (!form.noteName) return util.errorMsg('请输入笔记标题')
if (!form.noteContent) return util.errorMsg('请输入笔记内容')
if (!form.noteName) return Util.errorMsg('请输入笔记标题')
if (!form.noteContent) return Util.errorMsg('请输入笔记内容')
this.$post(this.api[form.noteId ? 'updateNote' : 'addNote'], form).then(res => {
this.getNote()
util.successMsg(form.noteId ? '修改成功' : '添加成功')
Util.successMsg(form.noteId ? '修改成功' : '添加成功')
this.showNoteAdd = false
this.noteForm = {
cid: this.courseId,
@ -543,7 +543,7 @@ export default {
type: "warning"
}).then(() => {
this.$post(`${this.api.deleteNotes}?noteId=${row.noteId}`).then(res => {
util.successMsg("删除成功");
Util.successMsg("删除成功");
this.getNote();
}).catch(res => { })
}).catch(() => { })
@ -604,7 +604,7 @@ export default {
type: "warning"
}).then(() => {
this.$post(`${this.api.deleteAComment}?commentId=${row.commentId}`).then(res => {
util.successMsg("删除成功");
Util.successMsg("删除成功");
this.getComment();
}).catch(res => { })
}).catch(() => { })
@ -612,7 +612,7 @@ export default {
//
submitComment (row, reply) {
const content = reply ? reply.replyContent : row ? row.replyContent : this.comment
if (!content) return util.errorMsg('请输入内容!')
if (!content) return Util.errorMsg('请输入内容!')
this.$post(this.api.addCommentStation, {
mallId: this.mallId,
content,
@ -827,6 +827,15 @@ export default {
this.showProjectDia()
})
} else { // python
// python
const opened = +localStorage.getItem('opened')
if (opened) {
Util.errorMsg('Python系统限单页活跃,请切换至当前已有的活跃实验页面。', 5000)
return false
} else {
localStorage.setItem('opened', 1)
}
this.$get(this.api.getTheMostRecentlyRunProject, {
cid: this.courseId
}).then(({ data }) => {
@ -844,23 +853,23 @@ export default {
// python
toPython (projectId) {
const id = this.systemIds
let token = util.local.get(Setting.tokenKey);
util.cookies.set('assessmentId', '', -1)
util.cookies.set('startTime', '', -1)
util.cookies.set('stopTime', '', -1)
projectId ? util.cookies.set('projectId', projectId) : util.cookies.set('projectId', '', -1)
util.cookies.set('token', token)
util.cookies.set('mallId', this.mallId)
util.cookies.set('third', this.third)
util.cookies.set('courseId', this.courseId)
util.cookies.set('curriculumName', encodeURIComponent(this.curriculumName))
util.cookies.set('systemId', id)
util.cookies.set('fromManager', 1)
util.cookies.set('isSubmit', '', -1)
util.cookies.set('competitionId', '', -1)
util.cookies.set('language', '', -1)
util.cookies.set('className', '', -1)
util.cookies.set('loaded', '', -1)
let token = Util.local.get(Setting.tokenKey);
Util.cookies.set('assessmentId', '', -1)
Util.cookies.set('startTime', '', -1)
Util.cookies.set('stopTime', '', -1)
projectId ? Util.cookies.set('projectId', projectId) : Util.cookies.set('projectId', '', -1)
Util.cookies.set('token', token)
Util.cookies.set('mallId', this.mallId)
Util.cookies.set('third', this.third)
Util.cookies.set('courseId', this.courseId)
Util.cookies.set('curriculumName', encodeURIComponent(this.curriculumName))
Util.cookies.set('systemId', id)
Util.cookies.set('fromManager', 1)
Util.cookies.set('isSubmit', '', -1)
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/#/` :
@ -877,7 +886,7 @@ export default {
}
const { systemId } = curProject
let token = util.local.get(Setting.tokenKey);
let token = Util.local.get(Setting.tokenKey);
this.third = curProject.type === 2 ? (curProject.systemId === 28 ? 'low' : 'ai') : ''
if (systemId == 11) {
//

@ -30,9 +30,9 @@ if (isPro) {
uploadURL = `http://121.37.12.51/`
host = "http://121.37.12.51/"; // 中台测试服
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/'
const ips = ['http://192.168.31.217:9000/', 'http://192.168.31.51:9000/', 'http://121.37.12.51/']
host = ips[+localStorage.getItem('ip')]
// host = 'http://192.168.31.217:9000/'
} else if (isSq) {
zcPath = `10.20.100.204:8883`
}

Loading…
Cancel
Save