From d543dbf308b04dab0bab8e5787b4b950bc0f75f9 Mon Sep 17 00:00:00 2001 From: yujialong <479214531@qq.com> Date: Wed, 17 May 2023 18:19:56 +0800 Subject: [PATCH] fix --- src/pages/account/login/index.vue | 1797 +++++++++++--------- src/pages/activity/list/index.vue | 771 +++++---- src/pages/activity/manage/manage/index.vue | 242 +-- src/pages/station/preview/index.vue | 1700 +++++++++--------- 4 files changed, 2396 insertions(+), 2114 deletions(-) diff --git a/src/pages/account/login/index.vue b/src/pages/account/login/index.vue index ba7fa4d..ce9e7b1 100644 --- a/src/pages/account/login/index.vue +++ b/src/pages/account/login/index.vue @@ -1,189 +1,317 @@ <template> - <div class="wrap"> - <div class="login"> - <div class="form"> - <h6 class="title">欢迎使用请登录</h6> - <ul class="tab"> - <li v-for="(item,index) in tabList" :key="index" :class="{active: form.distinguish == item.id}" @click="typeClick(item)">{{item.label}}</li> - </ul> - <el-form :model="form" :rules="rules" ref="form" style="margin-top: 20px"> - <!-- 学号工号 --> - <div v-show="!form.distinguish"> - <el-form-item class="school-select" prop="schoolId"> - <label class="label school"></label> - <el-select v-model="form.schoolId" clearable filterable placeholder="请选择学校"> - <el-option v-for="(item, i) in schoolList" :key="i" :label="item.schoolName" :value="item.schoolId"></el-option> - </el-select> - </el-form-item> - <div class="items"> - <el-form-item prop="type" style="width: 35%;margin-right: 15px"> - <label class="label workNumber"></label> - <el-select v-model="form.type" placeholder="请选择类型" @change="typeChange"> - <el-option label="学生学号" :value="1"></el-option> - <el-option label="老师工号" :value="0"></el-option> - </el-select> - </el-form-item> - <el-form-item class="flex-1" prop="workNumber"> - <label class="label account"></label> - <el-input v-model.trim="form.workNumber" :placeholder="'请输入' + (form.type ? '学生学号' : '老师工号')" @keyup.enter.native="submit"></el-input> - </el-form-item> - </div> - </div> - <!-- 手机号登录 --> - <el-form-item v-show="form.distinguish === 1" prop="account"> - <label class="label account"></label> - <el-input v-model.trim="form.account" placeholder="请输入账号" @keyup.enter.native="submit"></el-input> - </el-form-item> - <template v-if="form.distinguish === 2"> - <el-form-item prop="account"> - <label class="label account"></label> - <el-input v-model.trim="form.account" placeholder="请输入手机号/邮箱" @keyup.enter.native="submit"></el-input> - </el-form-item> - <el-form-item prop="code"> - <label class="label code"></label> - <div class="ver-code"> - <el-input v-model="form.code" placeholder="请输入验证码" maxlength="6" @keyup.enter.native="submit"></el-input> - <el-button type="text" @click="sendPhoneCodeLogin" :disabled="phoneDisabledLogin">{{ phoneBtnTextLogin }} - </el-button> - </div> - </el-form-item> - </template> - <template v-if="form.distinguish !== 2"> - <el-form-item prop="password"> - <label class="password label"></label> - <el-input - type="password" - placeholder="请输入密码" - v-model.trim="form.password" - @keyup.enter.native="submit" - > - </el-input> - </el-form-item> - <el-form-item prop="code"> - <label class="label code"></label> - <el-input - placeholder="请输入验证码" - v-model.trim="form.code" - @keyup.enter.native="submit" - > - </el-input> - <img @click="getVerImg" :src="verificationIMG" class="ver-img" alt=""> - </el-form-item> - </template> - <div class="bottom"> - <el-link v-if="toMatch" :underline="false" type="primary" @click="toAccount">暂无账号?点击申请</el-link> - <el-checkbox v-show="!form.distinguish" v-model="setDefault">设置为默认学校</el-checkbox> - </div> - <el-button class="submit" type="primary" @click="submit">登录</el-button> - </el-form> - </div> - </div> - <el-dialog title="绑定手机号" :visible.sync="phoneVisible" :close-on-click-modal="false" width="30%"> - <div style='padding: 0 13px 20px 13px;'> - 依据国家政策法规,需绑定手机号进行网络实名才可登录使用本平台 - </div> - <el-form label-width="60px"> - <el-form-item label="手机号"> - <el-input style="width: 100%;" placeholder="请输入手机号" v-model="phone" maxlength="11" @change="phoneChange"></el-input> - </el-form-item> - <el-form-item label="验证码"> - <div class="ver-code"> - <el-input v-model="phoneCode" placeholder="请输入验证码" maxlength="6"></el-input> - <el-button style="top: 1px" type="text" @click="sendPhoneCode(1)" :disabled="binding === '' || phoneDisabled">{{ phoneBtnText }} - </el-button> - </div> - </el-form-item> - </el-form> - <span slot="footer" class="dialog-footer"> - <el-button size="small" @click="phoneVisible = false">取 消</el-button> - <el-button size="small" type="primary" @click="phoneSubmit">确 定</el-button> - </span> - </el-dialog> - <el-dialog title="请选择" :visible.sync="selectVisible" :close-on-click-modal="false" custom-class="select-dia" width="643px"> - <ul class="port"> - <li :class="{active: selectedRole === 1}" @click="selectRole(1)"> - <img src="@/assets/img/login/male.png" alt=""> - <p>学生端</p> - </li> - <li :class="{active: selectedRole === 2}" @click="selectRole(2)"> - <img src="@/assets/img/login/female.png" alt=""> - <p>教师管理端</p> - </li> - </ul> - </el-dialog> - <el-dialog title="请选择您要登录的用户" :visible.sync="userVisible" :close-on-click-modal="false" custom-class="user-dia" width="500px"> - <p class="tips">该手机号已绑定以下用户信息</p> - <ul class="users"> - <li :class="{isEnable: !user.isEnable}" v-for="(user, i) in users" :key="i" @click="chooseUser(user)"> - <span>{{ user.schoolName }},{{ user.userName }},{{ user.workNumber }}{{ user.isEnable ? '' : '(已禁用)'}}</span> - <i class="el-icon-right"></i> - </li> - </ul> - </el-dialog> - <el-dialog :visible.sync="infoVisible" :close-on-click-modal="false" custom-class="info-dia" :show-close="false" width="400px"> - <div class="info-header"> - <i class="el-icon-warning"></i> - 提示 - </div> - <div class="info-wrap"> - <p class="tips">该手机号已与以下用户绑定</p> - <ul class="users"> - <li v-for="(user, i) in infos" :key="i"> - <span>{{ user.userName }}({{ user.schoolName }})</span> - </li> - </ul> - <div class="info-footer"> - <el-button size="small" type="primary" @click="bindPhone">是本人,继续绑定</el-button> - <el-button class="unbind" size="small" @click="unbindPhone">不是本人,解绑以上用户并绑定新用户</el-button> - </div> - </div> - </el-dialog> - <!-- 购买弹框 --> - <el-dialog title="温馨提示" :visible.sync="buyVisible" width="400px" center :close-on-click-modal="false"> - <div class="buy"> - <p class="tips">您所选择的院校暂未在本平台开通组织账号,请通知院校老师联系下方二维码客服咨询。</p> - <img src="@/assets/img/wechat-code.jpeg" alt=""> - </div> - </el-dialog> - - - <el-dialog title="账号申请" :visible.sync="accountVisible" :close-on-click-modal="false" width="500px" @close="accountClose"> - <el-form class="dia-form" ref="accountForm" label-width="110px" :model="accountForm" :rules="accountRules"> - <el-form-item prop="schoolId" label="所属院校"> - <el-select class="w-100" v-model="accountForm.schoolId" filterable placeholder="请选择院校" @change="schoolChange"> - <el-option v-for="(item, i) in schoolList" :key="i" :label="item.schoolName" :value="item.schoolId"></el-option> + <div class="wrap"> + <div class="login"> + <div class="form"> + <h6 class="title">欢迎使用请登录</h6> + <ul class="tab"> + <li v-for="(item,index) in tabList" + :key="index" + :class="{active: form.distinguish == item.id}" + @click="typeClick(item)">{{item.label}}</li> + </ul> + <el-form :model="form" + :rules="rules" + ref="form" + style="margin-top: 20px"> + <!-- 学号工号 --> + <div v-show="!form.distinguish"> + <el-form-item class="school-select" + prop="schoolId"> + <label class="label school"></label> + <el-select v-model="form.schoolId" + clearable + filterable + placeholder="请选择学校"> + <el-option v-for="(item, i) in schoolList" + :key="i" + :label="item.schoolName" + :value="item.schoolId"></el-option> </el-select> </el-form-item> - <el-form-item prop="workNumber" label="学号"> - <el-input placeholder="申请后无法修改,请确认填写正确" v-model="accountForm.workNumber" @change="workNumberChange"></el-input> - </el-form-item> - <el-form-item prop="userName" label="姓名"> - <el-input placeholder="请输入姓名" v-model="accountForm.userName" :disabled="formEnable"></el-input> - </el-form-item> - <el-form-item prop="phone" label="手机号"> - <el-input placeholder="请输入手机号" maxlength="11" v-model.trim="accountForm.phone" :disabled="formEnable"></el-input> + <div class="items"> + <el-form-item prop="type" + style="width: 35%;margin-right: 15px"> + <label class="label workNumber"></label> + <el-select v-model="form.type" + placeholder="请选择类型" + @change="typeChange"> + <el-option label="学生学号" + :value="1"></el-option> + <el-option label="老师工号" + :value="0"></el-option> + </el-select> + </el-form-item> + <el-form-item class="flex-1" + prop="workNumber"> + <label class="label account"></label> + <el-input v-model.trim="form.workNumber" + :placeholder="'请输入' + (form.type ? '学生学号' : '老师工号')" + @keyup.enter.native="submit"></el-input> + </el-form-item> + </div> + </div> + <!-- 手机号登录 --> + <el-form-item v-show="form.distinguish === 1" + prop="account"> + <label class="label account"></label> + <el-input v-model.trim="form.account" + placeholder="请输入账号" + @keyup.enter.native="submit"></el-input> + </el-form-item> + <template v-if="form.distinguish === 2"> + <el-form-item prop="account"> + <label class="label account"></label> + <el-input v-model.trim="form.account" + placeholder="请输入手机号/邮箱" + @keyup.enter.native="submit"></el-input> </el-form-item> - <el-form-item prop="code" label="验证码"> + <el-form-item prop="code"> + <label class="label code"></label> <div class="ver-code"> - <el-input v-model="accountForm.code" placeholder="请输入验证码" maxlength="6" :disabled="formEnable"></el-input> - <el-button style="top: 1px" type="text" @click="sendCode" :disabled="phoneDisabled && formEnable">{{ phoneBtnText }} + <el-input v-model="form.code" + placeholder="请输入验证码" + maxlength="6" + @keyup.enter.native="submit"></el-input> + <el-button type="text" + @click="sendPhoneCodeLogin" + :disabled="phoneDisabledLogin">{{ phoneBtnTextLogin }} </el-button> </div> </el-form-item> - <el-form-item prop="password" label="登录密码"> - <el-input placeholder="请输入登录密码" type="password" maxlength="6" v-model="accountForm.password" :disabled="formEnable"></el-input> + </template> + <template v-if="form.distinguish !== 2"> + <el-form-item prop="password"> + <label class="password label"></label> + <el-input type="password" + placeholder="请输入密码" + v-model.trim="form.password" + @keyup.enter.native="submit"> + </el-input> </el-form-item> - <el-form-item prop="rePassword" label="确认登录密码"> - <el-input placeholder="请再次输入登录密码" type="password" maxlength="6" v-model="accountForm.rePassword" :disabled="formEnable"></el-input> + <el-form-item prop="code"> + <label class="label code"></label> + <el-input placeholder="请输入验证码" + v-model.trim="form.code" + @keyup.enter.native="submit"> + </el-input> + <img @click="getVerImg" + :src="verificationIMG" + class="ver-img" + alt=""> </el-form-item> - </el-form> - <span slot="footer" class="dialog-footer"> - <el-button v-if="!formEnable" size="small" type="primary" @click="accountSubmit">申请</el-button> - <el-button size="small" @click="accountVisible = false">取消</el-button> - </span> - </el-dialog> - <v-footer ref="footer"></v-footer> + </template> + <div class="bottom"> + <el-link v-if="toMatch" + :underline="false" + type="primary" + @click="toAccount">暂无账号?点击申请</el-link> + <el-checkbox v-show="!form.distinguish" + v-model="setDefault">设置为默认学校</el-checkbox> + </div> + <el-button class="submit" + type="primary" + @click="submit">登录</el-button> + </el-form> + </div> </div> + <el-dialog title="绑定手机号" + :visible.sync="phoneVisible" + :close-on-click-modal="false" + width="30%"> + <div style='padding: 0 13px 20px 13px;'> + 依据国家政策法规,需绑定手机号进行网络实名才可登录使用本平台 + </div> + <el-form label-width="60px"> + <el-form-item label="手机号"> + <el-input style="width: 100%;" + placeholder="请输入手机号" + v-model="phone" + maxlength="11" + @change="phoneChange"></el-input> + </el-form-item> + <el-form-item label="验证码"> + <div class="ver-code"> + <el-input v-model="phoneCode" + placeholder="请输入验证码" + maxlength="6"></el-input> + <el-button style="top: 1px" + type="text" + @click="sendPhoneCode(1)" + :disabled="binding === '' || phoneDisabled">{{ phoneBtnText }} + </el-button> + </div> + </el-form-item> + </el-form> + <span slot="footer" + class="dialog-footer"> + <el-button size="small" + @click="phoneVisible = false">取 消</el-button> + <el-button size="small" + type="primary" + @click="phoneSubmit">确 定</el-button> + </span> + </el-dialog> + <el-dialog title="请选择" + :visible.sync="selectVisible" + :close-on-click-modal="false" + custom-class="select-dia" + width="643px"> + <ul class="port"> + <li :class="{active: selectedRole === 1}" + @click="selectRole(1)"> + <img src="@/assets/img/login/male.png" + alt=""> + <p>学生端</p> + </li> + <li :class="{active: selectedRole === 2}" + @click="selectRole(2)"> + <img src="@/assets/img/login/female.png" + alt=""> + <p>教师管理端</p> + </li> + </ul> + </el-dialog> + <el-dialog title="请选择您要登录的用户" + :visible.sync="userVisible" + :close-on-click-modal="false" + custom-class="user-dia" + width="500px"> + <p class="tips">该手机号已绑定以下用户信息</p> + <ul class="users"> + <li :class="{isEnable: !user.isEnable}" + v-for="(user, i) in users" + :key="i" + @click="chooseUser(user)"> + <span>{{ user.schoolName }},{{ user.userName }},{{ user.workNumber }}{{ user.isEnable ? '' : '(已禁用)'}}</span> + <i class="el-icon-right"></i> + </li> + </ul> + </el-dialog> + <el-dialog :visible.sync="infoVisible" + :close-on-click-modal="false" + custom-class="info-dia" + :show-close="false" + width="400px"> + <div class="info-header"> + <i class="el-icon-warning"></i> + 提示 + </div> + <div class="info-wrap"> + <p class="tips">该手机号已与以下用户绑定</p> + <ul class="users"> + <li v-for="(user, i) in infos" + :key="i"> + <span>{{ user.userName }}({{ user.schoolName }})</span> + </li> + </ul> + <div class="info-footer"> + <el-button size="small" + type="primary" + @click="bindPhone">是本人,继续绑定</el-button> + <el-button class="unbind" + size="small" + @click="unbindPhone">不是本人,解绑以上用户并绑定新用户</el-button> + </div> + </div> + </el-dialog> + <!-- 购买弹框 --> + <el-dialog title="温馨提示" + :visible.sync="buyVisible" + width="400px" + center + :close-on-click-modal="false"> + <div class="buy"> + <p class="tips">您所选择的院校暂未在本平台开通组织账号,请通知院校老师联系下方二维码客服咨询。</p> + <img src="@/assets/img/wechat-code.jpeg" + alt=""> + </div> + </el-dialog> + + <el-dialog title="账号申请" + :visible.sync="accountVisible" + :close-on-click-modal="false" + width="500px" + @close="accountClose"> + <el-form class="dia-form" + ref="accountForm" + label-width="110px" + :model="accountForm" + :rules="accountRules"> + <el-form-item prop="schoolId" + label="所属院校"> + <el-select class="w-100" + v-model="accountForm.schoolId" + filterable + placeholder="请选择院校" + @change="schoolChange"> + <el-option v-for="(item, i) in schoolList" + :key="i" + :label="item.schoolName" + :value="item.schoolId"></el-option> + </el-select> + </el-form-item> + <el-form-item prop="workNumber" + label="学号"> + <el-input placeholder="申请后无法修改,请确认填写正确" + v-model="accountForm.workNumber" + @change="workNumberChange"></el-input> + </el-form-item> + <el-form-item prop="userName" + label="姓名"> + <el-input placeholder="请输入姓名" + v-model="accountForm.userName" + :disabled="formEnable"></el-input> + </el-form-item> + <el-form-item prop="phone" + label="手机号"> + <el-input placeholder="请输入手机号" + maxlength="11" + v-model.trim="accountForm.phone" + :disabled="formEnable"></el-input> + </el-form-item> + <el-form-item prop="code" + label="验证码"> + <div class="ver-code"> + <el-input v-model="accountForm.code" + placeholder="请输入验证码" + maxlength="6" + :disabled="formEnable"></el-input> + <el-button style="top: 1px" + type="text" + @click="sendCode" + :disabled="phoneDisabled && formEnable">{{ phoneBtnText }} + </el-button> + </div> + </el-form-item> + <el-form-item prop="password" + label="登录密码"> + <el-input placeholder="请输入登录密码" + type="password" + maxlength="6" + v-model="accountForm.password" + :disabled="formEnable"></el-input> + </el-form-item> + <el-form-item prop="rePassword" + label="确认登录密码"> + <el-input placeholder="请再次输入登录密码" + type="password" + maxlength="6" + v-model="accountForm.rePassword" + :disabled="formEnable"></el-input> + </el-form-item> + </el-form> + <span slot="footer" + class="dialog-footer"> + <el-button v-if="!formEnable" + size="small" + type="primary" + @click="accountSubmit">申请</el-button> + <el-button size="small" + @click="accountVisible = false">取消</el-button> + </span> + </el-dialog> + <v-footer ref="footer"></v-footer> + </div> </template> <script> @@ -194,634 +322,634 @@ import Setting from "@/setting"; import axios from "axios" import { Loading } from 'element-ui' export default { - data: function() { - const workNumberPass = (rule, value, callback) => { - const val = this.accountForm.workNumber - if (val === '') { - callback(new Error('请输入学号')) - } else { - const pattern = /^[A-Za-z0-9]*$/ - if(pattern.test(val)){ - callback() - }else{ - callback(new Error('请输入正确学号格式')) - } - } + data: function () { + const workNumberPass = (rule, value, callback) => { + const val = this.accountForm.workNumber + if (val === '') { + callback(new Error('请输入学号')) + } else { + const pattern = /^[A-Za-z0-9]*$/ + if (pattern.test(val)) { + callback() + } else { + callback(new Error('请输入正确学号格式')) } - const phonePass = (rule, value, callback) => { - const val = this.accountForm.phone - if (val === '') { - callback(new Error('请输入手机号')) - } else { - const pattern = /^1[3456789]\d{9}$/ - if(pattern.test(val)){ - callback() - }else{ - callback(new Error('请输入正确手机号格式')) - } - } + } + } + const phonePass = (rule, value, callback) => { + const val = this.accountForm.phone + if (val === '') { + callback(new Error('请输入手机号')) + } else { + const pattern = /^1[3456789]\d{9}$/ + if (pattern.test(val)) { + callback() + } else { + callback(new Error('请输入正确手机号格式')) } - return { - tabList: [ - { - id: 0, - label: '学号/工号登录' - }, { - id: 1, - label: '学校管理员登录' - }, { - id: 2, - label: '手机号/邮箱' - } - ], - setDefault: !!util.local.get('schoolId'), // 本地缓存里有学校id,则默认勾选 - verificationIMG: '', - schoolList: [], - form: { - schoolId: '', - workNumber: '', - account: '', - password: '', - code: '', // 验证码 - random: '', // 随机数 - distinguish: 0, // 区分手机号账号登录,1为账号登录,2为手机号或邮箱登录 - type: 1, // 平台端区分:0->教师端 1->学生端 2->无端 - platform: Setting.platformId - }, - rules: { - schoolId: [{ required: true, message: "请选择学校", trigger: "change" }], - workNumber: [{ required: true, message: "请输入学生学号", trigger: "blur" }], - account: [{ required: false, message: "请输入账号", trigger: "blur" }], - password: [{ required: true, message: "请输入密码", trigger: "blur" }], - code: [{ required: true, message: "请输入验证码", trigger: "blur" }] - }, - phoneDisabledLogin: false, - phoneTimerLogin: null, - phoneBtnTextLogin: '发送验证码', + } + } + return { + tabList: [ + { + id: 0, + label: '学号/工号登录' + }, { + id: 1, + label: '学校管理员登录' + }, { + id: 2, + label: '手机号/邮箱' + } + ], + setDefault: !!util.local.get('schoolId'), // 本地缓存里有学校id,则默认勾选 + verificationIMG: '', + schoolList: [], + form: { + schoolId: '', + workNumber: '', + account: '', + password: '', + code: '', // 验证码 + random: '', // 随机数 + distinguish: 0, // 区分手机号账号登录,1为账号登录,2为手机号或邮箱登录 + type: 1, // 平台端区分:0->教师端 1->学生端 2->无端 + platform: Setting.platformId + }, + rules: { + schoolId: [{ required: true, message: "请选择学校", trigger: "change" }], + workNumber: [{ required: true, message: "请输入学生学号", trigger: "blur" }], + account: [{ required: false, message: "请输入账号", trigger: "blur" }], + password: [{ required: true, message: "请输入密码", trigger: "blur" }], + code: [{ required: true, message: "请输入验证码", trigger: "blur" }] + }, + phoneDisabledLogin: false, + phoneTimerLogin: null, + phoneBtnTextLogin: '发送验证码', - phoneVisible: false, - phone: '', - phoneCode: '', - phoneDisabled: false, - phoneTimer: null, - phoneOpener: '', - phoneBtnText: '发送验证码', - selectVisible: false, - selectedRole: '', - token: '', - userVisible: false, - users: [], - accountIds: [], - binding: '', - infoVisible: false, - infos: [], + phoneVisible: false, + phone: '', + phoneCode: '', + phoneDisabled: false, + phoneTimer: null, + phoneOpener: '', + phoneBtnText: '发送验证码', + selectVisible: false, + selectedRole: '', + token: '', + userVisible: false, + users: [], + accountIds: [], + binding: '', + infoVisible: false, + infos: [], - accountVisible: false, - formEnable: true, - accountForm: { - schoolId: '', - account: '', - code: '', - password: '', - rePassword: '', - phone: '', - userName: '', - workNumber: '', - uniqueIdentification: Date.now() - }, - accountRules: { - schoolId: [{ required: true, message: "请选择所属院校", trigger: "change" }], - userName: [{ required: true, message: "请输入姓名", trigger: "blur" }], - workNumber: [{ required: true, validator: workNumberPass, trigger: "blur" }], - phone: [{ required: true, validator: phonePass, trigger: "blur" }], - password: [{ required: true, message: "请输入密码", trigger: "blur" }], - rePassword: [{ required: true, message: "请再次输入密码", trigger: "blur" }], - code: [{ required: true, message: "请输入验证码", trigger: "blur" }] - }, - buyVisible: false - }; + accountVisible: false, + formEnable: true, + accountForm: { + schoolId: '', + account: '', + code: '', + password: '', + rePassword: '', + phone: '', + userName: '', + workNumber: '', + uniqueIdentification: Date.now() + }, + accountRules: { + schoolId: [{ required: true, message: "请选择所属院校", trigger: "change" }], + userName: [{ required: true, message: "请输入姓名", trigger: "blur" }], + workNumber: [{ required: true, validator: workNumberPass, trigger: "blur" }], + phone: [{ required: true, validator: phonePass, trigger: "blur" }], + password: [{ required: true, message: "请输入密码", trigger: "blur" }], + rePassword: [{ required: true, message: "请再次输入密码", trigger: "blur" }], + code: [{ required: true, message: "请输入验证码", trigger: "blur" }] + }, + buyVisible: false + }; + }, + computed: { + ...mapState('match', [ + 'toMatch' + ]), + ...mapState('project', [ + 'courseId' + ]) + }, + components: { + vFooter + }, + mounted () { + this.getVerImg() + this.getSchool() + // 页面离开的时候销毁手机和邮箱验证码定时器 + this.$once("hook:beforeDestroy", function () { + clearInterval(this.phoneTimer) + clearInterval(this.phoneTimerLogin) + this.phoneTimer = null + this.phoneTimerLogin = null + }) + }, + methods: { + ...mapMutations("user", [ + 'SET_CUSTOMERNAME' + ]), + ...mapActions("user", [ + "setInfo" + ]), + ...mapMutations('match', [ + 'SET_SOURCE' + ]), + // 赋值学校列表及id + setSchool (list) { + this.schoolList = list + // 取本地缓存里的学校id + const schoolId = util.local.get('schoolId') + if (schoolId) this.form.schoolId = schoolId }, - computed: { - ...mapState('match', [ - 'toMatch' - ]), - ...mapState('project', [ - 'courseId' - ]) + // 获取学校列表 + getSchool () { + this.$get(this.api.querySchool, { + provinceId: '', + cityId: '' + }).then(({ list }) => { + this.setSchool(list) + }).catch(res => { }) }, - components: { - vFooter + getVerImg () { // 获取验证码图片 + this.form.random = Math.floor(Math.random() * 999999999); + this.verificationIMG = this.api.verification + "?random=" + `${this.form.random}`; }, - mounted() { - this.getVerImg() - this.getSchool() - // 页面离开的时候销毁手机和邮箱验证码定时器 - this.$once("hook:beforeDestroy", function() { - clearInterval(this.phoneTimer) - clearInterval(this.phoneTimerLogin) - this.phoneTimer = null - this.phoneTimerLogin = null - }) + // 切换标签 + typeClick (tab) { + const { id } = tab + const form = this.form + // 切换了后,全部字段重置 + this.form = { + schoolId: form.schoolId, + workNumber: '', + account: '', + password: '', + code: '', + random: form.random, + distinguish: id, + type: 1, + platform: form.platform + } + this.$refs.form.clearValidate() + // 切换了登录方式后,校验规则要变化 + const rules = this.rules + rules.schoolId[0].required = id === 0 + rules.workNumber[0].required = id === 0 + rules.account[0].required = !!id + this.rules.account[0].message = id === 1 ? + '请输入账号' : + '请输入手机号/邮箱' }, - methods: { - ...mapMutations("user", [ - 'SET_CUSTOMERNAME' - ]), - ...mapActions("user", [ - "setInfo" - ]), - ...mapMutations('match', [ - 'SET_SOURCE' - ]), - // 赋值学校列表及id - setSchool(list) { - this.schoolList = list - // 取本地缓存里的学校id - const schoolId = util.local.get('schoolId') - if (schoolId) this.form.schoolId = schoolId - }, - // 获取学校列表 - getSchool() { - this.$get(this.api.querySchool, { - provinceId: '', - cityId: '' - }).then(({ list }) => { - this.setSchool(list) - }).catch(res => {}) - }, - getVerImg() { // 获取验证码图片 - this.form.random = Math.floor(Math.random() * 999999999); - this.verificationIMG = this.api.verification + "?random=" + `${this.form.random}`; - }, - // 切换标签 - typeClick(tab) { - const { id } = tab - const form = this.form - // 切换了后,全部字段重置 - this.form = { - schoolId: form.schoolId, - workNumber: '', - account: '', - password: '', - code: '', - random: form.random, - distinguish: id, - type: 1, - platform: form.platform - } - this.$refs.form.clearValidate() - // 切换了登录方式后,校验规则要变化 - const rules = this.rules - rules.schoolId[0].required = id === 0 - rules.workNumber[0].required = id === 0 - rules.account[0].required = !!id - this.rules.account[0].message = id === 1 ? - '请输入账号' : - '请输入手机号/邮箱' - }, - // 学号工号切换 - typeChange(id) { - this.rules.workNumber[0].message = id === 1 ? - '请输入学生学号' : - '请输入老师工号' - }, - // 刷新官网 - reloadIndex() { - try { - window.opener && window.opener.location.reload() - } catch(e) {} - }, - // 选择用户回调 - chooseUser(user) { - user.isEnable && this.$post(`${this.api.getToken}?id=${user.id}`).then(({ data }) => { - this.queryClient(data.token) - }).catch(res => {}) - }, - // 查询是否是客户,如果是客户,则弹出选择端的页面去选择跳转到哪个端 - queryClient(token) { - this.token = token - axios.get(this.api.isClient, { - headers: { - token - } - }).then(({ data }) => { - // 如果是客户 - if (data.customer) { - this.SET_CUSTOMERNAME(data.customerName) - this.selectVisible = true + // 学号工号切换 + typeChange (id) { + this.rules.workNumber[0].message = id === 1 ? + '请输入学生学号' : + '请输入老师工号' + }, + // 刷新官网 + reloadIndex () { + try { + window.opener && window.opener.location.reload() + } catch (e) { } + }, + // 选择用户回调 + chooseUser (user) { + user.isEnable && this.$post(`${this.api.getToken}?id=${user.id}`).then(({ data }) => { + this.queryClient(data.token) + }).catch(res => { }) + }, + // 查询是否是客户,如果是客户,则弹出选择端的页面去选择跳转到哪个端 + queryClient (token) { + this.token = token + axios.get(this.api.isClient, { + headers: { + token + } + }).then(({ data }) => { + // 如果是客户 + if (data.customer) { + this.SET_CUSTOMERNAME(data.customerName) + this.selectVisible = true + } else { + this.form.type ? this.setLogin() : this.toMang() + } + }).catch(res => { }) + }, + // 处理登录成功 + setLogin () { + util.local.set(Setting.tokenKey, this.token, Setting.tokenExpires) + util.cookies.remove('serverLogin') + this.reloadIndex() + util.successMsg('登录成功') + const { toMatch } = this + this.SET_SOURCE('') + this.$router.replace(this.courseId ? + `/preCourse/details?id=${this.courseId}` : + toMatch ? + `/touristMatch/details?id=` + toMatch : + '/station') + }, + // 提交登录 + submit () { + this.$refs.form.validate(valid => { + if (valid) { + const form = JSON.parse(JSON.stringify(this.form)) + const { distinguish } = form + if (!form.distinguish && this.setDefault) util.local.set('schoolId', form.schoolId) // 选的是学号工号登录,并且勾选了默认,则存入缓存 + if (util.local.get('schoolId') && !this.setDefault) util.local.remove('schoolId') // 本地缓存了学校id,并且没有勾选默认,则删除缓存 + if (distinguish) form.schoolId = '' + if (!distinguish) form.distinguish = 1 + this.$post(this.api.logins, form).then(({ status, data, message }) => { + // 未绑定手机号,则弹框去绑定 + if (status == 30001) { + this.phoneVisible = true + this.getVerImg() + form.code = '' + } else if (status == 200) { + const accounts = data.userAccounts + // 如果返回的是数组,则弹框给用户选择登录哪个用户,否则,直接登录 + if (accounts instanceof Array) { + // 如果只查询到一个用户,则直接登录,否则,弹框让用户选择 + if (accounts.length === 1) { + this.chooseUser(accounts[0]) + } else { + this.users = accounts + this.userVisible = true + } + } else { + this.queryClient(data.token) + } } else { - this.form.type ? this.setLogin() : this.toMang() + util.errorMsg(message) } - }).catch(res => {}) - }, - // 处理登录成功 - setLogin() { - util.local.set(Setting.tokenKey, this.token, Setting.tokenExpires) - util.cookies.remove('serverLogin') - this.reloadIndex() - util.successMsg('登录成功') - const { toMatch } = this - this.SET_SOURCE('') - this.$router.replace(this.courseId ? - `/preCourse/details?id=${this.courseId}` : - toMatch ? - `/touristMatch/details?id=` + toMatch : - '/station') - }, - // 提交登录 - submit() { - this.$refs.form.validate(valid => { - if (valid) { - const form = JSON.parse(JSON.stringify(this.form)) - const { distinguish } = form - if (!form.distinguish && this.setDefault) util.local.set('schoolId', form.schoolId) // 选的是学号工号登录,并且勾选了默认,则存入缓存 - if (util.local.get('schoolId') && !this.setDefault) util.local.remove('schoolId') // 本地缓存了学校id,并且没有勾选默认,则删除缓存 - if (distinguish) form.schoolId = '' - if (!distinguish) form.distinguish = 1 - this.$post(this.api.logins, form).then(({ status, data, message }) => { - // 未绑定手机号,则弹框去绑定 - if (status == 30001) { - this.phoneVisible = true - this.getVerImg() - form.code = '' - } else if (status == 200) { - const accounts = data.userAccounts - // 如果返回的是数组,则弹框给用户选择登录哪个用户,否则,直接登录 - if (accounts instanceof Array) { - // 如果只查询到一个用户,则直接登录,否则,弹框让用户选择 - if (accounts.length === 1) { - this.chooseUser(accounts[0]) - } else { - this.users = accounts - this.userVisible = true - } - } else { - this.queryClient(data.token) - } - } else { - util.errorMsg(message) - } - }).catch(res => { - this.getVerImg() - form.code = '' - }) - } - }); - }, - // 跳转到教师端 - toMang() { - const { token } = this - util.local.set('oc_server_token', token, Setting.tokenExpires) - // 从学生端登录到教师端的标识,教师端需要使用 - util.cookies.set('serverLogin', true, { - expires: new Date(Date.now() + 15 * 60 * 1000) // 15分钟后过期 + }).catch(res => { + this.getVerImg() + form.code = '' }) - axios.get(this.api.isClient, { + } + }); + }, + // 跳转到教师端 + toMang () { + const { token } = this + util.local.set('oc_server_token', token, Setting.tokenExpires) + // 从学生端登录到教师端的标识,教师端需要使用 + util.cookies.set('serverLogin', true, { + expires: new Date(Date.now() + 15 * 60 * 1000) // 15分钟后过期 + }) + axios.get(this.api.isClient, { + headers: { + token + } + }).then(({ data }) => { + // 如果是客户 + if (data.customerName) { + util.cookies.set('customerName', data.customerName) + } else { + // 查询姓名 + axios.get(Setting.apiBaseURL + this.api.queryUserInfoDetails, { headers: { - token + token: this.token } }).then(({ data }) => { - // 如果是客户 - if (data.customerName) { - util.cookies.set('customerName', data.customerName) - } else { - // 查询姓名 - axios.get(Setting.apiBaseURL + this.api.queryUserInfoDetails, { - headers: { - token: this.token - } - }).then(({ data }) => { - this.SET_CUSTOMERNAME(data.result.hrUserInfo.userName) - util.cookies.set('customerName', data.result.hrUserInfo.userName) - }).catch(err => {}) - } - - this.reloadIndex() - // if (this.courseId) { - // this.$router.replace(`/preCourse/details?id=${this.courseId}`) - // } else if (this.toMatch) { - // this.$router.replace(`/touristMatch`) - // } else { - // 跳转到教师端的重定向页面 - location.href = Setting.isDev ? - `http://${location.hostname}:8081/#/redirect?auth=${btoa(this.token)}` : - `${location.origin}/admin/#/redirect?auth=${window.btoa(this.token)}` - // } - }).catch(res => {}) - }, - // 选择端 - selectRole(val) { - this.selectedRole = val - if (val === 1) { - this.setLogin() - } else { - this.toMang() - } - }, - // 验证手机号 - verifyPhone(phone) { - if (!phone) { - this.$message.error("请输入手机号") - return false - } - if (!/^1[3456789]\d{9}$/.test(phone) && !/^([a-zA-Z]|[0-9])(\w|\-)+@[a-zA-Z0-9]+\.([a-zA-Z]{2,4})$/.test(phone)) { - this.$message.error("请输入正确的手机号/邮箱") - return false - } - return true - }, - - // 账号申请 - toAccount() { - this.accountVisible = true - }, - // 学号输入完回调。学校和学号都输入完后,调这个接口查询是否有存在的学生,如果没有,才能继续输入,如果有,不让添加 - workNumberChange() { + this.SET_CUSTOMERNAME(data.result.hrUserInfo.userName) + util.cookies.set('customerName', data.result.hrUserInfo.userName) + }).catch(err => { }) + } + + this.reloadIndex() + // if (this.courseId) { + // this.$router.replace(`/preCourse/details?id=${this.courseId}`) + // } else if (this.toMatch) { + // this.$router.replace(`/touristMatch`) + // } else { + // 跳转到教师端的重定向页面 + location.href = Setting.isDev ? + `http://${location.hostname}:8081/#/redirect?auth=${btoa(this.token)}` : + `${location.origin}/admin/#/redirect?auth=${window.btoa(this.token)}` + // } + }).catch(res => { }) + }, + // 选择端 + selectRole (val) { + this.selectedRole = val + if (val === 1) { + this.setLogin() + } else { + this.toMang() + } + }, + // 验证手机号 + verifyPhone (phone) { + if (!phone) { + this.$message.error("请输入手机号") + return false + } + if (!/^1[3456789]\d{9}$/.test(phone) && !/^([a-zA-Z]|[0-9])(\w|\-)+@[a-zA-Z0-9]+\.([a-zA-Z]{2,4})$/.test(phone)) { + this.$message.error("请输入正确的手机号/邮箱") + return false + } + return true + }, + + // 账号申请 + toAccount () { + this.accountVisible = true + }, + // 学号输入完回调。学校和学号都输入完后,调这个接口查询是否有存在的学生,如果没有,才能继续输入,如果有,不让添加 + workNumberChange () { + const form = this.accountForm + form.schoolId && form.workNumber && this.$get(`${this.api.enquireAboutSchoolStudents}?schoolId=${form.schoolId}&workNumber=${form.workNumber}&applyFor=1`).then(({ account }) => { + if (account) this.form = account + this.formEnable = !!account + }).catch(res => { + this.formEnable = true + }) + }, + // 学校选择回调 + schoolChange (schoolId) { + this.$get(this.api.getCustomerBySchoolId, { + schoolId + }).then(res => { + if (!res) { + this.accountVisible = false + this.buyVisible = true + } + }).catch(res => { }) + }, + // 发送验证码 + sendCode () { + const { phone } = this.accountForm + // 校验用户手机号是否存在 + phone && this.$get(`${this.api.checkPhoneOrEmailExist}?phone=${phone}&type=1&email=`).then(res => { + if (res) return util.errorMsg('手机号已存在,请更换手机号!') + if (!this.verifyPhone(phone)) return false + this.$post(`${this.api.sendPhoneVerificationCode}?phoneOrEmail=${phone}&loginOrBind=1&platform=${Setting.platformId}`).then(({ message }) => { + util.successMsg(message) + this.phoneCountdown() + }).catch(res => { }) + }).catch(res => { }) + }, + // 账号申请提交 + accountSubmit () { + this.$refs.accountForm.validate(valid => { + if (valid) { const form = this.accountForm - form.schoolId && form.workNumber && this.$get(`${this.api.enquireAboutSchoolStudents}?schoolId=${form.schoolId}&workNumber=${form.workNumber}&applyFor=1`).then(({ account }) => { - if (account) this.form = account - this.formEnable = !!account - }).catch(res => { - this.formEnable = true - }) - }, - // 学校选择回调 - schoolChange(schoolId) { - this.$get(this.api.getCustomerBySchoolId, { - schoolId - }).then(res => { - if (!res) { - this.accountVisible = false - this.buyVisible = true - } - }).catch(res => {}) - }, - // 发送验证码 - sendCode() { - const { phone } = this.accountForm - // 校验用户手机号是否存在 - phone && this.$get(`${this.api.checkPhoneOrEmailExist}?phone=${phone}&type=1&email=`).then(res => { - if (res) return util.errorMsg('手机号已存在,请更换手机号!') - if (!this.verifyPhone(phone)) return false - this.$post(`${this.api.sendPhoneVerificationCode}?phoneOrEmail=${phone}&loginOrBind=1&platform=${Setting.platformId}`).then(({ message }) => { - util.successMsg(message) - this.phoneCountdown() - }).catch(res => {}) - }).catch(res => {}) - }, - // 账号申请提交 - accountSubmit() { - this.$refs.accountForm.validate(valid => { - if (valid) { - const form = this.accountForm - if (form.password !== form.rePassword) return util.errorMsg('两次输入的密码不一致,请重新输入!') - // 平台id-端id-schoolId-workNumber组成账号 - form.account = `${Setting.platformId}-1-${form.schoolId}-${form.workNumber}` - this.$post(this.api.studentAccountApplication, form).then(res => { - this.accountVisible = false - util.successMsg('账号申请已提交,需管理员审核,请10分钟后再登录') - }).catch(res => {}) - } - }) - }, - // 账号申请关闭 - accountClose() { - this.accountForm = { - schoolId: '', - account: '', - code: '', - password: '', - rePassword: '', - phone: '', - userName: '', - workNumber: '', - uniqueIdentification: Date.now() - } - }, - - // 验证码倒计时 - phoneCountdownLogin() { - let count = 60 - if (!this.phoneTimerLogin) { - this.phoneDisabledLogin = true - this.phoneTimerLogin = setInterval(() => { - if (count > 0) { - count-- - this.phoneBtnTextLogin = `${count}秒后重试` - } else { - this.phoneDisabledLogin = false - clearInterval(this.phoneTimerLogin) - this.phoneTimerLogin = null - this.phoneBtnTextLogin = `发送验证码` - } - }, 1000) + if (form.password !== form.rePassword) return util.errorMsg('两次输入的密码不一致,请重新输入!') + // 平台id-端id-schoolId-workNumber组成账号 + form.account = `${Setting.platformId}-1-${form.schoolId}-${form.workNumber}` + this.$post(this.api.studentAccountApplication, form).then(res => { + this.accountVisible = false + util.successMsg('账号申请已提交,需管理员审核,请10分钟后再登录') + }).catch(res => { }) + } + }) + }, + // 账号申请关闭 + accountClose () { + this.accountForm = { + schoolId: '', + account: '', + code: '', + password: '', + rePassword: '', + phone: '', + userName: '', + workNumber: '', + uniqueIdentification: Date.now() + } + }, + + // 验证码倒计时 + phoneCountdownLogin () { + let count = 60 + if (!this.phoneTimerLogin) { + this.phoneDisabledLogin = true + this.phoneTimerLogin = setInterval(() => { + if (count > 0) { + count-- + this.phoneBtnTextLogin = `${count}秒后重试` + } else { + this.phoneDisabledLogin = false + clearInterval(this.phoneTimerLogin) + this.phoneTimerLogin = null + this.phoneBtnTextLogin = `发送验证码` } - }, - // 发送验证码 - sendPhoneCodeLogin() { - const phone = this.form.account - if (!this.verifyPhone(phone)) return false - this.$post(`${this.api.sendPhoneVerificationCode}?phoneOrEmail=${phone}&loginOrBind=0&platform=${Setting.platformId}`).then(({ message }) => { - util.successMsg(message) - this.phoneCountdownLogin() - }).catch(res => {}) - }, - // 继续绑定 - bindPhone() { - this.infoVisible = false + }, 1000) + } + }, + // 发送验证码 + sendPhoneCodeLogin () { + const phone = this.form.account + if (!this.verifyPhone(phone)) return false + this.$post(`${this.api.sendPhoneVerificationCode}?phoneOrEmail=${phone}&loginOrBind=0&platform=${Setting.platformId}`).then(({ message }) => { + util.successMsg(message) + this.phoneCountdownLogin() + }).catch(res => { }) + }, + // 继续绑定 + bindPhone () { + this.infoVisible = false + this.binding = true + this.sendPhoneCode(1) + }, + // 解除绑定 + unbindPhone () { + this.infoVisible = false + this.binding = false + this.sendPhoneCode(0) + }, + // 手机号失去焦点回调 + phoneChange () { + this.$post(`${this.api.getOtherAccountByPhone}?phone=${this.phone}&platform=${Setting.platformId}`).then(({ userAccounts }) => { + const list = userAccounts + if (list) { + list.map(e => { + const { userName } = e + if (userName.length > 1) e.userName = userName[0] + '*' + userName.substring(2) + }) + this.infos = list + this.accountIds = list.map(e => e.id) + this.infoVisible = true + } else { this.binding = true - this.sendPhoneCode(1) - }, - // 解除绑定 - unbindPhone() { - this.infoVisible = false - this.binding = false - this.sendPhoneCode(0) - }, - // 手机号失去焦点回调 - phoneChange() { - this.$post(`${this.api.getOtherAccountByPhone}?phone=${this.phone}&platform=${Setting.platformId}`).then(({ userAccounts }) => { - const list = userAccounts - if (list) { - list.map(e => { - const { userName } = e - if (userName.length > 1) e.userName = userName[0] + '*' + userName.substring(2) - }) - this.infos = list - this.accountIds = list.map(e => e.id) - this.infoVisible = true - } else { - this.binding = true - } - }).catch(res => {}) - }, - // 验证码倒计时 - phoneCountdown() { - let count = 60 - if (!this.phoneTimer) { - this.phoneDisabled = true - this.phoneTimer = setInterval(() => { - if (count > 0) { - count-- - this.phoneBtnText = `${count}秒后重试` - } else { - this.phoneDisabled = false - clearInterval(this.phoneTimer) - this.phoneTimer = null - this.phoneBtnText = `发送验证码` - } - }, 1000) - } - }, - // 发送验证码 - sendPhoneCode(bind) { - const { phone } = this - if (!this.verifyPhone(phone)) return false - // 不解绑发送验证码 - if (bind) { - this.$post(this.api.sendPhoneOrEmailCode, { - platform: Setting.platformId, - phone, - types: 2 - }).then(({ message }) => { - if (message.opener) { - this.phoneCountdown() - this.phoneOpener = message.opener - } else { - util.errorMsg(message) - } - }).catch(res => {}) + } + }).catch(res => { }) + }, + // 验证码倒计时 + phoneCountdown () { + let count = 60 + if (!this.phoneTimer) { + this.phoneDisabled = true + this.phoneTimer = setInterval(() => { + if (count > 0) { + count-- + this.phoneBtnText = `${count}秒后重试` } else { - this.$post(`${this.api.sendPhoneVerificationCode}?phoneOrEmail=${phone}&loginOrBind=1&platform=${Setting.platformId}`).then(({ message }) => { - util.successMsg(message) - this.phoneCountdown() - }).catch(res => {}) + this.phoneDisabled = false + clearInterval(this.phoneTimer) + this.phoneTimer = null + this.phoneBtnText = `发送验证码` } - }, - // 解绑 - unbind() { - const { password, platform, schoolId, type, workNumber } = this.form - this.$post(this.api.unbindAccounts, { - accountIds: this.accountIds, - code: this.phoneCode, - password, - phone: this.phone, - platform, - schoolId, - type, - workNumber, - }).then(({ data }) => { - this.token = data.token - this.setLogin() - }).catch(res => {}) - }, - // 绑定手机号 - phoneSubmit() { - const { phone, phoneCode } = this - if (!this.verifyPhone(phone)) return false - if (!phoneCode) return util.warningMsg('请输入验证码') - const { workNumber, schoolId } = this.form - if (this.binding) { - this.$post(this.api.bindPhoneOrEmail, { - mark: this.form.type, - phone, - types: 2, - code: phoneCode, - opener: this.phoneOpener, - platform: Setting.platformId, - account: workNumber, - schoolId - }).then(({ token }) => { - this.token = token - this.setLogin() - }).catch(res => {}) + }, 1000) + } + }, + // 发送验证码 + sendPhoneCode (bind) { + const { phone } = this + if (!this.verifyPhone(phone)) return false + // 不解绑发送验证码 + if (bind) { + this.$post(this.api.sendPhoneOrEmailCode, { + platform: Setting.platformId, + phone, + types: 2 + }).then(({ message }) => { + if (message.opener) { + this.phoneCountdown() + this.phoneOpener = message.opener } else { - this.unbind() + util.errorMsg(message) } - } + }).catch(res => { }) + } else { + this.$post(`${this.api.sendPhoneVerificationCode}?phoneOrEmail=${phone}&loginOrBind=1&platform=${Setting.platformId}`).then(({ message }) => { + util.successMsg(message) + this.phoneCountdown() + }).catch(res => { }) + } + }, + // 解绑 + unbind () { + const { password, platform, schoolId, type, workNumber } = this.form + this.$post(this.api.unbindAccounts, { + accountIds: this.accountIds, + code: this.phoneCode, + password, + phone: this.phone, + platform, + schoolId, + type, + workNumber, + }).then(({ data }) => { + this.token = data.token + this.setLogin() + }).catch(res => { }) + }, + // 绑定手机号 + phoneSubmit () { + const { phone, phoneCode } = this + if (!this.verifyPhone(phone)) return false + if (!phoneCode) return util.warningMsg('请输入验证码') + const { workNumber, schoolId } = this.form + if (this.binding) { + this.$post(this.api.bindPhoneOrEmail, { + mark: this.form.type, + phone, + types: 2, + code: phoneCode, + opener: this.phoneOpener, + platform: Setting.platformId, + account: workNumber, + schoolId + }).then(({ token }) => { + this.token = token + this.setLogin() + }).catch(res => { }) + } else { + this.unbind() + } } + } }; </script> <style scoped lang="scss"> .wrap { min-height: 100%; - background-color: #F3F6FA; + background-color: #f3f6fa; } .ver-code { - position: relative; - .el-button { - position: absolute; - top: 10px; - right: 10px; - } + position: relative; + .el-button { + position: absolute; + top: 10px; + right: 10px; + } } -.login{ +.login { min-height: calc(100vh - 43px); padding-top: calc((100vh - 584px) / 2); - background: url(../../../assets/img/shapes/shape1.png) (0 123px)/auto no-repeat, - url(../../../assets/img/shapes/shape2.png) (35px 238px)/auto no-repeat, - url(../../../assets/img/shapes/shape3.png) (0 485px)/auto no-repeat, - url(../../../assets/img/shapes/shape4.png) (right 50%)/auto no-repeat, - url(../../../assets/img/shapes/shape5.png) (right 80%)/auto no-repeat, - url(../../../assets/img/shapes/shape6.png) (right bottom)/auto no-repeat; - .tab{ + background: url(../../../assets/img/shapes/shape1.png) (0 123px) / auto no-repeat, + url(../../../assets/img/shapes/shape2.png) (35px 238px) / auto no-repeat, + url(../../../assets/img/shapes/shape3.png) (0 485px) / auto no-repeat, + url(../../../assets/img/shapes/shape4.png) (right 50%) / auto no-repeat, + url(../../../assets/img/shapes/shape5.png) (right 80%) / auto no-repeat, + url(../../../assets/img/shapes/shape6.png) (right bottom) / auto no-repeat; + .tab { display: flex; justify-content: space-between; align-items: center; margin-bottom: 24px; - border-bottom: 2px solid #E1E6F2; - li{ + border-bottom: 2px solid #e1e6f2; + li { padding: 18px 0; margin-bottom: -1px; font-size: 16px; color: #555; cursor: pointer; border-bottom: 4px solid transparent; - &:last-child{ + &:last-child { margin-right: 0; } - &.active{ - color: $main-color;; + &.active { + color: $main-color; border-bottom-color: $main-color; } } } .items { - display: flex; - align-items: center; + display: flex; + align-items: center; } - .form{ + .form { width: 436px; padding: 38px 38px 60px; margin: 0 auto 0; border-radius: 6px; background-color: #fff; - .title{ + .title { margin-bottom: 25px; font-size: 26px; - color: #0B1D30; + color: #0b1d30; letter-spacing: 4px; } } - /deep/.el-form-item{ + /deep/.el-form-item { margin-bottom: 20px; } - /deep/.el-input__inner{ + /deep/.el-input__inner { position: relative; height: 52px; padding: 0 20px 0 34px; line-height: 50px; - background-color: #FBFBFB; - border: 1px solid #E1E6F2; + background-color: #fbfbfb; + border: 1px solid #e1e6f2; border-radius: 4px !important; } .bottom { - display: flex; - justify-content: space-between; + display: flex; + justify-content: space-between; } .el-select { - width: 100%; + width: 100%; } .label { z-index: 1; @@ -832,33 +960,33 @@ export default { height: 18px; background: url(../../../assets/img/login/account.png) 0 0/100% 100% no-repeat; } - .school{ + .school { background-image: url(../../../assets/img/login/school.png); } - .workNumber{ + .workNumber { width: 17px; background-image: url(../../../assets/img/login/workNumber.png); } - .password{ + .password { top: 18px; background-image: url(../../../assets/img/login/password.png); } - .code{ + .code { top: 18px; background-image: url(../../../assets/img/login/code.png); } - .ver-img{ + .ver-img { position: absolute; top: 1px; right: 1px; } - /deep/.el-form-item__error{ + /deep/.el-form-item__error { top: 105%; left: auto; right: 0; - color: #FFA94E; + color: #ffa94e; } - .submit{ + .submit { width: 100%; height: 48px; margin-top: 30px; @@ -870,16 +998,16 @@ export default { border: 0; } } -.copyright{ +.copyright { padding: 18px 0; font-size: 12px; text-align: center; - background-color: #F3F6FA; - a{ - color:#B1B4B8; + background-color: #f3f6fa; + a { + color: #b1b4b8; font-size: 12px; - &:hover{ - opacity: .8; + &:hover { + opacity: 0.8; } } } @@ -894,9 +1022,10 @@ export default { margin-right: 86px; } &:hover img { - opacity: .9; + opacity: 0.9; } - &.active p, &:hover p { + &.active p, + &:hover p { background-color: #9278ff; } } @@ -917,101 +1046,101 @@ export default { margin-top: calc((100vh - 383px) / 2) !important; } /deep/.user-dia { - .tips { - margin-bottom: 20px; - text-align: center; - color: #666; - } - .users { - li { - display: flex; - justify-content: space-between; - align-items: center; - padding: 0 15px; - margin-bottom: 10px; - line-height: 40px; - font-size: 14px; - background-color: #ebeef5; - cursor: pointer; - &.isEnable { - color: #c0c4cc; - background-color: #f5f7fa; - cursor: not-allowed; - } - &:last-child { - margin-bottom: 0; - } - &:hover { - background-color: #d3e0ff; - } - i { - font-size: 16px; - } + .tips { + margin-bottom: 20px; + text-align: center; + color: #666; + } + .users { + li { + display: flex; + justify-content: space-between; + align-items: center; + padding: 0 15px; + margin-bottom: 10px; + line-height: 40px; + font-size: 14px; + background-color: #ebeef5; + cursor: pointer; + &.isEnable { + color: #c0c4cc; + background-color: #f5f7fa; + cursor: not-allowed; + } + &:last-child { + margin-bottom: 0; + } + &:hover { + background-color: #d3e0ff; + } + i { + font-size: 16px; + } + } } - } } /deep/.info-dia { - .el-dialog__header { - border-bottom: 0; - } - .info-header { - position: absolute; - top: 20px; - display: flex; - align-items: center; - font-size: 16px; - color: #333; - } - .el-icon-warning { - margin-right: 10px; - color: #e6a23c; - font-size: 24px; - } - .info-wrap { - padding: 10px 33px; - } - .users { - max-height: 125px; - margin-top: 20px; - overflow: auto; - li { - margin: 5px; - font-size: 14px; - color: #333; + .el-dialog__header { + border-bottom: 0; + } + .info-header { + position: absolute; + top: 20px; + display: flex; + align-items: center; + font-size: 16px; + color: #333; + } + .el-icon-warning { + margin-right: 10px; + color: #e6a23c; + font-size: 24px; + } + .info-wrap { + padding: 10px 33px; + } + .users { + max-height: 125px; + margin-top: 20px; + overflow: auto; + li { + margin: 5px; + font-size: 14px; + color: #333; + } + } + .info-footer { + display: flex; + justify-content: space-between; + margin-top: 20px; + } + .el-button { + width: 142px; + } + .unbind { + white-space: normal; + line-height: 1.6; } - } - .info-footer { - display: flex; - justify-content: space-between; - margin-top: 20px; - } - .el-button { - width: 142px; - } - .unbind { - white-space: normal; - line-height: 1.6; - } } /deep/.dia-form { - .w-100 { - width: 100%; - } - .tips { - display: flex; - justify-content: center; - align-items: center; - } + .w-100 { + width: 100%; + } + .tips { + display: flex; + justify-content: center; + align-items: center; + } } .buy { - text-align: center; - .tips { - margin-bottom: 10px; - font-size: 14px; - } - img { - width: 85%; - } + text-align: center; + .tips { + margin-bottom: 10px; + font-size: 14px; + } + img { + width: 85%; + } } @media (max-height: 680px) { .wrap .login { diff --git a/src/pages/activity/list/index.vue b/src/pages/activity/list/index.vue index f185775..611e7e5 100644 --- a/src/pages/activity/list/index.vue +++ b/src/pages/activity/list/index.vue @@ -1,99 +1,127 @@ <template> - <div class="wrap index"> - <div class="search"> - <h6>创业活动</h6> - <div class="input"> - <img src="@/assets/img/search.png" alt=""> - <input type="text" placeholder="请输入关键词" v-model="keyword"> - </div> - </div> + <div class="wrap index"> + <div class="search"> + <h6>创业活动</h6> + <div class="input"> + <img src="@/assets/img/search.png" + alt=""> + <input type="text" + placeholder="请输入关键词" + v-model="keyword"> + </div> + </div> - <div class="main"> - <div class="center-wrap list-inner"> - <ul v-if="token" class="nav"> - <li :class="{ active: form.whetherToSignUp === item.id }" v-for="(item, index) in typeList" :key="index" @click="changeType(item.id)">{{ item.name }} - </li> - </ul> - <div class="list-wrap"> - <!-- 课程筛选 --> - <div class="filter"> - <div> - <dl> - <dt>筛选排序:</dt> - <dd v-for="(item, i) in sorts" :key="i" :class="{active: form.filterSort == item.id}" @click="changeSort(item.id)">{{ item.name }}</dd> - </dl> - </div> - <el-button type="primary" @click="$router.push('manage')">我的项目</el-button> - </div> + <div class="main"> + <div class="center-wrap list-inner"> + <ul v-if="token" + class="nav"> + <li :class="{ active: form.whetherToSignUp === item.id }" + v-for="(item, index) in typeList" + :key="index" + @click="changeType(item.id)">{{ item.name }} + </li> + </ul> + <div class="list-wrap"> + <!-- 课程筛选 --> + <div class="filter"> + <div> + <dl> + <dt>筛选排序:</dt> + <dd v-for="(item, i) in sorts" + :key="i" + :class="{active: form.filterSort == item.id}" + @click="changeSort(item.id)">{{ item.name }}</dd> + </dl> + </div> + <el-button type="primary" + @click="$router.push('manage')">我的项目</el-button> + </div> - <div class="list"> - <template v-if="listData.length"> - <ul> - <li v-for="(item,index) in listData" :key="index" @click="toDetail(item)"> - <div class="left"> - <div class="cover"> - <img :src="item.coverUrl || 'https://huoran.oss-cn-shenzhen.aliyuncs.com/20230515/jpg/1657937339328520192.jpg'" alt=""> - </div> - <div class="info"> - <div class="title">{{ item.projectName }}</div> - <div class="metas"> - <div> - <span class="label">报名时间:</span><span class="val">{{ item.signUpStartTime}} ~ {{ item.signUpEndTime }}</span> - </div> - <div> - <span class="label">项目时间:</span><span class="val">{{ item.playStartTime}} ~ {{ item.playEndTime }}</span> - </div> - <template v-if="item.initiator"> - <div :class="{'flex-top': item.initiator.split(',').length > 1}"> - <span class="label">发起方: </span> - <span class="val">{{ item.initiator }}</span> - </div> - </template> - </div> - </div> - </div> - <div class="right"> - <p class="status" - :class="{wait: item.status == 0,signing: item.status == 2,signed: item.status == 1,playing: item.status == 4,finish: item.status == 3 || item.status == 4}" @click.stop="signup(item)">{{ statusList[item.status] }}</p> - <p class="end-text" v-if="item.end"> - 距离{{ endList[item.status] }}还有 - <em >{{ item.end }}</em> - </p> - </div> - </li> - </ul> - <div class="pagination"> - <el-pagination background layout="total, prev, pager, next" :total="totals" - @current-change="handleCurrentChange" - :current-page="page"> - </el-pagination> - </div> - </template> - <template v-else> - <div class="empty"> - <div> - <img src="@/assets/img/none.png" alt=""> - <p>暂无赛事</p> - </div> - </div> + <div class="list"> + <template v-if="listData.length"> + <ul> + <li v-for="(item,index) in listData" + :key="index" + @click="toDetail(item)"> + <div class="left"> + <div class="cover"> + <img :src="item.coverUrl || 'https://huoran.oss-cn-shenzhen.aliyuncs.com/20230515/jpg/1657937339328520192.jpg'" + alt=""> + </div> + <div class="info"> + <div class="title">{{ item.projectName }}</div> + <div class="metas"> + <div> + <span class="label">报名时间:</span><span class="val">{{ item.signUpStartTime}} ~ {{ item.signUpEndTime }}</span> + </div> + <div> + <span class="label">项目时间:</span><span class="val">{{ item.playStartTime}} ~ {{ item.playEndTime }}</span> + </div> + <template v-if="item.initiator"> + <div :class="{'flex-top': item.initiator.split(',').length > 1}"> + <span class="label">发起方: </span> + <span class="val">{{ item.initiator }}</span> + </div> </template> + </div> </div> + </div> + <div class="right"> + <p class="status" + :class="{wait: item.status == 0,signing: item.status == 2,signed: item.status == 1,playing: item.status == 4,finish: item.status == 3 || item.status == 4}" + @click.stop="signup(item)">{{ statusList[item.status] }}</p> + <p class="end-text" + v-if="item.end"> + 距离{{ endList[item.status] }}还有 + <em>{{ item.end }}</em> + </p> + </div> + </li> + </ul> + <div class="pagination"> + <el-pagination background + layout="total, prev, pager, next" + :total="totals" + @current-change="handleCurrentChange" + :current-page="page"> + </el-pagination> + </div> + </template> + <template v-else> + <div class="empty"> + <div> + <img src="@/assets/img/none.png" + alt=""> + <p>暂无赛事</p> </div> - </div> + </div> + </template> + </div> </div> - - <el-dialog title="报名" :visible.sync="signupVisible" :close-on-click-modal="false" width="300px"> - <el-form class="dia-form"> - <el-form-item> - <el-input placeholder="请输入4位数大赛邀请码" maxlength="4" v-model="invitationCode"></el-input> - </el-form-item> - </el-form> - <span slot="footer" class="dialog-footer"> - <el-button size="small" type="primary" @click="signupSubmit">报名</el-button> - <el-button size="small" @click="signupVisible = false">取消</el-button> - </span> - </el-dialog> + </div> </div> + + <el-dialog title="报名" + :visible.sync="signupVisible" + :close-on-click-modal="false" + width="300px"> + <el-form class="dia-form"> + <el-form-item> + <el-input placeholder="请输入4位数大赛邀请码" + maxlength="4" + v-model="invitationCode"></el-input> + </el-form-item> + </el-form> + <span slot="footer" + class="dialog-footer"> + <el-button size="small" + type="primary" + @click="signupSubmit">报名</el-button> + <el-button size="small" + @click="signupVisible = false">取消</el-button> + </span> + </el-dialog> + </div> </template> <script> @@ -102,270 +130,270 @@ import { Loading } from "element-ui"; import Setting from "@/setting" import util from "@/libs/util" export default { - data() { - return { - timer: null, - redisTimer: null, - token: util.local.get(Setting.tokenKey), - statusList: ["待报名", "取消报名", "马上报名", "报名截止", "已结束"], - endList: ["报名开始", "报名截止", "报名截止", "项目开始", "项目结束"], - typeList: [ - { - id: '', - name: "本校项目" - }, - { - id: 0, - name: "已报名" - } - ], - form: { - filterSort: 0, - whetherToSignUp: '' - }, - sorts: [ - { - id: 0, - name: '最近更新' - }, - { - id: 1, - name: '近期报名' - } - ], - sort: 1, - keyword: "", - searchTimer: null, - page: 1, - pageSize: 10, - totals: 0, - listData: [], - loadIns: null, - timerList: [], - signupVisible: false, - curRow: {}, - invitationCode: '' - }; - }, - watch: { - keyword: function(val) { - clearTimeout(this.searchTimer); - this.searchTimer = setTimeout(() => { - this.initData(); - }, 500); + data () { + return { + timer: null, + redisTimer: null, + token: util.local.get(Setting.tokenKey), + statusList: ["待报名", "取消报名", "马上报名", "报名截止", "已结束"], + endList: ["报名开始", "报名截止", "报名截止", "项目开始", "项目结束"], + typeList: [ + { + id: '', + name: "本校项目" + }, + { + id: 0, + name: "已报名" } - }, - mounted() { - this.getData() - this.$once('hook:beforeDestroy', function() { - this.clearTimer() - clearInterval(this.redisTimer) + ], + form: { + filterSort: 0, + whetherToSignUp: '' + }, + sorts: [ + { + id: 0, + name: '最近更新' + }, + { + id: 1, + name: '近期报名' + } + ], + sort: 1, + keyword: "", + searchTimer: null, + page: 1, + pageSize: 10, + totals: 0, + listData: [], + loadIns: null, + timerList: [], + signupVisible: false, + curRow: {}, + invitationCode: '' + }; + }, + watch: { + keyword: function (val) { + clearTimeout(this.searchTimer); + this.searchTimer = setTimeout(() => { + this.initData(); + }, 500); + } + }, + mounted () { + this.getData() + this.$once('hook:beforeDestroy', function () { + this.clearTimer() + clearInterval(this.redisTimer) + }) + }, + methods: { + ...mapMutations('match', [ + 'SET_TYPE' + ]), + getList () { + this.clearTimer() + const data = { + pageNum: this.page, + pageSize: this.pageSize, + platformSource: 2, + keyWords: this.keyword, + ...this.form + } + this.$post(this.api.schoolActivities, data).then(({ data }) => { + const { records } = data + this.listData = records + this.totals = data.total + this.handleStatus() + // this.loadIns.close(); + }).catch(res => { + // this.loadIns.close() }) }, - methods: { - ...mapMutations('match', [ - 'SET_TYPE' - ]), - getList() { - this.clearTimer() - const data = { - pageNum: this.page, - pageSize: this.pageSize, - platformSource: 2, - keyWords: this.keyword, - ...this.form - } - this.$post(this.api.schoolActivities, data).then(({ data }) => { - const { records } = data - this.listData = records - this.totals = data.total - this.handleStatus() - // this.loadIns.close(); - }).catch(res => { - // this.loadIns.close() - }) - }, - // 定时处理时间及状态 - handleStatus() { - this.listData.map(item => { - if (item.signUpStartTime && item.signUpEndTime && item.playStartTime && item.playEndTime) { - let total = '' - let time = '' - let status = '' - let signUpStartTime = new Date(this.core.dateCompatible(item.signUpStartTime)) // 报名开始时间 - let signUpEndTime = new Date(this.core.dateCompatible(item.signUpEndTime)) // 报名结束时间 - let playStartTime = new Date(this.core.dateCompatible(item.playStartTime)) // 比赛开始时间 - let playEndTime = new Date(this.core.dateCompatible(item.playEndTime)) // 比赛结束时间 - let timer = setInterval(() => { - const now = new Date() - if (now < signUpStartTime) { // 报名没开始 - status = 0 - total = signUpStartTime - now - } else if (now > signUpStartTime && now < signUpEndTime) { // 报名进行中 - // whetherToSignUp 0已报名,1未报名 - status = item.whetherToSignUp ? 2 : 1 // 1已报名,2立即报名 - total = signUpEndTime - now - } else if (now > signUpEndTime && now < playStartTime) { // 报名结束了,但比赛没开始 - status = 3 - total = playStartTime - now - } else if (now > playEndTime) { // 比赛结束 - status = 4 - } - this.$set(item, 'status', status) - total = total / 1000 - --total - if (total > 86400) { // 超过一天则显示天数 - // clearInterval(timer) - this.$set(item, 'end', Math.floor(total / 86400) + '天') - } else if (total > 0) { // 一天之内,显示时分秒 - let hours = Math.floor(total / (60 * 60)) - let minutes = Math.floor(total % (60 * 60) / 60) - let seconds = Math.floor(total % (60 * 60) % 60) - time = `${this.core.formateTime(hours)}:${this.core.formateTime(minutes)}:${this.core.formateTime(seconds)}` - if (total > 0) this.$set(item, 'end', time) - } else if (item.status === 4) { // 竞赛结束,清除定时器 - clearInterval(timer) - } - }, 1000) - this.timerList.push(timer) + // 定时处理时间及状态 + handleStatus () { + this.listData.map(item => { + if (item.signUpStartTime && item.signUpEndTime && item.playStartTime && item.playEndTime) { + let total = '' + let time = '' + let status = '' + let signUpStartTime = new Date(this.core.dateCompatible(item.signUpStartTime)) // 报名开始时间 + let signUpEndTime = new Date(this.core.dateCompatible(item.signUpEndTime)) // 报名结束时间 + let playStartTime = new Date(this.core.dateCompatible(item.playStartTime)) // 比赛开始时间 + let playEndTime = new Date(this.core.dateCompatible(item.playEndTime)) // 比赛结束时间 + let timer = setInterval(() => { + const now = new Date() + if (now < signUpStartTime) { // 报名没开始 + status = 0 + total = signUpStartTime - now + } else if (now > signUpStartTime && now < signUpEndTime) { // 报名进行中 + // whetherToSignUp 0已报名,1未报名 + status = item.whetherToSignUp ? 2 : 1 // 1已报名,2立即报名 + total = signUpEndTime - now + } else if (now > signUpEndTime && now < playStartTime) { // 报名结束了,但比赛没开始 + status = 3 + total = playStartTime - now + } else if (now > playEndTime) { // 比赛结束 + status = 4 } - }) - }, - // 清除定时器 - clearTimer() { - this.timerList.forEach(n => { - clearInterval(n) - }) - this.timerList = [] - }, - getData() { - // this.loadIns = Loading.service() - this.getList() - // if (!Setting.isDev) { - clearInterval(this.redisTimer) - this.redisTimer = setInterval(this.getRedis, 1000) - // } - }, - initData() { - this.page = 1 - this.getData() - }, - // 获取redis缓存 - getRedis() { - this.$post(this.api.getRedisCacheActivity).then(({ data }) => { - if (data) { - localStorage.getItem('activityTimestampClient') !== data && this.getList() // 本地缓存跟redis返回的不一样,就查询列表 - localStorage.setItem('activityTimestampClient', data) + this.$set(item, 'status', status) + total = total / 1000 + --total + if (total > 86400) { // 超过一天则显示天数 + // clearInterval(timer) + this.$set(item, 'end', Math.floor(total / 86400) + '天') + } else if (total > 0) { // 一天之内,显示时分秒 + let hours = Math.floor(total / (60 * 60)) + let minutes = Math.floor(total % (60 * 60) / 60) + let seconds = Math.floor(total % (60 * 60) % 60) + time = `${this.core.formateTime(hours)}:${this.core.formateTime(minutes)}:${this.core.formateTime(seconds)}` + if (total > 0) this.$set(item, 'end', time) + } else if (item.status === 4) { // 竞赛结束,清除定时器 + clearInterval(timer) } - }).catch(res => {}) - }, - changeType(type) { - const { form } = this - form.competitionScope = 3 - form.provinceId = '' - form.cityId = '' - form.filterSort = 2 - form.whetherToSignUp = type - this.initData() - }, - // 筛选排序 - changeSort(type) { - this.form.filterSort = type - this.initData() - }, - toDetail(item) { - this.$router.push(`/activity/details?id=${item.id}`); - }, - handleCurrentChange(val) { - this.page = val; - this.getData(); - }, + }, 1000) + this.timerList.push(timer) + } + }) + }, + // 清除定时器 + clearTimer () { + this.timerList.forEach(n => { + clearInterval(n) + }) + this.timerList = [] + }, + getData () { + // this.loadIns = Loading.service() + this.getList() + // if (!Setting.isDev) { + clearInterval(this.redisTimer) + this.redisTimer = setInterval(this.getRedis, 1000) + // } + }, + initData () { + this.page = 1 + this.getData() + }, + // 获取redis缓存 + getRedis () { + this.$post(this.api.getRedisCacheActivity).then(({ data }) => { + if (data) { + localStorage.getItem('activityTimestampClient') !== data && this.getList() // 本地缓存跟redis返回的不一样,就查询列表 + localStorage.setItem('activityTimestampClient', data) + } + }).catch(res => { }) + }, + changeType (type) { + const { form } = this + form.competitionScope = 3 + form.provinceId = '' + form.cityId = '' + form.filterSort = 2 + form.whetherToSignUp = type + this.initData() + }, + // 筛选排序 + changeSort (type) { + this.form.filterSort = type + this.initData() + }, + toDetail (item) { + this.$router.push(`/activity/details?id=${item.id}`); + }, + handleCurrentChange (val) { + this.page = val; + this.getData(); + }, - // 报名提交 - signupSubmit() { + // 报名提交 + signupSubmit () { + this.$post(this.api.saveActivityApplicant, { + activityId: this.curRow.id, + registrationInvitationCode: this.invitationCode + }).then(res => { + this.signupVisible = false + this.getData() + this.$message.success('报名成功') + }).catch(res => { }) + }, + // 报名 + signup (item) { + const { status, id } = item + if (status == 2) { // 报名 + // 如果需要邀请码 + if (item.isNeedCode) { + this.invitationCode = '' + this.curRow = item + this.signupVisible = true + } else { this.$post(this.api.saveActivityApplicant, { - activityId: this.curRow.id, - registrationInvitationCode: this.invitationCode + activityId: id }).then(res => { - this.signupVisible = false this.getData() this.$message.success('报名成功') - }).catch(res => {}) - }, - // 报名 - signup(item) { - const { status, id } = item - if (status == 2) { // 报名 - // 如果需要邀请码 - if (item.isNeedCode) { - this.invitationCode = '' - this.curRow = item - this.signupVisible = true - } else { - this.$post(this.api.saveActivityApplicant, { - activityId: id - }).then(res => { - this.getData() - this.$message.success('报名成功') - }).catch(res => {}) - } - } else if (status == 1) { - // 已报名,点击取消报名 - this.$confirm('是否要取消报名?', '提示', { - type: 'success' - }).then(() => { - this.$post(`${this.api.delActivityApplicant}?id=${item.cancelId}`).then(res => { - this.getData() - this.$message.success('取消报名成功') - }).catch(res => {}) - }).catch(() => {}) - } - }, - // 进入python系统 - toPython() { - const form = this.curItem.curStage - let token = util.local.get(Setting.tokenKey); - util.cookies.set('assessmentId', '', -1) - util.cookies.set('startTime', '', -1) - util.cookies.set('stopTime', '', -1) - util.cookies.set('projectId', form.projectId) - util.cookies.set('token', token) - util.cookies.set('courseId', form.cid) - util.cookies.set('curriculumName', escape(form.systemName)) - util.cookies.set('systemId', form.systemId) - util.cookies.set('competitionId', this.curItem.id) - util.cookies.set('stageId', form.stageId) - util.cookies.set('teamId', this.curItem.teamId) - util.cookies.set('stopTime', form.endTime) - util.cookies.set('resultsDetails', form.resultsDetails) - util.cookies.set('resultAnnouncementTime', form.resultAnnouncementTime) - util.cookies.set('fromManager', '', -1) - // 8个python子系统都跳这个地址,子系统会通过cookie里的systemId识别展示哪套系统 - location.href = process.env.NODE_ENV === 'development' ? - `http://${location.hostname}:8085/#/` : - Setting.isPro ? - `https://${location.hostname}/pyTrials` : - `${location.origin}/pyTrials` - }, - // 进入子系统 - toSub() { - const form = this.curItem - const { systemId, projectId, cid, stageId } = form.curStage - const competitionId = form.id - const teamId = form.teamId - let token = util.local.get(Setting.tokenKey); - if (systemId == 11) { - // 银行系统 - location.href = `${Setting.systemPath}/#/index/list?curriculumName=${this.curriculumName}&token=${token}&cid=${cid}&systemId=${systemId}&projectId=${projectId}&competitionId=${competitionId}&stageId=${stageId}&teamId=${teamId}&assessmentId=&classId=&stopTime=&test=true` - } else if (systemId == 12) { - // 众筹系统 - window.open(`http://120.78.139.126:8879?systemId=${systemId}&courseId=${cid}&projectId=${projectId}&token=${token}&userId=${this.userId}&classId=1&competitionId=${competitionId}&stageId=${stageId}&teamId=${teamId}`); - } else { - // python系统 - this.toPython() - } + }).catch(res => { }) } + } else if (status == 1) { + // 已报名,点击取消报名 + this.$confirm('是否要取消报名?', '提示', { + type: 'success' + }).then(() => { + this.$post(`${this.api.delActivityApplicant}?id=${item.cancelId}`).then(res => { + this.getData() + this.$message.success('取消报名成功') + }).catch(res => { }) + }).catch(() => { }) + } + }, + // 进入python系统 + toPython () { + const form = this.curItem.curStage + let token = util.local.get(Setting.tokenKey); + util.cookies.set('assessmentId', '', -1) + util.cookies.set('startTime', '', -1) + util.cookies.set('stopTime', '', -1) + util.cookies.set('projectId', form.projectId) + util.cookies.set('token', token) + util.cookies.set('courseId', form.cid) + util.cookies.set('curriculumName', escape(form.systemName)) + util.cookies.set('systemId', form.systemId) + util.cookies.set('competitionId', this.curItem.id) + util.cookies.set('stageId', form.stageId) + util.cookies.set('teamId', this.curItem.teamId) + util.cookies.set('stopTime', form.endTime) + util.cookies.set('resultsDetails', form.resultsDetails) + util.cookies.set('resultAnnouncementTime', form.resultAnnouncementTime) + util.cookies.set('fromManager', '', -1) + // 8个python子系统都跳这个地址,子系统会通过cookie里的systemId识别展示哪套系统 + location.href = process.env.NODE_ENV === 'development' ? + `http://${location.hostname}:8085/#/` : + Setting.isPro ? + `https://${location.hostname}/pyTrials` : + `${location.origin}/pyTrials` + }, + // 进入子系统 + toSub () { + const form = this.curItem + const { systemId, projectId, cid, stageId } = form.curStage + const competitionId = form.id + const teamId = form.teamId + let token = util.local.get(Setting.tokenKey); + if (systemId == 11) { + // 银行系统 + location.href = `${Setting.systemPath}/#/index/list?curriculumName=${this.curriculumName}&token=${token}&cid=${cid}&systemId=${systemId}&projectId=${projectId}&competitionId=${competitionId}&stageId=${stageId}&teamId=${teamId}&assessmentId=&classId=&stopTime=&test=true` + } else if (systemId == 12) { + // 众筹系统 + window.open(`http://120.78.139.126:8879?systemId=${systemId}&courseId=${cid}&projectId=${projectId}&token=${token}&userId=${this.userId}&classId=1&competitionId=${competitionId}&stageId=${stageId}&teamId=${teamId}`); + } else { + // python系统 + this.toPython() + } } + } }; </script> @@ -402,11 +430,11 @@ export default { border-radius: 4px; } } -.main{ - background: url(../../../assets/img/match-bg1.png) (0px 95px)/auto auto no-repeat, - url(../../../assets/img/match-bg2.png) (98% bottom)/auto auto no-repeat; +.main { + background: url(../../../assets/img/match-bg1.png) (0px 95px) / auto auto no-repeat, + url(../../../assets/img/match-bg2.png) (98% bottom) / auto auto no-repeat; .center-wrap { - width: 1078px; + width: 1078px; } } .filter { @@ -441,23 +469,23 @@ export default { } } .select-wrap { - display: inline-flex; - align-items: center; - margin: 0 10px; - .label { - margin-right: 10px; - white-space: nowrap; - } - .el-select { - width: 130px; - } + display: inline-flex; + align-items: center; + margin: 0 10px; + .label { + margin-right: 10px; + white-space: nowrap; + } + .el-select { + width: 130px; + } } .list-inner { display: flex; justify-content: center; - align-items:flex-start; + align-items: flex-start; } -.nav{ +.nav { width: 156px; text-align: right; overflow: hidden; @@ -516,11 +544,11 @@ export default { font-size: 14px; color: #fff; white-space: nowrap; - background-color: #52C41A; + background-color: #52c41a; border-radius: 4px; @include ellipsis(); &.wait { - background-color: #FAAD14; + background-color: #faad14; } &.signing { @@ -528,7 +556,7 @@ export default { } &.signed { - background-color: #52C41A; + background-color: #52c41a; } &.playing { background-color: #f96d6d; @@ -547,7 +575,7 @@ export default { cursor: pointer; &:hover { - opacity: .9; + opacity: 0.9; } &.disabled { @@ -558,7 +586,7 @@ export default { .end-text { margin-top: 10px; - color: rgba(0, 0, 0, .65); + color: rgba(0, 0, 0, 0.65); font-size: 12px; white-space: nowrap; @@ -597,7 +625,7 @@ export default { margin-bottom: 10px; font-size: 20px; font-weight: 500; - color: #0B1D30; + color: #0b1d30; word-break: break-all; @include mul-ellipsis(2); } @@ -614,7 +642,8 @@ export default { } } - .label, .val { + .label, + .val { font-size: 14px; color: #666; white-space: nowrap; @@ -639,13 +668,13 @@ export default { } } /deep/.dia-form { - .w-100 { - width: 100%; - } - .tips { - display: flex; - justify-content: center; - align-items: center; - } + .w-100 { + width: 100%; + } + .tips { + display: flex; + justify-content: center; + align-items: center; + } } </style> \ No newline at end of file diff --git a/src/pages/activity/manage/manage/index.vue b/src/pages/activity/manage/manage/index.vue index d6a2e35..e2a5246 100644 --- a/src/pages/activity/manage/manage/index.vue +++ b/src/pages/activity/manage/manage/index.vue @@ -1,20 +1,28 @@ <template> - <div> - <el-card shadow="hover" class="m-b-20"> - <div class="flex-between"> - <el-page-header @back="back" :content="name + '/管理'"></el-page-header> - </div> - </el-card> - <div class="page" style="margin-bottom: 24px"> - <div class="tabs"> - <a class="item" v-for="(item,index) in tabs" :key="index" :class="{active: index == active}" @click="tabChange(index)">{{ item }}</a> - </div> - <MatchDetail v-if="active == 'tab1'" ref="detail" /> - <MatchProgress v-else-if="active == 'tab2'" /> - <notice v-else-if="active == 'tab3'" /> - <MatchSignup v-else-if="active == 'tab4'" /> - </div> + <div> + <el-card shadow="hover" + class="m-b-20"> + <div class="flex-between"> + <el-page-header @back="back" + :content="name + '/管理'"></el-page-header> + </div> + </el-card> + <div class="page" + style="margin-bottom: 24px"> + <div class="tabs"> + <a class="item" + v-for="(item,index) in tabs" + :key="index" + :class="{active: index == active}" + @click="tabChange(index)">{{ item }}</a> + </div> + <MatchDetail v-if="active == 'tab1'" + ref="detail" /> + <MatchProgress v-else-if="active == 'tab2'" /> + <notice v-else-if="active == 'tab3'" /> + <MatchSignup v-else-if="active == 'tab4'" /> </div> + </div> </template> @@ -26,122 +34,122 @@ import notice from "./notice"; import MatchSignup from "./matchSignup"; import { mapState } from "vuex"; export default { - name: "matchManage", - data() { - return { - name: this.$route.query.name, - active: this.$route.query.tab || "tab1", - tabs: { - tab1: "项目详情", - tab2: "项目进展", - tab3: "公告通知", - tab4: "报名人员" - }, - }; - }, - components: { - MatchDetail, - MatchProgress, - notice, - MatchSignup + name: "matchManage", + data () { + return { + name: this.$route.query.name, + active: this.$route.query.tab || "tab1", + tabs: { + tab1: "项目详情", + tab2: "项目进展", + tab3: "公告通知", + tab4: "报名人员" + }, + }; + }, + components: { + MatchDetail, + MatchProgress, + notice, + MatchSignup + }, + beforeRouteLeave (to, from, next) { + const detail = this.$refs.detail + if (detail && detail.updateTime) { + this.$confirm(`编辑的内容未保存,是否保存并且发布?`, '提示.......', { + type: 'warning' + }).then(() => { + detail.save(detail.form.publishStatus) + }).catch(() => { + next() + }) + } else { + next() + } + }, + mounted () { + + }, + methods: { + back () { + this.handleSave(0) && this.backPage() }, - beforeRouteLeave(to, from, next) { - const detail = this.$refs.detail - if (detail && detail.updateTime) { - this.$confirm(`编辑的内容未保存,是否保存并且发布?`, '提示.......', { - type: 'warning' - }).then(() => { - detail.save(detail.form.publishStatus) - }).catch(() => { - next() - }) + // 判断是否需要confirm + handleSave (i) { + // 如果是赛事详情,则要判断是否已经保存,未保存则提示是否保存 + if (this.active === 'tab1') { + const detail = this.$refs.detail + if (detail && detail.updateTime) { + this.$confirm(`编辑的内容未保存,是否保存并且发布?`, '提示', { + type: 'warning' + }).then(() => { + detail.save(detail.form.publishStatus) + this.backOrTab(i) + }).catch(() => { + this.backOrTab(i) + }) + } else { + this.backOrTab(i) + } + return false } else { - next() + return true } }, - mounted() { - + // 返回列表 + backPage () { + this.$router.push(`/activity/manage?page=${this.$store.state.activity.page}`) }, - methods: { - back() { - this.handleSave(0) && this.backPage() - }, - // 判断是否需要confirm - handleSave(i) { - // 如果是赛事详情,则要判断是否已经保存,未保存则提示是否保存 - if (this.active === 'tab1') { - const detail = this.$refs.detail - if (detail && detail.updateTime) { - this.$confirm(`编辑的内容未保存,是否保存并且发布?`, '提示', { - type: 'warning' - }).then(() => { - detail.save(detail.form.publishStatus) - this.backOrTab(i) - }).catch(() => { - this.backOrTab(i) - }) - } else { - this.backOrTab(i) - } - return false - } else { - return true - } - }, - // 返回列表 - backPage(){ - this.$router.push(`/activity/manage?page=${this.$store.state.activity.page}`) - }, - // tab切换 - tabSwitch(i) { - this.active = i - this.$router.push(`manageDetail?id=${this.$route.query.id}&tab=${i}&name=${this.name}`) - }, - // 判断返回还是tab - backOrTab(i) { - i ? this.tabSwitch(i) : this.backPage() - }, - // tab回调 - tabChange(i) { - this.handleSave(i) && this.tabSwitch(i) - } + // tab切换 + tabSwitch (i) { + this.active = i + this.$router.push(`manageDetail?id=${this.$route.query.id}&tab=${i}&name=${this.name}`) + }, + // 判断返回还是tab + backOrTab (i) { + i ? this.tabSwitch(i) : this.backPage() + }, + // tab回调 + tabChange (i) { + this.handleSave(i) && this.tabSwitch(i) } + } }; </script> <style lang="scss" scoped> .tabs { - display: flex; - align-items: center; - padding: 0 24px; - border-bottom: 1px solid rgba(0, 0, 0, .06); - .item { - position: relative; - padding: 20px 0; - margin-right: 40px; - font-size: 16px; - color: rgba(0, 0, 0, 0.65); - cursor: pointer; + display: flex; + align-items: center; + padding: 0 24px; + border-bottom: 1px solid rgba(0, 0, 0, 0.06); + .item { + position: relative; + padding: 20px 0; + margin-right: 40px; + font-size: 16px; + color: rgba(0, 0, 0, 0.65); + cursor: pointer; - &:after { - content: ''; - position: absolute; - bottom: 0; - left: 0; - width: 100%; - height: 3px; - border-bottom: 3px solid transparent; - border-radius: 2px; - } + &:after { + content: ''; + position: absolute; + bottom: 0; + left: 0; + width: 100%; + height: 3px; + border-bottom: 3px solid transparent; + border-radius: 2px; + } - &.active { - font-weight: 500; - color: rgba(0, 0, 0, 0.85); - } + &.active { + font-weight: 500; + color: rgba(0, 0, 0, 0.85); + } - &.active:after { - border-bottom-color: $main-color; + &.active:after { + border-bottom-color: $main-color; + } } - } } </style> \ No newline at end of file diff --git a/src/pages/station/preview/index.vue b/src/pages/station/preview/index.vue index 914ba50..ade0b56 100644 --- a/src/pages/station/preview/index.vue +++ b/src/pages/station/preview/index.vue @@ -1,241 +1,354 @@ <template> - <div class="wrap"> - <breadcrumb :data="'实验台/' + curriculumName"></breadcrumb> - <div class="flex"> - <div class="cover" :class="{'is-word': showMask1}"> - <!--实验台不显示课程封面--> - <img v-if="coverUrl" :src="coverUrl" alt="" width="100%" height="100%"> - <template v-else-if="iframeSrc"> - <iframe class="inner fileIframe" id="fileIframe" :src="iframeSrc" frameborder="0"></iframe> - <template v-if="showMask"> - <div class="mask" style="width:100%;background: #393A3D;height: 30px;top: 53px;"></div> - <div class="mask" style="width:100%;background: #393A3D;height: 30px;top: 53px;"></div> - </template> - <template v-if="showMask1"> - <div class="word-mask" style="height: 40px;"></div> - <div class="word-mask2" - style="top: 55px;left: 28%;width: 44%;height: calc(100% - 80px);"></div> - </template> - <template v-if="showMask2"> - <div class="excel-mask1" style="height: 48px;"></div> - </template> - </template> - <div class="pdf" v-else-if="pdfSrc"> - <img class="full" src="@/assets/img/screen/full.png" alt="" @click="fullScreen"> - <p class="arrow"> - <span @click="changePdfPage(0)" class="turn el-icon-arrow-left" - :class="{grey: currentPage==1}"></span> - {{ currentPage }} / {{ pageCount }} - <span @click="changePdfPage(1)" class="turn el-icon-arrow-right" - :class="{grey: currentPage==pageCount}"></span> - </p> - <div style='color:#393A3D;height: 30px;background: #393A3D;'></div> - <pdf - class="pdf-wrap" - :src="pdfSrc" - :page="currentPage" - @num-pages="pageCount=$event" - @page-loaded="currentPage=$event" - @loaded="loadPdfHandler"> - </pdf> - </div> - <div class="inner" v-else-if="playAuth"> - <div class="video_wid" id="player"></div> - </div> + <div class="wrap"> + <breadcrumb :data="'实验台/' + curriculumName"></breadcrumb> + <div class="flex"> + <div class="cover" + :class="{'is-word': showMask1}"> + <!--实验台不显示课程封面--> + <img v-if="coverUrl" + :src="coverUrl" + alt="" + width="100%" + height="100%"> + <template v-else-if="iframeSrc"> + <iframe class="inner fileIframe" + id="fileIframe" + :src="iframeSrc" + frameborder="0"></iframe> + <template v-if="showMask"> + <div class="mask" + style="width:100%;background: #393A3D;height: 30px;top: 53px;"></div> + <div class="mask" + style="width:100%;background: #393A3D;height: 30px;top: 53px;"></div> + </template> + <template v-if="showMask1"> + <div class="word-mask" + style="height: 40px;"></div> + <div class="word-mask2" + style="top: 55px;left: 28%;width: 44%;height: calc(100% - 80px);"></div> + </template> + <template v-if="showMask2"> + <div class="excel-mask1" + style="height: 48px;"></div> + </template> + </template> + <div class="pdf" + v-else-if="pdfSrc"> + <img class="full" + src="@/assets/img/screen/full.png" + alt="" + @click="fullScreen"> + <p class="arrow"> + <span @click="changePdfPage(0)" + class="turn el-icon-arrow-left" + :class="{grey: currentPage==1}"></span> + {{ currentPage }} / {{ pageCount }} + <span @click="changePdfPage(1)" + class="turn el-icon-arrow-right" + :class="{grey: currentPage==pageCount}"></span> + </p> + <div style='color:#393A3D;height: 30px;background: #393A3D;'></div> + <pdf class="pdf-wrap" + :src="pdfSrc" + :page="currentPage" + @num-pages="pageCount=$event" + @page-loaded="currentPage=$event" + @loaded="loadPdfHandler"> + </pdf> + </div> + <div class="inner" + v-else-if="playAuth"> + <div class="video_wid" + id="player"></div> + </div> + </div> + <div class="catalog"> + <el-button v-if="!overdue" + class="renew" + type="primary" + size="small" + @click="showBuy">续费</el-button> + <a v-else + class="entry" + @click="entry"></a> + <div class="list"> + <h4 class="title">{{ courseName }}</h4> + <div> + <h6 class="pro-title">我的学习进度</h6> + <el-progress :stroke-width="12" + :percentage="schedule" + :format="percentFormat" + :text-color="'#fff'"></el-progress> + </div> + <div class="types"> + <div :class="['item', { active: type === 1 }]" + @click="typeChange(1)"> + <i class="icon el-icon-notebook-2"></i> 目录 </div> - <div class="catalog"> - <el-button v-if="!overdue" class="renew" type="primary" size="small" @click="showBuy">续费</el-button> - <a v-else class="entry" @click="entry"></a> - <div class="list"> - <h4 class="title">{{ courseName }}</h4> - <div> - <h6 class="pro-title">我的学习进度</h6> - <el-progress :stroke-width="12" :percentage="schedule" :format="percentFormat" :text-color="'#fff'"></el-progress> - </div> - <div class="types"> - <div :class="['item', { active: type === 1 }]" @click="typeChange(1)"> - <i class="icon el-icon-notebook-2"></i> 目录 - </div> - <div :class="['item', { active: type === 2 }]" @click="typeChange(2)"> - <i class="icon el-icon-timer"></i> 学习进度 - </div> - </div> - <div class="chapters"> - <template v-if="type === 1"> - <template v-if="chapterList.length"> - <div class="chapter" v-for="(item,index) in chapterList" :key="index"> - <div class="chapterName">{{ item.name }}</div> - <div class="section" v-if="item.subsectionList.length"> - <p class="sectionName" :class="{active: curLink === `${item.name}${section.name}`}" v-for="(section,i) in item.subsectionList" :key="i" @click="preview(section, item.name)"> - <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=""> - {{ section.name }} - </p> - </div> - </div> - </template> - </template> - <div v-else class="section"> - <p class="sectionName" v-for="(item, i) in progressList" :key="i" :title="item.projectName"> - {{ i + 1 }}. - {{ item.projectName }} - <i :class="['icon', item.whetherToStudyOrNot ? 'el-icon-success' : 'circle']" @click.stop="studySection(item)"></i> - </p> - </div> - </div> + <div :class="['item', { active: type === 2 }]" + @click="typeChange(2)"> + <i class="icon el-icon-timer"></i> 学习进度 + </div> + </div> + <div class="chapters"> + <template v-if="type === 1"> + <template v-if="chapterList.length"> + <div class="chapter" + v-for="(item,index) in chapterList" + :key="index"> + <div class="chapterName">{{ item.name }}</div> + <div class="section" + v-if="item.subsectionList.length"> + <p class="sectionName" + :class="{active: curLink === `${item.name}${section.name}`}" + v-for="(section,i) in item.subsectionList" + :key="i" + @click="preview(section, item.name)"> + <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=""> + {{ section.name }} + </p> + </div> </div> + </template> + </template> + <div v-else + class="section"> + <p class="sectionName" + v-for="(item, i) in progressList" + :key="i" + :title="item.projectName"> + {{ i + 1 }}. + {{ item.projectName }} + <i :class="['icon', item.whetherToStudyOrNot ? 'el-icon-success' : 'circle']" + @click.stop="studySection(item)"></i> + </p> </div> + </div> </div> - - <div class="tabs"> - <a class="item" v-for="(item, i) in tabs" :key="i" :class="{active: item.id == active}" @click="tabChange(item)">{{ item.name }}</a> + </div> + </div> + + <div class="tabs"> + <a class="item" + v-for="(item, i) in tabs" + :key="i" + :class="{active: item.id == active}" + @click="tabChange(item)">{{ item.name }}</a> + </div> + <div class="tab-content"> + <template v-if="active === 1"> + <div class="page"> + <p class="intro" + v-html="briefIntroduction"></p> </div> - <div class="tab-content"> - <template v-if="active === 1"> - <div class="page"> - <h6 class="l-title"> - <img src="@/assets/img/course1.png" alt=""> - 课程简介 - </h6> - <p class="intro" v-html="briefIntroduction"></p> - </div> - <div class="page"> - <h6 class="l-title"> - <img src="@/assets/img/course2.png" alt=""> - 课程目标 - </h6> - <p class="intro" v-html="teachingObjectives"></p> + </template> + <template v-if="active === 2"> + <div class="page"> + <template v-if="showNoteAdd"> + <el-form class="form" + ref="form" + label-width="120px" + center> + <el-form-item class="required" + label="笔记标题"> + <el-input placeholder="请输入笔记标题" + v-model="noteForm.noteName" + maxlength="30" + style="width: 400px"></el-input> + </el-form-item> + <el-form-item class="required" + label="笔记内容"> + <Editor api-key='rnk6zw9v267xqz7pf98twt1vmrvltmd436je7a642pckltda' + v-model="noteForm.noteContent" + :init="editorConfig" /> + </el-form-item> + </el-form> + <div class="text-right"> + <el-button type="primary" + @click="submitNote">保存</el-button> </div> </template> - <template v-if="active === 2"> - <div class="page"> - <template v-if="showNoteAdd"> - <el-form class="form" ref="form" label-width="120px" center> - <el-form-item class="required" label="笔记标题"> - <el-input placeholder="请输入笔记标题" v-model="noteForm.noteName" maxlength="30" style="width: 400px"></el-input> - </el-form-item> - <el-form-item class="required" label="笔记内容"> - <Editor api-key='rnk6zw9v267xqz7pf98twt1vmrvltmd436je7a642pckltda' v-model="noteForm.noteContent" :init="editorConfig" /> - </el-form-item> - </el-form> - <div class="text-right"> - <el-button type="primary" @click="submitNote">保存</el-button> - </div> - </template> - <template v-else> - <div class="tool"> - <ul class="filter"> - <li> - <label>搜索:</label> - <el-input placeholder="请输入标题" v-model="noteKeyword" clearable></el-input> - </li> - </ul> + <template v-else> + <div class="tool"> + <ul class="filter"> + <li> + <label>搜索:</label> + <el-input placeholder="请输入标题" + v-model="noteKeyword" + clearable></el-input> + </li> + </ul> + <div> + <el-button type="primary" + @click="addNote">新增笔记</el-button> + </div> + </div> + <el-timeline class="timeline"> + <el-timeline-item placement="top" + v-for="(item, i) in notes" + :key="i"> + <p class="sign">{{ item.createTime }}</p> + <div class="ver"> <div> - <el-button type="primary" @click="addNote">新增笔记</el-button> + {{ item.noteName }} + <span class="action"> + <i class="el-icon-edit-outline" + @click="editNote(item)"></i> + <i class="el-icon-delete" + @click="delNote(item)"></i> + </span> </div> </div> - <el-timeline class="timeline"> - <el-timeline-item placement="top" v-for="(item, i) in notes" :key="i"> - <p class="sign">{{ item.createTime }}</p> - <div class="ver"> - <div> - {{ item.noteName }} - <span class="action"> - <i class="el-icon-edit-outline" @click="editNote(item)"></i> - <i class="el-icon-delete" @click="delNote(item)"></i> - </span> - </div> - </div> - <div class="des" v-html="item.noteContent"></div> - </el-timeline-item> - </el-timeline> - </template> - </div> + <div class="des" + v-html="item.noteContent"></div> + </el-timeline-item> + </el-timeline> </template> - <template v-if="active === 4"> - <div class="page"> - <quill ref="quill" :border="true" v-model="msg" :height="150" :toTop="false" /> - <ul class="msg"> - <li v-for="(item, i) in msgs" :key="i"> + </div> + </template> + <template v-if="active === 4"> + <div class="page"> + <quill ref="quill" + :border="true" + v-model="msg" + :height="150" + :toTop="false" /> + <ul class="msg"> + <li v-for="(item, i) in msgs" + :key="i"> + <div class="li-wrap"> + <img :src="item.avatar" + alt="" + class="avatar"> + <div class="texts"> + <h6> + <span class="name">{{ item.userName }}</span> + 发表于 {{ item.createDate }} + </h6> + <div class="des" + v-html="item.content"></div> + </div> + <div class="action"> + <i class="icon el-icon-chat-dot-square"></i> + <i class="icon el-icon-delete"></i> + <img class="icon" + src="@/assets/img/like.png" + alt=""> + </div> + </div> + <div class="reply" + v-if="item.showReply"> + <quill :border="true" + v-model="item.replyContent" + :toTop="false" + :height="150" /> + <div class="m-t-10 text-right"> + <el-button type="primary" + size="mini">提交</el-button> + </div> + </div> + <ul class="msg children" + v-if="item.showChildren"> + <li v-for="(reply,i) in item.children" + :key="i"> <div class="li-wrap"> - <img :src="item.avatar" alt="" class="avatar"> + <img class="avatar" + :src="reply.avatar" + alt=""> <div class="texts"> - <h6> - <span class="name">{{ item.userName }}</span> - 发表于 {{ item.createDate }} - </h6> - <div class="des" v-html="item.content"></div> + <div class="name">{{reply.userName}}</div> + <div class="des" + v-html="reply.content"></div> + <div class="date">{{reply.createDate}}</div> </div> <div class="action"> <i class="icon el-icon-chat-dot-square"></i> <i class="icon el-icon-delete"></i> - <img class="icon" src="@/assets/img/like.png" alt=""> + <img class="icon" + src="@/assets/img/like.png" + alt=""> </div> </div> - <div class="reply" v-if="item.showReply"> - <quill :border="true" v-model="item.replyContent" :toTop="false" :height="150" /> + <div class="reply" + v-if="reply.showReply"> + <quill :border="true" + v-model="reply.replyContent" + :toTop="false" + :height="150" /> <div class="m-t-10 text-right"> - <el-button type="primary" size="mini">提交</el-button> + <el-button type="primary" + size="mini">提交</el-button> </div> - </div> - <ul class="msg children" v-if="item.showChildren"> - <li v-for="(reply,i) in item.children" :key="i"> - <div class="li-wrap"> - <img class="avatar" :src="reply.avatar" alt=""> - <div class="texts"> - <div class="name">{{reply.userName}}</div> - <div class="des" v-html="reply.content"></div> - <div class="date">{{reply.createDate}}</div> - </div> - <div class="action"> - <i class="icon el-icon-chat-dot-square"></i> - <i class="icon el-icon-delete"></i> - <img class="icon" src="@/assets/img/like.png" alt=""> - </div> - </div> - <div class="reply" v-if="reply.showReply"> - <quill :border="true" v-model="reply.replyContent" :toTop="false" :height="150" /> - <div class="m-t-10 text-right"> - <el-button type="primary" size="mini">提交</el-button> - </div> - </div> - </li> - </ul> - <div v-if="item.getCommentReplyNum" class="toggle"><span @click="item.showChildren = !item.showChildren">{{item.showChildren ? '收起所有回复' : `查看所有${item.getCommentReplyNum}条回复`}} <i class="el-icon-arrow-down"></i></span></div> + </div> </li> </ul> - </div> - </template> - </div> - - - <el-dialog title="请选择项目" v-loading="loading" :visible.sync="projectVisible" width="828px" custom-class="project-dia" :close-on-click-modal="false"> - <ul class="projects"> - <li v-for="(item, i) in projects" :key="i" :class="{active: curProject == item.projectId}" @click="selectProject(item)"> - <img src="@/assets/img/project.png" alt=""> - <span>{{ i + 1 }}. {{ item.projectName }}</span> + <div v-if="item.getCommentReplyNum" + class="toggle"><span @click="item.showChildren = !item.showChildren">{{item.showChildren ? '收起所有回复' : `查看所有${item.getCommentReplyNum}条回复`}} <i class="el-icon-arrow-down"></i></span></div> </li> </ul> - - <span slot="footer" class="dialog-footer"> - <el-button size="small" @click="projectVisible = false">取 消</el-button> - <el-button size="small" type="primary" @click="toSub">确 定</el-button> - </span> - </el-dialog> + </div> + </template> + </div> - <!-- 购买弹框 --> - <el-dialog title="温馨提示" :visible.sync="buyVisible" width="420px" center :close-on-click-modal="false"> - <div class="buy"> - <p class="tips">该课程订阅期限已到期,请联系院校管理员续费</p> - </div> - </el-dialog> + <el-dialog title="请选择项目" + v-loading="loading" + :visible.sync="projectVisible" + width="828px" + custom-class="project-dia" + :close-on-click-modal="false"> + <ul class="projects"> + <li v-for="(item, i) in projects" + :key="i" + :class="{active: curProject == item.projectId}" + @click="selectProject(item)"> + <img src="@/assets/img/project.png" + alt=""> + <span>{{ i + 1 }}. {{ item.projectName }}</span> + </li> + </ul> - <pdfDia :key="pdfVisible" :visible.sync="pdfVisible" :src.sync="pdfSrc"/> - </div> + <span slot="footer" + class="dialog-footer"> + <el-button size="small" + @click="projectVisible = false">取 消</el-button> + <el-button size="small" + type="primary" + @click="toSub">确 定</el-button> + </span> + </el-dialog> + + <!-- 购买弹框 --> + <el-dialog title="温馨提示" + :visible.sync="buyVisible" + width="420px" + center + :close-on-click-modal="false"> + <div class="buy"> + <p class="tips">该课程订阅期限已到期,请联系院校管理员续费</p> + </div> + </el-dialog> + + <pdfDia :key="pdfVisible" + :visible.sync="pdfVisible" + :src.sync="pdfSrc" /> + </div> </template> <script> @@ -249,471 +362,473 @@ import pdfDia from '@/components/pdf' import Editor from '@tinymce/tinymce-vue' import editorConfig from '@/components/editor' export default { - components: { pdf, breadcrumb, pdfDia, quill, Editor }, - data() { - return { - mallId: this.$route.query.mallId, - editorConfig, - startTime: Date.now(), // 页面进来的时间 - systemIds: '', - courseId: +this.$route.query.courseId, - curriculumName: this.$route.query.curriculumName, - type: 1, - video: "http://liuwanr.oss-cn-shenzhen.aliyuncs.com/mp4/20200519/1589871025648.mp4", - chapterList: [], // 章节列表 - progressList: [], - coverUrl: "", // 课程封面 - courseName: "", // 课程名称 - briefIntroduction: "", // 课程简介 - teachingObjectives: "", // 课程目标 - assessmentList: "", // 考核列表 - curLink: "", // 当前选中 - active: 1, - tabs: [ - { - id: 1, - name: '课程介绍' - }, - { - id: 2, - name: '课程笔记' - }, - { - id: 3, - name: '全国排行榜' - }, - { - id: 4, - name: '教学互动' - } - ], - playAuth: "", - player: null, - previewImg: "", - iframeSrc: "", - isWord: false, - isPPT: false, - isExcel: false, - showMask: false, - showMask1: false, - showMask2: false, - closePosi: { - top: "80px" - }, - pdfVisible: false, - pdfSrc: "", - currentPage: 0, // pdf文件页码 - pageCount: 0, // pdf文件总页数 - fileType: "pdf", // 文件类型 - desShrink: false, - projectVisible: false, - projects: [], - loading: false, - curProject: '', - overdue: 0, //是否过期 - buyVisible: false, - schedule: 0, - plan: '', - noteKeyword: '', - searchTimer: null, - notes: [], - showNoteAdd: false, - noteContent: '', - noteForm: { - cid: +this.$route.query.courseId, - noteContent: '', - noteName: '', - }, - msg: '', - msgs: [ - { - avatar: 'https://cube.elemecdn.com/3/7c/3ea6beec64369c2642b92c6726f1epng.png', - createDate: '2023-04-28 12:41:10', - userName: '刘恒', - content: '基础、个人、增值', - showReply: false, - getCommentReplyNum: 1, - showChildren: false, - children: [ - { - avatar: 'https://cube.elemecdn.com/3/7c/3ea6beec64369c2642b92c6726f1epng.png', - createDate: '2023-04-29 09:22:13', - userName: '公瑾', - content: '基础、个人、增值', - showReply: false, - } - ] - } - ] - }; + components: { pdf, breadcrumb, pdfDia, quill, Editor }, + data () { + return { + mallId: this.$route.query.mallId || '', + editorConfig, + startTime: Date.now(), // 页面进来的时间 + systemIds: '', + courseId: +this.$route.query.courseId, + curriculumName: this.$route.query.curriculumName, + type: 1, + video: "http://liuwanr.oss-cn-shenzhen.aliyuncs.com/mp4/20200519/1589871025648.mp4", + chapterList: [], // 章节列表 + progressList: [], + coverUrl: "", // 课程封面 + courseName: "", // 课程名称 + briefIntroduction: "", // 课程简介 + teachingObjectives: "", // 课程目标 + assessmentList: "", // 考核列表 + curLink: "", // 当前选中 + active: 1, + tabs: [ + { + id: 1, + name: '课程介绍' + }, + { + id: 2, + name: '课程笔记' + }, + { + id: 3, + name: '全国排行榜' + }, + { + id: 4, + name: '教学互动' + } + ], + playAuth: "", + player: null, + previewImg: "", + iframeSrc: "", + isWord: false, + isPPT: false, + isExcel: false, + showMask: false, + showMask1: false, + showMask2: false, + closePosi: { + top: "80px" + }, + pdfVisible: false, + pdfSrc: "", + currentPage: 0, // pdf文件页码 + pageCount: 0, // pdf文件总页数 + fileType: "pdf", // 文件类型 + desShrink: false, + projectVisible: false, + projects: [], + loading: false, + curProject: '', + overdue: 0, //是否过期 + buyVisible: false, + schedule: 0, + plan: '', + noteKeyword: '', + searchTimer: null, + notes: [], + showNoteAdd: false, + noteContent: '', + noteForm: { + cid: +this.$route.query.courseId, + noteContent: '', + noteName: '', + }, + msg: '', + msgs: [ + { + avatar: 'https://cube.elemecdn.com/3/7c/3ea6beec64369c2642b92c6726f1epng.png', + createDate: '2023-04-28 12:41:10', + userName: '刘恒', + content: '基础、个人、增值', + showReply: false, + getCommentReplyNum: 1, + showChildren: false, + children: [ + { + avatar: 'https://cube.elemecdn.com/3/7c/3ea6beec64369c2642b92c6726f1epng.png', + createDate: '2023-04-29 09:22:13', + userName: '公瑾', + content: '基础、个人、增值', + showReply: false, + } + ] + } + ] + }; + }, + computed: { + ...mapState("user", [ + "userId", "studentId", "roleId", "userName" + ]) + }, + watch: { + noteKeyword: function (val) { + clearTimeout(this.searchTimer); + this.searchTimer = setTimeout(() => { + this.getNote(); + }, 500); + } + }, + mounted () { + this.insertScript(); + this.getData(); + this.addRecord() + this.getNote() + }, + destroyed () { + // 记录播放时长 + this.$post(this.api.playRecordSave, { + courseId: this.courseId, + courseType: 0, + playTime: Math.ceil((Date.now() - this.startTime) / 1000 / 60) + }).then(({ data }) => { }).catch(res => { }) + }, + methods: { + goBack () { + this.$router.push('/station') }, - computed: { - ...mapState("user", [ - "userId", "studentId", "roleId", "userName" - ]) + async getData () { + let { data } = await this.$post(`${this.api.curriculumDetail}?cid=${this.courseId}&mallId=${this.mallId}`); + this.courseName = data.curriculumName; + // this.coverUrl = data.coverUrl; + this.briefIntroduction = data.briefIntroduction; + this.teachingObjectives = data.teachingObjectives; + this.assessmentList = data.assessmentConfig; + this.systemIds = data.systemIds + this.getStatus() }, - watch: { - noteKeyword: function(val) { - clearTimeout(this.searchTimer); - this.searchTimer = setTimeout(() => { - this.getNote(); - }, 500); - } + // 记录最近使用 + addRecord () { + this.$post(`${this.api.recordRecentUsage}?cid=${this.courseId}`).then(res => { }).catch(res => { }) + }, + // 查询是否过期 + getStatus () { + this.$get(this.api.whetherToRenewTheFee, { + cid: this.courseId + }).then(({ isRenew }) => { + // 1正常显示资源,0显示续费 + this.overdue = isRenew + this.getChapter(1) + this.getProgress() + }).catch(res => { }) + }, + // 获取章节小节 + async getChapter () { + let res = await this.$get(`${this.api.curriculumChapter}/${this.courseId}`); + this.chapterList = res.chapterList; + if (this.chapterList.length && this.chapterList[0].subsectionList && this.chapterList[0].subsectionList.length) { + this.preview(this.chapterList[0].subsectionList[0], this.chapterList[0].name, 1); + } }, - mounted() { - this.insertScript(); - this.getData(); - this.addRecord() + // 获取学习进度 + async getProgress () { + let res = await this.$post(`${this.api.courseLearningProgress}?courseId=${this.courseId}&systemId=${this.systemIds}`); + this.progressList = res.list + this.plan = res.plan + this.schedule = +(res.schedule.replace('%', '')) + }, + // 进度数字自定义 + percentFormat (val) { + return this.plan + }, + // 目录和进度切换 + typeChange (id) { + this.getChapter() + this.type = id + }, + // 获取课程笔记 + getNote () { + this.$get(this.api.curriculumNoteList, { + cid: this.courseId, + search: this.noteKeyword + }).then(res => { + this.notes = res.curriculumNotes + }).catch(res => { }) + }, + // 新增笔记 + addNote () { + this.noteForm = { + cid: this.courseId, + noteContent: '', + noteName: '', + } + this.showNoteAdd = true + }, + // 保存笔记 + submitNote () { + const form = this.noteForm + console.log(33, form, this.noteContent) + 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 ? '修改成功' : '添加成功') + this.showNoteAdd = false + }).catch(res => { }) }, - destroyed() { - // 记录播放时长 - this.$post(this.api.playRecordSave, { - courseId: this.courseId, - courseType: 0, - playTime: Math.ceil((Date.now() - this.startTime) / 1000 / 60) - }).then(({ data }) => {}).catch(res => {}) + // 删除笔记 + delNote (row) { + this.$confirm("此删除操作不可逆,是否确认删除选中项?", "提示", { + type: "warning" + }).then(() => { + this.$post(`${this.api.deleteNotes}?noteId=${row.noteId}`).then(res => { + util.successMsg("删除成功"); + this.getNote(); + }).catch(res => { }) + }).catch(() => { }) }, - methods: { - goBack() { - this.$router.push('/station') - }, - async getData() { - let { data } = await this.$post(`${this.api.curriculumDetail}?cid=${this.courseId}&mallId=${this.mallId}`); - this.courseName = data.curriculumName; - // this.coverUrl = data.coverUrl; - this.briefIntroduction = data.briefIntroduction; - this.teachingObjectives = data.teachingObjectives; - this.assessmentList = data.assessmentConfig; - this.systemIds = data.systemIds - this.getStatus() - }, - // 记录最近使用 - addRecord() { - this.$post(`${this.api.recordRecentUsage}?cid=${this.courseId}`).then(res => {}).catch(res => {}) - }, - // 查询是否过期 - getStatus() { - this.$get(this.api.whetherToRenewTheFee, { - cid: this.courseId - }).then(({ isRenew }) => { - // 1正常显示资源,0显示续费 - this.overdue = isRenew - this.getChapter(1) - this.getProgress() - }).catch(res => {}) - }, - // 获取章节小节 - async getChapter() { - let res = await this.$get(`${this.api.curriculumChapter}/${this.courseId}`); - this.chapterList = res.chapterList; - if (this.chapterList.length && this.chapterList[0].subsectionList && this.chapterList[0].subsectionList.length) { - this.preview(this.chapterList[0].subsectionList[0], this.chapterList[0].name, 1); - } - }, - // 获取学习进度 - async getProgress() { - let res = await this.$post(`${this.api.courseLearningProgress}?courseId=${this.courseId}&systemId=${this.systemIds}`); - this.progressList = res.list - this.plan = res.plan - this.schedule = +(res.schedule.replace('%', '')) - }, - // 进度数字自定义 - percentFormat(val) { - return this.plan - }, - // 目录和进度切换 - typeChange(id) { - this.getChapter() - this.type = id - }, - // 获取课程笔记 - getNote() { - this.$get(this.api.curriculumNoteList, { - cid: this.courseId, - search: this.noteKeyword - }).then(res => { - this.notes = res.curriculumNotes - }).catch(res => {}) - }, - // 新增笔记 - addNote() { - this.noteForm = { - cid: this.courseId, - noteContent: '', - noteName: '', - } - this.showNoteAdd = true - }, - // 保存笔记 - submitNote() { - const form = this.noteForm - console.log(33, form,this.noteContent) - 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 ? '修改成功' : '添加成功') - this.showNoteAdd = false - }).catch(res => {}) - }, - // 删除笔记 - delNote(row) { - this.$confirm("此删除操作不可逆,是否确认删除选中项?", "提示", { - type: "warning" - }).then(() => { - this.$post(`${this.api.deleteNotes}?noteId=${row.noteId}`).then(res => { - util.successMsg("删除成功"); - this.getNote(); - }).catch(res => {}) - }).catch(() => {}) - }, - // 编辑笔记 - editNote(row) { - this.noteForm = JSON.parse(JSON.stringify(row)) - this.showNoteAdd = true - }, - // 插入阿里云播放器脚本 - insertScript() { - const linkTag = document.createElement("link"); - linkTag.id = "aliplayerLink"; - linkTag.rel = "stylesheet"; - linkTag.href = "https://g.alicdn.com/de/prismplayer/2.8.2/skins/default/aliplayer-min.css"; - document.body.appendChild(linkTag); + // 编辑笔记 + editNote (row) { + this.noteForm = JSON.parse(JSON.stringify(row)) + this.showNoteAdd = true + }, + // 插入阿里云播放器脚本 + insertScript () { + const linkTag = document.createElement("link"); + linkTag.id = "aliplayerLink"; + linkTag.rel = "stylesheet"; + linkTag.href = "https://g.alicdn.com/de/prismplayer/2.8.2/skins/default/aliplayer-min.css"; + document.body.appendChild(linkTag); - const scriptTag = document.createElement("script"); - scriptTag.id = "aliplayerScript"; - scriptTag.type = "text/javascript"; - scriptTag.src = "https://g.alicdn.com/de/prismplayer/2.8.2/aliplayer-min.js"; - document.body.appendChild(scriptTag); - this.$once("hook:beforeDestroy", function() { - document.body.removeChild(document.querySelector("#aliplayerLink")); - document.body.removeChild(document.querySelector("#aliplayerScript")); + const scriptTag = document.createElement("script"); + scriptTag.id = "aliplayerScript"; + scriptTag.type = "text/javascript"; + scriptTag.src = "https://g.alicdn.com/de/prismplayer/2.8.2/aliplayer-min.js"; + document.body.appendChild(scriptTag); + this.$once("hook:beforeDestroy", function () { + document.body.removeChild(document.querySelector("#aliplayerLink")); + document.body.removeChild(document.querySelector("#aliplayerScript")); + }); + }, + // 显示咨询弹框 + showBuy () { + this.buyVisible = true + }, + transferType (ext) { + const suf = ext.toLowerCase() + if ('jpg,jpeg,png,gif,svg,psd'.includes(suf)) return '图片' + if ('mp4,3gp,mov,m4v,avi,dat,mkv,flv,vob,rmvb,rm,qlv'.includes(suf)) return '视频' + return suf + }, + // tab切换 + tabChange (item) { + this.active = item.id + }, + // 勾选/取消勾选学习进度 + studySection (item) { + item.whetherToStudyOrNot ? + this.$post(`${this.api.deleteLearningProgress}?id=${item.learningProgressId}`).then(res => { + this.getProgress() + }).catch(res => { }) : + this.$post(this.api.saveLearningProgress, { + cid: this.courseId, + projectId: item.projectId, + }).then(res => { + this.getProgress() + }).catch(res => { }) + }, + preview (row, chapterName, showDia = 0) { + // 如果没过期,则正常预览,否则显示购买弹框 + if (this.overdue || showDia) { + this.curLink = `${chapterName}${row.name}`; // 章节名称+小节名称,小节名称有重复的情况,如果只用小节名称判断,会有同时选中多个的情况 + this.playauth = ""; + this.coverUrl = ""; + this.pdfSrc = ""; + this.iframeSrc = ""; + this.isPPT = false; + this.isWord = false; + this.isExcel = false; + if (this.transferType(row.fileType) == "视频") { + this.$get(`${this.api.getPlayAuth}/${row.fileId}`).then(res => { + this.playAuth = res.data.playAuth; + // 如果已经产生了实例,则销毁重新创建,不然播放器会播放上一个视频 + if (this.player) { + this.player.dispose() + this.player = null + } + this.$nextTick(() => { + if (this.player) { + this.player.replayByVidAndPlayAuth(row.fileId, this.playAuth); + } else { + this.player = new Aliplayer({ + id: "player", + width: "100%", + autoplay: false, + vid: row.fileId, + playauth: this.playAuth, + encryptType: 1 //当播放私有加密流时需要设置。 + }); + } }); - }, - // 显示咨询弹框 - showBuy() { - this.buyVisible = true - }, - transferType(ext) { - const suf = ext.toLowerCase() - if('jpg,jpeg,png,gif,svg,psd'.includes(suf)) return '图片' - if('mp4,3gp,mov,m4v,avi,dat,mkv,flv,vob,rmvb,rm,qlv'.includes(suf)) return '视频' - return suf - }, - // tab切换 - tabChange(item) { - this.active = item.id - }, - // 勾选/取消勾选学习进度 - studySection(item) { - item.whetherToStudyOrNot ? - this.$post(`${this.api.deleteLearningProgress}?id=${item.learningProgressId}`).then(res => { - this.getProgress() - }).catch(res => {}) : - this.$post(this.api.saveLearningProgress, { - cid: this.courseId, - projectId: item.projectId, - }).then(res => { - this.getProgress() - }).catch(res => {}) - }, - preview(row, chapterName, showDia = 0) { - // 如果没过期,则正常预览,否则显示购买弹框 - if (this.overdue || showDia) { - this.curLink = `${chapterName}${row.name}`; // 章节名称+小节名称,小节名称有重复的情况,如果只用小节名称判断,会有同时选中多个的情况 - this.playauth = ""; - this.coverUrl = ""; - this.pdfSrc = ""; - this.iframeSrc = ""; - this.isPPT = false; - this.isWord = false; - this.isExcel = false; - if (this.transferType(row.fileType) == "视频") { - this.$get(`${this.api.getPlayAuth}/${row.fileId}`).then(res => { - this.playAuth = res.data.playAuth; - // 如果已经产生了实例,则销毁重新创建,不然播放器会播放上一个视频 - if (this.player) { - this.player.dispose() - this.player = null - } - this.$nextTick(() => { - if (this.player) { - this.player.replayByVidAndPlayAuth(row.fileId, this.playAuth); - } else { - this.player = new Aliplayer({ - id: "player", - width: "100%", - autoplay: false, - vid: row.fileId, - playauth: this.playAuth, - encryptType: 1 //当播放私有加密流时需要设置。 - }); - } - }); - }).catch(res => { - }); - } else if (this.transferType(row.fileType) == "图片") { - this.coverUrl = row.fileUrl; - } else if (row.fileType == "pdf") { - this.pdfSrc = row.fileUrl; + }).catch(res => { + }); + } else if (this.transferType(row.fileType) == "图片") { + this.coverUrl = row.fileUrl; + } else if (row.fileType == "pdf") { + this.pdfSrc = row.fileUrl; + } else { + this.$get(`${this.api.curriculumGetSubsection}/${row.id}`).then(res => { + if (row.fileType == "pptx") { + this.isPPT = true; + this.isWord = false; + this.isExcel = false; + } else if (row.fileType == "doc" || row.fileType == "docx") { + this.isPPT = false; + this.isWord = true; + this.isExcel = false; + } else if (row.fileType == "xls" || row.fileType == "xlsx") { + this.isExcel = true; + this.isPPT = false; + this.isWord = false; } else { - this.$get(`${this.api.curriculumGetSubsection}/${row.id}`).then(res => { - if (row.fileType == "pptx") { - this.isPPT = true; - this.isWord = false; - this.isExcel = false; - } else if (row.fileType == "doc" || row.fileType == "docx") { - this.isPPT = false; - this.isWord = true; - this.isExcel = false; - } else if (row.fileType == "xls" || row.fileType == "xlsx") { - this.isExcel = true; - this.isPPT = false; - this.isWord = false; - } else { - this.isPPT = false; - this.isWord = false; - this.isExcel = false; - } - if (this.isPPT) { - this.showMask = true; - } else { - this.showMask = false; - } - if (this.isWord) { - this.showMask1 = true; - } else { - this.showMask1 = false; - } - if (this.isExcel) { - this.showMask2 = true; - } else { - this.showMask2 = false; - } - this.iframeSrc = res.previewUrl; - }).catch(err => {}); + this.isPPT = false; + this.isWord = false; + this.isExcel = false; } - } else { - this.showBuy() - } - }, - closeIframe() { - this.iframeSrc = ""; - this.showMask = false; - this.showMask1 = false; - }, - closePdf() { - this.pdfSrc = ""; - this.currentPage = 1; - }, - changePdfPage(val) { - if (val === 0 && this.currentPage > 1) { - this.currentPage--; + if (this.isPPT) { + this.showMask = true; + } else { + this.showMask = false; } - if (val === 1 && this.currentPage < this.pageCount) { - this.currentPage++; + if (this.isWord) { + this.showMask1 = true; + } else { + this.showMask1 = false; } - }, - loadPdfHandler(e) { - this.currentPage = 1; - }, - // pdf全屏 - fullScreen() { - this.pdfVisible = true - }, - // 选择项目 - selectProject(item) { - this.curProject = item.projectId - }, - // 展示选择项目弹框 - queryProject() { - this.projectVisible = true - this.loading = true - this.$get(this.api.getProjectBySystemId, { - systemId: this.systemIds, - cId: this.courseId, // 课程id - permissions: 0 // 0: 练习,1: 考核 - }).then(({ projects }) => { - this.loading = false - this.projects = projects - }).catch(res => {}) - }, - // 进入实验 - entry() { - // 查询上次做的项目 - this.$get(this.api.getTheMostRecentlyRunProject, { - cid: this.courseId - }).then(({ data }) => { - // 返回了data则提示是否继续,否则,显示选择项目的弹框 - if (data && data.length) { - this.$confirm('是否要继续上次的实验?', '提示', { - confirmButtonText: '是', - cancelButtonText: '否', - type: 'success' - }).then(() => { - this.toPython(data[0].projectId) - }).catch(() => { - this.queryProject() - }) + if (this.isExcel) { + this.showMask2 = true; } else { - this.queryProject() + this.showMask2 = false; } - }).catch(res => { + this.iframeSrc = res.previewUrl; + }).catch(err => { }); + } + } else { + this.showBuy() + } + }, + closeIframe () { + this.iframeSrc = ""; + this.showMask = false; + this.showMask1 = false; + }, + closePdf () { + this.pdfSrc = ""; + this.currentPage = 1; + }, + changePdfPage (val) { + if (val === 0 && this.currentPage > 1) { + this.currentPage--; + } + if (val === 1 && this.currentPage < this.pageCount) { + this.currentPage++; + } + }, + loadPdfHandler (e) { + this.currentPage = 1; + }, + // pdf全屏 + fullScreen () { + this.pdfVisible = true + }, + // 选择项目 + selectProject (item) { + this.curProject = item.projectId + }, + // 展示选择项目弹框 + queryProject () { + this.projectVisible = true + this.loading = true + this.$get(this.api.getProjectBySystemId, { + systemId: this.systemIds, + cId: this.courseId, // 课程id + permissions: 0 // 0: 练习,1: 考核 + }).then(({ projects }) => { + this.loading = false + this.projects = projects + }).catch(res => { }) + }, + // 进入实验 + entry () { + // 查询上次做的项目 + this.$get(this.api.getTheMostRecentlyRunProject, { + cid: this.courseId + }).then(({ data }) => { + // 返回了data则提示是否继续,否则,显示选择项目的弹框 + if (data && data.length) { + this.$confirm('是否要继续上次的实验?', '提示', { + confirmButtonText: '是', + cancelButtonText: '否', + type: 'success' + }).then(() => { + this.toPython(data[0].projectId) + }).catch(() => { this.queryProject() }) - }, - // 进入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('courseId', this.courseId) - util.cookies.set('curriculumName', escape(this.curriculumName)) - util.cookies.set('systemId', id) - util.cookies.set('fromManager', '', -1) - util.cookies.set('competitionId', '', -1) - // 8个python子系统都跳这个地址,子系统会通过cookie里的systemId识别展示哪套系统 - location.href = process.env.NODE_ENV === 'development' ? - `http://${location.hostname}:8085/#/` : - Setting.isPro ? - `https://${location.hostname}/pyTrials` : - `${location.origin}/pyTrials` - }, - // 进入子系统 - toSub() { - const { systemId } = this.projects.find(e => e.projectId == this.curProject) - let token = util.local.get(Setting.tokenKey); - let roleId = this.roleId == 4 ? 0 : 1; - let userName = window.btoa(encodeURIComponent(this.userName)); - if (systemId == 11) { - // 银行系统 - location.href = `${Setting.systemPath}/#/index/list?curriculumName=${this.curriculumName}&token=${token}&cid=${this.courseId}&systemId=${this.systemIds}&projectId=${this.curProject}&assessmentId=&classId=&stopTime=&test=true` - } else if (systemId == 12) { - // 众筹系统 - window.open(`http://120.78.139.126:8879?systemId=${systemId}&courseId=${this.courseId}&projectId=${this.curProject}&token=${token}&userId=${this.userId}&classId=1`); - } else if (systemId == 21) { - window.open(`http://121.37.29.24:80/yyyflogin?userId=${this.userId}&userName=${userName}&userType=${roleId}&reqType=1&reqId=3989a0ad671849b99dcbdcc208782333&caseId=9681f86902314b10bc752909121f9ab9&authorization=87DIVy348Oxzj3ha&classId=1876&courserId=7ff5d4715b114b7398b6f26c20fac460`); - } else if (systemId == 22) { - window.open(`https://danbao.czcyedu.com/#/loginFromYyyf?userId=${this.userId}&userName=${userName}&userType=${roleId}&reqType=1&reqId=eb7d8355119d449184c548b07dc01ed9&caseId=1198241070647873538&authorization=87DIVy348Oxzj3ha&classId=1876&courserId=faaedd82adb9444285a5785e4a3dd4f9`); - } else { - // python系统 - this.toPython(this.curProject) - } + } else { + this.queryProject() } + }).catch(res => { + this.queryProject() + }) + }, + // 进入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('courseId', this.courseId) + util.cookies.set('curriculumName', escape(this.curriculumName)) + util.cookies.set('systemId', id) + util.cookies.set('mallId', this.mallId) + util.cookies.set('fromManager', '', -1) + util.cookies.set('competitionId', '', -1) + // 8个python子系统都跳这个地址,子系统会通过cookie里的systemId识别展示哪套系统 + location.href = process.env.NODE_ENV === 'development' ? + `http://${location.hostname}:8085/#/` : + Setting.isPro ? + `https://${location.hostname}/pyTrials` : + `${location.origin}/pyTrials` + }, + // 进入子系统 + toSub () { + const { systemId } = this.projects.find(e => e.projectId == this.curProject) + let token = util.local.get(Setting.tokenKey); + let roleId = this.roleId == 4 ? 0 : 1; + let userName = window.btoa(encodeURIComponent(this.userName)); + if (systemId == 11) { + // 银行系统 + location.href = `${Setting.systemPath}/#/index/list?curriculumName=${this.curriculumName}&token=${token}&cid=${this.courseId}&systemId=${this.systemIds}&projectId=${this.curProject}&assessmentId=&classId=&stopTime=&test=true` + } else if (systemId == 12) { + // 众筹系统 + window.open(`http://120.78.139.126:8879?systemId=${systemId}&courseId=${this.courseId}&projectId=${this.curProject}&token=${token}&userId=${this.userId}&classId=1`); + } else if (systemId == 21) { + window.open(`http://121.37.29.24:80/yyyflogin?userId=${this.userId}&userName=${userName}&userType=${roleId}&reqType=1&reqId=3989a0ad671849b99dcbdcc208782333&caseId=9681f86902314b10bc752909121f9ab9&authorization=87DIVy348Oxzj3ha&classId=1876&courserId=7ff5d4715b114b7398b6f26c20fac460`); + } else if (systemId == 22) { + window.open(`https://danbao.czcyedu.com/#/loginFromYyyf?userId=${this.userId}&userName=${userName}&userType=${roleId}&reqType=1&reqId=eb7d8355119d449184c548b07dc01ed9&caseId=1198241070647873538&authorization=87DIVy348Oxzj3ha&classId=1876&courserId=faaedd82adb9444285a5785e4a3dd4f9`); + } else { + // python系统 + this.toPython(this.curProject) + } } + } }; </script> <style lang="scss" scoped> -@import "../../../styles/page/station.scss"; +@import '../../../styles/page/station.scss'; $height: 700px; -.video_wid,.cover{ +.video_wid, +.cover { position: relative; width: 76%; height: $height !important; @@ -728,44 +843,45 @@ $height: 700px; } } .l-title { - font-size: 17px; + font-size: 17px; } -.cover{ +.cover { flex: 1; background-color: #252528; - img{ + img { border-radius: 8px; } - &.is-word{ + &.is-word { overflow: hidden; } } -.fileIframe{ +.fileIframe { height: $height !important; } -.video_wid,.inner{ +.video_wid, +.inner { width: 100%; height: 100% !important; border: 0; overflow: auto; } -.cover.is-word{ - .inner{ +.cover.is-word { + .inner { height: calc(100% + 38px) !important; margin-top: -38px; } } -.video_wid:focus{ +.video_wid:focus { outline: none; } -.catalog{ +.catalog { width: 296px; padding: 16px; margin-left: 12px; background-color: #252528; .renew { - width: 100%; - margin-bottom: 16px; + width: 100%; + margin-bottom: 16px; } .entry { display: block; @@ -775,70 +891,70 @@ $height: 700px; background: url(../../../assets/img/entry.png) 0 0/100% 100% no-repeat; cursor: pointer; &:hover { - opacity: .9; + opacity: 0.9; } } .types { - display: flex; - margin: 15px 0; - .item { - display: inline-flex; - justify-content: center; - align-items: center; - width: 120px; - height: 40px; - color: #fff; - background-color: #4e4e4e; - border-radius: 4px; - cursor: pointer; - &:first-child { - margin-right: 10px; - } - &:hover { - background-color: #528adf; + display: flex; + margin: 15px 0; + .item { + display: inline-flex; + justify-content: center; + align-items: center; + width: 120px; + height: 40px; + color: #fff; + background-color: #4e4e4e; + border-radius: 4px; + cursor: pointer; + &:first-child { + margin-right: 10px; + } + &:hover { + background-color: #528adf; + } + &.active { + background-color: $main-color; + } } - &.active { - background-color: $main-color; + .icon { + margin-right: 5px; + font-size: 18px; } - } - .icon { - margin-right: 5px; - font-size: 18px; - } } } -.list{ - height: calc(700px - 82px) ; +.list { + height: calc(700px - 82px); overflow-y: auto; - .title{ + .title { margin-bottom: 11px; color: #fff; font-size: 16px; } .pro-title { - margin-bottom: 5px; - color: #fff; - font-size: 12px; + margin-bottom: 5px; + color: #fff; + font-size: 12px; } /deep/.el-progress-bar { - width: 92%; + width: 92%; } /deep/.el-progress__text { - color: #fff; + color: #fff; } - .desc-wrap{ + .desc-wrap { position: relative; - .desc{ + .desc { font-size: 12px; color: rgba(0, 0, 0, 0.65); line-height: 22px; @include mul-ellipsis(2); - &.active{ + &.active { display: block; overflow: visible; } } - .arrow{ + .arrow { position: absolute; bottom: 2px; right: 0; @@ -846,42 +962,42 @@ $height: 700px; justify-content: space-between; width: 46px; background-color: #fff; - span{ + span { font-size: 14px; color: rgba(0, 0, 0, 0.65); } - img{ + img { width: 16px; cursor: pointer; } - &.active{ - span{ + &.active { + span { opacity: 0; } - img{ + img { transform: rotate(180deg); } } } } - .chapters{ + .chapters { margin-top: 16px; max-height: calc(100% - 53px); overflow: auto; } - .chapter{ + .chapter { margin-bottom: 20px; } - .chapterName{ + .chapterName { color: #fff; font-size: 14px; } - .section{ + .section { padding: 5px 15px; margin-top: 12px; background-color: #121214; } - .sectionName{ + .sectionName { position: relative; padding-right: 15px; margin: 12px 0; @@ -893,46 +1009,46 @@ $height: 700px; margin-right: 8px; } .icon { - position: absolute; - right: 0; - font-size: 14px; - color: #00c935; + position: absolute; + right: 0; + font-size: 14px; + color: #00c935; } .circle { - width: 14px; - height: 14px; - border-radius: 50%; - border: 1px solid #ccc; + width: 14px; + height: 14px; + border-radius: 50%; + border: 1px solid #ccc; } - &.active{ + &.active { color: #fff; } } } .buy { - text-align: center; - .tips { - margin-bottom: 10px; - font-size: 14px; - } - img { - width: 85%; - } + text-align: center; + .tips { + margin-bottom: 10px; + font-size: 14px; + } + img { + width: 85%; + } } -.el-image-viewer__wrapper{ +.el-image-viewer__wrapper { transform: translateY(-10px); - transition: transform .5s; + transition: transform 0.5s; - &.active{ - transform: translateY(0) + &.active { + transform: translateY(0); } } -.el-image-viewer__close{ +.el-image-viewer__close { z-index: 2000; top: 15px; right: 15px; - &.doc-close{ - i{ + &.doc-close { + i { color: #000 !important; } } @@ -945,20 +1061,20 @@ $height: 700px; background: rgba(0, 0, 0, 0.06); } -.mask{ +.mask { z-index: 9; position: absolute; - background-color: rgb(57,58,61); + background-color: rgb(57, 58, 61); } -.word-mask{ +.word-mask { z-index: 9; position: absolute; top: 0; right: 0; width: 100%; - background-color: rgb(243,242,241); + background-color: rgb(243, 242, 241); } -.word-mask1{ +.word-mask1 { z-index: 9; position: absolute; top: 0; @@ -966,12 +1082,12 @@ $height: 700px; width: 100%; background-color: #185abd; } -.word-mask2{ +.word-mask2 { z-index: 9; position: absolute; background-color: transparent; } -.excel-mask1{ +.excel-mask1 { z-index: 9; position: absolute; top: 0; @@ -979,31 +1095,31 @@ $height: 700px; width: 60%; background-color: #107c41; } -/deep/.pdf-dia{ +/deep/.pdf-dia { border-radius: 0 !important; - .el-dialog__header{ + .el-dialog__header { display: none; } - .el-dialog__body{ + .el-dialog__body { padding: 0; } - .el-dialog__headerbtn{ + .el-dialog__headerbtn { top: 10px; - .el-dialog__close{ + .el-dialog__close { color: #fff; font-size: 16px; } } } -.pdf{ +.pdf { position: relative; .full { - position: absolute; - top: 7px; - right: 10px; - cursor: pointer; + position: absolute; + top: 7px; + right: 10px; + cursor: pointer; } - .arrow{ + .arrow { padding: 10px 0; display: flex; justify-content: center; @@ -1011,57 +1127,57 @@ $height: 700px; font-size: 16px; color: #fff; background-color: #333; - .turn{ + .turn { margin: 0 10px; font-size: 18px; cursor: pointer; } } - .pdf-wrap{ + .pdf-wrap { width: 80%; margin: 0 auto; } } /deep/.project-dia { - .el-dialog__body { - padding: 28px 32px; - } + .el-dialog__body { + padding: 28px 32px; + } } .projects { - display: flex; - flex-wrap: wrap; - max-height: 400px; - overflow: auto; - li { - display: inline-flex; - align-items: center; - width: 238px; - padding: 16px; - margin: 0 20px 20px 0; - background-color: #F6F8FA; - border-radius: 16px; - cursor: pointer; - &:hover { - span { - color: #007EFF; - } - } - &:nth-child(3n) { - margin-right: 0; + display: flex; + flex-wrap: wrap; + max-height: 400px; + overflow: auto; + li { + display: inline-flex; + align-items: center; + width: 238px; + padding: 16px; + margin: 0 20px 20px 0; + background-color: #f6f8fa; + border-radius: 16px; + cursor: pointer; + &:hover { + span { + color: #007eff; + } + } + &:nth-child(3n) { + margin-right: 0; + } + &.active { + background-color: #f2f7ff; + span { + color: #3988ff; + } + } } - &.active { - background-color: #f2f7ff; - span { - color: #3988ff; - } + span { + max-width: 140px; + margin-left: 14px; + font-size: 14px; + color: #333; } - } - span { - max-width: 140px; - margin-left: 14px; - font-size: 14px; - color: #333; - } } .tabs { display: flex; @@ -1077,13 +1193,13 @@ $height: 700px; border-bottom: 3px solid transparent; cursor: pointer; &.active { - color: #007EFF; - border-color: #007EFF; + color: #007eff; + border-color: #007eff; } } } .tab-content { - width: 80%; + width: 80%; } @media (max-width: 1430px) { .wrap {