提交 1e93d3ba authored 作者: 王鹏飞's avatar 王鹏飞

移除无用文件

上级 20e1e6a1
/* Automatically generated by './build/bin/build-entry.js' */ /* Automatically generated by './build/bin/build-entry.js' */
/* 模块基于 element-ui,一定在 element-ui后加载 */ /* 模块基于 element-ui,一定在 element-ui后加载 */
import LoginModule from './login-module'
import Discuss from './discuss' import Discuss from './discuss'
const components = [ const components = [Discuss]
LoginModule,
Discuss
]
const install = function (Vue, opts = {}) { const install = function(Vue, opts = {}) {
components.forEach(component => { components.forEach(component => {
Vue.use(component, opts) Vue.use(component, opts)
}) })
...@@ -22,6 +18,5 @@ if (typeof window !== 'undefined' && window.Vue) { ...@@ -22,6 +18,5 @@ if (typeof window !== 'undefined' && window.Vue) {
export default { export default {
install, install,
LoginModule,
Discuss Discuss
} }
import BaseACTION from '@/action/base_action'
import { Login } from '../api'
export default class LoginAction extends BaseACTION {
/**
* 当前登录用户,检测是否该系统有权限
*/
getInfo () { return Login.getInfo().then(res => res) }
/**
* 调用登录接口
*/
userLogin (obj) {
return Login.userLogin(obj).then(res => {
if (res && res.url === undefined) {
res.url = webConf.others.url || ''
}
return res
})
}
/**
* 调用验证码登录
*/
codeLogin (obj) {
return Login.codeLogin(obj).then(res => {
if (res && res.url === undefined) {
res.url = webConf.others.url || ''
}
return res
})
}
/* 调用退出登录接口 */
outLogin () { return Login.outLogin().then(res => res) }
/**
* 调用获取验证码
*/
sendCode (obj) { return Login.sendCode(obj).then(res => res) }
/**
* 调用发送重置密码验证码
*/
sendResetPwdCode (obj) { return Login.sendResetPwdCode(obj).then(res => res) }
/**
* 调用重置密码验证码确认
*/
validateCode (obj) { return Login.validateCode(obj).then(res => res) }
/**
* 调用重置密码
*/
resetPwd (obj) { return Login.resetPwd(obj).then(res => res) }
/**
* 清空cookies
*/
clearCookies (obj) { return Login.clearCookies(obj).then(res => res) }
}
import LoginAction from './LoginAction'
const Login = new LoginAction()
export default Login
import LoginAPI from './login_api'
const Login = new LoginAPI(webConf)
export {
Login
}
import BaseAPI from '@/api/base_api'
export default class LoginAPI extends BaseAPI {
/**
* 调用登录接口
* @param {[string]} obj.login_name 用户名
* @param {[string]} obj.password 密码 md5加密
* @param {[string]} obj.service 传当前域名
*/
userLogin = (obj = {}) => this.post('/api/passport/rest/login', obj, { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } })
/**
* 调用退出登录
*/
outLogin = () => this.get('/api/passport/rest/logout', {}, { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } })
/**
* 当前登录用户,检测是否该系统有权限
*/
getInfo = () => this.get('/api/passport/account/get-user-info', {}, { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } })
/**
* 发送验证码
* @param {[string]} obj.mobile 手机号
* @param {[string]} obj.service 传当前域名
*/
sendCode = (obj = {}) => this.post('/api/usercenter/user/send-code', obj, { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } })
/**
* 验证码登录
* @param {[string]} obj.mobile 手机号
* @param {[string]} obj.code 验证码
* @param {[string]} obj.service 传当前域名
*/
codeLogin = (obj = {}) => this.post('/api/passport/rest/login', obj, { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } })
/**
* 发送重置密码验证码
* @param {[string]} obj.contact 手机号/邮箱
* @param {[string]} obj.source_type 值为 3
* @param {[string]} obj.service 传当前域名
*/
sendResetPwdCode = (obj = {}) => this.post('/api/usercenter/user/send-code', obj, { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } })
/**
* 重置密码验证码确认
* @param {[string]} obj.contact 手机号/邮箱
* @param {[string]} obj.code 验证码
* @param {[string]} obj.service 传当前域名
*/
validateCode = (obj = {}) => this.post('/api/passport/user_center/validate_code', obj, { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } })
/**
* 重置密码
* @param {[string]} obj.contact 手机号/邮箱
* @param {[string]} obj.code 验证码
* @param {[string]} obj.new_password 新的密码
* @param {[string]} obj.service 传当前域名
*/
resetPwd = (obj = {}) => this.post('/api/usercenter/user/update-pwd', obj, { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } })
/**
* 个人信息 - 修改密码
* @param {[string]} obj.old_password 验证码
* @param {[string]} obj.new_password 新的密码
* @param {[string]} obj.service 传当前域名
*/
updatePwd = (obj = {}) => this.post('/api/usercenter/user/change-pwd-by-cookie', obj, { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } })
/**
* 清空所有cookies
*/
clearCookies = (obj = {}) => this.post('https://learn-pbcsf.ezijing.com/api/clear/cookie', obj, { headers: { 'Content-Type': 'multipart/form-data' } })
}
/* Logo 字体 */
@font-face {
font-family: "iconfont logo";
src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834');
src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834#iefix') format('embedded-opentype'),
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.woff?t=1545807318834') format('woff'),
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.ttf?t=1545807318834') format('truetype'),
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.svg?t=1545807318834#iconfont') format('svg');
}
.logo {
font-family: "iconfont logo";
font-size: 160px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
/* tabs */
.nav-tabs {
position: relative;
}
.nav-tabs .nav-more {
position: absolute;
right: 0;
bottom: 0;
height: 42px;
line-height: 42px;
color: #666;
}
#tabs {
border-bottom: 1px solid #eee;
}
#tabs li {
cursor: pointer;
width: 100px;
height: 40px;
line-height: 40px;
text-align: center;
font-size: 16px;
border-bottom: 2px solid transparent;
position: relative;
z-index: 1;
margin-bottom: -1px;
color: #666;
}
#tabs .active {
border-bottom-color: #f00;
color: #222;
}
.tab-container .content {
display: none;
}
/* 页面布局 */
.main {
padding: 30px 100px;
width: 960px;
margin: 0 auto;
}
.main .logo {
color: #333;
text-align: left;
margin-bottom: 30px;
line-height: 1;
height: 110px;
margin-top: -50px;
overflow: hidden;
*zoom: 1;
}
.main .logo a {
font-size: 160px;
color: #333;
}
.helps {
margin-top: 40px;
}
.helps pre {
padding: 20px;
margin: 10px 0;
border: solid 1px #e7e1cd;
background-color: #fffdef;
overflow: auto;
}
.icon_lists {
width: 100% !important;
overflow: hidden;
*zoom: 1;
}
.icon_lists li {
width: 100px;
margin-bottom: 10px;
margin-right: 20px;
text-align: center;
list-style: none !important;
cursor: default;
}
.icon_lists li .code-name {
line-height: 1.2;
}
.icon_lists .icon {
display: block;
height: 100px;
line-height: 100px;
font-size: 42px;
margin: 10px auto;
color: #333;
-webkit-transition: font-size 0.25s linear, width 0.25s linear;
-moz-transition: font-size 0.25s linear, width 0.25s linear;
transition: font-size 0.25s linear, width 0.25s linear;
}
.icon_lists .icon:hover {
font-size: 100px;
}
.icon_lists .svg-icon {
/* 通过设置 font-size 来改变图标大小 */
width: 1em;
/* 图标和文字相邻时,垂直对齐 */
vertical-align: -0.15em;
/* 通过设置 color 来改变 SVG 的颜色/fill */
fill: currentColor;
/* path 和 stroke 溢出 viewBox 部分在 IE 下会显示
normalize.css 中也包含这行 */
overflow: hidden;
}
.icon_lists li .name,
.icon_lists li .code-name {
color: #666;
}
/* markdown 样式 */
.markdown {
color: #666;
font-size: 14px;
line-height: 1.8;
}
.highlight {
line-height: 1.5;
}
.markdown img {
vertical-align: middle;
max-width: 100%;
}
.markdown h1 {
color: #404040;
font-weight: 500;
line-height: 40px;
margin-bottom: 24px;
}
.markdown h2,
.markdown h3,
.markdown h4,
.markdown h5,
.markdown h6 {
color: #404040;
margin: 1.6em 0 0.6em 0;
font-weight: 500;
clear: both;
}
.markdown h1 {
font-size: 28px;
}
.markdown h2 {
font-size: 22px;
}
.markdown h3 {
font-size: 16px;
}
.markdown h4 {
font-size: 14px;
}
.markdown h5 {
font-size: 12px;
}
.markdown h6 {
font-size: 12px;
}
.markdown hr {
height: 1px;
border: 0;
background: #e9e9e9;
margin: 16px 0;
clear: both;
}
.markdown p {
margin: 1em 0;
}
.markdown>p,
.markdown>blockquote,
.markdown>.highlight,
.markdown>ol,
.markdown>ul {
width: 80%;
}
.markdown ul>li {
list-style: circle;
}
.markdown>ul li,
.markdown blockquote ul>li {
margin-left: 20px;
padding-left: 4px;
}
.markdown>ul li p,
.markdown>ol li p {
margin: 0.6em 0;
}
.markdown ol>li {
list-style: decimal;
}
.markdown>ol li,
.markdown blockquote ol>li {
margin-left: 20px;
padding-left: 4px;
}
.markdown code {
margin: 0 3px;
padding: 0 5px;
background: #eee;
border-radius: 3px;
}
.markdown strong,
.markdown b {
font-weight: 600;
}
.markdown>table {
border-collapse: collapse;
border-spacing: 0px;
empty-cells: show;
border: 1px solid #e9e9e9;
width: 95%;
margin-bottom: 24px;
}
.markdown>table th {
white-space: nowrap;
color: #333;
font-weight: 600;
}
.markdown>table th,
.markdown>table td {
border: 1px solid #e9e9e9;
padding: 8px 16px;
text-align: left;
}
.markdown>table th {
background: #F7F7F7;
}
.markdown blockquote {
font-size: 90%;
color: #999;
border-left: 4px solid #e9e9e9;
padding-left: 0.8em;
margin: 1em 0;
}
.markdown blockquote p {
margin: 0;
}
.markdown .anchor {
opacity: 0;
transition: opacity 0.3s ease;
margin-left: 8px;
}
.markdown .waiting {
color: #ccc;
}
.markdown h1:hover .anchor,
.markdown h2:hover .anchor,
.markdown h3:hover .anchor,
.markdown h4:hover .anchor,
.markdown h5:hover .anchor,
.markdown h6:hover .anchor {
opacity: 1;
display: inline-block;
}
.markdown>br,
.markdown>p>br {
clear: both;
}
.hljs {
display: block;
background: white;
padding: 0.5em;
color: #333333;
overflow-x: auto;
}
.hljs-comment,
.hljs-meta {
color: #969896;
}
.hljs-string,
.hljs-variable,
.hljs-template-variable,
.hljs-strong,
.hljs-emphasis,
.hljs-quote {
color: #df5000;
}
.hljs-keyword,
.hljs-selector-tag,
.hljs-type {
color: #a71d5d;
}
.hljs-literal,
.hljs-symbol,
.hljs-bullet,
.hljs-attribute {
color: #0086b3;
}
.hljs-section,
.hljs-name {
color: #63a35c;
}
.hljs-tag {
color: #333333;
}
.hljs-title,
.hljs-attr,
.hljs-selector-id,
.hljs-selector-class,
.hljs-selector-attr,
.hljs-selector-pseudo {
color: #795da3;
}
.hljs-addition {
color: #55a532;
background-color: #eaffea;
}
.hljs-deletion {
color: #bd2c00;
background-color: #ffecec;
}
.hljs-link {
text-decoration: underline;
}
/* 代码高亮 */
/* PrismJS 1.15.0
https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript */
/**
* prism.js default theme for JavaScript, CSS and HTML
* Based on dabblet (http://dabblet.com)
* @author Lea Verou
*/
code[class*="language-"],
pre[class*="language-"] {
color: black;
background: none;
text-shadow: 0 1px white;
font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
text-align: left;
white-space: pre;
word-spacing: normal;
word-break: normal;
word-wrap: normal;
line-height: 1.5;
-moz-tab-size: 4;
-o-tab-size: 4;
tab-size: 4;
-webkit-hyphens: none;
-moz-hyphens: none;
-ms-hyphens: none;
hyphens: none;
}
pre[class*="language-"]::-moz-selection,
pre[class*="language-"] ::-moz-selection,
code[class*="language-"]::-moz-selection,
code[class*="language-"] ::-moz-selection {
text-shadow: none;
background: #b3d4fc;
}
pre[class*="language-"]::selection,
pre[class*="language-"] ::selection,
code[class*="language-"]::selection,
code[class*="language-"] ::selection {
text-shadow: none;
background: #b3d4fc;
}
@media print {
code[class*="language-"],
pre[class*="language-"] {
text-shadow: none;
}
}
/* Code blocks */
pre[class*="language-"] {
padding: 1em;
margin: .5em 0;
overflow: auto;
}
:not(pre)>code[class*="language-"],
pre[class*="language-"] {
background: #f5f2f0;
}
/* Inline code */
:not(pre)>code[class*="language-"] {
padding: .1em;
border-radius: .3em;
white-space: normal;
}
.token.comment,
.token.prolog,
.token.doctype,
.token.cdata {
color: slategray;
}
.token.punctuation {
color: #999;
}
.namespace {
opacity: .7;
}
.token.property,
.token.tag,
.token.boolean,
.token.number,
.token.constant,
.token.symbol,
.token.deleted {
color: #905;
}
.token.selector,
.token.attr-name,
.token.string,
.token.char,
.token.builtin,
.token.inserted {
color: #690;
}
.token.operator,
.token.entity,
.token.url,
.language-css .token.string,
.style .token.string {
color: #9a6e3a;
background: hsla(0, 0%, 100%, .5);
}
.token.atrule,
.token.attr-value,
.token.keyword {
color: #07a;
}
.token.function,
.token.class-name {
color: #DD4A68;
}
.token.regex,
.token.important,
.token.variable {
color: #e90;
}
.token.important,
.token.bold {
font-weight: bold;
}
.token.italic {
font-style: italic;
}
.token.entity {
cursor: help;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>IconFont Demo</title>
<link rel="shortcut icon" href="https://gtms04.alicdn.com/tps/i4/TB1_oz6GVXXXXaFXpXXJDFnIXXX-64-64.ico" type="image/x-icon"/>
<link rel="stylesheet" href="https://g.alicdn.com/thx/cube/1.3.2/cube.min.css">
<link rel="stylesheet" href="demo.css">
<link rel="stylesheet" href="iconfont.css">
<script src="iconfont.js"></script>
<!-- jQuery -->
<script src="https://a1.alicdn.com/oss/uploads/2018/12/26/7bfddb60-08e8-11e9-9b04-53e73bb6408b.js"></script>
<!-- 代码高亮 -->
<script src="https://a1.alicdn.com/oss/uploads/2018/12/26/a3f714d0-08e6-11e9-8a15-ebf944d7534c.js"></script>
</head>
<body>
<div class="main">
<h1 class="logo"><a href="https://www.iconfont.cn/" title="iconfont 首页" target="_blank">&#xe86b;</a></h1>
<div class="nav-tabs">
<ul id="tabs" class="dib-box">
<li class="dib active"><span>Unicode</span></li>
<li class="dib"><span>Font class</span></li>
<li class="dib"><span>Symbol</span></li>
</ul>
<a href="https://www.iconfont.cn/manage/index?manage_type=myprojects&projectId=948269" target="_blank" class="nav-more">查看项目</a>
</div>
<div class="tab-container">
<div class="content unicode" style="display: block;">
<ul class="icon_lists dib-box">
<li class="dib">
<span class="icon selfAllIcon">&#xe68f;</span>
<div class="name">反馈意见</div>
<div class="code-name">&amp;#xe68f;</div>
</li>
<li class="dib">
<span class="icon selfAllIcon">&#xe655;</span>
<div class="name">help</div>
<div class="code-name">&amp;#xe655;</div>
</li>
<li class="dib">
<span class="icon selfAllIcon">&#xe60b;</span>
<div class="name">视频禁止</div>
<div class="code-name">&amp;#xe60b;</div>
</li>
<li class="dib">
<span class="icon selfAllIcon">&#xe60c;</span>
<div class="name">视频播放</div>
<div class="code-name">&amp;#xe60c;</div>
</li>
<li class="dib">
<span class="icon selfAllIcon">&#xe606;</span>
<div class="name">退出</div>
<div class="code-name">&amp;#xe606;</div>
</li>
<li class="dib">
<span class="icon selfAllIcon">&#xe627;</span>
<div class="name">五角星</div>
<div class="code-name">&amp;#xe627;</div>
</li>
<li class="dib">
<span class="icon selfAllIcon">&#xe614;</span>
<div class="name">五角星</div>
<div class="code-name">&amp;#xe614;</div>
</li>
<li class="dib">
<span class="icon selfAllIcon">&#xe611;</span>
<div class="name">关闭</div>
<div class="code-name">&amp;#xe611;</div>
</li>
<li class="dib">
<span class="icon selfAllIcon">&#xe632;</span>
<div class="name">刷新</div>
<div class="code-name">&amp;#xe632;</div>
</li>
<li class="dib">
<span class="icon selfAllIcon">&#xe743;</span>
<div class="name">全屏</div>
<div class="code-name">&amp;#xe743;</div>
</li>
<li class="dib">
<span class="icon selfAllIcon">&#xe60e;</span>
<div class="name">视频</div>
<div class="code-name">&amp;#xe60e;</div>
</li>
<li class="dib">
<span class="icon selfAllIcon">&#xe768;</span>
<div class="name">播放</div>
<div class="code-name">&amp;#xe768;</div>
</li>
<li class="dib">
<span class="icon selfAllIcon">&#xe650;</span>
<div class="name">文件</div>
<div class="code-name">&amp;#xe650;</div>
</li>
<li class="dib">
<span class="icon selfAllIcon">&#xe602;</span>
<div class="name">PPT</div>
<div class="code-name">&amp;#xe602;</div>
</li>
<li class="dib">
<span class="icon selfAllIcon">&#xe6ce;</span>
<div class="name">image-o</div>
<div class="code-name">&amp;#xe6ce;</div>
</li>
<li class="dib">
<span class="icon selfAllIcon">&#xe615;</span>
<div class="name">cc-book</div>
<div class="code-name">&amp;#xe615;</div>
</li>
<li class="dib">
<span class="icon selfAllIcon">&#xe66c;</span>
<div class="name">Grade</div>
<div class="code-name">&amp;#xe66c;</div>
</li>
<li class="dib">
<span class="icon selfAllIcon">&#xe609;</span>
<div class="name">学习</div>
<div class="code-name">&amp;#xe609;</div>
</li>
<li class="dib">
<span class="icon selfAllIcon">&#xe66b;</span>
<div class="name">nav</div>
<div class="code-name">&amp;#xe66b;</div>
</li>
<li class="dib">
<span class="icon selfAllIcon">&#xe607;</span>
<div class="name">密码</div>
<div class="code-name">&amp;#xe607;</div>
</li>
<li class="dib">
<span class="icon selfAllIcon">&#xe62e;</span>
<div class="name">人物</div>
<div class="code-name">&amp;#xe62e;</div>
</li>
<li class="dib">
<span class="icon selfAllIcon">&#xe601;</span>
<div class="name">statistic</div>
<div class="code-name">&amp;#xe601;</div>
</li>
<li class="dib">
<span class="icon selfAllIcon">&#xe67e;</span>
<div class="name">discover</div>
<div class="code-name">&amp;#xe67e;</div>
</li>
<li class="dib">
<span class="icon selfAllIcon">&#xe68a;</span>
<div class="name">settings</div>
<div class="code-name">&amp;#xe68a;</div>
</li>
<li class="dib">
<span class="icon selfAllIcon">&#xe71e;</span>
<div class="name">new</div>
<div class="code-name">&amp;#xe71e;</div>
</li>
<li class="dib">
<span class="icon selfAllIcon">&#xe734;</span>
<div class="name">album</div>
<div class="code-name">&amp;#xe734;</div>
</li>
</ul>
<div class="article markdown">
<h2 id="unicode-">Unicode 引用</h2>
<hr>
<p>Unicode 是字体在网页端最原始的应用方式,特点是:</p>
<ul>
<li>兼容性最好,支持 IE6+,及所有现代浏览器。</li>
<li>支持按字体的方式去动态调整图标大小,颜色等等。</li>
<li>但是因为是字体,所以不支持多色。只能使用平台里单色的图标,就算项目里有多色图标也会自动去色。</li>
</ul>
<blockquote>
<p>注意:新版 iconfont 支持多色图标,这些多色图标在 Unicode 模式下将不能使用,如果有需求建议使用symbol 的引用方式</p>
</blockquote>
<p>Unicode 使用步骤如下:</p>
<h3 id="-font-face">第一步:拷贝项目下面生成的 <code>@font-face</code></h3>
<pre><code class="language-css"
>@font-face {
font-family: 'selfAllIcon';
src: url('iconfont.eot');
src: url('iconfont.eot?#iefix') format('embedded-opentype'),
url('iconfont.woff2') format('woff2'),
url('iconfont.woff') format('woff'),
url('iconfont.ttf') format('truetype'),
url('iconfont.svg#selfAllIcon') format('svg');
}
</code></pre>
<h3 id="-iconfont-">第二步:定义使用 iconfont 的样式</h3>
<pre><code class="language-css"
>.selfAllIcon {
font-family: "selfAllIcon" !important;
font-size: 16px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
</code></pre>
<h3 id="-">第三步:挑选相应图标并获取字体编码,应用于页面</h3>
<pre>
<code class="language-html"
>&lt;span class="selfAllIcon"&gt;&amp;#x33;&lt;/span&gt;
</code></pre>
<blockquote>
<p>"selfAllIcon" 是你项目下的 font-family。可以通过编辑项目查看,默认是 "iconfont"。</p>
</blockquote>
</div>
</div>
<div class="content font-class">
<ul class="icon_lists dib-box">
<li class="dib">
<span class="icon selfAllIcon el-icon-self-fankuiyijian"></span>
<div class="name">
反馈意见
</div>
<div class="code-name">.el-icon-self-fankuiyijian
</div>
</li>
<li class="dib">
<span class="icon selfAllIcon el-icon-self-icon-test"></span>
<div class="name">
help
</div>
<div class="code-name">.el-icon-self-icon-test
</div>
</li>
<li class="dib">
<span class="icon selfAllIcon el-icon-self-shipinjinzhi"></span>
<div class="name">
视频禁止
</div>
<div class="code-name">.el-icon-self-shipinjinzhi
</div>
</li>
<li class="dib">
<span class="icon selfAllIcon el-icon-self-shipinbofang"></span>
<div class="name">
视频播放
</div>
<div class="code-name">.el-icon-self-shipinbofang
</div>
</li>
<li class="dib">
<span class="icon selfAllIcon el-icon-self-tuichu"></span>
<div class="name">
退出
</div>
<div class="code-name">.el-icon-self-tuichu
</div>
</li>
<li class="dib">
<span class="icon selfAllIcon el-icon-self-star_full"></span>
<div class="name">
五角星
</div>
<div class="code-name">.el-icon-self-star_full
</div>
</li>
<li class="dib">
<span class="icon selfAllIcon el-icon-self-wujiaoxing"></span>
<div class="name">
五角星
</div>
<div class="code-name">.el-icon-self-wujiaoxing
</div>
</li>
<li class="dib">
<span class="icon selfAllIcon el-icon-self-guanbi"></span>
<div class="name">
关闭
</div>
<div class="code-name">.el-icon-self-guanbi
</div>
</li>
<li class="dib">
<span class="icon selfAllIcon el-icon-self-xuexiao"></span>
<div class="name">
刷新
</div>
<div class="code-name">.el-icon-self-xuexiao
</div>
</li>
<li class="dib">
<span class="icon selfAllIcon el-icon-self-quanping"></span>
<div class="name">
全屏
</div>
<div class="code-name">.el-icon-self-quanping
</div>
</li>
<li class="dib">
<span class="icon selfAllIcon el-icon-self-shipin"></span>
<div class="name">
视频
</div>
<div class="code-name">.el-icon-self-shipin
</div>
</li>
<li class="dib">
<span class="icon selfAllIcon el-icon-self-iconset0481"></span>
<div class="name">
播放
</div>
<div class="code-name">.el-icon-self-iconset0481
</div>
</li>
<li class="dib">
<span class="icon selfAllIcon el-icon-self-wenjian"></span>
<div class="name">
文件
</div>
<div class="code-name">.el-icon-self-wenjian
</div>
</li>
<li class="dib">
<span class="icon selfAllIcon el-icon-self-PPT"></span>
<div class="name">
PPT
</div>
<div class="code-name">.el-icon-self-PPT
</div>
</li>
<li class="dib">
<span class="icon selfAllIcon el-icon-self-13"></span>
<div class="name">
image-o
</div>
<div class="code-name">.el-icon-self-13
</div>
</li>
<li class="dib">
<span class="icon selfAllIcon el-icon-self-cc-book"></span>
<div class="name">
cc-book
</div>
<div class="code-name">.el-icon-self-cc-book
</div>
</li>
<li class="dib">
<span class="icon selfAllIcon el-icon-self-grade"></span>
<div class="name">
Grade
</div>
<div class="code-name">.el-icon-self-grade
</div>
</li>
<li class="dib">
<span class="icon selfAllIcon el-icon-self-xuexi-"></span>
<div class="name">
学习
</div>
<div class="code-name">.el-icon-self-xuexi-
</div>
</li>
<li class="dib">
<span class="icon selfAllIcon el-icon-self-nav"></span>
<div class="name">
nav
</div>
<div class="code-name">.el-icon-self-nav
</div>
</li>
<li class="dib">
<span class="icon selfAllIcon el-icon-self-mima"></span>
<div class="name">
密码
</div>
<div class="code-name">.el-icon-self-mima
</div>
</li>
<li class="dib">
<span class="icon selfAllIcon el-icon-self-character"></span>
<div class="name">
人物
</div>
<div class="code-name">.el-icon-self-character
</div>
</li>
<li class="dib">
<span class="icon selfAllIcon el-icon-self-statistic"></span>
<div class="name">
statistic
</div>
<div class="code-name">.el-icon-self-statistic
</div>
</li>
<li class="dib">
<span class="icon selfAllIcon el-icon-self-discover"></span>
<div class="name">
discover
</div>
<div class="code-name">.el-icon-self-discover
</div>
</li>
<li class="dib">
<span class="icon selfAllIcon el-icon-self-settings"></span>
<div class="name">
settings
</div>
<div class="code-name">.el-icon-self-settings
</div>
</li>
<li class="dib">
<span class="icon selfAllIcon el-icon-self-new"></span>
<div class="name">
new
</div>
<div class="code-name">.el-icon-self-new
</div>
</li>
<li class="dib">
<span class="icon selfAllIcon el-icon-self-album"></span>
<div class="name">
album
</div>
<div class="code-name">.el-icon-self-album
</div>
</li>
</ul>
<div class="article markdown">
<h2 id="font-class-">font-class 引用</h2>
<hr>
<p>font-class 是 Unicode 使用方式的一种变种,主要是解决 Unicode 书写不直观,语意不明确的问题。</p>
<p>与 Unicode 使用方式相比,具有如下特点:</p>
<ul>
<li>兼容性良好,支持 IE8+,及所有现代浏览器。</li>
<li>相比于 Unicode 语意明确,书写更直观。可以很容易分辨这个 icon 是什么。</li>
<li>因为使用 class 来定义图标,所以当要替换图标时,只需要修改 class 里面的 Unicode 引用。</li>
<li>不过因为本质上还是使用的字体,所以多色图标还是不支持的。</li>
</ul>
<p>使用步骤如下:</p>
<h3 id="-fontclass-">第一步:引入项目下面生成的 fontclass 代码:</h3>
<pre><code class="language-html">&lt;link rel="stylesheet" href="./iconfont.css"&gt;
</code></pre>
<h3 id="-">第二步:挑选相应图标并获取类名,应用于页面:</h3>
<pre><code class="language-html">&lt;span class="selfAllIcon el-icon-self-xxx"&gt;&lt;/span&gt;
</code></pre>
<blockquote>
<p>"
selfAllIcon" 是你项目下的 font-family。可以通过编辑项目查看,默认是 "iconfont"。</p>
</blockquote>
</div>
</div>
<div class="content symbol">
<ul class="icon_lists dib-box">
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#el-icon-self-fankuiyijian"></use>
</svg>
<div class="name">反馈意见</div>
<div class="code-name">#el-icon-self-fankuiyijian</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#el-icon-self-icon-test"></use>
</svg>
<div class="name">help</div>
<div class="code-name">#el-icon-self-icon-test</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#el-icon-self-shipinjinzhi"></use>
</svg>
<div class="name">视频禁止</div>
<div class="code-name">#el-icon-self-shipinjinzhi</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#el-icon-self-shipinbofang"></use>
</svg>
<div class="name">视频播放</div>
<div class="code-name">#el-icon-self-shipinbofang</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#el-icon-self-tuichu"></use>
</svg>
<div class="name">退出</div>
<div class="code-name">#el-icon-self-tuichu</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#el-icon-self-star_full"></use>
</svg>
<div class="name">五角星</div>
<div class="code-name">#el-icon-self-star_full</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#el-icon-self-wujiaoxing"></use>
</svg>
<div class="name">五角星</div>
<div class="code-name">#el-icon-self-wujiaoxing</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#el-icon-self-guanbi"></use>
</svg>
<div class="name">关闭</div>
<div class="code-name">#el-icon-self-guanbi</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#el-icon-self-xuexiao"></use>
</svg>
<div class="name">刷新</div>
<div class="code-name">#el-icon-self-xuexiao</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#el-icon-self-quanping"></use>
</svg>
<div class="name">全屏</div>
<div class="code-name">#el-icon-self-quanping</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#el-icon-self-shipin"></use>
</svg>
<div class="name">视频</div>
<div class="code-name">#el-icon-self-shipin</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#el-icon-self-iconset0481"></use>
</svg>
<div class="name">播放</div>
<div class="code-name">#el-icon-self-iconset0481</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#el-icon-self-wenjian"></use>
</svg>
<div class="name">文件</div>
<div class="code-name">#el-icon-self-wenjian</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#el-icon-self-PPT"></use>
</svg>
<div class="name">PPT</div>
<div class="code-name">#el-icon-self-PPT</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#el-icon-self-13"></use>
</svg>
<div class="name">image-o</div>
<div class="code-name">#el-icon-self-13</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#el-icon-self-cc-book"></use>
</svg>
<div class="name">cc-book</div>
<div class="code-name">#el-icon-self-cc-book</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#el-icon-self-grade"></use>
</svg>
<div class="name">Grade</div>
<div class="code-name">#el-icon-self-grade</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#el-icon-self-xuexi-"></use>
</svg>
<div class="name">学习</div>
<div class="code-name">#el-icon-self-xuexi-</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#el-icon-self-nav"></use>
</svg>
<div class="name">nav</div>
<div class="code-name">#el-icon-self-nav</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#el-icon-self-mima"></use>
</svg>
<div class="name">密码</div>
<div class="code-name">#el-icon-self-mima</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#el-icon-self-character"></use>
</svg>
<div class="name">人物</div>
<div class="code-name">#el-icon-self-character</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#el-icon-self-statistic"></use>
</svg>
<div class="name">statistic</div>
<div class="code-name">#el-icon-self-statistic</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#el-icon-self-discover"></use>
</svg>
<div class="name">discover</div>
<div class="code-name">#el-icon-self-discover</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#el-icon-self-settings"></use>
</svg>
<div class="name">settings</div>
<div class="code-name">#el-icon-self-settings</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#el-icon-self-new"></use>
</svg>
<div class="name">new</div>
<div class="code-name">#el-icon-self-new</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#el-icon-self-album"></use>
</svg>
<div class="name">album</div>
<div class="code-name">#el-icon-self-album</div>
</li>
</ul>
<div class="article markdown">
<h2 id="symbol-">Symbol 引用</h2>
<hr>
<p>这是一种全新的使用方式,应该说这才是未来的主流,也是平台目前推荐的用法。相关介绍可以参考这篇<a href="">文章</a>
这种用法其实是做了一个 SVG 的集合,与另外两种相比具有如下特点:</p>
<ul>
<li>支持多色图标了,不再受单色限制。</li>
<li>通过一些技巧,支持像字体那样,通过 <code>font-size</code>, <code>color</code> 来调整样式。</li>
<li>兼容性较差,支持 IE9+,及现代浏览器。</li>
<li>浏览器渲染 SVG 的性能一般,还不如 png。</li>
</ul>
<p>使用步骤如下:</p>
<h3 id="-symbol-">第一步:引入项目下面生成的 symbol 代码:</h3>
<pre><code class="language-html">&lt;script src="./iconfont.js"&gt;&lt;/script&gt;
</code></pre>
<h3 id="-css-">第二步:加入通用 CSS 代码(引入一次就行):</h3>
<pre><code class="language-html">&lt;style&gt;
.icon {
width: 1em;
height: 1em;
vertical-align: -0.15em;
fill: currentColor;
overflow: hidden;
}
&lt;/style&gt;
</code></pre>
<h3 id="-">第三步:挑选相应图标并获取类名,应用于页面:</h3>
<pre><code class="language-html">&lt;svg class="icon" aria-hidden="true"&gt;
&lt;use xlink:href="#icon-xxx"&gt;&lt;/use&gt;
&lt;/svg&gt;
</code></pre>
</div>
</div>
</div>
</div>
<script>
$(document).ready(function () {
$('.tab-container .content:first').show()
$('#tabs li').click(function (e) {
var tabContent = $('.tab-container .content')
var index = $(this).index()
if ($(this).hasClass('active')) {
return
} else {
$('#tabs li').removeClass('active')
$(this).addClass('active')
tabContent.hide().eq(index).fadeIn()
}
})
})
</script>
</body>
</html>
@font-face {font-family: "selfAllIcon";
src: url('iconfont.eot?t=1585881159034'); /* IE9 */
src: url('iconfont.eot?t=1585881159034#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('data:application/x-font-woff2;charset=utf-8;base64,d09GMgABAAAAABL0AAsAAAAAIaQAABKlAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHEIGVgCGbgqveKYIATYCJANsCzgABCAFhREHgjAbtBszklW6I2T/9YF2hIqL33pkZeskki0qilLMcBKOil5m0SeZ2bXQpTAk9sOChXc5QXbNHyzMt4dSElBrZc/SA2IIJSFbQAcsGYRNhA6r6NR+wMbfZM7MSjYFyZD2DCWE74FkFZDzsb723E8QaDnhIgSOwUl+oLn9u7vB7m7NqDh6GNDDROjZMN2MGrGNGGzOlWLMggkGYPcwMBKxAobO+kSahT+aNj8f+I8wTrukgusHSbdOCUpzRwpCLn5bKJADAASHdnWQilZqSn3/gSZZeXAttZcxyxLcWBhSJEWSYnIppJz/El1/dP1SbgDsK+RAjT8lvO/oXw5RKGA3IyeMnHB+8L/meJRLk9BHHfS6/Gds6YOrRTLHaX+rMWrrOxNQqtNYYV76snWKJZ5pQJNjBQd3K3ZkS0JmBsXpGTFgUh3uSBVHVyMbbsuvH/6ZHIqJpLHnHlcdmL/PrDx0aEEhsK00ifkJnAYixlgkRINkRegWG2SsNEopd+K/k3TzF1GeR4qUKFepRoMh4022ynrHXHDNbZ9GOpva3A795EEWc3TZivWrPXpgnq3BWONNfBk9ecWpq5r+H3k0qpSqVyuWKFOsSLVMgxIVInVqNGkWVGnRqlQ5IYPG5RAW8Q2t5EHoNJJHOpXkmU5KXqRTT16iU0tephOTl+sk5JVUGKsBVwxWDyov1gCuGmwIVHlsPKgwNhkUZ6vAVYCtBxeBHQVXB3YMFNgFcE1g18A1g90GF8A+QaeKkU6dFkam6rQyMpcrlewQEhU4WdsA03GMokeUfPWc9oOLVMIjU5HgnSqXyCgRKwKJ7zEDxQ4i2UBtJDEQdH3oiDQaZurpHmKCsath+2NGjBg3buwYkE4bhq4RK4rpJYcPH2I5/WzQ0MHDhsGhM/Sp1mhkDDUNMC0Nh3nMmenpOnQNMFSAodvlB3X4y9WjwNB02p6dCbkWbeC2KSVIMYUMVWFlV3/d1BJza6n1rjM+ycpnMK95VHnHG2zWuvpPM47w48pZK+wZX6754ojoAVs9+/3QrkjMrST4iuzqnvcUq0EtarD6LkB8lOje/8vBm38D+xKoFfJzJvecYXUYchtrRAhHNQDkoesDGnmR4+N8e5r5ujkmcae1FOGZGXwEhnWQZI3pVqk2MpGtQjjDqFxQM86bYXtc8l5nufWmpUU7mteK1RGJXA1ZUSNuXR0elTJHtVIoqmmRuTorciJfBQxtDUzWdp+HQVyy1jlEKHIcEdjYECLgtk5EdkfY6wS0pLRfoy7yXCQ4d0P3KaGAYfx5M467G5/c9By1rAaf+vOB8lAkhP04tk/IHNq14wDZcfjgLiMYjKlPKSGYXD6uWDm0jxyTYTFwjh7hSnqx3vGjIiowN7NA9XzZw8UYB0/myz5FqkvIVrpDxBjynu9vw2ix6JJuPNGn7OlligNRcUl5lEkI/d700oRABGeYfQATcsi1dVwgj0SZCKQ3Vawe2hctFCDxZVgNHIKElCgrl3uLRmzMpItD7viUeT4Rwym5/k3z7X/jUkfN6n3swO1/rhWbIwZyralWpTM61XPkSpd/RkqpSGiJmZ+11V2CoWSKRgo+HFvj5fFeDm/jXOhKAFjFIT3265xqNBMf3L2k/2nv3ZiQtt3AZfCQdMc66qYHprzDDHmKHUiSjP4DEwYedLca0XraAcmHvSupQme6UWqNTEB/SdMPtQ9yG3hd6JgxkjnUVQRqSEf3yHOoT4mML6+Ca1kRworUglK7e8yUoVUe1BJDPRbMglrda3f3W6XW2IFsc4pZbo9K3etMH/jamBF1qYe9bWZ1Rninu/tOK+qwdtgcg1gjqgXVsH6wlRQsEJsMbVwNZ82SyEnB6K3XiGbOFBHLPq8raJRRtp9zu8MJLIOwRiUNTLlebGpNRgOF6sflufFOtRgK/fWMFFOZZ33QdU8kBt/uzsWiS/6VQxGh/XhnZG/dT30b/VZbaWy/p1zuk46+4Gay5fWWU4u/lQ92vh6AwCDIHCqHUw7wbJBzSCL3ZCopRdNp5RlIUg2kKDtYrQosfyQ7pT0VfnlUMhDb2j90WEXOwYxZro8CheV/GZqgOiXhGh2ijk+AHzBz6G5/faO/vKuFuRx692jUom34E2tiJk7ZItBotTRGJ/P1HRGtelgHQDU6raLm3ASjh/kqoHHlXViDq1kOAK1poolSqXGtZQRvZSg5MJX7rHMaoj34dyvCqMtUyEc/78kpBK6o5l2JyZBrAnHQBvDopBZ1cf3uf6E9eBw99Ye8Ar9uBiOB4kWAT6qDsNCJWkEzbB8fpt5Y3q3HK3g2V/I+vUO5qiqA7NVm5XmqsFLhOzkiolLIu71SSznoLrRjZpamr1niT6EQF+udaCid3RB0sBx/+x97Gm3TuX64fpOdQ+FncRrmRfenKfMelS7mZffpJFmwBPN8r3g0X81DoliMgvdpuyqJylTqXvrHIXI2Fg4tezJRZCECm9zx+3Oy4j5n1qz9fgs/VIpaNrU0vZKo9+l+3mvMVlNJYbQvRyvmFqfKj8JFtz5LjqblSohp5SkJ/ShOITm7OoNP87MjiBjBA6eYDnIjacWpzRQjMsOW21W78w16SmXLos3/WHEv78pF7I8dOPz5CJ5zBIq8Sn99P+cMczQlYqrLB1X5ctHGvnytEp7brXR6fpbSxAxCs1ZLlu/NVqdMxTFJ90hqbg/YNBJTBoUPtCNmTJbbxXL57bQYpzh/Kh7rb0dRySm9Wf7u1ejCM6S6+3mSX+j/ntW/TbjNPK3KRkwjbaSxjuPBqTNSXYFTA7uoadwu1Mji+K0NqByl+FkZMDdt+fJYYWz/3AMpKwDJaVme/ptC2vXV8tXF5WtCagYP4DnW2oopdV9DSLFakDEjGmj//ksjteFC2IVbFiRaBdYw8d7zr0NKmDYNSUnEJWYwS8QSM2VOTFmdJiGQlGnTIEGsZnFZ+AFu5/qWzhrefs11LtMbHNgrLj2qRCJRJO3UzXvjDvbi3CbYDU3cIpU6JuppxE/7mSsWlyaX3fZ+JRKJTbTdtHrXb1cY0ARZH0Gzhx5gg51IE5cOXdROsIV6JV6m7cTqXegu9c47na+4TPrXvJ/XUdPSXsM7S7B4rGYW1weJRJDmzKQB/4aHFRceJsHHv1DN5BKNhCstKZbgNIcYRMKVjB1bP3cbd5vm0tjxWzcH+Im3JugNCVsnw5LLzfqYcZQkYqaLNGxMwl0kPeJBIqk0JwnHhUr5g8ZUDEntH3KaLAs0G9enDs8MlfCnSvm5MGm2sBpJ06D0i37xt0UjJANnu8LwH28GDqlhBKwt7D3B4fylQBBR+zEmvCLEoW/R/So2xXkLkAB7Ch7pQj+ePvfDL79H2fPdv+5s0EcQVq1da3TjuBpb6ro105XjBnt9kyu4Gtet9X/w311NMPRlAQxYe/l4hL+OMYGlfbV68CF6mk2Zd+5yxvm6B7ropdwsDveWWK7MO3tZ5Jmtjza/aH9gvWjc4J3CXEQm2T9XhR+ip8Pmtz/7YBVRT7CJSzi0EFaC0QSaD3SORyOxEvp+mJrA1RLz5ucPsETQOBqxLF5L7LEB/gH3XdbXZ2pEXC1zYprxS8QmaomKn30WydTXV0Y0enCetm0havHoM6NWwr1sbgHiPd5Gv5RXULU4WH72lbuBm6XvB8TV4QdfdPmivt29B3u7ZWddT8/ZjSyUZbQf1H5r/gWNlX6RbuVZ8Yu4NRUcBdI/ymTh1eJlRO2TZ0cZXsu1Id1VV6aJwMsInH/juIfAWbEOSRuZvzOHbXhWutF147MFyex3p7dMBQqT3KXhdNq9gE7uHg26Bb0Fc3npWdr37zSlngUhxVK4nYcowPqOiGXqI1KRKRNvzgCbpHAWrGN+WAkRWGRvpkjkIHOQnJkTo1u0KFX48rZNSbeMjNnTuyeGtMvCMjMTH9PGU+SKiK3HWpdQbJ43j6271/QHttHmQ+eQaohbFvLtm5F5yNHoGCDAgQcYxCyPQdMumGw2D8coRXLQggIUmwo5ZyoHTR1EeXlATWPr98sg4Fz+LmdwBGD7UFwEibNA8Ga0Gi04iUnKv9CutNC6g0ZCnCzBpmBjUPmpEY2NUrYUJFWSxqaj1NH9ew0Jhq1XnpziJuCflZx8W2alrHshgdXtkrmJ3zSlzHp+/cYr652TG2Qz6Wg3jjDYj9iVrFiW0t5y1Pe9gSQlcx2vMmkrjmipspGxcRwe0TzPJW0gRKR8MnMgtrPx8U5sF1bPEd1JMjKxyi/+c4PHcTySp6PmP+JWfVi4aixHG+xfrnaKS0R92sg5B3J0Wf2Tp2fQXi3i3ITlF68vxyLQ6zexpWT9r8tF2IEb4s1JnCWTtHMOkG0+mGY6YjIhSp3mCNiCpE4H8nzA4cJNUxJDC0knZYlIEjq7GEvExNqscIAZ4uxjbceGHattvfvO5+3ddnUUsarogLhUWGq9FW31jCpN0DC+un9lrl5+Pqylbx/N44D4vPd5TA+ay9bxiSBbn/Z+R73b/3z/s/egIL4m8RtlRAWIifrGtTgJ+OVc5jfKhAhQo2uLcr7AycJdlI8CE//bhvEKnCBq7rlGiEDmj68cM6AuEZmRuTCzj82tmecvXTRz1nUxFR+X7HwwZA9lQRegFio8UloGyTmpnNNC/MuJAcQ5DK2aE4gsqWjSR8yIm1jvrvRW7C0tRAqQyvRWHPADf3zrIy1NsKQPY/O8/Nljy+qbN6uxGuzuGasOYvpVBVRcROXl5XJUgRpBAVmgQOSIBLGyzx42D0r0BLRbf8UJhQ5ghf2qBnEaQtb7frCCw3ShxG/P/0wV83+3r1rp1yyom9qv3O1/ZP2/2ZGVzlQlYmXgNwffr/BL1mLBIsAIV1dzbanh/rPpFrZOdC2RjBE+zi9d/mO9eAclrdM9jYeU98rOp6gcOdtfnDhRe+jjrkB8itDJyU3JFzV45cXtph1NmxhyznTBeG7m4PzTHQ31Lt4L0ePcZBZOle84qla/KCSVREtsZNtGKGHK5FzRnhpJSvKiNdHJ4RLIzaQK+v0uVXSaYHGL/B7uDlFeVNQbyJTg6oQ2nZngl35+WMqvwjN2vvIQ6/NEhDOhP6wXe7zaKaJXlfIffuaXEmZdW0J18JRE67tCs0YG7jsxTDpamSY7Tr16RR2fTpWjnQy8jmWCBp7BaYNBltaO+lK+aHtLNRzX24nXIFjWwXMyRJ7YgayBdPiAEVE3afv+bW3AAtZt0vbB1E3bxEMOrX8rOpwWMWaJCCtrPfspxTyLlWHllhpNrBs6fGZ8zKVRqSf4u/3fggt9XZvDohQWFj3rP9O8AZcd//hFgebQ+VXplTPWrAGkeqf5SuEQ9YoFeRvmrN+VtERWP9MI/QNsI9pdIXkObHpLMTrBCIeuTNfMLodN0j3m17EbKBlrGZWcVEZ5H9pHzULjxwWKTt5Yrp8wsnemY+oK1uBnNyMxho8nPWy6BOXFryQ75B/ehyW8GHKd58WDJYX+3oD4Evo/QOG6IInS0+0NFkDN/IXudHVscsYqPHcNG5h2I47liUdYJlQdcTAy9Ji72PDQPzWiraFWv2DSUDsNFhnaQ4b5hr7Qg34PPScHiw3d4iNW6LkwYIvLdL9Cr/OZaZifx2wbZkbRWUxQRzDRc9VNLJmityUHyX9wdwSr7x4aNocz4jec8Ut4q5/HbqRzXjC3x2YGUAz1XBjAn9c7pUcASE6dk1lOG+1ud4Fj7pU6qCyh5KI2uPeXnhkBpS+ngD+vS2qhu35pDbGxThiOxFNkhI6KjDGEgmRsNEjHjgTZWFFkqYEwafAyfFgMgyQEgNFQrUUiXKE+EsX2mGDU2B5Cw9jfNIepCAM4jvWPJElDvEOGEGQNmaKVZ+vkeVTOfKogV12iSIWOnCdXKZJUqtHOC4vlSr0qW3ve1ayVyrXzCmhNRYVHEpsy5CVybX69zDMoo3U6BaXQqoup9IzvTq5SqSmNVl0oz9WF5+t0mmEREQqq1/BcdTGQUmjJZdPpsfNQkGP+8gVyqZVQqHVI88ipKCRpRSqjw74dMTklPZVs2vB9IIAUxzYKmJuCqH8k9iEeyDBK4u6xjhCrgVI06F6EAiW211IrRkF6rXFe3ipqFGjo9grJ5dIJh/wUpsYwiHg5kiKuEV5uWvEcMozQvT5/JG0IimAIDXFAHIumsKTStuN6xiamZuYWllbWNrZ2owV2TAw5aMBOeyL43kc8jHqhAg8cnUWFAhsnbjz/ZCOKgaq4HUY4+BexZXXSOJ1wM6BVMsYOgWYW88zNW76delRi4uwujCN7dLq9zs2UO8XdZvX9/qucf5PSPXFdU5cBZrzBRrSvOjip2WDjNlU4wDTiQZEFEYRZQFtsWKib8KCVG4kKaDusOjytY4vEdgkAAA==') format('woff2'),
url('iconfont.woff?t=1585881159034') format('woff'),
url('iconfont.ttf?t=1585881159034') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */
url('iconfont.svg?t=1585881159034#selfAllIcon') format('svg'); /* iOS 4.1- */
}
.selfAllIcon {
font-family: "selfAllIcon" !important;
font-size: 16px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.el-icon-self-fankuiyijian:before {
content: "\e68f";
}
.el-icon-self-icon-test:before {
content: "\e655";
}
.el-icon-self-shipinjinzhi:before {
content: "\e60b";
}
.el-icon-self-shipinbofang:before {
content: "\e60c";
}
.el-icon-self-tuichu:before {
content: "\e606";
}
.el-icon-self-star_full:before {
content: "\e627";
}
.el-icon-self-wujiaoxing:before {
content: "\e614";
}
.el-icon-self-guanbi:before {
content: "\e611";
}
.el-icon-self-xuexiao:before {
content: "\e632";
}
.el-icon-self-quanping:before {
content: "\e743";
}
.el-icon-self-shipin:before {
content: "\e60e";
}
.el-icon-self-iconset0481:before {
content: "\e768";
}
.el-icon-self-wenjian:before {
content: "\e650";
}
.el-icon-self-PPT:before {
content: "\e602";
}
.el-icon-self-13:before {
content: "\e6ce";
}
.el-icon-self-cc-book:before {
content: "\e615";
}
.el-icon-self-grade:before {
content: "\e66c";
}
.el-icon-self-xuexi-:before {
content: "\e609";
}
.el-icon-self-nav:before {
content: "\e66b";
}
.el-icon-self-mima:before {
content: "\e607";
}
.el-icon-self-character:before {
content: "\e62e";
}
.el-icon-self-statistic:before {
content: "\e601";
}
.el-icon-self-discover:before {
content: "\e67e";
}
.el-icon-self-settings:before {
content: "\e68a";
}
.el-icon-self-new:before {
content: "\e71e";
}
.el-icon-self-album:before {
content: "\e734";
}
!function(o){var c,i='<svg><symbol id="el-icon-self-fankuiyijian" viewBox="0 0 1024 1024"><path d="M865.773 407.506c-16.142 0-29.127 12.986-29.127 29.127v375.982c0 12.622-10.316 22.938-22.938 22.938h-600.989c-12.622 0-22.938-10.316-22.938-22.938v-601.11c0-12.622 10.316-22.938 22.938-22.938h375.254c16.142 0 29.127-12.986 29.127-29.127s-12.986-29.127-29.127-29.127h-375.254c-44.783 0-81.191 36.409-81.191 81.191v600.989c0 44.783 36.409 81.191 81.191 81.191h600.989c44.783 0 81.191-36.409 81.191-81.191v-375.861c0-16.142-13.107-29.127-29.127-29.127z" fill="" ></path><path d="M334.324 551.322l-35.438 139.568c-2.548 9.952 0.364 20.511 7.646 27.792s17.84 10.194 27.792 7.646l139.568-35.438c5.098-1.334 9.709-3.884 13.471-7.646l387.876-387.876c26.457-26.457 26.093-69.905-0.729-96.848l-47.696-47.696c-26.943-26.943-70.39-27.307-96.848-0.729l-387.997 387.755c-3.641 3.762-6.311 8.374-7.646 13.471zM771.109 191.237c3.762-3.762 10.316-3.398 14.563 0.729l47.696 47.696c4.127 4.127 4.491 10.801 0.729 14.563l-29.977 29.977-62.988-62.988 29.977-29.977zM699.87 262.356l62.988 62.988-278.164 278.043-62.988-62.988 278.164-278.043zM385.539 586.516l53.157 53.157-71.239 18.083 18.083-71.239z" fill="" ></path></symbol><symbol id="el-icon-self-icon-test" viewBox="0 0 1024 1024"><path d="M512 896C299.936 896 128 724.064 128 512S299.936 128 512 128s384 171.936 384 384-171.936 384-384 384m0-832C264.96 64 64 264.96 64 512s200.96 448 448 448 448-200.96 448-448S759.04 64 512 64" fill="#181818" ></path><path d="M511.68 704a48 48 0 1 0 0 96 48 48 0 0 0 0-96M512 256l-0.288 0.032A160.16 160.16 0 0 0 352 416h64a96.096 96.096 0 0 1 95.712-95.968L512 320c52.928 0 96 43.072 96 96s-43.072 96-96 96l-0.288-0.032V512H480v128h64v-67.264A160.224 160.224 0 0 0 672 416c0-88.224-71.776-160-160-160" fill="#181818" ></path></symbol><symbol id="el-icon-self-shipinjinzhi" viewBox="0 0 1024 1024"><path d="M996.98153 272.786475c-0.200137-16.511287-13.909508-29.920453-30.620932-29.920453-11.507867 0-19.313202 4.803283-21.714844 6.604514L724.49526 396.871299v214.846868l220.250562 147.400762c2.50171 1.801231 10.206977 6.604515 21.714844 6.604515 16.811492 0 30.520864-13.509235 30.520864-30.12059V272.786475zM968.662171 735.502785c0 1.000684-1.000684 1.801231-2.101436 1.801231-2.601779 0-4.40301-0.800547-5.00342-1.20082L752.914688 596.507769V411.981628l207.742011-139.095084 0.800547-0.600411s2.101437-1.100752 4.903352-1.100752c1.200821 0 2.201505 0.900616 2.201505 1.901299V735.502785zM899.214698 94.864849L703.580964 295.10173c-4.903352-38.426268-38.3262-68.246653-78.653768-68.246653h-520.355712c-43.629825 0-79.154109 35.023942-79.154109 78.053356v414.683476c0 43.029415 35.524284 78.053357 79.154109 78.053356H212.145021L102.570116 909.821949l20.313887 19.813544 132.990911-136.093032 448.30646-458.3133v-0.100069l215.34721-220.35063-20.313886-19.913613zM675.862015 323.621225L239.964038 769.225838H104.471416c-28.019154 0-50.83475-22.315255-50.83475-49.633929V304.908433c0-27.418743 22.815597-49.633929 50.83475-49.633929h520.355712c28.119222 0 50.934819 22.315255 50.934819 49.633929v18.712792zM675.862015 719.591909c0 27.318675-22.815597 49.633929-50.83475 49.633929H385.763706l-27.819017 28.419427h266.882439c43.729893 0 79.154109-35.023942 79.154109-78.053356V382.561517l-28.21929 29.119906v307.910486z" ></path></symbol><symbol id="el-icon-self-shipinbofang" viewBox="0 0 1024 1024"><path d="M624.5 797.5H106.1c-44 0-79.8-35.2-79.8-78.6V305.7c0-43.4 35.7-78.6 79.8-78.6h518.4c21.6 0 41.9 8.4 57.1 23.6 14.8 14.8 22.8 34.4 22.8 55.1V719c-0.2 43.3-35.9 78.5-79.9 78.5zM106.1 257.2c-27.5 0-49.7 21.8-49.7 48.5v413.2c0 26.7 22.3 48.5 49.7 48.5h518.4c27.5 0 49.7-21.8 49.7-48.5V305.7c0-12.7-4.9-24.7-14-33.9-9.4-9.5-22.1-14.7-35.7-14.7H106.1z m858.7 508.5c-11.7 0-19.6-4.9-22.2-6.8L722.8 611.8v-215l219.6-147.1c2.6-1.9 10.5-6.8 22.2-6.8 17.1 0 31.2 13.8 31.4 30.7v461.1c0 17-14 31-31.2 31z m-4.5-31.1c0.5 0.3 2.1 1 4.5 1 0.8 0 1.3-0.4 1.3-0.9V274.1c0-0.5-0.6-1-1.3-1-2.3 0-3.9 0.6-4.4 1l-0.8 0.6v-0.3L752.9 412.8v182.9l207.4 138.9z m0.1-460.7z" ></path></symbol><symbol id="el-icon-self-tuichu" viewBox="0 0 1448 1024"><path d="M747.40131 645.568957h-2.236183c-5.332437 0-10.320847-2.064169-14.105157-5.84848l-110.777087-112.325214c-8.084663-8.084663-8.084663-21.157736-0.172015-29.070385l110.777088-110.777087c3.78431-3.78431 8.77272-5.84848 14.277171-5.84848h1.204099l1.204098-0.172014h1.032085c3.440282 0 6.880564 1.548127 9.116748 4.300353l0.86007 1.032085 0.860071 0.86007c3.78431 3.78431 6.020494 8.944734 6.020494 14.277171s-2.236183 10.492861-6.020494 14.277171l-76.202251 76.202251h443.108349c9.976818 1.720141 17.373425 10.148833 17.373425 20.297665s-7.224593 18.749538-17.373425 20.297666H684.788174l75.514195 77.062321 0.688056 0.688057c6.192508 5.676466 8.256677 14.793214 4.988409 22.533848-3.096254 7.224593-10.320847 12.213002-18.577524 12.213002z" ></path><path d="M725.727532 932.832521c-54.528473 0-107.680833-10.492861-158.080967-31.134554-51.432219-21.157736-97.532001-51.948261-136.751218-91.511506-39.047203-39.219217-69.493701-84.974971-90.651436-136.235176-20.985721-51.088191-31.650596-105.100622-31.306568-160.489165 0-168.2298 99.940198-319.946246 254.580883-386.171678 51.604233-21.845792 106.132706-33.026709 162.037292-33.026709 63.301193 0 126.774399 14.793214 183.539056 42.659499 57.968755 28.554342 109.22896 70.869814 148.276163 122.818075l0.172015 0.172014c6.70855 8.77272 4.988409 21.673778-3.784311 28.382328-4.472367 3.440282-9.116748 4.128339-12.213002 4.128339-6.364522 0-12.385016-2.92424-16.169326-8.084663-34.230808-44.723669-78.782463-82.050731-129.010583-107.680833C843.729212 149.652276 784.728372 135.547119 725.899546 135.547119c-49.196036 0-97.187972 9.460776-142.771711 28.210314-46.44381 19.093566-88.071225 46.959852-123.334118 82.738787-63.645221 63.301193-102.864438 147.416093-110.261044 237.035445-7.396607 89.619352 17.545439 179.066689 70.009743 252.000672 35.434907 49.024022 82.566773 89.447337 136.407189 116.453552 52.636318 26.490173 111.465144 40.423316 170.29397 40.423316 58.656812 0 117.485637-13.933143 169.949941-40.59533l0.172014-0.172014c50.572148-25.974131 95.467831-63.645221 129.526625-109.056946l0.172014-0.172014c3.096254-4.128339 7.740635-7.052579 12.901059-7.740635 0.860071-0.172014 1.548127-0.172014 2.408197-0.172014 4.300353 0 8.600706 1.376113 12.213002 4.128339 8.77272 6.880564 10.492861 19.781623 3.956325 28.89837-38.015118 50.056106-87.727196 91.683521-143.631783 120.237863-58.312783 29.414413-123.162103 45.067697-188.183437 45.067697z" ></path></symbol><symbol id="el-icon-self-star_full" viewBox="0 0 1024 1024"><path d="M958.733019 411.348626 659.258367 353.59527 511.998465 85.535095 364.741633 353.59527 65.265958 411.348626 273.72878 634.744555 235.88794 938.463881 511.998465 808.479435 788.091594 938.463881 750.250754 634.744555Z" ></path></symbol><symbol id="el-icon-self-wujiaoxing" viewBox="0 0 1024 1024"><path d="M959.008 406.016l-308-47.008L512 64 372.992 359.008l-308 47.008 223.008 228-52.992 324L512 805.024l276.992 152.992-52.992-324zM512 740L304 856.992l40-235.008-179.008-182.016 242.016-32 104.992-224 104 224 240.992 34.016L680 622.976l36.992 235.008z" ></path></symbol><symbol id="el-icon-self-guanbi" viewBox="0 0 1024 1024"><path d="M567.001395 495.286374 966.070272 96.236851c10.904781-10.905395 10.904781-28.573798 0-39.481242-10.907853-10.905395-28.575949-10.905395-39.482778 0L527.519539 455.806157 128.45271 56.75561c-10.905805-10.905395-28.574925-10.905395-39.481754 0-10.906829 10.906419-10.906829 28.574822 0 39.481242l399.067955 399.049523L88.970957 894.337946c-10.906829 10.906419-10.906829 28.573798 0 39.480218 5.45239 5.452186 12.652646 8.177254 19.741389 8.177254 7.197184 0 14.285926-2.725069 19.740365-8.177254l399.065907-399.052595L926.587494 933.818061c5.454438 5.452186 12.652646 8.177254 19.740365 8.177254 7.198208 0 14.28695-2.725069 19.742413-8.177254 10.904781-10.906419 10.904781-28.573798 0-39.480218L567.001395 495.286374z" ></path></symbol><symbol id="el-icon-self-xuexiao" viewBox="0 0 1024 1024"><path d="M925.76107 278.522458l-16.542768 49.136094c0 0-79.438237-196.570981-314.467111-245.720378 0 0-96.866165-21.942755-198.602244 0-13.964036 7.977695-254.891248 85.180008-297.91718 311.248813 0 0 9.928117 68.815295 49.646724 0 0 0 23.170722-176.919409 281.368272-262.098393l182.061522 0c0 0 211.844849 72.074525 264.812201 245.720378l16.556071 81.906451 49.640584 16.392342 16.556071-196.584284L925.76107 278.523481z" ></path><path d="M876.120486 636.506688c0 0-23.170722 176.919409-281.369296 262.098393L412.690692 898.605082c0 0-211.844849-72.074525-264.813225-245.720378l-16.548908-81.906451-49.653887-16.392342L65.126788 751.170195l33.104979 0 16.548908-49.136094c0 0 116.961852 225.768977 314.467111 245.720378 83.788312 19.951401 198.61657 0 198.61657 0s254.884085-85.180008 297.896714-311.24779C925.76107 636.506688 915.832953 567.691393 876.120486 636.506688z" ></path></symbol><symbol id="el-icon-self-quanping" viewBox="0 0 1024 1024"><path d="M664.035 409.382l244.223-243.378-0.837 137.922c-0.335 11.437 8.912 21.527 20.351 21.191h14.63c11.438-0.335 21.025-7.065 21.193-18.67l0.672-205.367c0-0.171 0.335-10.934 0.335-10.934 0.17-5.716-1.179-10.934-4.879-14.63-3.7-3.702-8.742-6.055-14.633-5.886l-10.428 0.171c-0.169 0-0.331 0-0.501 0.171l-203.69-0.846c-11.438 0.336-21.025 9.76-21.193 21.361v14.633c1.685 13.625 12.446 21.529 23.884 21.193l134.219 0.335-243.551 242.542c-11.101 11.104-11.101 29.095 0 40.197 11.104 11.269 29.101 11.269 40.203 0h-0.003M356.233 638.806l-244.393 242.544 0.842-137.253c0.336-11.435-8.918-21.523-20.355-21.193h-15.47c-11.438 0.335-21.025 7.065-21.193 18.672l-0.672 205.536c0 0.171-0.335 10.934-0.335 10.934-0.171 5.722 1.18 10.934 4.875 14.63 3.7 3.7 8.746 6.055 14.633 5.886l10.427-0.17c0.171 0 0.336 0 0.507-0.171l204.532 0.843c11.435-0.336 21.025-9.756 21.193-21.361v-14.63c-1.683-13.625-12.451-21.529-23.887-21.193l-134.222-0.335 243.38-242.539c11.104-11.104 11.104-29.101 0-40.203-10.929-11.268-28.757-11.268-39.857 0.001v0M964.271 947.109l-0.507-205.536c-0.336-11.438-9.76-18.335-21.194-18.672h-14.629c-11.439-0.331-20.521 9.759-20.356 21.193l0.843 137.927-244.393-243.214c-11.104-11.104-29.099-11.104-40.203 0-11.097 11.101-11.097 29.099 0 40.203l243.386 242.538-134.22 0.335c-11.438-0.335-22.034 7.739-23.887 21.193v14.633c0.335 11.437 9.76 21.025 21.193 21.361l203.69-0.843c0.17 0 0.335 0.17 0.507 0.17l10.428 0.171c5.716 0.17 10.934-2.016 14.63-5.886 3.698-3.7 5.042-8.912 4.875-14.63 0 0-0.169-10.764-0.169-10.934l0.004-0.002M152.885 126.645l134.22-0.335c11.435 0.335 22.031-7.739 23.883-21.193v-14.636c-0.336-11.437-9.753-21.025-21.193-21.36l-204.694 0.842c-0.17 0-0.336-0.171-0.509-0.171l-10.426-0.169c-5.722-0.17-10.934 2.015-14.633 5.885-3.698 3.7-5.050 8.912-4.875 14.633 0 0 0.335 10.763 0.335 10.933l0.502 205.536c0.171 11.435 9.759 18.335 21.193 18.667h15.475c11.437 0.335 20.519-9.753 20.349-21.191l-0.671-137.248 244.224 242.709c11.097 11.104 29.094 11.104 40.196 0 11.104-11.101 11.104-29.099 0-40.203l-243.38-242.703M152.885 126.645v0z" ></path></symbol><symbol id="el-icon-self-shipin" viewBox="0 0 1024 1024"><path d="M858.8 903.6H182.2c-61 0-110.8-49.6-110.8-110.8V279c0-61 49.6-110.8 110.8-110.8h676.6c61 0 110.8 49.6 110.8 110.8v513.8c-0.2 61-49.8 110.8-110.8 110.8zM182.2 208.4c-39 0-70.8 31.8-70.8 70.8v513.8c0 39 31.8 70.8 70.8 70.8h676.6c39 0 70.8-31.8 70.8-70.8v-514c0-39-31.8-70.8-70.8-70.8H182.2z" fill="#262435" ></path><path d="M225.4 903.6c-11 0-20-9-20-20V188.4c0-11 9-20 20-20s20 9 20 20v695.2c0 11-8.8 20-20 20zM815.4 903.6c-11 0-20-9-20-20V188.4c0-11 9-20 20-20s20 9 20 20v695.2c0 11-9 20-20 20z" fill="#262435" ></path><path d="M225.4 399.2h-134c-11 0-20-9-20-20s9-20 20-20h134c11 0 20 9 20 20s-8.8 20-20 20zM225.4 556h-134c-11 0-20-9-20-20s9-20 20-20h134c11 0 20 9 20 20s-8.8 20-20 20zM225.4 732.6h-134c-11 0-20-9-20-20s9-20 20-20h134c11 0 20 9 20 20s-8.8 20-20 20z" fill="#262435" ></path><path d="M949.4 399.2h-134c-11 0-20-9-20-20s9-20 20-20h134c11 0 20 9 20 20s-9 20-20 20zM949.4 556h-134c-11 0-20-9-20-20s9-20 20-20h134c11 0 20 9 20 20s-9 20-20 20zM949.4 732.6h-134c-11 0-20-9-20-20s9-20 20-20h134c11 0 20 9 20 20s-9 20-20 20z" fill="#262435" ></path><path d="M432 679.2c-3.4 0-7-0.8-10-2.6-6.2-3.6-10-10.2-10-17.4V412.8c0-7.2 3.8-13.8 10-17.4 6.2-3.6 13.8-3.6 20 0l213.4 123.2c6.2 3.6 10 10.2 10 17.4s-3.8 13.8-10 17.4L442 676.4c-3.2 1.8-6.6 2.8-10 2.8z m20-231.8v177.2l153.4-88.6-153.4-88.6z" fill="#262435" ></path></symbol><symbol id="el-icon-self-iconset0481" viewBox="0 0 1024 1024"><path d="M512 42.666667C253.866667 42.666667 42.666667 251.733333 42.666667 512s211.2 469.333333 469.333333 469.333333c260.266667 0 469.333333-209.066667 469.333333-469.333333S772.266667 42.666667 512 42.666667zM512 938.666667C277.333333 938.666667 85.333333 746.666667 85.333333 512 85.333333 277.333333 277.333333 85.333333 512 85.333333c234.666667 0 426.666667 192 426.666667 426.666667C938.666667 746.666667 746.666667 938.666667 512 938.666667zM716.8 494.933333 716.8 494.933333l-4.266667-2.133333c0 0 0 0-2.133333 0l-292.266667-168.533333 0 0C413.866667 322.133333 409.6 320 405.333333 320c-12.8 0-21.333333 8.533333-21.333333 21.333333l0 341.333333c0 12.8 8.533333 21.333333 21.333333 21.333333 4.266667 0 8.533333-2.133333 12.8-4.266667l0 0 292.266667-168.533333c0 0 0 0 2.133333 0l4.266667-2.133333 0 0c4.266667-4.266667 8.533333-10.666667 8.533333-17.066667S721.066667 499.2 716.8 494.933333zM426.666667 646.4 426.666667 377.6 661.333333 512 426.666667 646.4z" ></path></symbol><symbol id="el-icon-self-wenjian" viewBox="0 0 1024 1024"><path d="M752 80H272c-70.4 0-128 57.6-128 128v608c0 70.4 57.6 128 128 128h353.6c33.6 0 65.6-12.8 91.2-36.8l126.4-126.4c24-24 36.8-56 36.8-91.2V208c0-70.4-57.6-128-128-128zM208 816V208c0-35.2 28.8-64 64-64h480c35.2 0 64 28.8 64 64v464h-96c-70.4 0-128 57.6-128 128v80H272c-35.2 0-64-28.8-64-64z m462.4 44.8c-4.8 4.8-9.6 8-14.4 11.2V800c0-35.2 28.8-64 64-64h75.2l-124.8 124.8z" fill="#4A576A" ></path><path d="M368 352h288c17.6 0 32-14.4 32-32s-14.4-32-32-32H368c-17.6 0-32 14.4-32 32s14.4 32 32 32zM496 608h-128c-17.6 0-32 14.4-32 32s14.4 32 32 32h128c17.6 0 32-14.4 32-32s-14.4-32-32-32zM368 512h288c17.6 0 32-14.4 32-32s-14.4-32-32-32H368c-17.6 0-32 14.4-32 32s14.4 32 32 32z" fill="#4A576A" ></path></symbol><symbol id="el-icon-self-PPT" viewBox="0 0 1024 1024"><path d="M855.5 345.9L616 106.5c-5.3-5.3-12.4-8.2-19.9-8.2H174.3c-7.8 0-14.1 6.3-14.1 14.1v801.9c0 7.8 6.3 14.1 14.1 14.1h675.3c7.8 0 14.1-6.3 14.1-14.1V365.8c0-7.5-2.9-14.7-8.2-19.9z m-53 514.8h-581v-695h376.6v204.2h204.3l0.1 490.8z" ></path><path d="M520.2 632.7h-49v101.9H405V443.5h121.7c70.6 1.8 107.2 32.2 109.8 91.3 1 66.1-37.8 98.8-116.3 97.9z m-5.3-138.9h-43.7v88.6h43.7c34.4-0.9 52-15.9 52.9-45-0.9-28.2-18.5-42.7-52.9-43.6z" ></path></symbol><symbol id="el-icon-self-13" viewBox="0 0 1024 1024"><path d="M147.2 180.8h728c41.6 0 76.8 35.2 76.8 76.8v552c0 41.6-35.2 76.8-76.8 76.8h-728c-41.6 0-76.8-35.2-76.8-76.8v-552c0-41.6 35.2-76.8 76.8-76.8v0zM147.2 926.4c243.2 0 486.4 0 728 0 64 0 115.2-51.2 115.2-115.2 0-184 0-368 0-552 0-64-51.2-115.2-115.2-115.2-243.2 0-486.4 0-728 0-64 0-115.2 51.2-115.2 115.2 0 184 0 368 0 552 0 62.4 51.2 115.2 115.2 115.2z" ></path><path d="M201.6 419.2c0 44.8 36.8 81.6 81.6 81.6s81.6-36.8 81.6-81.6c0-44.8-36.8-81.6-81.6-81.6-44.8 0-81.6 36.8-81.6 81.6v0zM240 419.2c0-24 19.2-43.2 43.2-43.2s43.2 19.2 43.2 43.2c0 24-19.2 43.2-43.2 43.2-22.4 0-43.2-19.2-43.2-43.2z" ></path><path d="M675.2 499.2l203.2 203.2c8 8 8 19.2 0 27.2v0c-8 8-19.2 8-27.2 0l-203.2-203.2c-14.4-14.4-40-14.4-54.4 0l-163.2 161.6c-30.4 30.4-80 30.4-110.4 0l-25.6-25.6c-14.4-14.4-40-14.4-54.4 0l-67.2 67.2c-8 8-19.2 8-27.2 0v0c-8-8-8-19.2 0-27.2l67.2-67.2c30.4-30.4 80-30.4 110.4 0l25.6 25.6c14.4 14.4 40 14.4 54.4 0l161.6-161.6c30.4-30.4 80-30.4 110.4 0z" ></path></symbol><symbol id="el-icon-self-cc-book" viewBox="0 0 1024 1024"><path d="M682.697195 859.707167 242.160807 859.707167c-12.152784 0-22.025643-9.893324-22.025643-22.026666 0-12.130272 9.872858-22.025643 22.025643-22.025643l440.537412 0c12.130272 0 22.025643 9.895371 22.025643 22.025643C704.723861 849.813842 694.82849 859.707167 682.697195 859.707167z" ></path><path d="M841.773214 158.324912c-12.955056 0-23.51967 10.543124-23.51967 23.520693l0 705.638185c0 12.95608-10.56666 23.520693-23.521716 23.520693L277.262256 911.004483c-38.911218 0-70.564126-31.650861-70.564126-70.564126 0-38.910195 31.652907-70.563102 70.564126-70.563102l423.382707 0c38.911218 0 70.565149-31.652907 70.565149-70.563102L771.210112 134.803195c0-38.911218-31.653931-70.564126-70.565149-70.564126L230.218824 64.23907c-38.911218 0-70.563102 31.652907-70.563102 70.564126l0 705.637162c0 64.823378 52.785204 117.608581 117.606535 117.608581l517.468548 0c38.909172 0 70.563102-31.653931 70.563102-70.565149L865.293907 181.845605C865.293907 168.868035 854.727247 158.324912 841.773214 158.324912zM230.218824 111.281479l470.426139 0c12.955056 0 23.521716 10.543124 23.521716 23.521716l0 564.510958c0 12.955056-10.56666 23.520693-23.521716 23.520693l-423.382707 0c-26.439162 0-50.90232 8.820899-70.564126 23.566742L206.698131 134.803195C206.698131 121.824603 217.241254 111.281479 230.218824 111.281479z" ></path></symbol><symbol id="el-icon-self-grade" viewBox="0 0 1024 1024"><path d="M863.721739 554.295652c24.486957-48.973913 28.93913-102.4 28.93913-160.278261C892.66087 189.217391 734.608696 22.26087 527.582609 22.26087 320.556522 22.26087 162.504348 189.217391 162.504348 394.017391c0 57.878261 4.452174 111.304348 28.93913 160.278261L51.2 792.486957c0 0 95.721739 35.617391 193.669565 55.652174 64.556522 73.46087 117.982609 151.373913 117.982609 151.373913l129.113043-247.095652c8.904348 0 20.034783 0 26.713043 0 8.904348 0 20.034783 0 26.713043 0l138.017391 233.73913c0 0 57.878261-64.556522 124.66087-138.017391 97.947826-20.034783 193.669565-55.652174 193.669565-55.652174L863.721739 554.295652 863.721739 554.295652 863.721739 554.295652zM353.947826 903.791304c0 0-46.747826-60.104348-89.043478-102.4-62.330435-17.808696-144.695652-35.617391-144.695652-35.617391L215.930435 601.043478c51.2 66.782609 135.791304 129.113043 220.382609 149.147826L353.947826 903.791304 353.947826 903.791304zM520.904348 710.121739c-80.13913 0-309.426087-48.973913-316.104348-316.104348C198.121739 224.834783 351.721739 64.556522 520.904348 64.556522c169.182609 0 329.46087 162.504348 329.46087 329.46087C852.591304 650.017391 601.043478 710.121739 520.904348 710.121739L520.904348 710.121739zM685.634783 903.791304l-82.365217-151.373913c84.591304-20.034783 182.53913-84.591304 233.73913-151.373913l95.721739 164.730435c0 0-82.365217 17.808696-144.695652 35.617391L685.634783 903.791304 685.634783 903.791304zM527.582609 175.86087c-117.982609 0-213.704348 95.721739-213.704348 213.704348s95.721739 213.704348 213.704348 213.704348c117.982609 0 213.704348-95.721739 213.704348-213.704348S645.565217 175.86087 527.582609 175.86087L527.582609 175.86087 527.582609 175.86087zM534.26087 558.747826c-53.426087 0-169.182609-20.034783-178.086957-178.086957-4.452174-84.591304 95.721739-164.730435 178.086957-164.730435 84.591304 0 162.504348 95.721739 164.730435 178.086957C701.217391 505.321739 587.686957 558.747826 534.26087 558.747826L534.26087 558.747826zM534.26087 558.747826" ></path></symbol><symbol id="el-icon-self-xuexi-" viewBox="0 0 1024 1024"><path d="M996.5 287.1L567.6 68.8c-34.8-17.6-76.4-17.6-111.2 0L27.5 286.4C10.6 295 0 312.1 0 331.2c0 19 10.5 36.2 27.5 44.8l219.8 111.8v305c0 33.9 18.8 64.4 49 79.7l164.9 83.6c15.9 8.1 33.4 12.1 50.9 12.1s35-4 50.9-12.1l164.9-83.6c30.2-15.3 49-45.9 49-79.7V488.2L901.4 425v111.9c0 15.2 12.3 27.5 27.5 27.5s27.5-12.3 27.5-27.5V401.6c0-1.5-0.1-2.9-0.3-4.3l40.4-20.5c17-8.6 27.5-25.8 27.5-44.8 0-19.1-10.5-36.3-27.5-44.9zM721.8 792.9c0 13.1-7.2 24.8-18.9 30.8L538 907.3c-16.3 8.3-35.8 8.3-52.1 0L321 823.7c-11.6-5.9-18.9-17.7-18.9-30.8V515.8l154.2 78.5c17.4 8.8 36.5 13.2 55.6 13.2s38.2-4.4 55.6-13.2l154.2-78.2v276.8z m-179-247.6c-19.3 9.8-42.3 9.8-61.5 0L60.5 331.2l420.7-213.4c19.3-9.8 42.3-9.8 61.5 0l420.7 214.1-420.6 213.4z" fill="" ></path></symbol><symbol id="el-icon-self-nav" viewBox="0 0 1024 1024"><path d="M888.838 319.775l-751.1 0c-23.944 0-43.339-19.553-43.339-43.646l0-40.012c0-24.093 19.395-43.645 43.339-43.645l751.1 0c23.923 0 43.334 19.554 43.334 43.645l0 40.012c-0.001 24.093-19.411 43.646-43.333 43.646l0 0zM888.838 587.509l-751.1 0c-23.944 0-43.339-19.533-43.339-43.64l0-39.998c0-24.115 19.395-43.647 43.339-43.647l751.1 0c23.923 0 43.334 19.533 43.334 43.647l0 39.998c-0.001 24.107-19.411 43.64-43.333 43.64l0 0zM888.838 876.17l-751.1 0c-23.944 0-43.339-19.532-43.339-43.627l0-40.017c0-24.093 19.395-43.641 43.339-43.641l751.1 0c23.923 0 43.334 19.548 43.334 43.641l0 40.017c-0.001 24.094-19.411 43.627-43.333 43.627l0 0z" ></path></symbol><symbol id="el-icon-self-mima" viewBox="0 0 1024 1024"><path d="M791.366 459.07l-459.174-0.791c-0.186-61.936-16.847-157.926 36.027-216.192 32.142-35.52 86.326-72.068 144.127-72.068 85.395 0 149.246 64.412 180.166 144.126 9.009 22.992 16.936 35.38 36.037 36.037 47.899 1.45 44.986-49.075 36.029-72.067C719.914 163.03 636.118 97.953 512.346 97.953c-84.12 0-130.475 17.265-180.154 72.065-76.009 83.746-72.259 219.151-72.067 288.26l-26.795 0.791c-25.045 0-45.273 20.034-45.273 44.667v378.249c0 24.774 20.269 44.755 45.273 44.755h557.99c25.009 0 45.273-19.989 45.273-44.755V503.737c0.046-24.678-20.218-44.667-45.227-44.667zM765.68 818.35c0 9.966-3.476 18.514-10.58 25.52-7.045 7.051-15.56 10.58-25.517 10.58H296.362c-9.966 0-18.472-3.478-25.475-10.58-7.051-7.049-10.624-15.553-10.624-25.52V565.635c0-19.878 16.166-36.054 36.098-36.054h433.212c19.932 0 36.107 16.176 36.107 36.054V818.35z" fill="" ></path></symbol><symbol id="el-icon-self-character" viewBox="0 0 1024 1024"><path d="M921.087359 990.72v-35.2A410.24 410.24 0 0 0 661.887359 576a307.2 307.2 0 1 0-300.8 0 410.24 410.24 0 0 0-256 380.8v35.2H101.887359a32 32 0 0 0 32 32 32 32 0 0 0 32-32v-34.56a345.6 345.6 0 0 1 691.2 0v35.2a31.36 31.36 0 0 0 31.36 30.08 32 32 0 0 0 32.64-32zM270.207359 307.2A241.28 241.28 0 1 1 511.487359 548.48 241.28 241.28 0 0 1 270.207359 307.2z" ></path></symbol><symbol id="el-icon-self-statistic" viewBox="0 0 1024 1024"><path d="M838.33 659.732c0 33.422-21.592 54.388-54.39 54.388H240.059c-32.796 0-54.388-20.966-54.388-54.388 0 0-0.409-482.507-0.409-516.961h653.477c0 54.85-0.409 516.96-0.409 516.96zM76.892 88.655v54.389h54.389v516.689c0 64.45 44.707 108.776 108.776 108.776h163.166L294.447 958.87l81.909-0.353 108.45-190.006h54.388l108.45 190.006 81.909 0.353-108.777-190.36h163.166c64.069 0 108.776-44.326 108.776-108.776v-516.69h54.389v-54.39H76.893v0.001z m271.942 543.883c15.038 0 27.194-12.156 27.194-27.194V496.568c0-15.011-12.156-27.195-27.194-27.195s-27.195 12.183-27.195 27.195v108.776c0 15.038 12.156 27.194 27.195 27.194z m326.33 0c15.039 0 27.195-12.156 27.195-27.194V360.597c0-15.011-12.156-27.195-27.195-27.195s-27.194 12.183-27.194 27.195v244.747c0 15.038 12.156 27.194 27.194 27.194z m-163.165 0c15.039 0 27.194-12.156 27.194-27.194v-326.33c0-15.011-12.155-27.195-27.194-27.195s-27.194 12.183-27.194 27.195v326.33c0 15.038 12.155 27.194 27.194 27.194z" ></path></symbol><symbol id="el-icon-self-discover" viewBox="0 0 1024 1024"><path d="M544 288c0-52.928-43.072-96-96-96s-96 43.072-96 96 43.072 96 96 96S544 340.928 544 288zM416 288c0-17.632 14.368-32 32-32s32 14.368 32 32-14.368 32-32 32S416 305.632 416 288z" ></path><path d="M304 448C259.904 448 224 483.904 224 528 224 572.128 259.904 608 304 608s80-35.872 80-80C384 483.904 348.096 448 304 448zM304 544C295.168 544 288 536.832 288 528S295.168 512 304 512s16 7.168 16 16S312.832 544 304 544z" ></path><path d="M640 736m-64 0a2 2 0 1 0 128 0 2 2 0 1 0-128 0Z" ></path><path d="M887.84 268.672c39.744-60.672 64.256-113.184 64.224-148.96 0-22.976-9.312-36.928-17.12-44.576-38.08-37.376-110.016-3.2-160.768 25.664-15.328 8.736-20.704 28.288-11.968 43.648 8.736 15.36 28.32 20.704 43.648 11.968 49.408-28.16 73.248-33.088 82.496-33.696-1.504 41.376-95.328 202.432-330.208 433.504-226.368 222.72-398.656 324.672-442.24 325.376 0.96-11.36 8.768-44.448 58.528-118.688 1.312-1.888 2.4-3.968 3.232-6.144l2.304-5.92c0.256-0.64 0.288-1.344 0.512-2.016 8.8-10.24 10.816-25.088 3.392-37.248C147.328 651.616 128 582.592 128 512 128 300.256 300.256 128 512 128c59.296 0 116.096 13.12 168.864 39.04 15.936 7.776 35.04 1.184 42.816-14.656 7.776-15.84 1.248-35.008-14.624-42.816C647.424 79.328 581.12 64 512 64 264.96 64 64 264.96 64 512c0 76.064 19.488 150.496 56.064 216.64-0.192 0.576-0.64 1.056-0.8 1.632C51.168 832.608 35.2 895.68 68.928 928.768c11.008 10.784 25.632 15.584 43.072 15.584 39.328 0 92.864-24.928 150.08-60.896C336.096 933.408 421.952 960 512 960c247.04 0 448-200.96 448-448C960 424.864 934.912 341.248 887.84 268.672zM512 896c-68.288 0-133.728-17.888-191.84-51.552 128.288-92.256 258.432-218.56 282.848-242.624 89.152-87.712 178.56-187.04 244.64-275.968C879.2 382.592 896 446.112 896 512 896 723.744 723.744 896 512 896z" ></path></symbol><symbol id="el-icon-self-settings" viewBox="0 0 1024 1024"><path d="M512 608c-52.928 0-96-43.072-96-96s43.072-96 96-96 96 43.072 96 96S564.928 608 512 608zM512 480c-17.632 0-32 14.368-32 32s14.368 32 32 32 32-14.368 32-32S529.632 480 512 480z" ></path><path d="M631.04 960c-10.016 0-19.712-4.736-25.856-13.12l-73.408-100.48c-13.664 0.832-25.92 0.864-39.584 0l-73.376 100.48c-7.904 10.816-21.728 15.616-34.656 11.872-34.592-9.888-67.488-23.456-97.76-40.32-11.712-6.528-18.112-19.648-16.032-32.896l19.2-123.264c-9.824-8.704-19.136-18.016-27.84-27.808l-123.264 19.2c-13.056 1.984-26.336-4.352-32.896-16.064-16.896-30.368-30.464-63.296-40.32-97.824-3.68-12.864 1.056-26.72 11.904-34.624l100.448-73.376C177.152 524.96 176.928 518.4 176.928 512s0.224-12.96 0.672-19.776L77.12 418.816c-10.816-7.936-15.584-21.728-11.904-34.656 9.856-34.496 23.424-67.392 40.32-97.792 6.56-11.712 19.712-18.048 32.896-16.064l123.264 19.2c8.736-9.824 18.016-19.104 27.84-27.84l-19.2-123.264C268.288 125.184 274.72 112.064 286.432 105.536c30.4-16.896 63.296-30.464 97.76-40.32 12.928-3.648 26.72 1.056 34.656 11.904l73.376 100.448c13.568-0.896 25.824-0.896 39.584 0l73.408-100.48c7.904-10.848 21.664-15.52 34.656-11.904 34.464 9.856 67.328 23.424 97.76 40.32 11.712 6.528 18.112 19.648 16.064 32.896L734.432 261.76c9.824 8.736 19.104 18.016 27.808 27.776l123.328-19.2c13.152-2.016 26.336 4.384 32.864 16.032 16.896 30.4 30.496 63.296 40.352 97.824 3.648 12.896-1.088 26.688-11.904 34.624l-100.48 73.408c0.448 6.816 0.672 13.376 0.672 19.776s-0.224 12.96-0.672 19.776l100.48 73.376c10.816 7.904 15.552 21.728 11.904 34.624-9.856 34.496-23.424 67.424-40.352 97.824-6.528 11.712-19.488 18.048-32.896 16.064l-123.296-19.2c-8.672 9.76-17.984 19.072-27.808 27.776l19.232 123.296c2.048 13.248-4.352 26.368-16.064 32.896-30.24 16.832-63.136 30.4-97.76 40.32C636.928 959.584 633.984 960 631.04 960zM337.152 872.672c13.984 6.752 28.544 12.704 43.552 17.92l70.528-96.576c6.784-9.28 17.984-14.272 29.472-12.896 20.576 2.336 42.08 2.336 62.624 0 11.84-1.376 22.72 3.616 29.472 12.896l70.528 96.576c15.04-5.184 29.6-11.168 43.552-17.92l-18.432-118.368c-1.76-11.36 2.72-22.848 11.712-30.016 16.384-12.992 31.264-27.872 44.16-44.128 7.168-8.992 18.4-13.504 30.016-11.744l118.368 18.432c6.752-14.016 12.736-28.576 17.92-43.552l-96.576-70.528c-9.28-6.784-14.208-18.016-12.896-29.472 1.152-10.272 1.952-20.704 1.952-31.296s-0.768-21.024-1.952-31.296c-1.312-11.424 3.616-22.688 12.896-29.472l96.576-70.56c-5.152-15.008-11.168-29.568-17.92-43.552l-118.4 18.432c-11.328 1.696-22.816-2.688-29.984-11.744-12.896-16.256-27.776-31.104-44.16-44.128-8.992-7.168-13.472-18.592-11.712-29.984l18.432-118.4c-14.016-6.752-28.576-12.736-43.52-17.92l-70.56 96.576c-6.784 9.28-17.696 14.368-29.472 12.928-20.544-2.368-42.016-2.4-62.56 0-11.52 1.344-22.752-3.616-29.536-12.896l-70.528-96.576c-14.976 5.152-29.536 11.136-43.552 17.92l18.432 118.368c1.76 11.392-2.72 22.848-11.744 30.016-16.32 12.928-31.2 27.808-44.128 44.128-7.168 9.024-18.56 13.472-30.016 11.744l-118.368-18.432c-6.752 14.016-12.736 28.576-17.92 43.552l96.576 70.56c9.312 6.784 14.24 18.08 12.896 29.536C241.696 491.008 240.928 501.408 240.928 512s0.768 20.992 1.952 31.264c1.344 11.456-3.616 22.688-12.896 29.504l-96.576 70.528c5.184 15.008 11.168 29.568 17.92 43.552l118.368-18.432c11.392-1.76 22.848 2.752 30.016 11.744 12.896 16.32 27.744 31.168 44.128 44.128 9.024 7.168 13.504 18.624 11.744 30.016L337.152 872.672z" ></path></symbol><symbol id="el-icon-self-new" viewBox="0 0 1024 1024"><path d="M963.072 446.336c0-211.744-200.96-384-448-384s-448 172.256-448 384c0 116.48 63.008 226.048 172.896 300.672 14.656 9.984 34.528 6.144 44.448-8.512 9.952-14.624 6.112-34.528-8.512-44.448-92.032-62.496-144.832-152.768-144.832-247.712 0-176.448 172.256-320 384-320 211.744 0 384 143.552 384 320 0 176.448-172.256 320-384 320-1.984 0-3.68 0.768-5.568 1.12-15.104-2.688-30.464 5.216-35.776 20.192-6.144 17.376-46.368 46.656-94.144 73.792 17.472-58.208 9.088-70.688 3.52-78.976-6.72-9.984-17.92-15.936-29.92-15.936-17.664 0-32 14.304-32 32 0 5.824 1.536 11.264 4.256 15.936-3.232 18.24-17.216 60.864-33.088 99.872-4.928 12.096-1.984 25.984 7.36 35.072 6.112 5.888 14.112 8.992 22.272 8.992 4.384 0 8.8-0.896 12.992-2.752 36.48-16.256 147.68-69.12 187.616-125.664C766.144 826.496 963.072 655.904 963.072 446.336z" ></path><path d="M342.624 604.544c4.672 2.4 9.664 3.52 14.592 3.52 11.616 0 22.816-6.336 28.512-17.408l71.584-139.488 91.584 142.208c5.824 9.024 15.744 14.528 26.464 14.688 0.16 0 0.32 0 0.448 0 10.56 0 20.48-5.216 26.432-13.984l128.8-188.864c9.984-14.624 6.176-34.528-8.416-44.48-14.624-9.952-34.528-6.208-44.48 8.416l-101.632 148.992-95.456-148.288c-6.176-9.6-17.152-14.752-28.48-14.656-11.424 0.576-21.696 7.2-26.912 17.344l-96.896 188.896C320.672 577.184 326.88 596.48 342.624 604.544z" ></path></symbol><symbol id="el-icon-self-album" viewBox="0 0 1024 1024"><path d="M256 448m-64 0a2 2 0 1 0 128 0 2 2 0 1 0-128 0Z" ></path><path d="M714.688 256 181.312 256C116.64 256 64 308.64 64 373.312l0 405.376C64 843.36 116.64 896 181.312 896l533.376 0C779.36 896 832 843.36 832 778.688L832 373.312C832 308.64 779.36 256 714.688 256zM768 778.688C768 808.096 744.096 832 714.688 832L181.312 832C151.936 832 128 808.096 128 778.688L128 373.312C128 343.936 151.936 320 181.312 320l533.376 0C744.096 320 768 343.936 768 373.312L768 778.688z" ></path><path d="M842.688 128 256 128C238.336 128 224 142.336 224 160s14.336 32 32 32l586.688 0C872.096 192 896 215.936 896 245.312L896 640c0 17.696 14.304 32 32 32s32-14.304 32-32L960 245.312C960 180.64 907.36 128 842.688 128z" ></path><path d="M672.64 448.736c-129.056 0-143.936 72.672-152.832 116.096-7.2 35.168-10.4 39.968-28.64 42.88-34.976 5.568-44 0.192-58.912-8.8-15.456-9.312-36.672-22.08-77.952-23.168C227.616 573.12 194.112 723.84 192.704 730.24c-3.712 17.28 7.264 34.304 24.544 38.016 2.272 0.512 4.544 0.704 6.752 0.704 14.752 0 28-10.24 31.264-25.248 0.224-1.056 23.232-104.032 95.488-104.032 0.64 0 1.28 0 1.92 0.032 24.352 0.608 33.632 6.208 46.496 13.984 24.032 14.464 48.352 25.76 102.08 17.184 64.192-10.272 74.432-60.192 81.184-93.216 8.32-40.512 13.312-64.928 90.144-64.928 17.696 0 32-14.336 32-32S690.304 448.736 672.64 448.736z" ></path></symbol></svg>',l=(c=document.getElementsByTagName("script"))[c.length-1].getAttribute("data-injectcss");if(l&&!o.__iconfont__svg__cssinject__){o.__iconfont__svg__cssinject__=!0;try{document.write("<style>.svgfont {display: inline-block;width: 1em;height: 1em;fill: currentColor;vertical-align: -0.1em;font-size:16px;}</style>")}catch(c){console&&console.log(c)}}!function(c){if(document.addEventListener)if(~["complete","loaded","interactive"].indexOf(document.readyState))setTimeout(c,0);else{var l=function(){document.removeEventListener("DOMContentLoaded",l,!1),c()};document.addEventListener("DOMContentLoaded",l,!1)}else document.attachEvent&&(e=c,s=o.document,h=!1,(i=function(){try{s.documentElement.doScroll("left")}catch(c){return void setTimeout(i,50)}t()})(),s.onreadystatechange=function(){"complete"==s.readyState&&(s.onreadystatechange=null,t())});function t(){h||(h=!0,e())}var e,s,h,i}(function(){var c,l,t,e,s,h;(c=document.createElement("div")).innerHTML=i,i=null,(l=c.getElementsByTagName("svg")[0])&&(l.setAttribute("aria-hidden","true"),l.style.position="absolute",l.style.width=0,l.style.height=0,l.style.overflow="hidden",t=l,(e=document.body).firstChild?(s=t,(h=e.firstChild).parentNode.insertBefore(s,h)):e.appendChild(t))})}(window);
\ No newline at end of file
{
"id": "948269",
"name": "self-all",
"font_family": "selfAllIcon",
"css_prefix_text": "el-icon-self-",
"description": "所有外包项目,图标库",
"glyphs": [
{
"icon_id": "1546564",
"name": "反馈意见",
"font_class": "fankuiyijian",
"unicode": "e68f",
"unicode_decimal": 59023
},
{
"icon_id": "8777427",
"name": "help",
"font_class": "icon-test",
"unicode": "e655",
"unicode_decimal": 58965
},
{
"icon_id": "11720124",
"name": "视频禁止",
"font_class": "shipinjinzhi",
"unicode": "e60b",
"unicode_decimal": 58891
},
{
"icon_id": "11720125",
"name": "视频播放",
"font_class": "shipinbofang",
"unicode": "e60c",
"unicode_decimal": 58892
},
{
"icon_id": "11717677",
"name": "退出",
"font_class": "tuichu",
"unicode": "e606",
"unicode_decimal": 58886
},
{
"icon_id": "551615",
"name": "五角星",
"font_class": "star_full",
"unicode": "e627",
"unicode_decimal": 58919
},
{
"icon_id": "2681717",
"name": "五角星",
"font_class": "wujiaoxing",
"unicode": "e614",
"unicode_decimal": 58900
},
{
"icon_id": "632985",
"name": "关闭",
"font_class": "guanbi",
"unicode": "e611",
"unicode_decimal": 58897
},
{
"icon_id": "646387",
"name": "刷新",
"font_class": "xuexiao",
"unicode": "e632",
"unicode_decimal": 58930
},
{
"icon_id": "1010014",
"name": "全屏",
"font_class": "quanping",
"unicode": "e743",
"unicode_decimal": 59203
},
{
"icon_id": "2198788",
"name": "视频",
"font_class": "shipin",
"unicode": "e60e",
"unicode_decimal": 58894
},
{
"icon_id": "554517",
"name": "播放",
"font_class": "iconset0481",
"unicode": "e768",
"unicode_decimal": 59240
},
{
"icon_id": "4251768",
"name": "文件",
"font_class": "wenjian",
"unicode": "e650",
"unicode_decimal": 58960
},
{
"icon_id": "5620349",
"name": "PPT",
"font_class": "PPT",
"unicode": "e602",
"unicode_decimal": 58882
},
{
"icon_id": "720044",
"name": "image-o",
"font_class": "13",
"unicode": "e6ce",
"unicode_decimal": 59086
},
{
"icon_id": "372115",
"name": "cc-book",
"font_class": "cc-book",
"unicode": "e615",
"unicode_decimal": 58901
},
{
"icon_id": "938307",
"name": "Grade",
"font_class": "grade",
"unicode": "e66c",
"unicode_decimal": 58988
},
{
"icon_id": "4657687",
"name": "学习",
"font_class": "xuexi-",
"unicode": "e609",
"unicode_decimal": 58889
},
{
"icon_id": "1174321",
"name": "nav",
"font_class": "nav",
"unicode": "e66b",
"unicode_decimal": 58987
},
{
"icon_id": "1418216",
"name": "密码",
"font_class": "mima",
"unicode": "e607",
"unicode_decimal": 58887
},
{
"icon_id": "3090318",
"name": "人物",
"font_class": "character",
"unicode": "e62e",
"unicode_decimal": 58926
},
{
"icon_id": "6918240",
"name": "statistic",
"font_class": "statistic",
"unicode": "e601",
"unicode_decimal": 58881
},
{
"icon_id": "30446",
"name": "discover",
"font_class": "discover",
"unicode": "e67e",
"unicode_decimal": 59006
},
{
"icon_id": "30480",
"name": "settings",
"font_class": "settings",
"unicode": "e68a",
"unicode_decimal": 59018
},
{
"icon_id": "90850",
"name": "new",
"font_class": "new",
"unicode": "e71e",
"unicode_decimal": 59166
},
{
"icon_id": "151470",
"name": "album",
"font_class": "album",
"unicode": "e734",
"unicode_decimal": 59188
}
]
}
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
<!--
2013-9-30: Created.
-->
<svg>
<metadata>
Created by iconfont
</metadata>
<defs>
<font id="selfAllIcon" horiz-adv-x="1024" >
<font-face
font-family="selfAllIcon"
font-weight="500"
font-stretch="normal"
units-per-em="1024"
ascent="896"
descent="-128"
/>
<missing-glyph />
<glyph glyph-name="fankuiyijian" unicode="&#59023;" d="M865.773 488.494c-16.142 0-29.127-12.986-29.127-29.127v-375.982c0-12.622-10.316-22.938-22.938-22.938h-600.989c-12.622 0-22.938 10.316-22.938 22.938v601.11c0 12.622 10.316 22.938 22.938 22.938h375.254c16.142 0 29.127 12.986 29.127 29.127s-12.986 29.127-29.127 29.127h-375.254c-44.783 0-81.191-36.409-81.191-81.191v-600.989c0-44.783 36.409-81.191 81.191-81.191h600.989c44.783 0 81.191 36.409 81.191 81.191v375.861c0 16.142-13.107 29.127-29.127 29.127zM334.324 344.678l-35.438-139.568c-2.548-9.952 0.364-20.511 7.646-27.792s17.84-10.194 27.792-7.646l139.568 35.438c5.098 1.334 9.709 3.884 13.471 7.646l387.876 387.876c26.457 26.457 26.093 69.905-0.729 96.848l-47.696 47.696c-26.943 26.943-70.39 27.307-96.848 0.729l-387.997-387.755c-3.641-3.762-6.311-8.374-7.646-13.471zM771.109 704.763c3.762 3.762 10.316 3.398 14.563-0.729l47.696-47.696c4.127-4.127 4.491-10.801 0.729-14.563l-29.977-29.977-62.988 62.988 29.977 29.977zM699.87 633.644l62.988-62.988-278.164-278.043-62.988 62.988 278.164 278.043zM385.539 309.484l53.157-53.157-71.239-18.083 18.083 71.239z" horiz-adv-x="1024" />
<glyph glyph-name="icon-test" unicode="&#58965;" d="M512 0C299.936 0 128 171.936 128 384S299.936 768 512 768s384-171.936 384-384-171.936-384-384-384m0 832C264.96 832 64 631.04 64 384s200.96-448 448-448 448 200.96 448 448S759.04 832 512 832M511.68 192a48 48 0 1 1 0-96 48 48 0 0 1 0 96M512 640l-0.288-0.032A160.16 160.16 0 0 1 352 480h64a96.096 96.096 0 0 0 95.712 95.968L512 576c52.928 0 96-43.072 96-96s-43.072-96-96-96l-0.288 0.032V384H480v-128h64v67.264A160.224 160.224 0 0 1 672 480c0 88.224-71.776 160-160 160" horiz-adv-x="1024" />
<glyph glyph-name="shipinjinzhi" unicode="&#58891;" d="M996.98153 623.213525c-0.200137 16.511287-13.909508 29.920453-30.620932 29.920453-11.507867 0-19.313202-4.803283-21.714844-6.604514L724.49526 499.128701v-214.846868l220.250562-147.400762c2.50171-1.801231 10.206977-6.604515 21.714844-6.604515 16.811492 0 30.520864 13.509235 30.520864 30.12059V623.213525zM968.662171 160.497215c0-1.000684-1.000684-1.801231-2.101436-1.801231-2.601779 0-4.40301 0.800547-5.00342 1.20082L752.914688 299.492231V484.018372l207.742011 139.095084 0.800547 0.600411s2.101437 1.100752 4.903352 1.100752c1.200821 0 2.201505-0.900616 2.201505-1.901299V160.497215zM899.214698 801.135151L703.580964 600.89827c-4.903352 38.426268-38.3262 68.246653-78.653768 68.246653h-520.355712c-43.629825 0-79.154109-35.023942-79.154109-78.053356v-414.683476c0-43.029415 35.524284-78.053357 79.154109-78.053356H212.145021L102.570116-13.821949l20.313887-19.813544 132.990911 136.093032 448.30646 458.3133v0.100069l215.34721 220.35063-20.313886 19.913613zM675.862015 572.378775L239.964038 126.774162H104.471416c-28.019154 0-50.83475 22.315255-50.83475 49.633929V591.091567c0 27.418743 22.815597 49.633929 50.83475 49.633929h520.355712c28.119222 0 50.934819-22.315255 50.934819-49.633929v-18.712792zM675.862015 176.408091c0-27.318675-22.815597-49.633929-50.83475-49.633929H385.763706l-27.819017-28.419427h266.882439c43.729893 0 79.154109 35.023942 79.154109 78.053356V513.438483l-28.21929-29.119906v-307.910486z" horiz-adv-x="1024" />
<glyph glyph-name="shipinbofang" unicode="&#58892;" d="M624.5 98.5H106.1c-44 0-79.8 35.2-79.8 78.6V590.3c0 43.4 35.7 78.6 79.8 78.6h518.4c21.6 0 41.9-8.4 57.1-23.6 14.8-14.8 22.8-34.4 22.8-55.1V177c-0.2-43.3-35.9-78.5-79.9-78.5zM106.1 638.8c-27.5 0-49.7-21.8-49.7-48.5v-413.2c0-26.7 22.3-48.5 49.7-48.5h518.4c27.5 0 49.7 21.8 49.7 48.5V590.3c0 12.7-4.9 24.7-14 33.9-9.4 9.5-22.1 14.7-35.7 14.7H106.1z m858.7-508.5c-11.7 0-19.6 4.9-22.2 6.8L722.8 284.2v215l219.6 147.1c2.6 1.9 10.5 6.8 22.2 6.8 17.1 0 31.2-13.8 31.4-30.7v-461.1c0-17-14-31-31.2-31z m-4.5 31.1c0.5-0.3 2.1-1 4.5-1 0.8 0 1.3 0.4 1.3 0.9V621.9c0 0.5-0.6 1-1.3 1-2.3 0-3.9-0.6-4.4-1l-0.8-0.6v0.3L752.9 483.2v-182.9l207.4-138.9z m0.1 460.7z" horiz-adv-x="1024" />
<glyph glyph-name="tuichu" unicode="&#58886;" d="M747.40131 250.431043h-2.236183c-5.332437 0-10.320847 2.064169-14.105157 5.84848l-110.777087 112.325214c-8.084663 8.084663-8.084663 21.157736-0.172015 29.070385l110.777088 110.777087c3.78431 3.78431 8.77272 5.84848 14.277171 5.84848h1.204099l1.204098 0.172014h1.032085c3.440282 0 6.880564-1.548127 9.116748-4.300353l0.86007-1.032085 0.860071-0.86007c3.78431-3.78431 6.020494-8.944734 6.020494-14.277171s-2.236183-10.492861-6.020494-14.277171l-76.202251-76.202251h443.108349c9.976818-1.720141 17.373425-10.148833 17.373425-20.297665s-7.224593-18.749538-17.373425-20.297666H684.788174l75.514195-77.062321 0.688056-0.688057c6.192508-5.676466 8.256677-14.793214 4.988409-22.533848-3.096254-7.224593-10.320847-12.213002-18.577524-12.213002zM725.727532-36.832521c-54.528473 0-107.680833 10.492861-158.080967 31.134554-51.432219 21.157736-97.532001 51.948261-136.751218 91.511506-39.047203 39.219217-69.493701 84.974971-90.651436 136.235176-20.985721 51.088191-31.650596 105.100622-31.306568 160.489165 0 168.2298 99.940198 319.946246 254.580883 386.171678 51.604233 21.845792 106.132706 33.026709 162.037292 33.026709 63.301193 0 126.774399-14.793214 183.539056-42.659499 57.968755-28.554342 109.22896-70.869814 148.276163-122.818075l0.172015-0.172014c6.70855-8.77272 4.988409-21.673778-3.784311-28.382328-4.472367-3.440282-9.116748-4.128339-12.213002-4.128339-6.364522 0-12.385016 2.92424-16.169326 8.084663-34.230808 44.723669-78.782463 82.050731-129.010583 107.680833C843.729212 746.347724 784.728372 760.452881 725.899546 760.452881c-49.196036 0-97.187972-9.460776-142.771711-28.210314-46.44381-19.093566-88.071225-46.959852-123.334118-82.738787-63.645221-63.301193-102.864438-147.416093-110.261044-237.035445-7.396607-89.619352 17.545439-179.066689 70.009743-252.000672 35.434907-49.024022 82.566773-89.447337 136.407189-116.453552 52.636318-26.490173 111.465144-40.423316 170.29397-40.423316 58.656812 0 117.485637 13.933143 169.949941 40.59533l0.172014 0.172014c50.572148 25.974131 95.467831 63.645221 129.526625 109.056946l0.172014 0.172014c3.096254 4.128339 7.740635 7.052579 12.901059 7.740635 0.860071 0.172014 1.548127 0.172014 2.408197 0.172014 4.300353 0 8.600706-1.376113 12.213002-4.128339 8.77272-6.880564 10.492861-19.781623 3.956325-28.89837-38.015118-50.056106-87.727196-91.683521-143.631783-120.237863-58.312783-29.414413-123.162103-45.067697-188.183437-45.067697z" horiz-adv-x="1448" />
<glyph glyph-name="star_full" unicode="&#58919;" d="M958.733 484.651l-299.475 57.753-147.26 268.060-147.257-268.060-299.476-57.753 208.463-223.396-37.841-303.719 276.111 129.984 276.093-129.984-37.841 303.719z" horiz-adv-x="1024" />
<glyph glyph-name="wujiaoxing" unicode="&#58900;" d="M959.008 489.984l-308 47.008L512 832 372.992 536.992l-308-47.008 223.008-228-52.992-324L512 90.976l276.992-152.992-52.992 324zM512 156L304 39.008l40 235.008-179.008 182.016 242.016 32 104.992 224 104-224 240.992-34.016L680 273.024l36.992-235.008z" horiz-adv-x="1024" />
<glyph glyph-name="guanbi" unicode="&#58897;" d="M567.001395 400.713626 966.070272 799.763149c10.904781 10.905395 10.904781 28.573798 0 39.481242-10.907853 10.905395-28.575949 10.905395-39.482778 0L527.519539 440.193843 128.45271 839.24439c-10.905805 10.905395-28.574925 10.905395-39.481754 0-10.906829-10.906419-10.906829-28.574822 0-39.481242l399.067955-399.049523L88.970957 1.662054c-10.906829-10.906419-10.906829-28.573798 0-39.480218 5.45239-5.452186 12.652646-8.177254 19.741389-8.177254 7.197184 0 14.285926 2.725069 19.740365 8.177254l399.065907 399.052595L926.587494-37.818061c5.454438-5.452186 12.652646-8.177254 19.740365-8.177254 7.198208 0 14.28695 2.725069 19.742413 8.177254 10.904781 10.906419 10.904781 28.573798 0 39.480218L567.001395 400.713626z" horiz-adv-x="1024" />
<glyph glyph-name="xuexiao" unicode="&#58930;" d="M925.761 617.478l-16.543-49.136c0 0-79.438 196.571-314.467 245.72 0 0-96.866 21.943-198.602 0-13.964-7.978-254.891-85.18-297.917-311.249 0 0 9.928-68.815 49.647 0 0 0 23.171 176.919 281.368 262.098h182.062c0 0 211.845-72.075 264.812-245.72l16.556-81.906 49.641-16.392 16.556 196.584h-33.112zM876.12 259.493c0 0-23.171-176.919-281.369-262.098l-182.060-0c0 0-211.845 72.075-264.813 245.72l-16.549 81.906-49.654 16.392-16.548-196.584h33.105l16.549 49.136c0 0 116.962-225.769 314.467-245.72 83.788-19.951 198.617 0 198.617 0s254.884 85.18 297.897 311.248c0 0-9.928 68.815-49.641 0z" horiz-adv-x="1024" />
<glyph glyph-name="quanping" unicode="&#59203;" d="M664.035 486.618l244.223 243.378-0.837-137.922c-0.335-11.437 8.912-21.527 20.351-21.191h14.63c11.438 0.335 21.025 7.065 21.193 18.67l0.672 205.367c0 0.171 0.335 10.934 0.335 10.934 0.17 5.716-1.179 10.934-4.879 14.63-3.7 3.702-8.742 6.055-14.633 5.886l-10.428-0.171c-0.169 0-0.331 0-0.501-0.171l-203.69 0.846c-11.438-0.336-21.025-9.76-21.193-21.361v-14.633c1.685-13.625 12.446-21.529 23.884-21.193l134.219-0.335-243.551-242.542c-11.101-11.104-11.101-29.095 0-40.197 11.104-11.269 29.101-11.269 40.203 0h-0.003M356.233 257.194l-244.393-242.544 0.842 137.253c0.336 11.435-8.918 21.523-20.355 21.193h-15.47c-11.438-0.335-21.025-7.065-21.193-18.672l-0.672-205.536c0-0.171-0.335-10.934-0.335-10.934-0.171-5.722 1.18-10.934 4.875-14.63 3.7-3.7 8.746-6.055 14.633-5.886l10.427 0.17c0.171 0 0.336 0 0.507 0.171l204.532-0.843c11.435 0.336 21.025 9.756 21.193 21.361v14.63c-1.683 13.625-12.451 21.529-23.887 21.193l-134.222 0.335 243.38 242.539c11.104 11.104 11.104 29.101 0 40.203-10.929 11.268-28.757 11.268-39.857-0.001v0M964.271-51.109l-0.507 205.536c-0.336 11.438-9.76 18.335-21.194 18.672h-14.629c-11.439 0.331-20.521-9.759-20.356-21.193l0.843-137.927-244.393 243.214c-11.104 11.104-29.099 11.104-40.203 0-11.097-11.101-11.097-29.099 0-40.203l243.386-242.538-134.22-0.335c-11.438 0.335-22.034-7.739-23.887-21.193v-14.633c0.335-11.437 9.76-21.025 21.193-21.361l203.69 0.843c0.17 0 0.335-0.17 0.507-0.17l10.428-0.171c5.716-0.17 10.934 2.016 14.63 5.886 3.698 3.7 5.042 8.912 4.875 14.63 0 0-0.169 10.764-0.169 10.934l0.004 0.002M152.885 769.355l134.22 0.335c11.435-0.335 22.031 7.739 23.883 21.193v14.636c-0.336 11.437-9.753 21.025-21.193 21.36l-204.694-0.842c-0.17 0-0.336 0.171-0.509 0.171l-10.426 0.169c-5.722 0.17-10.934-2.015-14.633-5.885-3.698-3.7-5.050-8.912-4.875-14.633 0 0 0.335-10.763 0.335-10.933l0.502-205.536c0.171-11.435 9.759-18.335 21.193-18.667h15.475c11.437-0.335 20.519 9.753 20.349 21.191l-0.671 137.248 244.224-242.709c11.097-11.104 29.094-11.104 40.196 0 11.104 11.101 11.104 29.099 0 40.203l-243.38 242.703M152.885 769.355v0z" horiz-adv-x="1024" />
<glyph glyph-name="shipin" unicode="&#58894;" d="M858.8-7.6H182.2c-61 0-110.8 49.6-110.8 110.8V617c0 61 49.6 110.8 110.8 110.8h676.6c61 0 110.8-49.6 110.8-110.8v-513.8c-0.2-61-49.8-110.8-110.8-110.8zM182.2 687.6c-39 0-70.8-31.8-70.8-70.8v-513.8c0-39 31.8-70.8 70.8-70.8h676.6c39 0 70.8 31.8 70.8 70.8v514c0 39-31.8 70.8-70.8 70.8H182.2zM225.4-7.6c-11 0-20 9-20 20V707.6c0 11 9 20 20 20s20-9 20-20v-695.2c0-11-8.8-20-20-20zM815.4-7.6c-11 0-20 9-20 20V707.6c0 11 9 20 20 20s20-9 20-20v-695.2c0-11-9-20-20-20zM225.4 496.8h-134c-11 0-20 9-20 20s9 20 20 20h134c11 0 20-9 20-20s-8.8-20-20-20zM225.4 340h-134c-11 0-20 9-20 20s9 20 20 20h134c11 0 20-9 20-20s-8.8-20-20-20zM225.4 163.4h-134c-11 0-20 9-20 20s9 20 20 20h134c11 0 20-9 20-20s-8.8-20-20-20zM949.4 496.8h-134c-11 0-20 9-20 20s9 20 20 20h134c11 0 20-9 20-20s-9-20-20-20zM949.4 340h-134c-11 0-20 9-20 20s9 20 20 20h134c11 0 20-9 20-20s-9-20-20-20zM949.4 163.4h-134c-11 0-20 9-20 20s9 20 20 20h134c11 0 20-9 20-20s-9-20-20-20zM432 216.8c-3.4 0-7 0.8-10 2.6-6.2 3.6-10 10.2-10 17.4V483.2c0 7.2 3.8 13.8 10 17.4 6.2 3.6 13.8 3.6 20 0l213.4-123.2c6.2-3.6 10-10.2 10-17.4s-3.8-13.8-10-17.4L442 219.6c-3.2-1.8-6.6-2.8-10-2.8z m20 231.8v-177.2l153.4 88.6-153.4 88.6z" horiz-adv-x="1024" />
<glyph glyph-name="iconset0481" unicode="&#59240;" d="M512 853.333333C253.866667 853.333333 42.666667 644.266667 42.666667 384s211.2-469.333333 469.333333-469.333333c260.266667 0 469.333333 209.066667 469.333333 469.333333S772.266667 853.333333 512 853.333333zM512-42.666667C277.333333-42.666667 85.333333 149.333333 85.333333 384 85.333333 618.666667 277.333333 810.666667 512 810.666667c234.666667 0 426.666667-192 426.666667-426.666667C938.666667 149.333333 746.666667-42.666667 512-42.666667zM716.8 401.066667 716.8 401.066667l-4.266667 2.133333c0 0 0 0-2.133333 0l-292.266667 168.533333 0 0C413.866667 573.866667 409.6 576 405.333333 576c-12.8 0-21.333333-8.533333-21.333333-21.333333l0-341.333333c0-12.8 8.533333-21.333333 21.333333-21.333333 4.266667 0 8.533333 2.133333 12.8 4.266667l0 0 292.266667 168.533333c0 0 0 0 2.133333 0l4.266667 2.133333 0 0c4.266667 4.266667 8.533333 10.666667 8.533333 17.066667S721.066667 396.8 716.8 401.066667zM426.666667 249.6 426.666667 518.4 661.333333 384 426.666667 249.6z" horiz-adv-x="1024" />
<glyph glyph-name="wenjian" unicode="&#58960;" d="M752 816H272c-70.4 0-128-57.6-128-128v-608c0-70.4 57.6-128 128-128h353.6c33.6 0 65.6 12.8 91.2 36.8l126.4 126.4c24 24 36.8 56 36.8 91.2V688c0 70.4-57.6 128-128 128zM208 80V688c0 35.2 28.8 64 64 64h480c35.2 0 64-28.8 64-64v-464h-96c-70.4 0-128-57.6-128-128v-80H272c-35.2 0-64 28.8-64 64z m462.4-44.8c-4.8-4.8-9.6-8-14.4-11.2V96c0 35.2 28.8 64 64 64h75.2l-124.8-124.8zM368 544h288c17.6 0 32 14.4 32 32s-14.4 32-32 32H368c-17.6 0-32-14.4-32-32s14.4-32 32-32zM496 288h-128c-17.6 0-32-14.4-32-32s14.4-32 32-32h128c17.6 0 32 14.4 32 32s-14.4 32-32 32zM368 384h288c17.6 0 32 14.4 32 32s-14.4 32-32 32H368c-17.6 0-32-14.4-32-32s14.4-32 32-32z" horiz-adv-x="1024" />
<glyph glyph-name="PPT" unicode="&#58882;" d="M855.5 550.1L616 789.5c-5.3 5.3-12.4 8.2-19.9 8.2H174.3c-7.8 0-14.1-6.3-14.1-14.1v-801.9c0-7.8 6.3-14.1 14.1-14.1h675.3c7.8 0 14.1 6.3 14.1 14.1V530.2c0 7.5-2.9 14.7-8.2 19.9z m-53-514.8h-581v695h376.6v-204.2h204.3l0.1-490.8zM520.2 263.3h-49v-101.9H405V452.5h121.7c70.6-1.8 107.2-32.2 109.8-91.3 1-66.1-37.8-98.8-116.3-97.9z m-5.3 138.9h-43.7v-88.6h43.7c34.4 0.9 52 15.9 52.9 45-0.9 28.2-18.5 42.7-52.9 43.6z" horiz-adv-x="1024" />
<glyph glyph-name="13" unicode="&#59086;" d="M147.2 715.2h728c41.6 0 76.8-35.2 76.8-76.8v-552c0-41.6-35.2-76.8-76.8-76.8h-728c-41.6 0-76.8 35.2-76.8 76.8v552c0 41.6 35.2 76.8 76.8 76.8v0zM147.2-30.4c243.2 0 486.4 0 728 0 64 0 115.2 51.2 115.2 115.2 0 184 0 368 0 552 0 64-51.2 115.2-115.2 115.2-243.2 0-486.4 0-728 0-64 0-115.2-51.2-115.2-115.2 0-184 0-368 0-552 0-62.4 51.2-115.2 115.2-115.2zM201.6 476.8c0-44.8 36.8-81.6 81.6-81.6s81.6 36.8 81.6 81.6c0 44.8-36.8 81.6-81.6 81.6-44.8 0-81.6-36.8-81.6-81.6v0zM240 476.8c0 24 19.2 43.2 43.2 43.2s43.2-19.2 43.2-43.2c0-24-19.2-43.2-43.2-43.2-22.4 0-43.2 19.2-43.2 43.2zM675.2 396.8l203.2-203.2c8-8 8-19.2 0-27.2v0c-8-8-19.2-8-27.2 0l-203.2 203.2c-14.4 14.4-40 14.4-54.4 0l-163.2-161.6c-30.4-30.4-80-30.4-110.4 0l-25.6 25.6c-14.4 14.4-40 14.4-54.4 0l-67.2-67.2c-8-8-19.2-8-27.2 0v0c-8 8-8 19.2 0 27.2l67.2 67.2c30.4 30.4 80 30.4 110.4 0l25.6-25.6c14.4-14.4 40-14.4 54.4 0l161.6 161.6c30.4 30.4 80 30.4 110.4 0z" horiz-adv-x="1024" />
<glyph glyph-name="cc-book" unicode="&#58901;" d="M682.697 24.293l-440.536 0c-12.153 0-22.026 9.893-22.026 22.027 0 12.13 9.873 22.026 22.026 22.026l440.537 0c12.13 0 22.026-9.895 22.026-22.026 0-12.133-9.895-22.027-22.027-22.027zM841.773 725.675c-12.955 0-23.52-10.543-23.52-23.521l0-705.638c0-12.956-10.567-23.521-23.522-23.521l-517.47 0c-38.911 0-70.564 31.651-70.564 70.564 0 38.91 31.653 70.563 70.564 70.563l423.383 0c38.911 0 70.565 31.653 70.565 70.563l0 564.511c0 38.911-31.654 70.564-70.565 70.564l-470.426 0c-38.911 0-70.563-31.653-70.563-70.564l0-705.637c0-64.823 52.785-117.609 117.607-117.609l517.469 0c38.909 0 70.563 31.654 70.563 70.565l0 705.638c0 12.978-10.567 23.521-23.521 23.521zM230.219 772.719l470.426 0c12.955 0 23.522-10.543 23.522-23.522l0-564.511c0-12.955-10.567-23.521-23.522-23.521l-423.383 0c-26.439 0-50.902-8.821-70.564-23.567l0 611.598c0 12.979 10.543 23.522 23.521 23.522z" horiz-adv-x="1024" />
<glyph glyph-name="grade" unicode="&#58988;" d="M863.721739 341.704348c24.486957 48.973913 28.93913 102.4 28.93913 160.278261C892.66087 706.782609 734.608696 873.73913 527.582609 873.73913 320.556522 873.73913 162.504348 706.782609 162.504348 501.982609c0-57.878261 4.452174-111.304348 28.93913-160.278261L51.2 103.513043c0 0 95.721739-35.617391 193.669565-55.652174 64.556522-73.46087 117.982609-151.373913 117.982609-151.373913l129.113043 247.095652c8.904348 0 20.034783 0 26.713043 0 8.904348 0 20.034783 0 26.713043 0l138.017391-233.73913c0 0 57.878261 64.556522 124.66087 138.017391 97.947826 20.034783 193.669565 55.652174 193.669565 55.652174L863.721739 341.704348 863.721739 341.704348 863.721739 341.704348zM353.947826-7.791304c0 0-46.747826 60.104348-89.043478 102.4-62.330435 17.808696-144.695652 35.617391-144.695652 35.617391L215.930435 294.956522c51.2-66.782609 135.791304-129.113043 220.382609-149.147826L353.947826-7.791304 353.947826-7.791304zM520.904348 185.878261c-80.13913 0-309.426087 48.973913-316.104348 316.104348C198.121739 671.165217 351.721739 831.443478 520.904348 831.443478c169.182609 0 329.46087-162.504348 329.46087-329.46087C852.591304 245.982609 601.043478 185.878261 520.904348 185.878261L520.904348 185.878261zM685.634783-7.791304l-82.365217 151.373913c84.591304 20.034783 182.53913 84.591304 233.73913 151.373913l95.721739-164.730435c0 0-82.365217-17.808696-144.695652-35.617391L685.634783-7.791304 685.634783-7.791304zM527.582609 720.13913c-117.982609 0-213.704348-95.721739-213.704348-213.704348s95.721739-213.704348 213.704348-213.704348c117.982609 0 213.704348 95.721739 213.704348 213.704348S645.565217 720.13913 527.582609 720.13913L527.582609 720.13913 527.582609 720.13913zM534.26087 337.252174c-53.426087 0-169.182609 20.034783-178.086957 178.086957-4.452174 84.591304 95.721739 164.730435 178.086957 164.730435 84.591304 0 162.504348-95.721739 164.730435-178.086957C701.217391 390.678261 587.686957 337.252174 534.26087 337.252174L534.26087 337.252174zM534.26087 337.252174" horiz-adv-x="1024" />
<glyph glyph-name="xuexi-" unicode="&#58889;" d="M996.5 608.9L567.6 827.2c-34.8 17.6-76.4 17.6-111.2 0L27.5 609.6C10.6 601 0 583.9 0 564.8c0-19 10.5-36.2 27.5-44.8l219.8-111.8v-305c0-33.9 18.8-64.4 49-79.7l164.9-83.6c15.9-8.1 33.4-12.1 50.9-12.1s35 4 50.9 12.1l164.9 83.6c30.2 15.3 49 45.9 49 79.7V407.8L901.4 471v-111.9c0-15.2 12.3-27.5 27.5-27.5s27.5 12.3 27.5 27.5V494.4c0 1.5-0.1 2.9-0.3 4.3l40.4 20.5c17 8.6 27.5 25.8 27.5 44.8 0 19.1-10.5 36.3-27.5 44.9zM721.8 103.10000000000002c0-13.1-7.2-24.8-18.9-30.8L538-11.299999999999955c-16.3-8.3-35.8-8.3-52.1 0L321 72.29999999999995c-11.6 5.9-18.9 17.7-18.9 30.8V380.20000000000005l154.2-78.5c17.4-8.8 36.5-13.2 55.6-13.2s38.2 4.4 55.6 13.2l154.2 78.2v-276.8z m-179 247.6c-19.3-9.8-42.3-9.8-61.5 0L60.5 564.8l420.7 213.4c19.3 9.8 42.3 9.8 61.5 0l420.7-214.1-420.6-213.4z" horiz-adv-x="1024" />
<glyph glyph-name="nav" unicode="&#58987;" d="M888.838 576.225l-751.1 0c-23.944 0-43.339 19.553-43.339 43.646l0 40.012c0 24.093 19.395 43.645 43.339 43.645l751.1 0c23.923 0 43.334-19.554 43.334-43.645l0-40.012c-0.001-24.093-19.411-43.646-43.333-43.646l0 0zM888.838 308.491l-751.1 0c-23.944 0-43.339 19.533-43.339 43.64l0 39.998c0 24.115 19.395 43.647 43.339 43.647l751.1 0c23.923 0 43.334-19.533 43.334-43.647l0-39.998c-0.001-24.107-19.411-43.64-43.333-43.64l0 0zM888.838 19.83l-751.1 0c-23.944 0-43.339 19.532-43.339 43.627l0 40.017c0 24.093 19.395 43.641 43.339 43.641l751.1 0c23.923 0 43.334-19.548 43.334-43.641l0-40.017c-0.001-24.094-19.411-43.627-43.333-43.627l0 0z" horiz-adv-x="1024" />
<glyph glyph-name="mima" unicode="&#58887;" d="M791.366 436.93l-459.174 0.791c-0.186 61.936-16.847 157.926 36.027 216.192 32.142 35.52 86.326 72.068 144.127 72.068 85.395 0 149.246-64.412 180.166-144.126 9.009-22.992 16.936-35.38 36.037-36.037 47.899-1.45 44.986 49.075 36.029 72.067C719.914 732.97 636.118 798.047 512.346 798.047c-84.12 0-130.475-17.265-180.154-72.065-76.009-83.746-72.259-219.151-72.067-288.26l-26.795-0.791c-25.045 0-45.273-20.034-45.273-44.667v-378.249c0-24.774 20.269-44.755 45.273-44.755h557.99c25.009 0 45.273 19.989 45.273 44.755V392.263c0.046 24.678-20.218 44.667-45.227 44.667zM765.68 77.65c0-9.966-3.476-18.514-10.58-25.52-7.045-7.051-15.56-10.58-25.517-10.58H296.362c-9.966 0-18.472 3.478-25.475 10.58-7.051 7.049-10.624 15.553-10.624 25.52V330.365c0 19.878 16.166 36.054 36.098 36.054h433.212c19.932 0 36.107-16.176 36.107-36.054V77.65z" horiz-adv-x="1024" />
<glyph glyph-name="character" unicode="&#58926;" d="M921.087359-94.72000000000003v35.2A410.24 410.24 0 0 1 661.887359 320a307.2 307.2 0 1 1-300.8 0 410.24 410.24 0 0 1-256-380.8v-35.2H101.887359a32 32 0 0 1 32-32 32 32 0 0 1 32 32v34.56a345.6 345.6 0 0 0 691.2 0v-35.2a31.36 31.36 0 0 1 31.36-30.08 32 32 0 0 1 32.64 32zM270.207359 588.8A241.28 241.28 0 1 0 511.487359 347.52 241.28 241.28 0 0 0 270.207359 588.8z" horiz-adv-x="1024" />
<glyph glyph-name="statistic" unicode="&#58881;" d="M838.33 236.26800000000003c0-33.422-21.592-54.388-54.39-54.388H240.059c-32.796 0-54.388 20.966-54.388 54.388 0 0-0.409 482.507-0.409 516.961h653.477c0-54.85-0.409-516.96-0.409-516.96zM76.892 807.345v-54.389h54.389v-516.689c0-64.45 44.707-108.776 108.776-108.776h163.166L294.447-62.870000000000005l81.909 0.353 108.45 190.006h54.388l108.45-190.006 81.909-0.353-108.777 190.36h163.166c64.069 0 108.776 44.326 108.776 108.776v516.69h54.389v54.39H76.893v-0.001z m271.942-543.883c15.038 0 27.194 12.156 27.194 27.194V399.432c0 15.011-12.156 27.195-27.194 27.195s-27.195-12.183-27.195-27.195v-108.776c0-15.038 12.156-27.194 27.195-27.194z m326.33 0c15.039 0 27.195 12.156 27.195 27.194V535.403c0 15.011-12.156 27.195-27.195 27.195s-27.194-12.183-27.194-27.195v-244.747c0-15.038 12.156-27.194 27.194-27.194z m-163.165 0c15.039 0 27.194 12.156 27.194 27.194v326.33c0 15.011-12.155 27.195-27.194 27.195s-27.194-12.183-27.194-27.195v-326.33c0-15.038 12.155-27.194 27.194-27.194z" horiz-adv-x="1024" />
<glyph glyph-name="discover" unicode="&#59006;" d="M544 608c0 52.928-43.072 96-96 96s-96-43.072-96-96 43.072-96 96-96S544 555.072 544 608zM416 608c0 17.632 14.368 32 32 32s32-14.368 32-32-14.368-32-32-32S416 590.368 416 608zM304 448C259.904 448 224 412.096 224 368 224 323.872 259.904 288 304 288s80 35.872 80 80C384 412.096 348.096 448 304 448zM304 352C295.168 352 288 359.168 288 368S295.168 384 304 384s16-7.168 16-16S312.832 352 304 352zM640 160m-64 0a2 2 0 1 0 128 0 2 2 0 1 0-128 0ZM887.84 627.328c39.744 60.672 64.256 113.184 64.224 148.96 0 22.976-9.312 36.928-17.12 44.576-38.08 37.376-110.016 3.2-160.768-25.664-15.328-8.736-20.704-28.288-11.968-43.648 8.736-15.36 28.32-20.704 43.648-11.968 49.408 28.16 73.248 33.088 82.496 33.696-1.504-41.376-95.328-202.432-330.208-433.504-226.368-222.72-398.656-324.672-442.24-325.376 0.96 11.36 8.768 44.448 58.528 118.688 1.312 1.888 2.4 3.968 3.232 6.144l2.304 5.92c0.256 0.64 0.288 1.344 0.512 2.016 8.8 10.24 10.816 25.088 3.392 37.248C147.328 244.384 128 313.408 128 384 128 595.744 300.256 768 512 768c59.296 0 116.096-13.12 168.864-39.04 15.936-7.776 35.04-1.184 42.816 14.656 7.776 15.84 1.248 35.008-14.624 42.816C647.424 816.672 581.12 832 512 832 264.96 832 64 631.04 64 384c0-76.064 19.488-150.496 56.064-216.64-0.192-0.576-0.64-1.056-0.8-1.632C51.168 63.392 35.2 0.32 68.928-32.768c11.008-10.784 25.632-15.584 43.072-15.584 39.328 0 92.864 24.928 150.08 60.896C336.096-37.408 421.952-64 512-64c247.04 0 448 200.96 448 448C960 471.136 934.912 554.752 887.84 627.328zM512 0c-68.288 0-133.728 17.888-191.84 51.552 128.288 92.256 258.432 218.56 282.848 242.624 89.152 87.712 178.56 187.04 244.64 275.968C879.2 513.408 896 449.888 896 384 896 172.256 723.744 0 512 0z" horiz-adv-x="1024" />
<glyph glyph-name="settings" unicode="&#59018;" d="M512 288c-52.928 0-96 43.072-96 96s43.072 96 96 96 96-43.072 96-96S564.928 288 512 288zM512 416c-17.632 0-32-14.368-32-32s14.368-32 32-32 32 14.368 32 32S529.632 416 512 416zM631.04-64c-10.016 0-19.712 4.736-25.856 13.12l-73.408 100.48c-13.664-0.832-25.92-0.864-39.584 0l-73.376-100.48c-7.904-10.816-21.728-15.616-34.656-11.872-34.592 9.888-67.488 23.456-97.76 40.32-11.712 6.528-18.112 19.648-16.032 32.896l19.2 123.264c-9.824 8.704-19.136 18.016-27.84 27.808l-123.264-19.2c-13.056-1.984-26.336 4.352-32.896 16.064-16.896 30.368-30.464 63.296-40.32 97.824-3.68 12.864 1.056 26.72 11.904 34.624l100.448 73.376C177.152 371.04 176.928 377.6 176.928 384s0.224 12.96 0.672 19.776L77.12 477.184c-10.816 7.936-15.584 21.728-11.904 34.656 9.856 34.496 23.424 67.392 40.32 97.792 6.56 11.712 19.712 18.048 32.896 16.064l123.264-19.2c8.736 9.824 18.016 19.104 27.84 27.84l-19.2 123.264C268.288 770.816 274.72 783.936 286.432 790.464c30.4 16.896 63.296 30.464 97.76 40.32 12.928 3.648 26.72-1.056 34.656-11.904l73.376-100.448c13.568 0.896 25.824 0.896 39.584 0l73.408 100.48c7.904 10.848 21.664 15.52 34.656 11.904 34.464-9.856 67.328-23.424 97.76-40.32 11.712-6.528 18.112-19.648 16.064-32.896L734.432 634.24c9.824-8.736 19.104-18.016 27.808-27.776l123.328 19.2c13.152 2.016 26.336-4.384 32.864-16.032 16.896-30.4 30.496-63.296 40.352-97.824 3.648-12.896-1.088-26.688-11.904-34.624l-100.48-73.408c0.448-6.816 0.672-13.376 0.672-19.776s-0.224-12.96-0.672-19.776l100.48-73.376c10.816-7.904 15.552-21.728 11.904-34.624-9.856-34.496-23.424-67.424-40.352-97.824-6.528-11.712-19.488-18.048-32.896-16.064l-123.296 19.2c-8.672-9.76-17.984-19.072-27.808-27.776l19.232-123.296c2.048-13.248-4.352-26.368-16.064-32.896-30.24-16.832-63.136-30.4-97.76-40.32C636.928-63.584 633.984-64 631.04-64zM337.152 23.328c13.984-6.752 28.544-12.704 43.552-17.92l70.528 96.576c6.784 9.28 17.984 14.272 29.472 12.896 20.576-2.336 42.08-2.336 62.624 0 11.84 1.376 22.72-3.616 29.472-12.896l70.528-96.576c15.04 5.184 29.6 11.168 43.552 17.92l-18.432 118.368c-1.76 11.36 2.72 22.848 11.712 30.016 16.384 12.992 31.264 27.872 44.16 44.128 7.168 8.992 18.4 13.504 30.016 11.744l118.368-18.432c6.752 14.016 12.736 28.576 17.92 43.552l-96.576 70.528c-9.28 6.784-14.208 18.016-12.896 29.472 1.152 10.272 1.952 20.704 1.952 31.296s-0.768 21.024-1.952 31.296c-1.312 11.424 3.616 22.688 12.896 29.472l96.576 70.56c-5.152 15.008-11.168 29.568-17.92 43.552l-118.4-18.432c-11.328-1.696-22.816 2.688-29.984 11.744-12.896 16.256-27.776 31.104-44.16 44.128-8.992 7.168-13.472 18.592-11.712 29.984l18.432 118.4c-14.016 6.752-28.576 12.736-43.52 17.92l-70.56-96.576c-6.784-9.28-17.696-14.368-29.472-12.928-20.544 2.368-42.016 2.4-62.56 0-11.52-1.344-22.752 3.616-29.536 12.896l-70.528 96.576c-14.976-5.152-29.536-11.136-43.552-17.92l18.432-118.368c1.76-11.392-2.72-22.848-11.744-30.016-16.32-12.928-31.2-27.808-44.128-44.128-7.168-9.024-18.56-13.472-30.016-11.744l-118.368 18.432c-6.752-14.016-12.736-28.576-17.92-43.552l96.576-70.56c9.312-6.784 14.24-18.08 12.896-29.536C241.696 404.992 240.928 394.592 240.928 384s0.768-20.992 1.952-31.264c1.344-11.456-3.616-22.688-12.896-29.504l-96.576-70.528c5.184-15.008 11.168-29.568 17.92-43.552l118.368 18.432c11.392 1.76 22.848-2.752 30.016-11.744 12.896-16.32 27.744-31.168 44.128-44.128 9.024-7.168 13.504-18.624 11.744-30.016L337.152 23.328z" horiz-adv-x="1024" />
<glyph glyph-name="new" unicode="&#59166;" d="M963.072 449.664c0 211.744-200.96 384-448 384s-448-172.256-448-384c0-116.48 63.008-226.048 172.896-300.672 14.656-9.984 34.528-6.144 44.448 8.512 9.952 14.624 6.112 34.528-8.512 44.448-92.032 62.496-144.832 152.768-144.832 247.712 0 176.448 172.256 320 384 320 211.744 0 384-143.552 384-320 0-176.448-172.256-320-384-320-1.984 0-3.68-0.768-5.568-1.12-15.104 2.688-30.464-5.216-35.776-20.192-6.144-17.376-46.368-46.656-94.144-73.792 17.472 58.208 9.088 70.688 3.52 78.976-6.72 9.984-17.92 15.936-29.92 15.936-17.664 0-32-14.304-32-32 0-5.824 1.536-11.264 4.256-15.936-3.232-18.24-17.216-60.864-33.088-99.872-4.928-12.096-1.984-25.984 7.36-35.072 6.112-5.888 14.112-8.992 22.272-8.992 4.384 0 8.8 0.896 12.992 2.752 36.48 16.256 147.68 69.12 187.616 125.664C766.144 69.504 963.072 240.096 963.072 449.664zM342.624 291.456c4.672-2.4 9.664-3.52 14.592-3.52 11.616 0 22.816 6.336 28.512 17.408l71.584 139.488 91.584-142.208c5.824-9.024 15.744-14.528 26.464-14.688 0.16 0 0.32 0 0.448 0 10.56 0 20.48 5.216 26.432 13.984l128.8 188.864c9.984 14.624 6.176 34.528-8.416 44.48-14.624 9.952-34.528 6.208-44.48-8.416l-101.632-148.992-95.456 148.288c-6.176 9.6-17.152 14.752-28.48 14.656-11.424-0.576-21.696-7.2-26.912-17.344l-96.896-188.896C320.672 318.816 326.88 299.52 342.624 291.456z" horiz-adv-x="1024" />
<glyph glyph-name="album" unicode="&#59188;" d="M256 448m-64 0a2 2 0 1 0 128 0 2 2 0 1 0-128 0ZM714.688 640 181.312 640C116.64 640 64 587.36 64 522.688l0-405.376C64 52.64 116.64 0 181.312 0l533.376 0C779.36 0 832 52.64 832 117.312L832 522.688C832 587.36 779.36 640 714.688 640zM768 117.312C768 87.904 744.096 64 714.688 64L181.312 64C151.936 64 128 87.904 128 117.312L128 522.688C128 552.064 151.936 576 181.312 576l533.376 0C744.096 576 768 552.064 768 522.688L768 117.312zM842.688 768 256 768C238.336 768 224 753.664 224 736s14.336-32 32-32l586.688 0C872.096 704 896 680.064 896 650.688L896 256c0-17.696 14.304-32 32-32s32 14.304 32 32L960 650.688C960 715.36 907.36 768 842.688 768zM672.64 447.264c-129.056 0-143.936-72.672-152.832-116.096-7.2-35.168-10.4-39.968-28.64-42.88-34.976-5.568-44-0.192-58.912 8.8-15.456 9.312-36.672 22.08-77.952 23.168C227.616 322.88 194.112 172.16 192.704 165.76c-3.712-17.28 7.264-34.304 24.544-38.016 2.272-0.512 4.544-0.704 6.752-0.704 14.752 0 28 10.24 31.264 25.248 0.224 1.056 23.232 104.032 95.488 104.032 0.64 0 1.28 0 1.92-0.032 24.352-0.608 33.632-6.208 46.496-13.984 24.032-14.464 48.352-25.76 102.08-17.184 64.192 10.272 74.432 60.192 81.184 93.216 8.32 40.512 13.312 64.928 90.144 64.928 17.696 0 32 14.336 32 32S690.304 447.264 672.64 447.264z" horiz-adv-x="1024" />
</font>
</defs></svg>
{
"LoginModule": {
"CodeLogin": {
"iphone": "Mobile Phone number",
"inputIphone": "Please enter Mobile Phone number",
"rightIphoneStr": "Please enter the right format Mobile Phone number",
"code": "SMS verification code",
"sendCode": "Send code",
"inputCode": "Please enter SMS verification code",
"afterMiniutes": "s before resend",
"isRemember": "Remember Me",
"submitbtn": "Log In"
},
"ForgetLogin": {
"step1": "Step 1",
"step2": "Step 2",
"step3": "Step 3",
"inputStr": "Please enter Register Mobile Phone number Or Mail",
"rightStr": "Please enter the right Format Mobile Phone number Or Mail",
"checkRightStr": "Please check whether the Mobile Phone number or Email",
"sendCode": "Send",
"codeSuccess": "The verification code has been successfully sent. No more then five times every day.",
"codeStr": "Code arrive to :",
"iphoneCode": "Iphone Code",
"mailCode": "Mail Code",
"input4Code": "Input Four Number Code",
"afterMiniutes": "s before resend",
"prev": "Prev",
"next": "Next",
"newPwd": "New Password",
"placeholder": "Please enter 6-20 letters, numbers and punctuation marks, not just numbers",
"repeatNewPwd": "Repeat New Password",
"repeatPlaceholder": "Please repeat enter new password",
"checkPwd": "Input twice is not same",
"finish": "Finish",
"tipStr": "Password set success",
"goLogin": "Log In"
},
"NormalLogin": {
"account": "Account",
"inputAccount": "Please enter Email or UserID",
"password": "Password",
"inputPassword": "Please enter Password",
"isRemember": "Remember Me",
"submitbtn": "Log In"
},
"Others": {
"noSysRole": "You do not have system permissions, please contact the system administrator",
"outloginStr": "The account has been signed out, please change the account",
"formCheckStr": "Please check",
"tip": "Tips",
"right": "Confirm"
}
}
}
import Cookies from 'js-cookie'
import VueI18n from 'vue-i18n'
import language from './language'
import zhCNLocale from 'element-ui/lib/locale/lang/zh-CN'
import enLocale from 'element-ui/lib/locale/lang/en'
export default () => {
let _locale = 'zh-CN'
/* 国际化初始化 */
const _defaultLocale = 'zh-CN'
const _lang = Cookies.get('lang') || window.navigator.language || window.navigator.userLanguage || ''
if (_lang) {
if (language[_lang]) {
_locale = _lang
} else {
let flag = true
/* 做一下 兼容性处理 */
for (const k in language) {
const reg = new RegExp(k, 'gi')
if (reg.test(_lang)) {
_locale = k
flag = false
break
}
}
if (flag) {
/* 当前语言版本 - 不再我们的语言库中,那么默认 en */
_locale = _defaultLocale
Cookies.set('lang', _defaultLocale, { expires: 30, domain: '.ezijing.com' })
}
}
}
return new VueI18n({
locale: _locale, // 定义默认语言为中文
messages: {
'zh-CN': Object.assign(require('./zh-CN.json'), zhCNLocale),
en: Object.assign(require('./en.json'), enLocale)
}
})
}
/* 定义语言模型 - key 值定义 跟 languages i18n 中 保持一致 */
const language = {
'zh-CN': { show: '语言', arr: [{ 'zh-CN': '中文' }, { en: 'English' }] },
en: { show: 'Language', arr: [{ 'zh-CN': '中文' }, { en: 'English' }] }
}
export default language
{
"LoginModule": {
"CodeLogin": {
"iphone": "手机号",
"inputIphone": "请输入手机号",
"rightIphoneStr": "请输入正确格式的手机号",
"code": "短信验证码",
"sendCode": "发送验证码",
"inputCode": "请输入短信验证码",
"afterMiniutes": "s后重发",
"isRemember": "记住我",
"submitbtn": "登录"
},
"ForgetLogin": {
"step1": "步骤1",
"step2": "步骤2",
"step3": "步骤3",
"inputStr": "请输入注册手机号/邮箱",
"rightStr": "请输入正确格式的手机号/邮箱",
"checkRightStr": "请检查手机号或邮箱是否输入正确",
"sendCode": "发送验证码",
"codeSuccess": "验证码已成功发送,请耐心等待。每天最高发送5次",
"codeStr": "验证码已发送至:",
"iphoneCode": "手机验证码",
"mailCode": "邮箱验证码",
"input4Code": "请输入4位验证码",
"afterMiniutes": "s后重发",
"prev": "上一步",
"next": "下一步",
"newPwd": "新密码",
"placeholder": "请输入6-20个字母、数字及标点符号,不可仅数字",
"repeatNewPwd": "重复新密码",
"repeatPlaceholder": "请重新输入新密码",
"checkPwd": "两次输入密码不一致",
"finish": "完成",
"tipStr": "密码设置成功",
"goLogin": "登 录"
},
"NormalLogin": {
"account": "账号",
"inputAccount": "请输入手机号",
"password": "密码",
"inputPassword": "请输入密码",
"isRemember": "记住我",
"submitbtn": "登录"
},
"Others": {
"noSysRole": "您当前没有系统权限,请联络系统管理员",
"outloginStr": "账号已退出,请更换账号",
"formCheckStr": "请根据输入框提示,检查输入项。",
"tip": "提示",
"right": "确定"
}
}
}
import './index.scss'
import NormalLogin from './src/NormalLogin.vue'
import CodeLogin from './src/CodeLogin.vue'
import ForgetLogin from './src/ForgetLogin.vue'
const components = [
NormalLogin,
CodeLogin,
ForgetLogin
]
const install = function (Vue, opts = {}) {
/* 存在国际化 */
if (opts.i18n) {
const msgs = opts.i18n.messages
for (const k in msgs) {
opts.i18n.setLocaleMessage(k, Object.assign(msgs[k], require('./assets/languages/' + k + '.json')))
}
}
components.forEach(component => {
Vue.component(component.name, component)
})
}
/* istanbul ignore if */
if (typeof window !== 'undefined' && window.Vue) {
install(window.Vue)
}
export default {
install,
NormalLogin,
CodeLogin,
ForgetLogin
}
/* Extra small devices (portrait phones, less than 576px) */
@media (max-width: 575px) {}
/* Small devices (landscape phones, 576px and up) */
@media (min-width: 576px) and (max-width: 767px) {}
/* Medium devices (tablets, 768px and up) */
@media (min-width: 768px) and (max-width: 991px) {}
/* Large devices (desktops, 992px and up) */
@media (min-width: 992px) and (max-width: 1199px) {}
/* Extra large devices (large desktops, 1200px and up) */
@media (min-width: 1200px) {}
<template>
<el-form ref="setAccountform" :model="setAccount" :rules="accountRules">
<el-form-item prop="user">
<el-input class="self-input" v-model="setAccount.user" type="text" :placeholder="$t('LoginModule.CodeLogin.iphone')" @keyup.enter.native="onSubmitSetAccount">
</el-input>
</el-form-item>
<el-form-item prop="pwd" style="margin-bottom: 4px;">
<el-input v-model="setAccount.pwd" :disabled="isSendDisable" type="text" :placeholder="$t('LoginModule.CodeLogin.code')" @keyup.enter.native="onSubmitSetAccount">
<el-button slot="suffix" size="mini" :disabled="isSendDisable || isSendCode" @click="sendCode">{{sendBtnText}}</el-button>
</el-input>
</el-form-item>
<el-form-item prop="isRemember" style="margin-bottom: 0px; text-align: left;">
<el-checkbox v-model="setAccount.isRemember" :label="$t('LoginModule.NormalLogin.isRemember')" name="type"></el-checkbox>
</el-form-item>
<el-form-item>
<el-button type="primary" class="login-btn" @click="onSubmitSetAccount">{{$t('LoginModule.CodeLogin.submitbtn')}}</el-button>
</el-form-item>
<slot name="text"></slot>
</el-form>
</template>
<script>
import Login from '../action'
export default {
name: 'CodeLogin',
componentName: 'CodeLogin',
props: {
attr: {
type: Object,
required: false,
default () {
return {}
}
},
query: {
type: Object,
required: false,
default () {
return {}
}
}
},
data () {
/* 账号输入正确时,才能获取验证码 */
const checkAccount = (rule, value, callback) => {
/* 手机格式 */
if (/^1[3-9]\d{9}$/.test(value)) {
this.isSendDisable = false
callback()
} else {
this.isSendDisable = true
callback(new Error(this.$t('LoginModule.CodeLogin.rightIphoneStr')))
}
}
return {
isSendDisable: true, // 是否可以发送
isSendCode: false, // 是否已发送验证码
timeInterval: null, // 定时器,倒计时
sendBtnText: this.$t('LoginModule.CodeLogin.sendCode'), // 按钮 文字
setAccount: {},
accountRules: {
user: [
{ required: true, message: this.$t('LoginModule.CodeLogin.inputIphone'), trigger: 'blur' },
{ validator: checkAccount, trigger: 'change' }
],
pwd: [
{ required: true, message: this.$t('LoginModule.CodeLogin.inputCode'), trigger: 'blur' }
]
}
}
},
beforeDestroy () { /* 清空倒计时 */ this.clearTime() },
methods: {
/* 发送验证码 */
sendCode () {
if (!this.isSendCode) {
// const loading = this.$loading({ lock: true, text: '', spinner: '', background: 'rgba(255, 255, 255, 0.9)' })
Login.sendCode({
/* 老版发送验证码 */
mobile: this.setAccount.user,
/* 新版发送验证码 */
account: this.setAccount.user
}).then(res => {
/* 发送验证码不管是否成功,都开始倒计时 */
let time = 60
this.isSendCode = true
this.sendBtnText = '60' + this.$t('LoginModule.CodeLogin.afterMiniutes')
this.timeInterval = setInterval(() => {
if (time-- > 0) {
this.sendBtnText = time + this.$t('LoginModule.CodeLogin.afterMiniutes')
} else {
this.isSendCode = false
this.sendBtnText = this.$t('LoginModule.CodeLogin.sendCode')
clearInterval(this.timeInterval)
}
}, 1000)
}).catch(error => {
this.$message.error(error.message)
})
}
},
/* 清空倒计时 */
clearTime () {
this.isSendCode = true
this.sendBtnText = this.$t('LoginModule.CodeLogin.sendCode')
clearInterval(this.timeInterval)
},
onSubmitSetAccount () {
this.$refs.setAccountform.validate((valid) => {
if (valid) {
Login.codeLogin({
/* 新版 */
account: this.setAccount.user,
password: this.setAccount.pwd,
type: 2,
RememberMe: this.setAccount.isRemember ? 'true' : 'false',
service: window.location.origin
}).then(data => {
if (data.code !== 0) { return }
if (data.url) {
/* 查询上次跳转信息,并跳转回去 */
if (this.query.rd) {
window.location.href = data.url + decodeURIComponent(this.query.rd)
} else {
window.location.href = data.url
}
} else {
this.$alert(this.$t('LoginModule.Others.noSysRole'), this.$t('LoginModule.Others.tip'), {
confirmButtonText: this.$t('LoginModule.Others.right'),
callback: action => {
Login.outLogin().then(res => {
this.$message({
type: 'info',
message: this.$t('LoginModule.Others.outloginStr')
})
})
}
})
}
}).catch(error => {
this.$message.error(error.message)
})
} else {
this.$message.error(this.$t('LoginModule.Others.formCheckStr'))
return false
}
})
}
}
}
</script>
<style lang="scss" scoped>
.login-btn { margin-top: 0; width: 100%; }
</style>
<template>
<div class="content-s">
<div class="step3">
<el-form ref="form3" label-width="100px" :model="accountSet" :rules="accountRules" label-position="top">
<el-row type="flex" class="row-bg" justify="center">
<el-col :xs="24" :md="10">
<el-form-item prop="account" :label="$t('LoginModule.NormalLogin.account')">
<el-input v-model="accountSet.account" type="text" :placeholder="$t('LoginModule.ForgetLogin.inputStr')"></el-input>
</el-form-item>
<el-form-item prop="code" :label="(accountSet.type ? $t('LoginModule.ForgetLogin.mailCode') : $t('LoginModule.ForgetLogin.iphoneCode'))">
<el-input v-model="accountSet.code" type="text" :placeholder="$t('LoginModule.ForgetLogin.input4Code')">
<el-button slot="append" type="primary" @click="sendCode">{{sendBtnText}}</el-button>
</el-input>
</el-form-item>
<el-form-item prop="newpwd" :label="$t('LoginModule.ForgetLogin.newPwd')">
<el-input v-model="accountSet.newpwd" type="password" :placeholder="$t('LoginModule.ForgetLogin.placeholder')"></el-input>
</el-form-item>
<el-form-item prop="repwd" :label="$t('LoginModule.ForgetLogin.repeatNewPwd')">
<el-input v-model="accountSet.repwd" type="password" :placeholder="$t('LoginModule.ForgetLogin.repeatPlaceholder')"></el-input>
</el-form-item>
<el-form-item>
<el-button style="width: 100%;" type="primary" @click="onSubmitForm">{{$t('LoginModule.ForgetLogin.finish')}}</el-button>
</el-form-item>
</el-col>
</el-row>
</el-form>
<slot name="go-back"></slot>
</div>
<el-dialog
title=""
:visible.sync="centerDialogVisible"
width="30%"
center append-to-body>
<i class="el-icon-success" style="display: block; font-size: 0.6rem; text-align: center; color: #67c23a;"></i>
<span style="display: block; margin-top: 0.2rem; text-align: center;">{{$t('LoginModule.ForgetLogin.tipStr')}}</span>
<span slot="footer" class="dialog-footer">
<el-button type="primary" @click="goLogin">{{$t('LoginModule.ForgetLogin.goLogin')}}</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
import Login from '../action'
export default {
name: 'ForgetLogin',
componentName: 'ForgetLogin',
props: {
attr: {
type: Object,
required: false,
default () {
return {}
}
},
query: {
type: Object,
required: false,
default () {
return {}
}
}
},
data () {
/* 检查账号格式 */
const checkAccount = (rule, value, callback) => {
if (!/^(1[3-9]\d{9}|[\w\.]+@\w+(\.\w+)+)$/.test(value)) { // eslint-disable-line
callback(new Error(this.$t('LoginModule.ForgetLogin.rightStr')))
} else {
/* 手机格式 */
if (/^(1[3-9]\d{9}$)/.test(value)) {
this.accountSet.type = 0
}
/* 邮箱格式 */
if (/^([\w\.]+@\w+(\.\w+)+)/.test(value)) { // eslint-disable-line
this.accountSet.type = 1
}
callback()
}
}
/* 检查密码 */
const checkPwd = (rule, value, callback) => {
if (value === this.accountSet.newpwd) {
callback()
} else {
callback(new Error(this.$t('LoginModule.ForgetLogin.checkPwd')))
}
}
return {
isSendCode: false, // 是否已发送验证码
timeInterval: null, // 定时器,倒计时
sendBtnText: this.$t('LoginModule.ForgetLogin.sendCode'), // 按钮 文字
accountSet: {
type: 0, // 0:表示手机格式,1:表示邮箱格式
account: '',
code: ''
},
accountRules: {
account: [
{ required: true, message: this.$t('LoginModule.ForgetLogin.inputStr'), trigger: 'blur' },
{ validator: checkAccount, trigger: 'change' }
],
code: [
{ required: true, message: this.$t('LoginModule.ForgetLogin.input4Code'), trigger: 'blur' },
{ pattern: /^(\d{4})$/, message: this.$t('LoginModule.ForgetLogin.input4Code'), trigger: 'change' }
],
newpwd: [
{ required: true, message: this.$t('LoginModule.ForgetLogin.newPwd'), trigger: 'blur' },
{ pattern: /^.*[^\d]+.*$/, message: this.$t('LoginModule.ForgetLogin.placeholder'), trigger: 'blur' }
],
repwd: [
{ required: true, message: this.$t('LoginModule.ForgetLogin.repeatPlaceholder'), trigger: 'blur' },
{ validator: checkPwd, trigger: 'change' }
]
},
centerDialogVisible: false // 修改密码成功弹框
}
},
beforeDestroy () { /* 清空倒计时 */ this.clearTime() },
methods: {
/* 发送验证码 */
sendCode () {
if (!this.isSendCode) {
Login.sendResetPwdCode({ account: this.accountSet.account }).then(res => {
if (res.code === 0) {
/* 发送验证码不管是否成功,都开始倒计时 */
let time = 60
this.isSendCode = true
this.sendBtnText = '60' + this.$t('LoginModule.ForgetLogin.afterMiniutes')
this.timeInterval = setInterval(() => {
if (time-- > 0) {
this.sendBtnText = time + this.$t('LoginModule.ForgetLogin.afterMiniutes')
} else {
this.isSendCode = false
this.sendBtnText = this.$t('LoginModule.ForgetLogin.sendCode')
clearInterval(this.timeInterval)
}
}, 1000)
this.$message({
type: 'success',
message: this.$t('LoginModule.ForgetLogin.codeSuccess'),
duration: 10000
})
} else {
return new Error(JSON.stringify(res))
}
})
}
},
/* 清空倒计时 */
clearTime () {
this.isSendCode = false
this.sendBtnText = this.$t('LoginModule.ForgetLogin.sendCode')
clearInterval(this.timeInterval)
},
/* 第三步 提交 */
onSubmitForm () {
this.$refs.form3.validate((valid) => {
if (valid) {
Login.resetPwd({
account: this.accountSet.account,
code: this.accountSet.code,
password: this.accountSet.newpwd,
passwordR: this.accountSet.repwd
}).then(data => {
if (data.code === 0) {
this.centerDialogVisible = true
} else {
return new Error(JSON.stringify(data))
}
})
} else {
this.$message.error(this.$t('LoginModule.Others.formCheckStr'))
return false
}
})
},
/**
* 关闭弹框时,跳转 登录页
*/
goLogin () {
this.centerDialogVisible = false
/* 跳转到 登录 */
this.$router.push({ path: '/login/index' })
}
}
}
</script>
<style lang="scss" scoped>
.content-s {
position: absolute;
left: 50%;
top: 22%;
padding: 20px 0;
width: calc(100% - 20px);
max-width: 1000px;
box-shadow: 0px 3px 10px rgba(0, 0, 0, 0.3);
transform: translateX(-50%);
background: #fff;
}
/* forget 登录 */
.step1 { font-size: 16px; width: 90%; margin: 20px auto 0 auto; }
.step2 { font-size: 16px; width: 71%; margin: 20px auto 0 auto; }
.step2 .txt-title { margin-bottom: 0.3rem; color: #999; text-align: center; }
.step2 .operate { margin-top: 0.2rem; }
.step3 { font-size: 16px; margin: 10px 20px 0; text-align: left;}
::v-deep .el-form-item__label{ line-height:1; }
</style>
<template>
<el-form ref="setAccountform" :model="setAccount" :rules="accountRules">
<el-form-item prop="user">
<el-input class="self-input" v-model="setAccount.user" type="text" :placeholder="$t('LoginModule.NormalLogin.account')" @keyup.enter.native="onSubmitSetAccount">
<i slot="prefix" class="el-input__icon el-icon-self-character"></i>
</el-input>
</el-form-item>
<el-form-item prop="pwd" style="margin-bottom: 4px;">
<el-input v-model="setAccount.pwd" type="password" :placeholder="$t('LoginModule.NormalLogin.password')" @keyup.enter.native="onSubmitSetAccount">
<i slot="prefix" class="el-input__icon el-icon-self-mima"></i>
</el-input>
</el-form-item>
<el-form-item prop="isRemember" style="margin-bottom: 0px; text-align: left;">
<el-checkbox v-model="setAccount.isRemember" :label="$t('LoginModule.NormalLogin.isRemember')" name="type"></el-checkbox>
</el-form-item>
<el-form-item>
<el-button type="primary" class="login-btn" @click="onSubmitSetAccount">{{$t('LoginModule.NormalLogin.submitbtn')}}</el-button>
</el-form-item>
<slot name="text"></slot>
</el-form>
</template>
<script>
import Login from '../action'
export default {
name: 'NormalLogin',
componentName: 'NormalLogin',
props: {
attr: {
type: Object,
required: false,
default () {
return {}
}
},
query: {
type: Object,
required: false,
default () {
return {}
}
}
},
data () {
return {
// rememberMe:
setAccount: {},
accountRules: {
user: [
{ required: true, message: this.$t('LoginModule.NormalLogin.inputAccount'), trigger: 'blur' }
// { pattern: /^(1[3-9]\d{9}|[\w\.]+@\w+(\.\w+)+)$/, message: '请输入正确格式的手机号/邮箱', trigger: 'change' } // eslint-disable-line
],
pwd: [
{ required: true, message: this.$t('LoginModule.NormalLogin.inputPassword'), trigger: 'blur' }
]
}
}
},
mounted () {
// Login.clearCookies({}).then(res => res)
},
methods: {
onSubmitSetAccount () {
this.$refs.setAccountform.validate((valid) => {
if (valid) {
Login.userLogin({
/* 老版登录 */
// login_name: this.setAccount.user,
// password: md5('uokoaduw' + this.setAccount.pwd.split('').reverse().join('') + 'auhgniq'),
/* 新版登录 */
account: this.setAccount.user,
password: this.setAccount.pwd,
type: 1,
RememberMe: this.setAccount.isRemember ? 'true' : 'false',
service: window.location.origin
}).then(res => {
if (res.code !== 0) { return }
if (this.attr.url) {
window.location.href = this.attr.url
return
}
if (res.url) {
/* 查询上次跳转信息,并跳转回去 */
if (this.query.rd) {
window.location.href = res.url + decodeURIComponent(this.query.rd)
} else {
window.location.href = res.url
}
} else {
this.$alert(this.$t('LoginModule.Others.noSysRole'), this.$t('LoginModule.Others.tip'), {
confirmButtonText: this.$t('LoginModule.Others.right'),
callback: action => {
Login.outLogin().then(res => {
this.$message({
type: 'info',
message: this.$t('LoginModule.Others.outloginStr')
})
})
}
})
}
/* 重置账号、密码 */
// this.$refs['setAccountform'].resetFields()
}).catch(e => {
this.$message({
type: 'error',
message: e.message
})
})
} else {
this.$message.error(this.$t('LoginModule.Others.formCheckStr'))
return false
}
})
}
}
}
</script>
<style lang="scss" scoped>
.login-btn { margin-top: 0; width: 100%; }
</style>
<template>
<div class="p-con">
<div class="hd">
<img src="@/assets/images/logo.png" alt="logo">
<div class="txt">在线学习系统</div>
<!-- <s-language></s-language> -->
</div>
<div class="bd">
<div class="top50 container">
<el-row>
<el-col :xs="2" :sm="7" :md="3" :lg="3" :xl="3"><div style="height: 1px;"></div></el-col>
<el-col class="hidden-xs-only hidden-sm-only" :md="10" :lg="10" :xl="10">
<img src="@/assets/images/login-left-bg.png" alt="左侧-sofia logo">
</el-col>
<el-col :xs="20" :sm="10" :md="6" :lg="6" :xl="6">
<code-login>
<div class="text" slot="text">
<span class="code-login">
<template v-if="query.rd">
<router-link class="router-link-class" active-class="router-link-active-class" :to="{ path: '/login/index?rd=' + query.rd }">{{$t('Login.normalLogin')}}</router-link>
</template>
<template v-else>
<router-link class="router-link-class" active-class="router-link-active-class" :to="{ name: 'login-normal' }">{{$t('Login.normalLogin')}}</router-link>
</template>
</span>
<span class="forget-pwd">
<template v-if="query.rd">
<router-link class="router-link-class" active-class="router-link-active-class" :to="{ path: '/login/forget?rd=' + query.rd }">{{$t('Login.forgetPassword')}}</router-link>
</template>
<template v-else>
<router-link class="router-link-class" active-class="router-link-active-class" :to="{ name: 'login-forget' }">{{$t('Login.forgetPassword')}}</router-link>
</template>
<!-- <div class="router-link-class" @click="dialogMsg">{{$t('Login.forgetPassword')}}</div> -->
</span>
</div>
</code-login>
</el-col>
<el-col :xs="2" :sm="7" :md="5" :lg="5" :xl="5"><div style="height: 1px;"></div></el-col>
</el-row>
</div>
</div>
<div class="ft">
<div class="num">学习平台服务电话:010-62793299</div>
<div class="time">服务时间:9:00-18:00</div>
<div class="txt">Copyright © 2017 Zijing Education. All rights reserved. 清控紫荆(北京)教育科技股份有限公司 京ICP证150431号 京公网安备 11010802023681号</div>
</div>
</div>
</template>
<script>
import sLanguage from '@/components/languageSwitch/index.vue'
export default {
components: { sLanguage },
props: {
params: { type: Object, required: false, default () { return {} } },
query: { type: Object, required: false, default () { return {} } }
},
data () {
return {}
},
metaInfo () {
return {
title: this.$t('Login.title'),
meta: []
}
},
mounted () {},
methods: {
dialogMsg () {
this.$message({
type: 'success',
message: this.$t('Login.findPwdStr')
})
}
}
}
</script>
<style lang="scss" scoped>
.p-con { position: relative; width: 100%; height: 100%; background: #981838; color: #535353; text-align: center; }
/* 头部 */
.p-con .hd { position: absolute; top: 0; left: 0; right: 0; background: #ffffff; }
.p-con .hd img { display: block; margin: 0 auto; padding: 0.3rem 0 0.1rem 0; }
.p-con .hd .txt { margin: 0 auto; padding: 0 0 0.2rem 0; letter-spacing: 0.05rem; font-size: 0.32rem; font-weight: 700; }
/* 底部 */
.p-con .ft { position: fixed; bottom: 0; left: 0; right: 0; padding: 0.4rem 0 0.1rem 0; background: #e5e5e5; }
.p-con .ft .num { font-size: 0.14rem; line-height: 1.5; }
.p-con .ft .time { font-size: 0.14rem; line-height: 1.5; }
.p-con .ft .txt { padding: 0.1rem; color: #898989; font-size: 0.12rem; line-height: 1.5; }
/* 中间部分 */
.p-con .bd { position: relative; padding: 1.45rem 0 1.3rem 0; margin: 0 auto; height: 100%; min-height: 6rem; box-sizing: border-box; }
.p-con .bd .router-link-class { color: #ffffff; text-decoration: none; }
/* code 登录 */
.p-con .bd .top50 { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); }
.p-con .bd .top50 img { display: block; margin: 0 auto; }
.p-con .bd .top50 .login-btn { margin-top: 0.1rem; background: #ffffff; border-color: #ffffff; color: #000; width: 100%; }
.p-con .bd .top50 .text { margin-top: -16px; color: #e5e5e5; font-size: 16px; line-height: 1.5; overflow: hidden; }
.p-con .bd .top50 .text .code-login { float: left; cursor: pointer; }
.p-con .bd .top50 .text .forget-pwd { float: right; cursor: pointer; }
/* Extra small devices (portrait phones, less than 576px) */
@media (max-width: 575px) { .container { position: relative; margin: 0 auto; width: 100%; } }
/* Small devices (landscape phones, 576px and up) */
@media (min-width: 576px) and (max-width: 767px) { .container { position: relative; margin: 0 auto; width: 576px; } }
/* Medium devices (tablets, 768px and up) */
@media (min-width: 768px) and (max-width: 991px) { .container { position: relative; margin: 0 auto; width: 768px; } }
/* Large devices (desktops, 992px and up) */
@media (min-width: 992px) and (max-width: 1199px) { .container { position: relative; margin: 0 auto; width: 992px; } }
/* Extra large devices (large desktops, 1200px and up) */
@media (min-width: 1200px) { .container { position: relative; margin: 0 auto; width: 1200px; } }
</style>
<template>
<div class="p-con">
<div class="hd">
<img src="@/assets/images/logo.png" alt="logo">
<div class="txt">在线学习系统</div>
</div>
<div class="bd">
<div class="top50 container">
<forget-login class="content-s-self">
<div class="go-back" slot="go-back">
<template v-if="query.rd">
<router-link class="router-link-class" style="color: #000;" active-class="router-link-active-class" :to="{ path: '/login/index?rd=' + query.rd }">返回登录</router-link>
</template>
<template v-else>
<router-link class="router-link-class" style="color: #000;" active-class="router-link-active-class" :to="{ name: 'login-normal' }">返回登录</router-link>
</template>
</div>
</forget-login>
</div>
</div>
<div class="ft">
<div class="num">学习平台服务电话:010-62793299</div>
<div class="time">服务时间:9:00-18:00</div>
<div class="txt">Copyright © 2017 Zijing Education. All rights reserved. 清控紫荆(北京)教育科技股份有限公司 京ICP证150431号 京公网安备 11010802023681号</div>
</div>
</div>
</template>
<script>
import sLanguage from '@/components/languageSwitch/index.vue'
export default {
components: { sLanguage },
props: {
params: { type: Object, required: false, default () { return {} } },
query: { type: Object, required: false, default () { return {} } }
},
data () {
return {}
},
metaInfo () {
return {
title: this.$t('Login.title'),
meta: []
}
},
mounted () {},
methods: {
dialogMsg () {
this.$message({
type: 'success',
message: this.$t('Login.findPwdStr')
})
}
}
}
</script>
<style lang="scss" scoped>
.p-con { position: relative; width: 100%; height: 100%; background: #981838; color: #535353; text-align: center; }
/* 头部 */
.p-con .hd { position: absolute; top: 0; left: 0; right: 0; background: #ffffff; }
.p-con .hd img { display: block; margin: 0 auto; padding: 0.3rem 0 0.1rem 0; }
.p-con .hd .txt { margin: 0 auto; padding: 0 0 0.2rem 0; letter-spacing: 0.05rem; font-size: 0.32rem; font-weight: 700; }
/* 底部 */
.p-con .ft { position: fixed; bottom: 0; left: 0; right: 0; padding: 0.4rem 0 0.1rem 0; background: #e5e5e5; }
.p-con .ft .num { font-size: 0.14rem; line-height: 1.5; }
.p-con .ft .time { font-size: 0.14rem; line-height: 1.5; }
.p-con .ft .txt { padding: 0.1rem; color: #898989; font-size: 0.12rem; line-height: 1.5; }
/* 中间部分 */
.p-con .bd { position: relative; padding: 1.45rem 0 1.3rem 0; margin: 0 auto; height: 100%; min-height: 6rem; box-sizing: border-box; }
.p-con .bd .router-link-class { color: #ffffff; text-decoration: none; }
/* forget 登录 */
.content-s-self { top: 50%; transform: translate(-50%, -50%); }
.go-back { margin-top: 0.2rem; text-align: left; }
/* Extra small devices (portrait phones, less than 576px) */
@media (max-width: 575px) { .container { position: relative; margin: 0 auto; width: 100%; height: 100%; } }
/* Small devices (landscape phones, 576px and up) */
@media (min-width: 576px) and (max-width: 767px) { .container { position: relative; margin: 0 auto; width: 576px; height: 100%; } }
/* Medium devices (tablets, 768px and up) */
@media (min-width: 768px) and (max-width: 991px) { .container { position: relative; margin: 0 auto; width: 768px; height: 100%; } }
/* Large devices (desktops, 992px and up) */
@media (min-width: 992px) and (max-width: 1199px) { .container { position: relative; margin: 0 auto; width: 992px; height: 100%; } }
/* Extra large devices (large desktops, 1200px and up) */
@media (min-width: 1200px) { .container { position: relative; margin: 0 auto; width: 1200px; height: 100%; } }
</style>
<template>
<div class="p-con">
<div class="hd">
<img src="@/assets/images/logo.png" alt="logo">
<div class="txt">在线学习系统</div>
<!-- <s-language></s-language> -->
</div>
<div class="bd">
<div class="top50 container">
<el-row>
<el-col :xs="2" :sm="7" :md="3" :lg="3" :xl="3"><div style="height: 1px;"></div></el-col>
<el-col class="hidden-xs-only hidden-sm-only" :md="10" :lg="10" :xl="10">
<img src="@/assets/images/login-left-bg.png" alt="左侧-sofia logo">
</el-col>
<el-col :xs="20" :sm="10" :md="6" :lg="6" :xl="6">
<normal-login>
<div class="text" slot="text">
<span class="code-login">
<template v-if="query.rd">
<router-link class="router-link-class" active-class="router-link-active-class" :to="{ path: '/login/code?rd=' + query.rd }">{{$t('Login.codeLogin')}}</router-link>
</template>
<template v-else>
<router-link class="router-link-class" active-class="router-link-active-class" :to="{ name: 'login-code' }">{{$t('Login.codeLogin')}}</router-link>
</template>
</span>
<span class="forget-pwd">
<template v-if="query.rd">
<router-link class="router-link-class" active-class="router-link-active-class" :to="{ path: '/login/forget?rd=' + query.rd }">{{$t('Login.forgetPassword')}}</router-link>
</template>
<template v-else>
<router-link class="router-link-class" active-class="router-link-active-class" :to="{ name: 'login-forget' }">{{$t('Login.forgetPassword')}}</router-link>
</template>
<!-- <div class="router-link-class" @click="dialogMsg">{{$t('Login.forgetPassword')}}</div> -->
</span>
</div>
</normal-login>
</el-col>
<el-col :xs="2" :sm="7" :md="5" :lg="5" :xl="5"><div style="height: 1px;"></div></el-col>
</el-row>
</div>
</div>
<div class="ft">
<div class="num">学习平台服务电话:010-62793299</div>
<div class="time">服务时间:9:00-18:00</div>
<div class="txt">Copyright © 2017 Zijing Education. All rights reserved. 清控紫荆(北京)教育科技股份有限公司 京ICP证150431号 京公网安备 11010802023681号</div>
</div>
</div>
</template>
<script>
import sLanguage from '@/components/languageSwitch/index.vue'
export default {
components: { sLanguage },
props: {
params: { type: Object, required: false, default () { return {} } },
query: { type: Object, required: false, default () { return {} } }
},
data () {
return {}
},
metaInfo () {
return {
title: this.$t('Login.title'),
meta: []
}
},
mounted () {},
methods: {
dialogMsg () {
this.$message({
type: 'success',
message: this.$t('Login.findPwdStr')
})
}
}
}
</script>
<style lang="scss" scoped>
.p-con { position: relative; width: 100%; height: 100%; background: #981838; color: #535353; text-align: center; }
/* 头部 */
.p-con .hd { position: absolute; top: 0; left: 0; right: 0; background: #ffffff; }
.p-con .hd img { display: block; margin: 0 auto; padding: 0.3rem 0 0.1rem 0; }
.p-con .hd .txt { margin: 0 auto; padding: 0 0 0.2rem 0; letter-spacing: 0.05rem; font-size: 0.32rem; font-weight: 700; }
/* 底部 */
.p-con .ft { position: fixed; bottom: 0; left: 0; right: 0; padding: 0.4rem 0 0.1rem 0; background: #e5e5e5; }
.p-con .ft .num { font-size: 0.14rem; line-height: 1.5; }
.p-con .ft .time { font-size: 0.14rem; line-height: 1.5; }
.p-con .ft .txt { padding: 0.1rem; color: #898989; font-size: 0.12rem; line-height: 1.5; }
/* 中间部分 */
.p-con .bd { position: relative; padding: 1.45rem 0 1.3rem 0; margin: 0 auto; height: 100%; min-height: 6rem; box-sizing: border-box; }
.p-con .bd .router-link-class { color: #ffffff; text-decoration: none; }
/* normal 登录 */
.p-con .bd .top50 { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); }
.p-con .bd .top50 img { display: block; margin: 0 auto; }
.p-con .bd .top50 .login-btn { margin-top: 0.1rem; background: #ffffff; border-color: #ffffff; color: #000; width: 100%; }
.p-con .bd .top50 .text { margin-top: -16px; color: #e5e5e5; font-size: 16px; line-height: 1.5; overflow: hidden; }
.p-con .bd .top50 .text .code-login { float: left; cursor: pointer; }
.p-con .bd .top50 .text .forget-pwd { float: right; cursor: pointer; }
/* Extra small devices (portrait phones, less than 576px) */
@media (max-width: 575px) { .container { position: relative; margin: 0 auto; width: 100%; } }
/* Small devices (landscape phones, 576px and up) */
@media (min-width: 576px) and (max-width: 767px) { .container { position: relative; margin: 0 auto; width: 576px; } }
/* Medium devices (tablets, 768px and up) */
@media (min-width: 768px) and (max-width: 991px) { .container { position: relative; margin: 0 auto; width: 768px; } }
/* Large devices (desktops, 992px and up) */
@media (min-width: 992px) and (max-width: 1199px) { .container { position: relative; margin: 0 auto; width: 992px; } }
/* Extra large devices (large desktops, 1200px and up) */
@media (min-width: 1200px) { .container { position: relative; margin: 0 auto; width: 1200px; } }
</style>
<template>
<div class="play-paper">
<div class="play-paper-body">
<div class="play-paper-title"><div><h3>{{chapterName}}</h3></div></div>
<div class="play-paper-content play-chapter-exam">
<template v-if="this.exam.id">
<div class='exam'>
<div style='text-align: center;'>
<div class='topic'>
<!-- <div class='tit'>{{exam.title}}</div> -->
<template v-if='exam.score'><div class='cur'>正确率:{{exam.score}}%</div></template>
</div>
</div>
<div style=''>
<template v-for='(item, index) in exam.group'>
<template v-if='item.type == 1'>
<div v-bind:key="index" class='q-group' @click="radioClick" :data-index='index'>
<div class='q-num'>{{index+1}}.</div><div class='q-title' v-html='item.title'></div><div class='q-type'>(单选题)</div>
<el-radio-group class='radio-group' @change='radioChange' v-model="item.sel">
<template v-for='(item1, index1) in item.arr'>
<!-- checked='{{item1.selected}}' -->
<el-radio v-bind:key="index1" :label='index1' :disabled='!!item.cur' :class='["radio", (item.cur && item1.checked && "success"), (item.cur && !item1.checked && item1.selected && "error")]'>{{ index1 == 0 ? "A" : (index1 == 1 ? "B" : (index1 == 2 ? "C" : (index1 == 3 ? "D" : (index1 == 4 ? "E" : (index1 == 5 ? "F" : (index1 == 6 ? "G" : (index1 == 7 ? "H" : (index1 == 8 ? "I" : (index1 == 9 ? "J" : "K"))))))))) }}. {{item1.option}}</el-radio>
</template>
</el-radio-group>
<template v-if='item.cur'><div class='result'>学生答案:<div :class='["stu", (item.is_correct ? "success" : "error")]'>{{item.stuAnswer}}</div>&nbsp;&nbsp;&nbsp;&nbsp;正确答案:{{item.cur}}</div></template>
</div>
</template>
<template v-if='item.type == 2'>
<div v-bind:key="index" class='q-group' @click="checkboxClick" :data-index='index'>
<div class='q-num'>{{index+1}}.</div><div class='q-title' v-html='item.title'></div><div class='q-type'>(多选题)</div>
<el-checkbox-group class='checkbox-group' @change='checkboxChange' v-model="item.arrSel">
<template v-for='(item1, index1) in item.arr'>
<!-- value='{{index1}}' -->
<el-checkbox v-bind:key="item1.id" :label='index1' :checked='!!item1.selected' :disabled='!!item.cur' :class='["checkbox", (item.cur && item1.checked && "success"), (item.cur && !item1.checked && item1.selected && "error")]'>{{ index1 == 0 ? "A" : (index1 == 1 ? "B" : (index1 == 2 ? "C" : (index1 == 3 ? "D" : (index1 == 4 ? "E" : (index1 == 5 ? "F" : (index1 == 6 ? "G" : (index1 == 7 ? "H" : (index1 == 8 ? "I" : (index1 == 9 ? "J" : "K"))))))))) }}. {{item1.option}}</el-checkbox>
</template>
</el-checkbox-group>
<template v-if='item.cur'><div class='result'>学生答案:<div :class='["stu", (item.is_correct ? "success" : "error")]'>{{item.stuAnswer}}</div>&nbsp;&nbsp;&nbsp;&nbsp;正确答案:{{item.cur}}</div></template>
</div>
</template>
</template>
</div>
<div :class='["btn", (exam.work_contents && "on")]' @click='submitExam' :data-submit='!!exam.work_contents' @mousedown='_SubmitMouseLeftDown()'>{{exam.work_contents ? "已提交" : "提交"}}</div>
<div class='care'>(注意:测试只有一次提交机会)</div>
<!-- <div :class='["btn"]' @click='repeatExam($event, true)' v-if="exam.work_contents">重做</div> -->
</div>
</template>
</div>
</div>
</div>
</template>
<script>
import cAction from '@action'
// import CKEDITOR from 'CKEDITOR'
export default {
props: {
chapterId: { type: String, require: false },
chapterName: { type: String, require: false },
chapterExam: { type: Object, require: false },
sid: { type: String, require: false },
cid: { type: String, require: false },
id: { type: String, require: false }
},
data () {
return {
exam: {
// id: '',
// semester_id: '',
// title: '家族财富传承第一章试题',
// score: '100',
// work_contents: '',
// group: [{
// id: '',
// type: 1, // 判别是 单选还是多选
// title: '<p>一般延续好几代,采取防御战略维持企业的家族企业类型是( )。</p>',
// arr: [
// { id: '', checked: true, option: '闪电型', selected: 0 },
// { id: '', checked: true, option: '不老型', selected: 1 },
// { id: '', checked: false, option: '长存型', selected: 1 },
// { id: '', checked: false, option: '持续创业型', selected: 0 }
// ],
// cur: '1',
// arrSel: [],
// sel: ''
// }]
},
// 提交时,传入的参数值
param: {
course_id: '',
chapter_id: '',
work_id: '',
semester_id: '',
work_contents: '',
duration: 0,
score: 0
},
/* 进入页面记录初试时间 */
startTime: '',
/* 记录所有题目是否都答过 */
recordAll: [],
setTime: null,
/* 当前 radio点击 */
radioCur: '',
/* 当前 checkbox点击 */
checkCur: ''
}
},
mounted () {
this.loadAjax()
},
methods: {
arrRandomSort (arr) {
/* 对json.questions 进行一次乱序排列 */
let tmpJson = null
tmpJson = arr.shift()
arr.push(tmpJson)
tmpJson = arr.shift()
arr.push(tmpJson)
tmpJson = arr.shift()
arr.push(tmpJson)
},
unArrRandomSort (arr) {
/* 取消乱序排列,恢复原顺序 */
let tmpJson = null
tmpJson = arr.pop()
arr.unshift(tmpJson)
tmpJson = arr.pop()
arr.unshift(tmpJson)
tmpJson = arr.pop()
arr.unshift(tmpJson)
},
/**
* 将返回值 - 对照到对应 data上
*/
updateData (json) {
this.param = {
course_id: json.course_id,
chapter_id: json.chapter_id,
work_id: json.work_id,
semester_id: json.semester_id,
work_contents: '',
duration: 0,
score: 0
}
this.startTime = new Date().getTime()
this.arrRandomSort(json.questions)
const _data = {
id: json.id,
semester_id: json.semester_id,
title: json.work_title,
score: json.score || (json.score === 0 ? '0' : ''),
work_contents: json.work_contents || '',
group: json.questions.map(function (_, i) {
let str = ''
let stuAnswer = '' // 学生答案
let stuIsCorrect = 0 // 学生是否答对
let _json = _.question_options ? JSON.parse(_.question_options) : []
_json.forEach(function (__, j) {
if (__.checked) {
switch (j) {
case 0: str += 'A,'; break
case 1: str += 'B,'; break
case 2: str += 'C,'; break
case 3: str += 'D,'; break
case 4: str += 'E,'; break
case 5: str += 'F,'; break
case 6: str += 'G,'; break
case 7: str += 'H,'; break
case 8: str += 'I,'; break
case 9: str += 'J,'; break
}
}
})
let sel = '' // 单选选中
/* 答过题目时 */
if (json.work_contents) {
const a = JSON.parse(json.work_contents)
for (let i = 0; i < a.length; i++) {
if (a[i].question_id === _.id) {
_json = a[i].options
stuIsCorrect = a[i].is_correct
break
}
}
/* 单选选中 */
if (_.question_type === 1) {
for (let i = 0; i < _json.length; i++) {
if (_json[i].selected) {
sel = i
switch (i) {
case 0: stuAnswer = 'A,'; break
case 1: stuAnswer = 'B,'; break
case 2: stuAnswer = 'C,'; break
case 3: stuAnswer = 'D,'; break
case 4: stuAnswer = 'E,'; break
case 5: stuAnswer = 'F,'; break
case 6: stuAnswer = 'G,'; break
case 7: stuAnswer = 'H,'; break
case 8: stuAnswer = 'I,'; break
case 9: stuAnswer = 'J,'; break
}
break
}
}
}
/* 多选选中 */
if (_.question_type === 2) {
for (let i = 0; i < _json.length; i++) {
if (_json[i].selected) {
switch (i) {
case 0: stuAnswer += 'A,'; break
case 1: stuAnswer += 'B,'; break
case 2: stuAnswer += 'C,'; break
case 3: stuAnswer += 'D,'; break
case 4: stuAnswer += 'E,'; break
case 5: stuAnswer += 'F,'; break
case 6: stuAnswer += 'G,'; break
case 7: stuAnswer += 'H,'; break
case 8: stuAnswer += 'I,'; break
case 9: stuAnswer += 'J,'; break
}
}
}
}
}
return {
id: _.id,
type: _.question_type,
title: _.question_content,
arr: _json,
cur: (json.work_contents && str.substr(0, str.length - 1)) || '',
arrSel: [],
sel: sel,
stuAnswer: stuAnswer.substr(0, stuAnswer.length - 1),
is_correct: stuIsCorrect
}
})
}
return _data
},
/**
* 将返回值 - 对照到对应 data上
* 增加这个的目的,由于循环改变data对象时,又由于 v-bind:key使用相同
* 导致,有些选项勾选状态不显示,所有在不改变对象引用的前提下,直接改值
* 所以 产生当前方法
* 直接 把数据值 赋值给 exam对象
*/
updateData1 (json) {
this.exam.id = json.id
this.exam.semester_id = json.semester_id
this.exam.title = json.work_title
this.exam.score = json.score || '0'
this.exam.work_contents = json.work_contents || ''
this.arrRandomSort(json.questions)
for (let i = 0; i < this.exam.group.length; i++) {
let str = ''
let stuAnswer = '' // 学生答案
let stuIsCorrect = 0 // 学生是否答对
const _ = json.questions[i]
let _json = JSON.parse(_.question_options)
_json.forEach(function (__, j) {
if (__.checked) {
switch (j) {
case 0: str += 'A,'; break
case 1: str += 'B,'; break
case 2: str += 'C,'; break
case 3: str += 'D,'; break
case 4: str += 'E,'; break
case 5: str += 'F,'; break
case 6: str += 'G,'; break
case 7: str += 'H,'; break
case 8: str += 'I,'; break
case 9: str += 'J,'; break
}
}
})
let sel = '' // 单选选中
/* 答过题目时 */
if (json.work_contents) {
const a = JSON.parse(json.work_contents)
for (let i = 0; i < a.length; i++) {
if (a[i].question_id === _.id) {
_json = a[i].options
stuIsCorrect = a[i].is_correct
break
}
}
/* 单选选中 */
if (_.question_type === 1) {
for (let i = 0; i < _json.length; i++) {
if (_json[i].selected) {
sel = i
switch (i) {
case 0: stuAnswer = 'A,'; break
case 1: stuAnswer = 'B,'; break
case 2: stuAnswer = 'C,'; break
case 3: stuAnswer = 'D,'; break
case 4: stuAnswer = 'E,'; break
case 5: stuAnswer = 'F,'; break
case 6: stuAnswer = 'G,'; break
case 7: stuAnswer = 'H,'; break
case 8: stuAnswer = 'I,'; break
case 9: stuAnswer = 'J,'; break
}
break
}
}
}
/* 多选选中 */
if (_.question_type === 2) {
for (let i = 0; i < _json.length; i++) {
if (_json[i].selected) {
switch (i) {
case 0: stuAnswer += 'A,'; break
case 1: stuAnswer += 'B,'; break
case 2: stuAnswer += 'C,'; break
case 3: stuAnswer += 'D,'; break
case 4: stuAnswer += 'E,'; break
case 5: stuAnswer += 'F,'; break
case 6: stuAnswer += 'G,'; break
case 7: stuAnswer += 'H,'; break
case 8: stuAnswer += 'I,'; break
case 9: stuAnswer += 'J,'; break
}
}
}
}
}
this.exam.group[i].id = _.id
this.exam.group[i].type = _.question_type
this.exam.group[i].title = _.question_content
this.exam.group[i].cur = (json.work_contents && str.substr(0, str.length - 1)) || ''
this.exam.group[i].arrSel = []
this.exam.group[i].sel = sel
this.exam.group[i].stuAnswer = stuAnswer.substr(0, stuAnswer.length - 1)
this.exam.group[i].is_correct = stuIsCorrect
const _arr = this.exam.group[i].arr
for (let j = 0; j < _arr.length; j++) {
_arr[j].selected = _json[j].selected
_arr[j].id = _arr[j].id + '1'
}
}
},
/**
* 生命周期函数--监听页面加载
*/
loadAjax () {
const loading = this.$loading({ lock: true, text: '', spinner: '', background: 'rgba(255, 255, 255, 0.9)' })
cAction.Player.getExamDetail(this.sid, this.cid, this.id).then(_data => {
const json = _data.homework
if (json) {
json.score = _data.score
json.work_contents = _data.work_contents
this.exam = this.updateData(json)
} else {
this.exam = {}
}
}).catch(e => { this.$message.error(e.message) }).finally(() => {
this.setTime = setInterval(() => {
// console.log(this.chapterExam.work_id, this.id)
if (this.chapterExam.work_id && this.chapterExam.work_id === this.id) {
if (!this.exam.id) {
this.exam = this.updateData(this.chapterExam)
/* 滚动到头部 */
document.querySelector('.play-paper').scrollTop = 0
}
clearInterval(this.setTime)
}
}, 50)
loading.close()
})
},
/**
* 辅助 radio选择
*/
radioClick (e) {
this.radioCur = e.currentTarget.dataset.index
},
/**
* radio选择
* PC端 值会 返回 选择的 值
*/
radioChange (val) {
const i = this.radioCur
const arr = this.exam.group[i].arr
const value = val
for (let j = 0; j < arr.length; j++) {
arr[j].selected = 0
}
arr[value].selected = 1
this.exam.group[i].arr = arr
this.recordAll.push(i)
},
/**
* 辅助 checkbox选择
*/
checkboxClick (e) {
this.checkboxCur = e.currentTarget.dataset.index
},
/**
* checkbox选择
*/
checkboxChange (val) {
const i = this.checkboxCur
const arr = this.exam.group[i].arr
const value = val
for (let j = 0; j < arr.length; j++) {
arr[j].selected = 0
}
for (let j = 0; j < value.length; j++) {
arr[value[j]].selected = 1
}
this.exam.group[i].arr = arr
if (!value.length) {
this.recordAll = this.recordAll.filter(function (_, m) { return _ !== i })
} else {
this.recordAll.push(i)
}
},
/**
* 提交试题
*/
submitExam (e) {
if (e.currentTarget.dataset.submit) {
this.$message.error('已做过,不能再提交')
return
}
// /* 计算答题时间 */
this.param.duration = Math.floor((new Date().getTime() - this.startTime) / 1000)
const group = this.exam.group
const total = group.length
const arr = []
let score = 0
let correct = 0
for (let m = 0; m < total; m++) {
let n = 0
for (; n < this.recordAll.length; n++) {
if (this.recordAll[n] === m + '') { break }
}
if (n === this.recordAll.length) {
// console.log(this.recordAll)
this.$message.error('还有题目未做,不能提交')
return
}
}
/* 重新定义 - 上传字段 并计算分数 */
// is_correct
for (let i = 0; i < group.length; i++) {
correct = 0
if (group[i].type === 1) { // 单选的正确 判断
group[i].arr.forEach(function (_, i) {
if (_.checked && _.selected) { correct = 1; score += 1 }
})
}
if (group[i].type === 2) { // 多选的正确 判断
let flag = true
group[i].arr.forEach(function (_, i) {
if (_.checked !== !!_.selected) { flag = false }
})
if (flag) { correct = 1; score += 1 }
}
arr.push({
question_id: group[i].id,
is_correct: correct,
options: group[i].arr
})
}
this.unArrRandomSort(arr)
this.param.work_contents = JSON.stringify(arr)
this.param.score = (score / total * 100).toFixed(1)
const loading = this.$loading({ lock: true, text: '', spinner: '', background: 'rgba(255, 255, 255, 0.9)' })
cAction.Player.submitExamDetail(this.param).then(_res => {
if (_res.status) {
cAction.Player.getExamDetail(this.sid, this.cid, this.id).then(_data => {
const json = _data.homework
if (json) {
json.score = _data.score
json.work_contents = _data.work_contents
this.updateData1(json) // 特殊处理
}
}).catch(e => { this.$message.error(e.message) })
} else {
this.$message.error(_res.data.error)
}
}).catch(e => { this.$message.error(e.message) }).finally(() => { loading.close() })
},
_SubmitMouseLeftDown () {
const _fn1 = this.repeatExam.bind(this, false)
document.addEventListener('keydown', _fn1, false)
const _fn3 = function () {
document.removeEventListener('keydown', _fn1)
document.removeEventListener('mouseup', _fn3)
}
document.addEventListener('mouseup', _fn3, false)
},
/**
* 重做
*/
repeatExam (e, flag) {
let _flag = flag
/* 字母 f */
if (e.keyCode === 70) {
_flag = true
}
if (!_flag) { return }
const loading = this.$loading({ lock: true, text: '', spinner: '', background: 'rgba(255, 255, 255, 0.9)' })
cAction.Player.getExamDetail(this.sid, this.cid, this.id).then(_data => {
this.exam = {}
}).catch(e => { this.$message.error(e.message) }).finally(() => {
this.setTime = setInterval(() => {
// console.log(this.chapterExam.work_id, this.id)
if (this.chapterExam.work_id && this.chapterExam.work_id === this.id) {
if (!this.exam.id) {
this.exam = this.updateData(this.chapterExam)
/* 滚动到头部 */
document.querySelector('.play-paper').scrollTop = 0
}
clearInterval(this.setTime)
}
}, 50)
loading.close()
})
}
},
watch: {
id: {
handler () {
this.loadAjax()
}
}
}
}
</script>
<style lang="scss" scoped>
.play {
.exam { padding: 0; }
.exam .topic { display: inline-block; margin-bottom: 0.1rem; }
.exam .topic .tit { margin: 0 auto; padding: 0 0.2rem; text-align: center; font-size: 0.24rem; color: #313131; background: #fff; box-sizing: border-box; -webkit-box-sizing: border-box; }
.exam .topic .cur { text-align: center; font-size: 0.18rem; color: #313131; line-height: 0.4rem; }
/* 循环 所有选择题 */
.exam .q-group { padding: 0.1rem 0.1rem; border-bottom: 1px solid #c9c9c97a; overflow: hidden; }
.exam .q-group .q-num { float: left; margin-right: 0.1rem; font-size: 0.16rem; color: #676a6c; }
.exam .q-group .q-title { float: left; width: 90%; font-size: 0.16rem; color: #676a6c; text-align: justify; }
.exam .q-group .q-type { float: right; font-size: 0.16rem; color: #676a6c; }
.exam .q-group .radio-group { float: left; margin-top: 0.1rem; width: 100%; }
.exam .q-group .radio-group .radio { display: block; font-size: 0.18rem; color: #3f3b3a; line-height: 0.3rem; margin-bottom: 0.1rem; }
.exam .q-group .checkbox-group { float: left; margin-top: 0.1rem; width: 100%; }
.exam .q-group .checkbox-group .checkbox { display: block; font-size: 0.18rem; color: #3f3b3a; line-height: 0.3rem; margin-bottom: 0.1rem; }
.exam .q-group .radio-group .radio.error, .exam .q-group .checkbox-group .checkbox.error { color: #d80000; }
.exam .q-group .radio-group .radio.success, .exam .q-group .checkbox-group .checkbox.success { color: #090; }
.exam .q-group .result { float: right; font-size: 0.18rem; color: #3f3b3a; margin-right: 0; }
.exam .q-group .result .stu { display: inline-block; }
.exam .q-group .result .stu.error { color: #d80000; }
.exam .q-group .result .stu.success { color: #090; }
.exam .q-group:last-child { border-bottom: none; }
.exam .btn { margin: 0.2rem auto; width: 60%; height: 0.5rem; line-height: 0.5rem; font-size: 0.16rem; text-align: center; font-weight: 300; color: #fff; border-radius: 0.1rem; background: #b49441; cursor: pointer; }
.exam .btn.on { opacity: 0.5; }
.exam .care { font-size: 0.16rem; color: #d80000; text-align: center; }
}
</style>
<template>
<div class="play-paper">
<div class="play-paper-body">
<div class="play-paper-title">
<div>
<h3>{{exam.title}}</h3>
</div>
</div>
<template v-if="status.isStart">
<div class="play-paper-content">
<template v-if="exam.id">
<div class="exam">
<!-- <div style='text-align: center;'> -->
<!-- <div class='topic'> -->
<!-- <div class='tit'>{{exam.title}}</div> -->
<template v-if="exam.type === 2">
<template v-if="exam.score">
<div style="font-size: 18px;">分数:{{exam.score.total}}</div>
</template>
</template>
<template v-else-if="exam.type === 1">
<div class="no-exam">试卷批改中,请耐心等待</div>
</template>
<!-- </div> -->
<!-- </div> -->
<template v-if="(exam.type !== 1)">
<div
style="text-align: center;"
v-if="exam.paper_deadline"
>考试截止时间为:{{exam.paper_deadline}}</div>
<template v-for="question in exam.examination">
<!-- 单选题 -->
<template v-if="question.radioList.length">
<template v-for="(item, index) in question.radioList">
<div v-bind:key="item.id" class="q-group" :data-index="index">
<div class="q-num">{{index+1}}.</div>
<div class="q-title" v-html="item.content"></div>
<div class="q-type">(单选题)</div>
<el-radio-group class="radio-group" v-model="item.user_answer">
<template v-for="(item1, index1) in item.options">
<el-radio
v-bind:key="item1.id"
:label="item1.id"
:disabled="isSubmited"
:class="['radio', ((item.right_answer && !!exam.type) ? (item1.id === item.right_answer ? 'success' : 'error') : '')]"
>{{ index1 | getLetter() }}. {{item1.option}}</el-radio>
</template>
</el-radio-group>
<template v-if="item.right_answer && !!exam.type">
<div class="result">
学生答案:
<div
:class="['stu', (item.right_answer === item.user_answer ? 'success' : 'error')]"
>{{ item.user_answer | getRadioAnswer(item.options) }}</div>
&nbsp;&nbsp;&nbsp;&nbsp;正确答案:{{ item.right_answer | getRadioAnswer(item.options) }}
</div>
</template>
<div class="analysis" v-if="item.analysis">
<p>解析:</p>
<div v-html="item.analysis"></div>
</div>
</div>
</template>
</template>
<!-- 多选题 -->
<template v-if="question.checkboxList.length">
<template v-for="(item, index) in question.checkboxList">
<div v-bind:key="item.id" class="q-group" :data-index="index">
<div class="q-num">{{question.radioList.length+index+1}}.</div>
<div class="q-title" v-html="item.content"></div>
<div class="q-type">(多选题)</div>
<el-checkbox-group class="checkbox-group" v-model="item.user_answer">
<template v-for="(item1, index1) in item.options">
<el-checkbox
v-bind:key="item1.id"
:label="item1.id"
:disabled="isSubmited"
:class="['checkbox', ((item.right_answer.length && !!exam.type) ? (isCheckboxChecked(item1.id, item.right_answer) ? 'success' : 'error') : '')]"
>{{ index1 | getLetter() }}. {{item1.option}}</el-checkbox>
</template>
</el-checkbox-group>
<template v-if="item.right_answer.length && !!exam.type">
<div class="result">
学生答案:
<div
:class="['stu', ((item.right_answer.length && isCheckboxRight(item.user_answer, item.right_answer)) ? 'success' : 'error')]"
>{{ item.user_answer | getCheckboxAnswer(item.options) }}</div>
&nbsp;&nbsp;&nbsp;&nbsp;正确答案:{{ item.right_answer | getCheckboxAnswer(item.options) }}
</div>
</template>
<div class="analysis" v-if="item.analysis">
<p>解析:</p>
<div v-html="item.analysis"></div>
</div>
</div>
</template>
</template>
<!-- 简答题 -->
<template v-if="question.shortAnswerList.length">
<template v-for="(item, index) in question.shortAnswerList">
<div class="q-group" :key="index">
<div
class="q-sa-title"
>{{question.radioList.length+question.checkboxList.length+index+1}}.&nbsp;&nbsp;简答题</div>
<div class="edit_html" v-html="item.content || ''"></div>
<v-editor v-model="item.user_answer" :disabled="isSubmited"></v-editor>
<div style="height: 10px;"></div>
<!-- 利用key值自动更新组件 -->
<component
:is="item.upload.type"
v-bind:key="item.upload.id + new Date().getTime()"
:item="item.upload"
:formData="item"
:isUpload="!exam.type"
></component>
<div class="result" v-if="item.check_comment">评语:{{item.check_comment}}</div>
<div class="analysis" v-if="item.analysis">
<p>解析:</p>
<div v-html="item.analysis"></div>
</div>
</div>
</template>
</template>
</template>
<div
:class="['btn', (isSubmited && 'on')]"
@click="submitExam"
:data-submit="isSubmited"
@mousedown="_SubmitMouseLeftDown()"
>{{isSubmited ? "已提交" : "提交"}}</div>
<div class="care">(注意:考试只有一次提交机会)</div>
<!-- <div :class='["btn"]' @click='repeatExam($event, true)' v-if="exam.work_contents">重做</div> -->
</template>
</div>
</template>
</div>
</template>
<template v-else>
<div class="exam">
<!-- <p>考试须知:</p> -->
<div style="text-align: left;" v-if="exam.paper_deadline">考试截止时间为:{{exam.paper_deadline}}</div>
<template v-if="isExamTime">
<div
style="width: 25%;"
:class="['btn']"
@click="beginExam(true)"
@mousedown="beginExam(true)"
>开始考试</div>
</template>
</div>
</template>
</div>
</div>
</template>
<script>
import cAction from '@action'
import Base64 from 'Base64'
import VEditor from '@/components/editor.vue'
const A_Z = (function() {
const result = []
for (let i = 0; i < 26; i++) {
result.push(String.fromCharCode(65 + i))
}
return result
})()
var getLetter = val => {
return A_Z[val]
}
export default {
props: {
chapters: {
type: Array,
default() {
return []
}
},
sid: { type: String, require: false },
cid: { type: String, require: false },
id: { type: String, require: false }
},
components: { VEditor },
filters: {
getLetter: getLetter,
getRadioAnswer: (val, arr) => {
for (let i = 0; i < arr.length; i++) {
if (arr[i].id === val) {
return getLetter(i)
}
}
},
getCheckboxAnswer: (val, arr) => {
let str = ''
for (let i = 0; i < val.length; i++) {
const tmpId = val[i]
for (let j = 0; j < arr.length; j++) {
if (arr[j].id === tmpId) {
str += getLetter(j) + ','
break
}
}
}
return str.substr(0, str.length - 1)
}
},
data() {
return {
_time: null, // 定时器,自动化提交
exam: {},
status: {
isStart: false,
startTime: '',
terminateTime: '',
serverTime: '',
examinationStatus: '',
type: 0,
isPublished: 0
}
}
},
watch: {
id: {
handler() {
this.init()
}
}
},
computed: {
// 当前章节
activeChatper() {
let found = null
for (const item of this.chapters) {
found = item.children.find(subItem => subItem.id === this.id)
if (found) {
break
}
}
return found || {}
},
// 是否是考试时间
isExamTime() {
if (!this.exam.paper_deadline) {
return true
}
// 大于开始时间,小于结束时间
const endTime = +new Date(this.exam.paper_deadline)
const currentTime = new Date().getTime()
return currentTime < endTime
},
// 考试完成
isExamComplete() {
// 考试完成,批改完成并且公布成绩
return this.exam.is_published === 1 && this.exam.type === 2
},
// 是否提交
isSubmited() {
return this.exam.type === 1 || this.exam.type === 2
}
},
mounted() {
this.init()
this.$emit('changeSideBar', '')
setTimeout(() => {
if (window.document.getElementById('switch-btn')) {
window.document.getElementById('switch-btn').style.display = 'none'
}
}, 500)
},
destroyed() {
if (this._time) {
clearInterval(this._time)
this._time = null
}
if (window.document.getElementById('switch-btn')) {
window.document.getElementById('switch-btn').style.display = 'block'
}
},
methods: {
isCheckboxRight: (val, arr) => {
let flag = true
for (let i = 0; i < arr.length; i++) {
const tmpId = arr[i]
let j = 0
for (; j < val.length; j++) {
if (val[j] === tmpId) {
break
}
}
if (j === val.length) {
flag = false
break
}
}
return flag
},
isCheckboxChecked: (val, arr) => {
let i = 0
for (; i < arr.length; i++) {
if (arr[i].id === val || arr[i] === val) {
return true
}
}
return false
},
init() {
const data = this.activeChatper.paper
const exam = {}
exam.id = data.id
exam.title = data.paper_title
exam.score = {}
exam.type = 3
exam.examination = data.examination.map(exam => {
for (let i = 0; i < exam.radioList.length; i++) {
exam.radioList[i].user_answer = ''
exam.radioList[i].right_answer = ''
exam.radioList[i].get_score = -1
}
for (let i = 0; i < exam.checkboxList.length; i++) {
exam.checkboxList[i].user_answer = []
exam.checkboxList[i].right_answer = []
exam.checkboxList[i].get_score = -1
}
for (let i = 0; i < exam.shortAnswerList.length; i++) {
exam.shortAnswerList[i].user_answer = ''
exam.shortAnswerList[i].get_score = -1
exam.shortAnswerList[i].attachments = []
exam.shortAnswerList[i].upload = {
type: 'upload-form',
label: '附件上传:',
model: 'attachments',
action: webConf.apiBaseURL + '/util/upload-file',
data: {
special: 'exam'
},
attrs: {
multiple: true,
headers: {
tenant: 'sofia'
}
},
html: `
<div style="color: #72818c; font-size: 14px;">
<p style="margin: 0;">支持doc,docx,ppt,xls,txt,rar,zip,pdf,jpg,pic,png格式的文件,文件小于30M。</p>
</div>
`
}
}
return exam
})
exam.paper_deadline = data.paper_deadline
this.exam = JSON.parse(JSON.stringify(exam))
// this.loadExamStatus()
// this.loadExamInfo()
this.loadAjax()
if (this._time) {
clearInterval(this._time)
this._time = null
}
this._time = setInterval(() => {
// this.loadExamStatus()
if (!this.isSubmited && this.status.isStart) {
// console.log(11, '暂存')
this.submitExam({ submitType: true }) // 暂存, submitType: true 暂存;其他或不填为提交
}
/* 到时间 自动提交 */
if (
!this.isSubmited &&
this.status.isStart &&
new Date(this.status.terminateTime).getTime() -
new Date(this.status.serverTime).getTime() <=
5000
) {
this.submitExam({ submitType: false, currentTarget: { dataset: {} } })
}
}, 10000)
},
/* 定时调用 - 考试状态 */
loadExamStatus() {
cAction.Player.getExamStatus(this.cid, this.sid, this.id)
.then(_data => {
if (_data.status && _data.status === 200) {
this.status.startTime = this.setTime(_data.start_time)
this.status.terminateTime = _data.terminate_time
this.status.serverTime = this.setTime(_data.server_time)
this.status.examinationStatus = _data.examination_status
} else {
this.$message.error('数据异常,请联系管理员')
}
})
.catch(e => {
this.$message.error(e.message)
})
.finally(() => {})
},
/* 时间格式化(解决safari时间兼容问题); */
setTime(time) {
return time.replace(/-/g, '/')
},
/* 开始考试 */
beginExam(flag) {
this.status.isStart = true
// this.loadAjax(flag)
},
/* 加载题库基本数据 */
loadExamInfo() {
const loading = this.$loading({
lock: true,
text: '',
spinner: '',
background: 'rgba(255, 255, 255, 0.9)'
})
cAction.Player.getExamInfo(this.cid, this.sid)
.then(_data => {
this.exam = _data
this.exam.id = this.id
})
.catch(e => {
this.$message.error(e.message)
})
.finally(() => {
loading.close()
/* 正在考试,考试结束 */
this.beginExam()
})
},
/**
* 生命周期函数--监听页面加载
* @param flag 通过该字段 判别是点击进入考试 还是 自动调用
*/
loadAjax(flag) {
const loading = this.$loading({
lock: true,
text: '',
spinner: '',
background: 'rgba(255, 255, 255, 0.9)'
})
cAction.Player.getExamAnswer(this.cid, this.sid, this.id, {
paper_type: 0
})
.then(_data => {
if (_data.code === 8001) {
console.log(
'没有考试内容,认为是第一次答题,并且在答题期间,所以显示考试开始页面'
)
} else {
this.status.isStart = _data.type !== 3
this.exam.title = _data.title
this.$set(this.exam, 'type', _data.type)
this.exam.score = _data.score
this.exam.submitted_time = _data.submitted_time
this.exam.isPublished = _data.isPublished
this.status.type = _data.type
this.status.isPublished = _data.isPublished
this.exam.examination = this.exam.examination.map((exam, index) => {
const rawExam = _data.examination[index]
if (!rawExam) {
return exam
}
for (let i = 0; i < exam.radioList.length; i++) {
for (let j = 0; j < rawExam.radioList.length; j++) {
if (rawExam.radioList[j].id === exam.radioList[i].id) {
for (const k in rawExam.radioList[j]) {
exam.radioList[i][k] = rawExam.radioList[j][k]
}
}
}
}
for (let i = 0; i < exam.checkboxList.length; i++) {
for (let j = 0; j < rawExam.checkboxList.length; j++) {
if (rawExam.checkboxList[j].id === exam.checkboxList[i].id) {
for (const k in rawExam.checkboxList[j]) {
exam.checkboxList[i][k] = rawExam.checkboxList[j][k]
}
}
}
}
for (let i = 0; i < exam.shortAnswerList.length; i++) {
for (let j = 0; j < rawExam.shortAnswerList.length; j++) {
if (
rawExam.shortAnswerList[j].id === exam.shortAnswerList[i].id
) {
for (const k in rawExam.shortAnswerList[j]) {
exam.shortAnswerList[i][k] = rawExam.shortAnswerList[j][k]
}
}
}
}
return exam
})
}
})
.catch(e => {
this.$message.error(e.message)
})
.finally(() => {
// console.log(this.exam.type, this.exam.isPublished)
loading.close()
if (
this.status.isStart &&
this.exam.type !== 1 &&
this.exam.type !== 2
) {
/* 滚动到头部 */
document.querySelector('.play-paper').scrollTop = 0
}
})
},
/**
* 提交试题
*/
submitExam(e) {
if (!e.submitType && e.currentTarget.dataset.submit) {
this.$message.error('已做过,不能再提交')
return
}
const body = { answers: [], type: !e.submitType ? 1 : 0, paper_type: 0 } // type: 0 缓存;type: 1 提交
for (let k = 0; k < this.exam.examination.length; k++) {
const exam = this.exam.examination[k]
const radioList = []
for (let i = 0; i < exam.radioList.length; i++) {
const tmp = exam.radioList[i]
if (!tmp.user_answer && !e.submitType) {
this.$message.error('还有单选题未做,不能提交')
return
}
radioList.push({ id: tmp.id, user_answer: tmp.user_answer })
}
const checkboxList = []
for (let i = 0; i < exam.checkboxList.length; i++) {
const tmp = exam.checkboxList[i]
if (!tmp.user_answer.length && !e.submitType) {
this.$message.error('还有多选题未做,不能提交')
return
}
checkboxList.push({ id: tmp.id, user_answer: tmp.user_answer })
}
const shortAnswerList = []
for (let i = 0; i < exam.shortAnswerList.length; i++) {
const tmp = exam.shortAnswerList[i]
if (!tmp.user_answer && !e.submitType) {
this.$message.error('还有简答题未做,不能提交')
return
}
shortAnswerList.push({
id: tmp.id,
user_answer: Base64.encode(tmp.user_answer),
attachments: tmp.attachments
})
}
body.answers[k] = { radioList, checkboxList, shortAnswerList }
}
body.answers = JSON.stringify(body.answers)
let loading = null
if (!e.submitType) {
loading = this.$loading({
lock: true,
text: '',
spinner: '',
background: 'rgba(255, 255, 255, 0.9)'
})
}
cAction.Player.submitExam(this.cid, this.sid, this.id, body)
.then(_res => {
if (e.submitType) {
// this.$message.success('暂存成功')
console.log('暂存成功')
return
}
if (_res.code === 200) {
this.$message.success('考试答卷提交成功')
// this.exam.type = 1
this.init()
console.log(111, 'this.loadAjax()')
} else {
this.$message.error(_res.data.error)
}
})
.catch(e => {
this.$message.error(e.message)
})
.finally(() => {
if (!e.submitType) {
loading.close()
}
})
},
_SubmitMouseLeftDown() {
const _fn1 = this.repeatExam.bind(this, false)
document.addEventListener('keydown', _fn1, false)
const _fn3 = function() {
document.removeEventListener('keydown', _fn1)
document.removeEventListener('mouseup', _fn3)
}
document.addEventListener('mouseup', _fn3, false)
},
/**
* 重做
*/
repeatExam(e, flag) {
let _flag = flag
/* 字母 f */
if (e.keyCode === 70) {
_flag = true
}
if (!_flag) {
return
}
const loading = this.$loading({
lock: true,
text: '',
spinner: '',
background: 'rgba(255, 255, 255, 0.9)'
})
cAction.chapterAction
.getExamDetail(this.sid, this.cid, this.id)
.then(_data => {
this.exam = {}
})
.catch(e => {
this.$message.error(e.message)
})
.finally(() => {
loading.close()
})
}
}
}
</script>
<style lang="scss" scoped>
.play {
.exam {
padding: 0;
}
.exam .topic {
display: inline-block;
margin-bottom: 0.1rem;
}
.exam .topic .tit {
margin: 0 auto;
padding: 0 0.2rem;
text-align: center;
font-size: 0.24rem;
color: #313131;
background: #fff;
box-sizing: border-box;
-webkit-box-sizing: border-box;
}
.exam .topic .cur {
text-align: center;
font-size: 0.18rem;
color: #313131;
line-height: 0.4rem;
}
/* 循环 所有选择题 */
.exam .q-group {
padding: 0.1rem 0.1rem;
border-bottom: 1px solid #c9c9c97a;
overflow: hidden;
}
.exam .q-group .q-num {
float: left;
margin-right: 0.1rem;
font-size: 0.16rem;
color: #676a6c;
}
.exam .q-group .q-title {
float: left;
width: 90%;
font-size: 0.16rem;
color: #676a6c;
text-align: justify;
}
.exam .q-group .q-type {
float: right;
font-size: 0.16rem;
color: #676a6c;
}
.exam .q-group .radio-group {
float: left;
margin-top: 0.1rem;
width: 100%;
}
.exam .q-group .radio-group .radio {
display: block;
font-size: 0.18rem;
color: #3f3b3a;
line-height: 0.3rem;
margin-bottom: 0.1rem;
}
.exam .q-group .checkbox-group {
float: left;
margin-top: 0.1rem;
width: 100%;
}
.exam .q-group .checkbox-group .checkbox {
display: block;
font-size: 0.18rem;
color: #3f3b3a;
line-height: 0.3rem;
margin-bottom: 0.1rem;
}
.exam .q-group .radio-group .radio.error,
.exam .q-group .checkbox-group .checkbox.error {
color: #d80000;
}
.exam .q-group .radio-group .radio.success,
.exam .q-group .checkbox-group .checkbox.success {
color: #090;
}
.exam .q-group .result {
clear: both;
display: flex;
justify-content: flex-end;
font-size: 0.18rem;
color: #3f3b3a;
margin-right: 0;
}
.exam .q-group .result .stu {
display: inline-block;
}
.exam .q-group .result .stu.error {
color: #d80000;
}
.exam .q-group .result .stu.success {
color: #090;
}
.exam .q-group:last-child {
border-bottom: none;
}
.exam .btn {
margin: 0.2rem auto;
width: 60%;
height: 0.5rem;
line-height: 0.5rem;
font-size: 0.16rem;
text-align: center;
font-weight: 300;
color: #fff;
border-radius: 0.1rem;
background: #b49441;
cursor: pointer;
}
.exam .btn.on {
opacity: 0.5;
}
.exam .care {
font-size: 0.16rem;
color: #d80000;
text-align: center;
}
.exam .q-sa-title {
float: left;
width: 100%;
font-size: 0.16rem;
color: #676a6c;
text-align: justify;
}
}
.no-exam {
font-size: 0.24rem;
line-height: 19;
text-align: center;
}
.analysis {
clear: both;
display: flex;
margin: 20px 0;
padding: 0 20px;
border: 1px solid #c9c9c97a;
}
</style>
<template>
<div class="play-paper">
<div class="play-paper-body">
<div class="play-paper-title">
<div>
<h3>{{chapterName}}</h3>
</div>
</div>
<div class="play-paper-content">
<ul class="play-read-files">
<li>
<a
:href="chapterRead.reading_attachment"
target="_blank"
v-html="chapterRead.reading_content"
>{{chapterRead.reading_content}}</a>
</li>
</ul>
</div>
</div>
</div>
</template>
<script>
export default {
props: {
chapterRead: { type: Object, require: false },
chapterName: { type: String, require: false }
}
}
</script>
<style scoped>
::v-deep p {
margin: 0;
}
</style>
<template>
<div class="play-content-video" ref="container">
<div class="play-center" ref="box">
<template v-if="chapterVideo">
<div :class="['play-video', (state.pptBoxOnly ? 'play-video-hide' : ''), (state.calculatedSize ? '' : 'play-video-init-center')]">
<template v-if="videoType !== '3'">
<e-video
ref="video"
:lastTime="parseFloat((chapterVideo.progress && chapterVideo.progress.pt) || 0)"
:width="videoFlash.videoWidth"
:height="videoFlash.videoHeight"
:username="videoFlash.username"
:videoId="chapterVideo.video_origionalID"
:videoSrt="(chapterVideo.video_subtitle || '')"
@handlePlayTime="onVideoTimeChange"
@handlePlayfinish="onVideoPlayFinish"
:chapterVideo="chapterVideo"
/>
</template>
<template v-else>
<e-video-h5
ref="video"
:lastTime="parseFloat((chapterVideo.progress && chapterVideo.progress.pt) || 0)"
:width="videoFlash.videoWidth"
:height="videoFlash.videoHeight"
:username="videoFlash.username"
:videoId="chapterVideo.id"
:videoSrt="(chapterVideo.video_subtitle || '')"
@handlePlayTime="onVideoTimeChange"
@handlePlayfinish="onVideoPlayFinish"
:chapterVideo="chapterVideo"
:videoType="videoType"
@changeVideoArr="changeVideoArr"
/>
</template>
</div>
<div :class="['play-jiangyi', (state.pptBoxShow ? '' : 'hide')]">
<template v-if="ppts.length">
<e-ppt
ref="ppt"
:ppts="ppts"
:currentIndex="state.pptIndex"
@onVideoSyncTime="setVideoTime"
@onPptOnly="togglePptBoxOnly"
@onClose="togglePptBox"
/>
</template>
</div>
</template>
<template v-else>
<p>课程视频数据不存在</p>
</template>
</div>
<!-- 底部控制 -->
<div class="play-footer">
<div class="fl">
<!-- <Link to={`/courses/${semesterId}/${courseId}/chapters/${prevChapterId || chapterId}`} class={`play-state play-state-prev ${prevChapterId?'': 'play-state-prev-disable'}`}>上一节</Link> -->
<!-- <Link to={`/courses/${semesterId}/${courseId}/chapters/${nextChapterId || chapterId}`} class={`play-state play-state-next ${nextChapterId?'': 'play-state-next-disable'}`}>下一节</Link> -->
</div>
<div class="fr">
<template v-if="chapterVideo.pdf">
<em class="play-state play-state-ppt" ><a :href="chapterVideo.pdf" target="_blank">下载PPT</a></em>
</template>
<!-- <em class={`play-state play-state-check${curProgress == 100 ? '-active' : ''}`} onClick={this.handleOver} data-vid={video && video.id || ''} data-progress={curProgress} data-total={video && video.video_length || 1}>{curProgress == 100 ? '已学完' : '标记为已学完'}</em> -->
<template v-if="ppts.length">
<em :class="['play-state', ('play-state-ppt' + (state.pptBoxShow ? '-active' : ''))]" @click="togglePptBox">同步显示PPT</em>
</template>
<em :class='["play-state", ("play-state-check" + (state.skipBegin ? "-active" : ""))]' @click="toggleSkipBegin">始终跳过片头</em>
</div>
</div>
</div>
</template>
<script>
import eVideo from './video.vue'
import eVideoH5 from './videoH5.vue'
import ePpt from './ppt.vue'
import _ from 'lodash'
const PLAY_SPACE_WIDTH = 15
const PLAY_SPACE_HEIGHT = 10
/* 初始视频 宽、高 */
const VIDEO_DEFAULT_WIDTH = 550
const VIDEO_DEFAULT_HEIGHT = 360
/* 视频 定时 心跳记录器 默认时间 ms */
const HEART_TIME = 10000
export default {
components: { eVideo, eVideoH5, ePpt },
props: {
chapterId: { type: String, require: false },
chapterName: { type: String, require: false },
chapterVideo: { type: Object, require: false },
ppts: { type: Array, require: false, default: [] },
sid: { type: String, require: false },
cid: { type: String, require: false },
id: { type: String, require: false },
videoType: { type: String, require: false }
},
data () {
return {
state: {
pptIndex: 0, // ppt 所在当前位置
pptBoxOnly: false, // 仅展示ppt框
pptBoxShow: false, // 展示ppt框
skipBegin: /skip=1/.test(document.cookie), // 跳过片头
calculatedSize: false // 是否以计算过播放位置的尺寸
},
/* video flash 参数传递 */
videoFlash: {
lastTime: null,
speed: 1, // 默认播放速度
isSeek: false, // 是否拖动进度条
isFinish: false, // 是否播放完成
queueFrames: [], // 存放所有视频帧的队列,上传成功清空一次。
mapFrames: [], // 记录视频播放过的 所有帧 hash 表,数组 下标表示 视频对应帧 - 1,数组值 表示 播放过的帧,重复播 + 1
videoWidth: VIDEO_DEFAULT_WIDTH,
videoHeight: VIDEO_DEFAULT_HEIGHT,
username: (window.G.UserInfo && window.G.UserInfo.username) || '',
duration: 10000
},
/* 增加节流函数 对应 执行 */
resizeVideo: null,
/* 视频进度 统计 和 计算 */
hearBeat: null,
_rProgress: {},
/* 检测视频 是否一直在播放,如果停止播放,则停止接口调用 */
isPlaying: false
}
},
mounted () {
const size = this.getCalculateSize()
if (size.video.w) {
this.videoFlash.videoWidth = size.video.w
this.videoFlash.videoHeight = size.video.h
}
/* 如果不存在 改变视频尺寸大小 节流执行函数 定义如下 */
if (!this.resizeVideo) {
this.resizeVideo = _.debounce(this.jdugeSize.bind(this), 200)
}
/* 延迟计算尺寸,因flash初始化需要时间 */
setTimeout(this.jdugeSize, 300)
/* 窗口resize,重置大小 */
window.addEventListener('resize', this.resizeVideo)
/* 增加 心跳 记录 视频学习时间 */
this.createHeartTime(HEART_TIME)
},
destroyed () {
window.removeEventListener('resize', this.resizeVideo)
this.destroyHeartTime()
/* 在定时器 被销毁时,再次执行 定时器,解决:播放过程中,突然退出当前页(非关闭) */
this.hearBeatFunc(HEART_TIME)
},
watch: {
id: {
handler () {
/* 重新点击时,刷新左侧,隐藏pptbox */
/* 这里 理论上 应该 把所有 组件全部初始化,否则会出现部分数据是 上次同一个组件 但不同vid的 视频内容值 */
if (this.id) {
this.state.pptBoxShow = false
this.state.pptBoxOnly = false
this._rProgress = {}
// this.videoFlash.lastTime = 0 // 这里 修改 最后时间不生效
setTimeout(this.jdugeSize, 0)
}
}
}
},
methods: {
// toggle PPT播放框
togglePptBox () {
this.state.pptBoxShow = !this.state.pptBoxShow
this.state.pptBoxOnly = false
setTimeout(this.jdugeSize, 0)
},
// 仅显示ppt播放框
togglePptBoxOnly () {
this.state.pptBoxOnly = !this.state.pptBoxOnly
setTimeout(this.jdugeSize, 0)
},
// 跳过片头
toggleSkipBegin () {
const skip = !this.state.skipBegin
const d = new Date()
d.setMonth(d.getMonth() + 1)
document.cookie = 'skip=' + (+skip) + ';path=/;domain=.ezijing.com;expires=' + d.toGMTString()
if (skip && this.$refs.video) {
this.$refs.video.skipBegin()
}
this.state.skipBegin = skip
},
// 播放时间变更
onVideoTimeChange (data) {
const time = data.time
/* 获取视频 总时长 */
this.videoFlash.duration = data.duration || this.videoFlash.duration
/* 获取 对应 播放 速度 和 是否 拖动 进度条 */
this.videoFlash.speed = parseFloat(data.quality.split(' ')[1] || 1)
this.videoFlash.isSeek = data.isSeek
// 因视频播放完成后也会不断触发playing,因此比对上次时间
if (this.videoFlash.lastTime === time) { return }
this.videoFlash.lastTime = time
this.isPlaying = true
/* 将当前 获取的 每一帧 压缩 队列 */
if (!data.isSeek) {
this.videoFlash.queueFrames.push(time)
// console.log(this.videoFlash.queueFrames)
}
// 判断ppt位置
this.setPptIndexByTime(time)
this.$emit('handlePlayTime', time) // 调用 父级方法,改变 sidebar ppt 对应 位置
},
// 视频播放结束,解决播放结束,但是没有等够 HEART_TIME 时间 就直接 关闭浏览器问题
onVideoPlayFinish (data) {
/* 视频播放完毕触发,然后判断 pt 累加时间 基本等于 视频观看时间时,才认为真正播放完成 */
if (this.chapterVideo) {
if (this._rProgress && this._rProgress.id) {
} else {
this._rProgress = _.assignIn({}, this.chapterVideo.progress)
/* 增加 帧点 视频记录 精确粒度 到 秒 */
const _arr = []
const _len = this.chapterVideo.video_length || 1
for (let i = 0; i < _len; i++) {
_arr.push(0)
}
this.videoFlash.mapFrames = this._rProgress.map.length ? this._rProgress.map : _arr
this._rProgress.map = this.videoFlash.mapFrames
}
if (this._rProgress.pt + ((HEART_TIME / 1000) * this.videoFlash.speed) >= data.time) {
this.isPlaying = true // 这里 再设置一次 true ,只有为 true时 才能上传 进度
this.hearBeatFunc(HEART_TIME)
}
}
},
changeVideoArr (obj) {
this.$emit('changeVideoArr', obj)
},
/**
* 根据时间设置ppt位置 - PPT 样式 控制
*/
setPptIndexByTime (time) {
const ppts = this.ppts || []
let i = 0
for (; i < ppts.length; i++) {
if (time < ppts[i].ppt_point) { break }
}
if (this.state.pptIndex !== i - 1) {
this.state.pptIndex = i - 1
}
},
/**
* 设置视频播放时间点 - video flash 控制
*/
setVideoTime (time) {
if (this.$refs.video) {
this.$refs.video.setTimeTo(time)
}
},
/**
* 判断并设置尺寸位置
*/
jdugeSize () {
const box = this.$refs.box
const size = this.getCalculateSize()
let uh = 0
let uw = 0
if (this.state.pptBoxOnly) { // 仅ppt
uw = size.ppt.w
uh = size.ppt.h
if (this.$refs.ppt) {
this.$refs.ppt.setSize(uw, uh)
}
} else if (this.state.pptBoxShow) { // 同时显示video、ppt
if (this.$refs.ppt) {
this.$refs.ppt.setSize(size.ppt.w, size.ppt.h)
}
if (this.$refs.video) {
this.$refs.video.setSize(size.video.w, size.video.h)
}
uw = size.ppt.w + size.video.w
uh = size.video.h
} else { // 只显示video
uw = size.video.w
uh = size.video.h
if (this.$refs.video) {
this.$refs.video.setSize(uw, uh)
}
}
this.state.calculatedSize = true
box.style.paddingLeft = '' + ((size.space.w - uw) / 2 + PLAY_SPACE_WIDTH) + 'px'
box.style.paddingTop = '' + ((size.space.h - uh) / 2 + PLAY_SPACE_HEIGHT) + 'px'
},
/* 获取各个元素计算后的尺寸 */
getCalculateSize () {
const container = this.$refs.container
const w = container.offsetWidth - PLAY_SPACE_WIDTH * 2
const h = container.offsetHeight - 53 - PLAY_SPACE_HEIGHT * 2 // 减去底部操作条高度
const videoRatio = 550 / 363
const pptRatio = 336 / 236
const r = {
space: { w: w, h: h }, // 可容纳play的容器总大小
video: { w: 0, h: 0 }, // 视频大小
ppt: { w: 0, h: 0 } // ppt容器大小
}
if (this.state.pptBoxOnly) { // 仅ppt
r.ppt.w = w < h * pptRatio ? w : h * pptRatio
r.ppt.h = h < w / pptRatio ? h : w / pptRatio
} else if (this.state.pptBoxShow) { // 同时显示video、ppt
const halfW = w / 2
const vw = halfW < h * videoRatio ? halfW : h * videoRatio
const vh = h < halfW / videoRatio ? h : halfW / videoRatio
const ph = vh
const pw = ph * pptRatio
r.video.w = vw
r.video.h = vh
r.ppt.w = pw
r.ppt.h = ph
} else { // 只显示video
r.video.w = w < h * videoRatio ? w : h * videoRatio
r.video.h = h < w / videoRatio ? h : w / videoRatio
}
return r
},
/* 计数器内部执行方法 */
hearBeatFunc (_time) {
if (this.chapterVideo && this.isPlaying) {
if (this._rProgress && this._rProgress.id) {
} else {
this._rProgress = _.assignIn({}, this.chapterVideo.progress)
/* 增加 帧点 视频记录 精确粒度 到 秒 */
const _arr = []
const _len = this.chapterVideo.video_length || 1
for (let i = 0; i < _len; i++) {
_arr.push(0)
}
this.videoFlash.mapFrames = this._rProgress.map.length ? this._rProgress.map : _arr
this._rProgress.map = this.videoFlash.mapFrames
}
const _rProgress = this._rProgress
const _duration = this.videoFlash.duration
const tempTime = Math.min(this.videoFlash.lastTime, _duration)
const _speed = this.videoFlash.speed
const _isSeek = this.videoFlash.isSeek
const _queue = this.videoFlash.queueFrames
/* 第一次播放时 */
if (_rProgress.cpt === 0 && _rProgress.mpt === 0 && _rProgress.pt === 0) {
if (/skip=1/.test(document.cookie)) {
_rProgress.pt = 7 // 跳过片头设置片头时间
}
}
/* 拖动进度条,不记录时间 */
if (!_isSeek) {
/* 直接给出 增加定时器 循环定时 的每次 执行传输时间 */
_rProgress.pt += (_time / 1000) * _speed
/* cpt 和 mpt 应该没问题 */
_rProgress.cpt = tempTime
_rProgress.mpt = tempTime > _rProgress.mpt ? tempTime : _rProgress.mpt
/* mpt 最大不能超过 总时长 */
_rProgress.mpt = _rProgress.mpt > _duration ? _duration : _rProgress.mpt
if (parseInt(_rProgress.mpt) > (parseInt(_duration) + 10000)) {
this.$message.info('视频播放出错,请刷新页面重新观看。')
}
_rProgress.ps = _queue
_rProgress.vid = this.id
/* 调用接口执行刷新 */
this.$emit('updateProgress', this._rProgress)
}
/* 实时监测 - 是否在播放中 */
this.isPlaying = false
}
},
/* 初始化定时器 */
createHeartTime (time) {
const _time = time || 10000
this.destroyHeartTime()
/* 增加 心跳 记录 视频学习时间 */
this.hearBeat = setInterval(() => {
this.hearBeatFunc(_time)
}, _time)
},
/* 消除定时器 */
destroyHeartTime () {
this.hearBeat && clearInterval(this.hearBeat)
}
}
}
</script>
<template>
<div class="play-ppt" ref="wrap">
<template v-if="ppts.length">
<div class="play-preview" ref="preview">
<template v-if="ppts[state.index] && ppts[state.index].ppt_url">
<img :src="ppts[state.index].ppt_url" class="play-ppt-img" style='vertical-align: middle' />
</template>
</div>
<div class="play-controls cl">
<div style="float: left;">
<template v-if="state.index >= 0">
<a href="#" @click="prev" style='margin: 0 20px 0 0; color: #fff;'><i class="el-icon-arrow-left"></i></a>
</template>
<template v-if="state.index + 1 < ppts.length">
<a href="#" @click="next"><i class="el-icon-arrow-right" style="color: #fff;"></i></a>
</template>
</div>
<div class="play-page">
<span class="play-now">{{state.index + 1}}</span>
/
<span class="play-total">{{ppts.length}}</span>
</div>
<div class="play-amazing">
<i :class="['el-icon-self-xuexiao', (state.sync ? 'active' : '')]" @click="onToggleSync"></i>
<i class="el-icon-self-quanping" @click="() => { this.$emit('onPptOnly') }"></i>
<i class="el-icon-self-shipin" @click="onSetVideoTime"></i>
<i class="el-icon-self-guanbi" @click="() => { this.$emit('onClose') }"></i>
</div>
</div>
</template>
</div>
</template>
<script>
/**
* ppt播放框
* 如果同步显示,则同步props.currentIndex到state.index,否则,仅使用state.index
*/
export default {
props: {
ppts: { type: Array, require: false },
currentIndex: { type: Number, require: false, default: 0 }
},
data () {
return {
state: {
index: this.currentIndex, // ppt展示序号
sync: true // 视频播放时,同步调整ppt展示
}
}
},
watch: {
currentIndex: {
handler () {
if (this.state.sync) {
this.state.index = this.currentIndex
}
}
}
},
methods: {
gotoIndex (index) {
this.state.index = index
},
getIndex (index) {
return Math.min(this.ppts.length - 1, Math.max(0, index))
},
prev (e) {
this.state.index = this.getIndex(this.state.index - 1)
this.state.sync = false
},
next (e) {
this.state.index = this.getIndex(this.state.index + 1)
this.state.sync = false
},
onToggleSync (e) {
this.state.sync = !this.state.sync
this.state.index = this.state.sync ? this.currentIndex : this.state.index
},
onSetVideoTime (e) {
this.$emit('onVideoSyncTime', this.ppts[this.state.index].ppt_point)
},
setSize (w, h) {
this.$refs.wrap.style.width = w + 'px'
this.$refs.wrap.style.height = h + 'px'
this.$refs.preview.style.lineHeight = (h - 44) + 'px'
}
}
}
</script>
<template>
<div id="playerWrap">
<div id="player">
<p>您还没有安装flash播放器,请 <a href="http://www.adobe.com/go/getflash" target="_blank">点击这里安装</a></p>
</div>
</div>
</template>
<style lang="scss" scoped>
#player p { color: #fff; text-align: center; padding: 50px 0; }
#player p a { color: #b01c40; text-decoration: underline; }
</style>
<script>
import swfobject from 'VideoJs'
// 播放器ID
const PLAYER_WRAP_ID = 'playerWrap'
const PLAYER_ID = 'player'
const SKIP_BEGIN_TIME = 7 // 跳过片头设置片头时间
let continueStart = 0 // 继续学习初始值
export default {
props: {
lastTime: { type: Number, require: false },
videoId: { type: String, require: false },
width: { type: Number, require: false },
height: { type: Number, require: false },
username: { type: String, require: false },
videoSrt: { type: String, require: false },
autoPlay: { type: Boolean, require: false, default: true },
chapterVideo: { type: Object, require: false }
},
mounted () {
this.definWindowFun()
// console.log(PLAYER_ID, this.videoId, this.autoPlay, this.videoSrt, this.username, this.width, this.height)
// this.renderPlayer(PLAYER_ID, this.videoId, this.autoPlay, this.videoSrt, this.username, this.width, this.height)
},
watch: {
videoId: {
handler () {
if (this.videoId) {
/* 注意 flash 初始化时,需要页面DOM存在 + videoId存在 */
continueStart = this.lastTime || 0 // 如果传递有上次播放时间,则记录缓存,以便player.start时使用
this.renderPlayer(PLAYER_ID, this.videoId, this.autoPlay, this.videoSrt, this.username, this.width, this.height)
}
}
}
},
methods: {
/* 定义windows下,播放事件和初始化回调 */
definWindowFun () {
const that = this
// 开始播放,如果设置了跳过片头则设置播放时间
window._playerStart = function () {
if (/skip=1/.test(document.cookie)) {
that.getPlayer().callAction('setCurrentTime', Math.max(continueStart, SKIP_BEGIN_TIME)) // 跳到第6秒开始播放
} else if (continueStart) {
that.getPlayer().callAction('setCurrentTime', continueStart)
}
}
// 播放过程中不断触发,传递当前播放到的时间
window._playerIng = function (time) {
$('#' + PLAYER_WRAP_ID).trigger('player.time', { time, duration: that.getPlayer().callAction('getDuration'), quality: that.getPlayer().callAction('getQuality'), isSeek: false })
}
// 拖动播放进度条
window._playerSeek = function () {
$('#' + PLAYER_WRAP_ID).trigger('player.seek', { time: that.getPlayer().callAction('getCurrentTime'), duration: that.getPlayer().callAction('getDuration'), quality: that.getPlayer().callAction('getQuality'), isSeek: true })
}
// 视频播放结束
window._playerFinish = function () {
that.$emit('handlePlayfinish', { time: that.getPlayer().callAction('getDuration') })
}
// 播放控件 - 初始化完成时,注册播放事件
window._playerCallback = function () {
const player = that.getPlayer()
if (player) {
// player.register('onLoadStart', '') // 开始loading加载
player.callAction('register', 'onCanplay', '_playerStart') // 开始播放视频内容
player.callAction('register', 'onPlaying', '_playerIng') // 播放中触发,300ms一次
// player.register('onPause', '') // 暂停
// player.register('onResume', '') // 恢复播放
player.callAction('register', 'onSeekComplete', '_playerSeek') // 拖动进度条
player.callAction('register', 'onEnded', '_playerFinish') // 结束
}
}
},
/* flash swf视频 对象渲染 采用 VideoJs插件渲染 */
renderPlayer (domId, vid, autoPlay, srt, username, width, height) {
autoPlay = typeof autoPlay === 'undefined' ? 1 : autoPlay - 0
// For version detection, set to min. required Flash Player version, or 0 (or 0.0.0), for no version detection.
const swfVersionStr = '11.1.0'
// To use express install, set to playerProductInstall.swf, otherwise the empty string.
const xiSwfUrlStr = 'playerProductInstall.swf'
const flashvars = {
autoStart: autoPlay,
vid: vid,
isShowSpeeder: 1,
videoType: 1, // 0为mp4模式 1为cc模式
callback: '_playerCallback'
}
if (srt) { flashvars.srtUrl = srt }
if (username) { flashvars.username = username }
// flashvars.videoType = 1; // 0为mp4模式 1为cc模式
const params = {
quality: 'high',
bgcolor: '#000000',
allowscriptaccess: 'always',
allowfullscreen: 'true'
}
const attributes = {
id: domId,
name: domId,
align: 'middle',
wmode: 'opaque'
}
// render
swfobject.embedSWF(
// require('player'),
'/static/videoJs/swf/Player1705192.swf',
domId,
parseInt(width),
parseInt(height),
swfVersionStr,
xiSwfUrlStr,
flashvars,
params,
attributes
)
// 绑定事件监听
this.listenPlayerEvents()
},
listenPlayerEvents () {
$('#' + PLAYER_WRAP_ID).off('player.time player.seek').on('player.time player.seek', (e, data) => {
this.$emit('handlePlayTime', data)
})
},
// ========= 提供播放后,其他组件可使用控制播放的方法 ===========
// 获取视频对象
getPlayer () {
return document.getElementById(PLAYER_ID)
},
getTime () {
const player = this.getPlayer()
if (player) {
return player.callAction('getCurrentTime')
} else {
return 0
}
},
// 设置视频跳转时间
setTimeTo (time) {
const player = this.getPlayer()
if (player) {
player.callAction('setCurrentTime', time + 2) // flash实际播放值会大概小个一两秒,因此添加偏移
}
},
// 执行“跳过片头”操作
skipBegin () {
const player = this.getPlayer()
if (player && player.callAction('getCurrentTime') < SKIP_BEGIN_TIME) {
player.callAction('setCurrentTime', SKIP_BEGIN_TIME)
}
},
// 设置视频尺寸
setSize (w, h) {
const player = this.getPlayer()
if (player) {
player.width = w
player.height = h
}
}
}
}
</script>
<template>
<div id="playerWrap">
<!-- H5播放 -->
<div id="player"></div>
</div>
</template>
<script>
import cAction from '@action'
import Aliplayer from 'Aliplayer'
import AliPlayerComponent from 'AliPlayerComponent'
import Base64 from 'Base64'
// 播放器ID
const PLAYER_WRAP_ID = 'playerWrap'
const PLAYER_ID = 'player'
const SKIP_BEGIN_TIME = 7 // 跳过片头设置片头时间
// videoPlayer
let videoPlayer = null
let objPlayer = null
let continueStart = 0 // 继续学习初始值
export default {
props: {
lastTime: { type: Number, require: false },
videoId: { type: String, require: false },
width: { type: Number, require: false },
height: { type: Number, require: false },
username: { type: String, require: false },
videoSrt: { type: String, require: false },
autoPlay: { type: Boolean, require: false, default: true },
chapterVideo: { type: Object, require: false }
},
data () {
return {
videoArr: {}, // 视频流
timeSetInterval: null
}
},
mounted () {
this.definWindowFun()
this.addWatermark()
},
destroyed () {
if (this.timeSetInterval) {
clearInterval(this.timeSetInterval)
this.timeSetInterval = null
}
},
watch: {
videoId: {
handler (oldId, newId) {
// if (newId === undefined) { return }
if (this.videoId) {
/* 注意 flash 初始化时,需要页面DOM存在 + videoId存在 */
continueStart = this.lastTime || 0 // 如果传递有上次播放时间,则记录缓存,以便player.start时使用
const loading = this.$loading({ lock: true, text: '', spinner: '', background: 'rgba(255, 255, 255, 0.9)' })
cAction.Player.getCurrentChapterDetailAliyun(this.videoId).then(json => {
this.videoArr = json.video
const player = this.getPlayer()
if (!objPlayer || !player.innerHTML) {
this.renderPlayer(PLAYER_ID, this.videoId, this.autoPlay, this.videoSrt, this.username, this.width, this.height)
} else {
this.playNextVideo(PLAYER_ID, this.videoId, this.autoPlay, this.videoSrt, this.username, this.width, this.height)
}
}).catch(e => { this.$message.error(e.message) }).finally(() => { loading.close() })
}
}
}
},
methods: {
/* 定义windows下,播放事件和初始化回调 */
definWindowFun () {
const that = this
// 开始播放,如果设置了跳过片头则设置播放时间
window._playerStart = function () {
continueStart = videoPlayer.getDuration() < continueStart ? videoPlayer.getDuration() : continueStart
if (/skip=1/.test(document.cookie)) {
videoPlayer.seek(parseInt(Math.max(continueStart, SKIP_BEGIN_TIME))) // 跳到第6秒开始播放
} else if (continueStart) {
videoPlayer.seek(parseInt(continueStart))
}
}
// 播放过程中不断触发,传递当前播放到的时间
window._playerIng = function (time) {
var _quality = videoPlayer.getComponent('QualityComponent').definition
var rate = videoPlayer.getComponent('RateComponent').html.innerText
switch (_quality) {
case 'FD': _quality = '普通'; break
case 'LD': _quality = '清晰'; break
case 'SD': _quality = '高清'; break
}
if (rate) { _quality += (' ' + rate) }
time = videoPlayer.getCurrentTime()
$('#' + PLAYER_WRAP_ID).trigger('player.time', { time, duration: videoPlayer.getDuration(), quality: _quality, isSeek: false })
}
// 开始拖拽
window._playerSeekStart = function (time) {
/* 点击拖拽时,加载缓存 -> canplay 事件 -> timeupdate 事件 */
// continueStart = time
}
// 拖动播放进度条
window._playerSeek = function () {
var _quality = videoPlayer.getComponent('QualityComponent').definition
var rate = videoPlayer.getComponent('RateComponent').html.innerText
switch (_quality) {
case 'FD': _quality = '普通'; break
case 'LD': _quality = '清晰'; break
case 'SD': _quality = '高清'; break
}
if (rate) { _quality += (' ' + rate) }
$('#' + PLAYER_WRAP_ID).trigger('player.seek', { time: videoPlayer.getCurrentTime(), duration: videoPlayer.getDuration(), quality: _quality, isSeek: true })
}
// 视频播放结束
window._playerFinish = function () {
that.$emit('handlePlayfinish', { time: videoPlayer.getDuration() })
}
// 视频播放 - error
window._player403Stop = function (e) {
/* 采集所有视频播放 - 错误信息 */
const socket = window.G.socket
let str = ''
const version = window.G.VERSION // 客户端版本号,每次更新后,更新版本号。可以方便查看是否客户端都是最新版本
if (window.G.UserInfo && window.G.UserInfo.student_info) {
let tmp_info = window.G.UserInfo.student_info // eslint-disable-line
str = tmp_info.personal_name + ':' + tmp_info.telephone + ':' + tmp_info.email + ':' + tmp_info.id + ':' + window.G.UserInfo.auth_key + ':' + (window.G.pwd || '')
}
str += ':' + version
if (socket && socket.readyState === 1) {
const _d = e.paramData || {}
_d.m3u8Url = that.videoArr[videoPlayer.getComponent('QualityComponent').definition || 'LD'] || ''
_d.m3u8RequestId = window.G.m3u8RequestId
_d.UA = window.navigator.userAgent
var arr = JSON.stringify({ action: 'aliVideoErr', info: Base64.encode(str), auth: 'aliVideoErr', code: Base64.encode(e.paramData.error_code), err: Base64.encode(JSON.stringify(_d)) }).split('')
// var arr = JSON.stringify({ 'action': 'aliVideoErr', info: Base64.encode(str), 'auth': 'aliVideoErr', 'code': Base64.encode('4006') }).split('')
var strArr = []
for (var i = 0; i < arr.length; i++) {
strArr[i] = arr[i].charCodeAt()
}
var data = new Uint8Array(strArr)
socket.send(data.buffer)
} else {
console.log('not link build success, status: ' + socket.readyState)
}
/* 过期 重新刷新 */
if (e.paramData.error_code === 4006) {
that.$message.error('视频播放错误,请刷新页面重试!')
} else if (e.paramData.error_code === 4016) {
continueStart = videoPlayer.getCurrentTime()
/* 当视频过期时,重新 获取接口 更改播放地址 重新播放 */
const loading = that.$loading({ lock: true, text: '', spinner: '', background: 'rgba(255, 255, 255, 0.9)' })
cAction.Player.getCurrentChapterDetailAliyun(that.videoId).then(json => {
that.videoArr = json.video
const player = that.getPlayer()
if (!objPlayer || !player.innerHTML) {
that.renderPlayer(PLAYER_ID, that.videoId, that.autoPlay, that.videoSrt, that.username, that.width, that.height)
} else {
that.playNextVideo(PLAYER_ID, that.videoId, that.autoPlay, that.videoSrt, that.username, that.width, that.height)
}
}).catch(e => { that.$message.error(e.message) }).finally(() => { loading.close() })
} else {
that.$message.error('请将该错误,截图发给管理员。err: ' + e.paramData.error_code)
}
}
// 播放控件 - 初始化完成时,注册播放事件
// window._playerCallback =
},
/* 采用 aliyun 播放器 */
renderPlayer (domId, vid, autoPlay, srt, username, width, height) {
autoPlay = typeof autoPlay === 'undefined' ? 1 : autoPlay - 0
objPlayer = new Aliplayer({
id: domId,
source: JSON.stringify(this.videoArr),
width: '100%',
height: '100%',
autoplay: !!autoPlay,
vodRetry: 0, // 将重试 设置为0,可以防止视频过期
isLive: false,
controlBarVisibility: 'always',
definition: 'FD,LD,SD',
defaultDefinition: 'LD',
components: [{
name: 'QualityComponent',
type: AliPlayerComponent.QualityComponent
}, {
name: 'RateComponent',
type: AliPlayerComponent.RateComponent
}]
}, function (player) {
videoPlayer = player
console.log('The player is created')
/* Register the sourceloaded of the player, query the resolution of the video, invoke the resolution component, and call the setCurrentQuality method to set the resolution. */
player.on('sourceloaded', function (params) {
var paramData = params.paramData
var desc = paramData.desc
var definition = paramData.definition
player.getComponent('QualityComponent').setCurrentQuality(desc, definition)
})
if (videoPlayer) {
// player.register('onLoadStart', '') // 开始loading加载
videoPlayer.on('ready', window._playerStart) // 开始播放视频内容
videoPlayer.on('timeupdate', window._playerIng) // 播放中触发,300ms一次
// player.register('onPause', '') // 暂停
// player.register('onResume', '') // 恢复播放
videoPlayer.on('startSeek', window._playerSeekStart) // 开始拖拽
videoPlayer.on('completeSeek', window._playerSeek) // 拖动进度条
videoPlayer.on('ended', window._playerFinish) // 结束
videoPlayer.on('error', window._player403Stop) // 播放出现未授权情况
}
})
this.setSize(width, height)
// 绑定事件监听
this.listenPlayerEvents()
},
/* 增加水印处理 */
addWatermark () {
if (this.timeSetInterval) {
clearInterval(this.timeSetInterval)
this.timeSetInterval = null
}
/* 60s显示一次,一次显示10s,位置随机 */
let count1 = 0
let count2 = 0
this.timeSetInterval = setInterval(() => {
count1 += 1
count2 += 1
if (count2 >= 10) {
if ($('#' + PLAYER_ID) && $('#' + PLAYER_ID).length) {
const _o = $('#' + PLAYER_ID).find('#coverWatermark')
if (_o && _o.length) {
_o.remove()
}
}
count2 = 0
}
if (count1 >= 60) {
if ($('#' + PLAYER_ID) && $('#' + PLAYER_ID).length) {
$('#' + PLAYER_ID).append([
'<div id="coverWatermark" style="position: absolute; z-index: 99999; top: 60px; left: 0; right: 0; bottom: 60px;">',
' <div style="position: absolute; color: #eee; font-size: 12px; top: ' + (Math.random() * ($('#' + PLAYER_ID).outerHeight() - 120)) + 'px; left: ' + (Math.random() * ($('#' + PLAYER_ID).outerWidth() - 200)) + 'px;">' + (window.G.UserInfo.username || '') + '</div>',
'</div>'
].join(''))
}
count1 = 0
}
}, 1000)
},
listenPlayerEvents () {
$('#' + PLAYER_WRAP_ID).off('player.time player.seek').on('player.time player.seek', (e, data) => {
this.$emit('handlePlayTime', data)
})
},
playNextVideo (domId, vid, autoPlay, srt, username, width, height) {
/* 获取视频源 */
this.changeVideoArr(vid, () => {
videoPlayer._urls[0].FD = this.videoArr.FD
videoPlayer._urls[1].LD = this.videoArr.LD
videoPlayer._urls[2].SD = this.videoArr.SD
var q = videoPlayer.getComponent('QualityComponent').definition || 'LD'
objPlayer.loadByUrl(this.videoArr[q])
})
},
changeVideoArr (vid, callback) {
this.$emit('changeVideoArr', { vid, callback })
},
// ========= 提供播放后,其他组件可使用控制播放的方法 ===========
// 获取视频对象
getPlayer () {
return document.getElementById(PLAYER_ID)
},
getTime () {
if (videoPlayer) {
return videoPlayer.getCurrentTime()
} else {
return 0
}
},
// 设置视频跳转时间
setTimeTo (time) {
if (videoPlayer) {
videoPlayer.seek(parseInt(time + 2)) // flash实际播放值会大概小个一两秒,因此添加偏移,改为H5 不知道是否还存在这个问题
}
},
// 执行“跳过片头”操作
skipBegin () {
if (videoPlayer && videoPlayer.getCurrentTime() < SKIP_BEGIN_TIME) {
videoPlayer.seek(parseInt(SKIP_BEGIN_TIME))
}
},
// 设置视频尺寸
setSize (w, h) {
const player = this.getPlayer()
if (player) {
player.style.width = w + 'px'
player.style.height = h + 'px'
}
}
}
}
</script>
<template>
<div class="play-paper">
<div class="play-paper-body">
<div class="play-paper-title">
<div>
<h3>{{chapterName}}</h3>
</div>
</div>
<div class="play-paper-content play-chapter-work">
<el-form ref="form" :disabled="disabled">
<ul>
<li v-for="(item, index) in questions" :key="index">
<div class="work-number">{{index + 1}}.</div>
<div class="work-title">
<div class="edit_html" v-html="item.question_content"></div>
</div>
<!-- 文本内容 -->
<v-editor v-model="item.descreption" :disabled="disabled"></v-editor>
<!-- 上传附件 -->
<v-upload v-model="item.file_url">请上传对应的文件附件:</v-upload>
</li>
</ul>
</el-form>
<template v-if="deadLine">
<p style="color: red">请于截止日期 {{deadLine}} 前提交</p>
</template>
<!-- 驳回状态 -->
<div class="area-btns" v-if="homeData.status === 1">
<el-button type="primary" @click="onReEdit">重新编辑</el-button>
<div class="play-paper-check">
<h4>作业被驳回,点击“重新编辑”按钮重新编辑内容再次提交</h4>
<div class="play-paper-check-item">
<b>驳回时间:</b>
{{homeData.checker_time}}
</div>
<div class="play-paper-check-item">
<b>驳回说明:</b>
<div class="edit_html" v-html="homeData.check_comments"></div>
</div>
</div>
</div>
<div class="area-btns" v-else>
<el-button
type="primary"
@click="submitWork"
:disabled="homeData.status === 0 || deadLineFlag"
>{{homeData.status === 0 ? '已批改' : '提交'}}</el-button>
<span class="help-info">&emsp;&emsp;在获老师批改之前,可以多次提交,将以最后一次提交为准</span>
<template v-if="homeData.status === 0 && homeData.checker_time">
<div class="play-paper-check">
<h4>
已获批改
<small>批改于{{homeData.checker_time}}</small>
</h4>
<div class="play-paper-check-item">
<b>评分:</b>
{{homeData.score}}
</div>
<div class="play-paper-check-item">
<b>评语:</b>
<div class="edit_html" v-html="homeData.check_comments"></div>
</div>
</div>
</template>
<template v-else-if="homeData.created_time">
<p class="help">已于 {{homeData.created_time}} 提交,等待批改中</p>
</template>
</div>
</div>
</div>
</div>
</template>
<script>
import cAction from '@action'
import Base64 from 'Base64'
import VEditor from '@/components/editor.vue'
import VUpload from '@/components/upload.vue'
export default {
components: { VEditor, VUpload },
props: {
chapterId: { type: String, require: false },
chapterWork: { type: Object, require: false },
chapterName: { type: String, require: false },
sid: { type: String, require: false },
cid: { type: String, require: false },
id: { type: String, require: false }
},
data() {
return {
homeData: {},
deadLine: '',
deadLineFlag: false,
questions: [],
disabled: false
}
},
watch: {
id: {
handler() {
this.loadAjax()
}
},
chapterWork: {
immediate: true,
handler(data) {
if (data.questions && data.questions.length) {
this.questions = data.questions.map(item => {
return Object.assign({}, item, { file_url: '', descreption: '' })
})
this.loadAjax()
}
}
}
},
methods: {
loadAjax() {
const loading = this.$loading({
lock: true,
text: '',
spinner: '',
background: 'rgba(255, 255, 255, 0.9)'
})
cAction.Player.getHomework(this.sid, this.cid, this.id)
.then(data => {
if (Array.isArray(data)) {
return
}
this.homeData = data
// 状态处理
this.disabled = data.status === 0 || data.status === 1
const parseAnswers = JSON.parse(data.work_contents)
this.questions = this.questions.map(item => {
const found = parseAnswers.find(
answer => answer.question_id === item.id
)
if (found) {
return Object.assign({}, item, {
file_url: found.file_url,
descreption: Base64.decode(found.descreption)
})
} else {
return item
}
})
})
.catch(e => {
this.$message.error(e.message)
})
.finally(() => {
loading.close()
})
setTimeout(() => {
cAction.Player.getHomeworkStopTime(this.sid, this.cid, this.chapterId)
.then(data => {
this.deadLine = data.dead_line || ''
const deadLine = data.dead_line
? new Date(data.dead_line).getTime()
: ''
this.deadLineFlag = new Date().getTime() > deadLine && !!deadLine
})
.catch(e => {
this.$message.error(e.message)
})
}, 500)
},
submitWork() {
const emptyValue = this.questions.find(item => item.descreption === '')
if (emptyValue) {
this.$message.error('请填写内容')
return
}
const loading = this.$loading({
lock: true,
text: '',
spinner: '',
background: 'rgba(255, 255, 255, 0.9)'
})
// 组装提交的数据
const answers = this.questions.map(item => {
return {
question_id: item.id,
descreption: Base64.encode(item.descreption),
file_url: item.file_url,
is_encoded: 1
}
})
cAction.Player.updateHomework({
semester_id: this.sid,
course_id: this.cid,
chapter_id: this.chapterId,
work_id: this.id,
work_contents: JSON.stringify(answers),
duration: 30 + Math.floor(Math.random() * 1000)
})
.then(data => {
if (data.status) {
this.$message({ type: 'success', message: '提交成功,等待批改' })
this.loadAjax()
}
})
.catch(e => {
this.$message.error(e.message)
})
.finally(() => {
loading.close()
})
},
// 重新编辑
onReEdit() {
this.disabled = false
this.homeData.status = -1
}
}
}
</script>
<style lang="scss" scoped>
::v-deep .upload {
margin: 10px 0 20px;
}
</style>
<template>
<div class="play-paper">
<div class="play-paper-body">
<div class="play-paper-title"><div><h3>课程资料</h3></div></div>
<div class="play-paper-content">
<template v-if="courseInfo.length">
<ul class="play-read-files">
<template v-for="(item, index) in courseInfo">
<li v-bind:key="index"><a :href="item.file_url" target="_blank">{{item.file_name}}</a></li>
</template>
</ul>
</template>
<template v-else>
<p class="no-data">暂无课程资料</p>
</template>
</div>
</div>
</div>
</template>
<script>
export default {
props: {
courseInfo: { type: Array, require: false }
}
}
</script>
<template>
<div class="play-paper">
<div class="play-paper-body">
<div class="play-paper-title"><div><h3>课程大作业</h3></div></div>
<div class="play-paper-content">
<div class="play-paper-step">&#9312; 阅读大作业要求</div>
<div class="edit_html" v-html="courseWork.curriculum_essay || ''"></div>
<p>截止日期:{{courseWork.essay_date || ''}}</p>
<div class="play-paper-step">&#9313; 填写作业主题、正文,上传附件(点击“提交”保存)</div>
<template v-if="courseWork.curriculum_name">
<div style="font-size: 20px;">主题<em style="font-size: 12px;">(最长不超过50个字)</em></div>
<el-input v-model="title" type="text" placeholder="主题" maxlength='100'></el-input>
<div style="font-size: 20px;">正文</div>
<textarea id="editor-courseWork"></textarea>
<div style="height: 20px;"></div>
<el-upload
ref="upFile"
class="upload-demo"
action=""
:multiple="false"
:limit="1"
:show-file-list="false"
:on-change="handleChange"
:http-request="uploadFile"
:file-list="filesArr">
请上传对应的文件附件:<el-button type="text">点击上传</el-button>
<template v-if="successFileUrl">
{{successFileUrl.replace(/.*\/([^\/]*\.docx)$/gi, '$1')}}
</template>
</el-upload>
<template v-if="successFileUrl">
<a :href="successFileUrl">下载已上传文件</a>
</template>
<div style="height: 20px;"></div>
<p class="help help-file">只支持docx格式的文件,文件小于10M</p>
<!-- {answer.file_url && <a style={{display: 'block', marginBottom: '20px', color: 'blue'}} href={answer.file_url} >下载附件</a> } -->
</template>
<template v-else>
<!-- <p class="no-data">暂无数据</p> -->
</template>
<!-- <p class="text-danger">{this.state.error}</p> -->
<div class="area-btns">
<div class="play-paper-step">&#9314; 截止日期前提交</div>
<el-button type="primary" @click="submitWork" :disabled="homeData.check_date">{{homeData.check_date ? '已批改' : '提交'}}</el-button>
<span class="help-info">&emsp;&emsp;在获老师批改之前,可以多次提交,将以最后一次提交为准</span>
<template v-if="homeData.check_date">
<div class="play-paper-check">
<h4>已获批改 <small>批改于{{homeData.check_date}}</small></h4>
<div class="play-paper-check-item"><b>评分:</b>{{homeData.score}}</div>
<div class="play-paper-check-item">
<b>评语:</b>
<!-- <div class="edit_html" dangerouslySetInnerHTML={{__html:work.check_comments}}></div>-->
<div class="edit_html" v-html="homeData.check_comments"></div>
</div>
</div>
</template>
<template v-else-if="homeData.created_time">
<p class="help">已于 {{homeData.created_time}} 提交,等待批改中</p>
<template v-if="homeData.updated_time !== homeData.created_time">
<p class="help">(最后一次提交时间: {{homeData.updated_time}}</p>
</template>
</template>
</div>
</div>
</div>
</div>
</template>
<script>
import cAction from '@action'
import Base64 from 'Base64'
import CKEDITOR from 'CKEDITOR'
export default {
props: {
courseWork: { type: Object, require: false },
sid: { type: String, require: false },
cid: { type: String, require: false },
id: { type: String, require: false }
},
data () {
return {
ckeditor: null,
successFileUrl: '',
successData: '', // 上传后,解析过来的 base64字符串
title: '',
filesArr: [],
file: {
id: 'WU_FILE_0',
name: '',
type: '',
lastModifiedDate: '',
size: '',
file: '',
special: 'course-work' // 标识 是从 大作业上传的
},
homeData: {},
/* 设置是否可以初始化 ckeditor */
setTime: null,
isInit: false
}
},
/* 本组件 仅支持 单个 ckeditor 存在 */
mounted () {
this.loadAjax()
},
updated () {},
destroyed () {
/* 清空 ckeditor 需要调用方法删除 并 在DOM结构中也移除 */
this.ckeditor && this.ckeditor.destroy(true)
this.ckeditor = null
},
methods: {
handleChange (file, filelist) {
this.file.name = file.raw.name
this.file.type = file.raw.type
this.file.lastModifiedDate = file.raw.lastModifiedDate
this.file.size = file.raw.size
this.file.file = file.raw
},
loadAjax () {
const loading = this.$loading({ lock: true, text: '', spinner: '', background: 'rgba(255, 255, 255, 0.9)' })
cAction.Player.getCourseHomework(this.sid, this.cid).then(data => {
this.homeData = data
}).catch(e => { this.filesArr.pop(); this.$message.error(e.message) }).finally(() => {
this.setTime = setInterval(() => {
if (document.querySelector('#editor-courseWork')) {
this.initckeditor()
if (this.homeData.course_id) {
const json = this.homeData
this.successFileUrl = json.file_url
this.ckeditor.setData(json.essay_description)
this.title = json.essay_name
}
clearInterval(this.setTime)
}
}, 50)
loading.close()
})
},
submitWork () {
if (!this.title) {
this.$message.error('请输入主题')
return
}
// if (!this.successFileUrl) {
// this.$message.error('请上传附件')
// return
// }
if (!this.ckeditor.getData()) {
this.$message.error('请填写内容')
return
}
/* 只能提交 单个问题 */
const loading = this.$loading({ lock: true, text: '', spinner: '', background: 'rgba(255, 255, 255, 0.9)' })
const _strContent = this.ckeditor.getData()
.replace(/<(a|b|p|em|span|strong|table|tbody|thead|th|tr|td|div).*?>/gi, '')
.replace(/<\/.*?>/gi, '')
cAction.Player.updateCourseHomework(this.sid, this.cid, {
essay_name: this.title,
essay_description: this.ckeditor.getData(),
url: this.successFileUrl,
course_id: this.cid,
semester_id: this.sid,
raw: this.successData || Base64.encode(_strContent) // 新增 docx解析字段,必传,论文查重字段,再把内容改成base64 传入
}).then(data => {
if (data.status) {
this.$message({ type: 'success', message: '提交成功,等待批改' })
this.loadAjax()
}
}).catch(e => { this.filesArr.pop(); this.$message.error(e.message) }).finally(() => { loading.close() })
},
uploadFile () {
if (!/\.(docx)$/gi.test(this.file.name)) {
this.$message.error('文件格式不对,请重新上传')
this.filesArr.pop()
return
}
const loading = this.$loading({ lock: true, text: '', spinner: '', background: 'rgba(255, 255, 255, 0.9)' })
cAction.Player.uploadFile(this.file).then(data => {
if (data.error) {
this.$message.error('提示待定!!!!!')
} else {
this.successFileUrl = data.url
this.successData = data.dataStr || '' // 新增base64字符串 解析docx文档
this.filesArr.pop()
}
}).catch(e => { this.filesArr.pop(); this.$message.error(e.message) }).finally(() => { loading.close() })
},
/* 初始化 ckeditor */
initckeditor () {
!this.ckeditor && (this.ckeditor = CKEDITOR.replace('editor-courseWork', {
height: 600,
uiColor: '#eeeeee',
filebrowserImageUploadUrl: '/api/ck/form/ckeditor-upload',
fileTools_requestHeaders: { tenant: 'sofia' },
// resize_enabled: typeof this.props.resizable === 'boolean' ? this.props.resizable : true,
toolbar: [
// { name: 'document', items: ['Source', '-', 'Save', 'NewPage', 'Preview'] },
{ name: 'styles', items: ['Styles', 'Format', 'Font', 'FontSize'] },
{ name: 'colors', items: ['TextColor', 'BGColor'] },
{ name: 'tools', items: ['Maximize', 'ShowBlocks'] },
// { name: 'clipboard', items: ['Cut', 'Copy', 'Paste', 'PasteText', 'PasteFromWord', '-', 'Undo', 'Redo'] },
{ name: 'editing', items: ['Find', 'Replace'] },
// { name: 'forms', items: ['Form', 'Checkbox', 'Radio', 'TextField', 'Textarea', 'Select', 'Button', 'ImageButton', 'HiddenField'] },
'/',
{ name: 'basicstyles', items: ['Bold', 'Italic', 'Underline', 'Strike', 'Subscript', 'Superscript', '-', 'RemoveFormat'] },
{ name: 'paragraph', items: ['NumberedList', 'BulletedList', '-', 'Outdent', 'Indent', '-', 'Blockquote', 'CreateDiv', '-', 'JustifyLeft', 'JustifyCenter', 'JustifyRight', 'JustifyBlock', '-', 'BidiLtr', 'BidiRtl'] },
{ name: 'links', items: ['Link', 'Unlink', 'Anchor'] },
{ name: 'insert', items: ['Image', 'Table', 'HorizontalRule'] }
]
}))
}
}
}
</script>
<template>
<div class="play-paper">
<div class="play-paper-body">
<template v-if="status.examinationStatus === '00'">
<div class="no-exam">暂无考试</div>
</template>
<template v-else-if="status.examinationStatus === '90'">
<div class="play-paper-title">
<div>
<h3>{{exam.title}}</h3>
</div>
</div>
<template v-if="status.type === 2 && status.isPublished === 1">
<template v-if="exam.score.total !== undefined">
<div style="font-size: 18px;">总分:{{exam.score.total}}</div>
</template>
</template>
<template v-else-if="status.type === 0">
<div class="no-exam">考试结束 - 尚未进行考试</div>
</template>
<template v-else>
<div class="no-exam">考试结束 - 试卷批改中,请耐心等待</div>
</template>
</template>
<template v-else>
<div class="play-paper-title">
<div>
<h3>{{exam.title}}</h3>
</div>
</div>
<template v-if="status.isStart">
<div class="play-paper-content">
<template v-if="exam.id">
<div class="exam">
<!-- <div style='text-align: center;'> -->
<!-- <div class='topic'> -->
<!-- <div class='tit'>{{exam.title}}</div> -->
<template v-if="exam.type === 2 && exam.isPublished === 1">
<template v-if="exam.score.total !== undefined">
<div style="font-size: 18px;">总分:{{exam.score.total}}</div>
</template>
</template>
<template v-else-if="exam.type === 1">
<div class="no-exam">试卷批改中,请耐心等待</div>
</template>
<!-- </div> -->
<!-- </div> -->
<template v-if="(exam.type !== 1)">
<div style="text-align: center;">考试截止时间为:{{status.terminateTime}}</div>
<template v-for="question in exam.examination">
<!-- 单选题 -->
<template v-if="question.radioList.length">
<template v-for="(item, index) in question.radioList">
<div v-bind:key="item.id" class="q-group" :data-index="index">
<div class="q-num">{{index+1}}.</div>
<div class="q-title" v-html="item.content"></div>
<div class="q-type">(单选题)</div>
<el-radio-group class="radio-group" v-model="item.user_answer">
<template v-for="(item1, index1) in item.options">
<el-radio
v-bind:key="item1.id"
:label="item1.id"
:disabled="isSubmited"
:class="['radio', ((item.right_answer) ? (item1.id === item.right_answer ? 'success' : 'error') : '')]"
>{{ index1 | getLetter() }}. {{item1.option}}</el-radio>
</template>
</el-radio-group>
<template v-if="item.right_answer && !!exam.type">
<div class="result">
学生答案:
<div
:class="['stu', (item.right_answer === item.user_answer ? 'success' : 'error')]"
>{{ item.user_answer | getRadioAnswer(item.options) }}</div>
&nbsp;&nbsp;&nbsp;&nbsp;正确答案:{{ item.right_answer | getRadioAnswer(item.options) }}
</div>
</template>
<div class="analysis" v-if="item.analysis">
<p>解析:</p>
<div v-html="item.analysis"></div>
</div>
</div>
</template>
</template>
<!-- 多选题 -->
<template v-if="question.checkboxList.length">
<template v-for="(item, index) in question.checkboxList">
<div v-bind:key="item.id" class="q-group" :data-index="index">
<div class="q-num">{{question.radioList.length+index+1}}.</div>
<div class="q-title" v-html="item.content"></div>
<div class="q-type">(多选题)</div>
<el-checkbox-group class="checkbox-group" v-model="item.user_answer">
<template v-for="(item1, index1) in item.options">
<el-checkbox
v-bind:key="item1.id"
:label="item1.id"
:disabled="isSubmited"
:class="['checkbox', ((item.right_answer.length) ? (isCheckboxChecked(item1.id, item.right_answer) ? 'success' : 'error') : '')]"
>{{ index1 | getLetter() }}. {{item1.option}}</el-checkbox>
</template>
</el-checkbox-group>
<template v-if="item.right_answer.length && !!exam.type">
<div class="result">
学生答案:
<div
:class="['stu', ((item.right_answer.length && isCheckboxRight(item.user_answer, item.right_answer)) ? 'success' : 'error')]"
>{{ item.user_answer | getCheckboxAnswer(item.options) }}</div>
&nbsp;&nbsp;&nbsp;&nbsp;正确答案:{{ item.right_answer | getCheckboxAnswer(item.options) }}
</div>
</template>
<div class="analysis" v-if="item.analysis">
<p>解析:</p>
<div v-html="item.analysis"></div>
</div>
</div>
</template>
</template>
<!-- 简答题 -->
<template v-if="question.shortAnswerList.length">
<template v-for="(item, index) in question.shortAnswerList">
<div class="q-group" :key="index">
<div
class="q-sa-title"
>{{question.radioList.length+question.checkboxList.length+index+1}}.&nbsp;&nbsp;简答题</div>
<div class="edit_html" v-html="item.content || ''"></div>
<v-editor v-model="item.user_answer" :disabled="isSubmited"></v-editor>
<div style="height: 10px;"></div>
<!-- 利用key值自动更新组件 -->
<component
:is="item.upload.type"
v-bind:key="item.upload.id + new Date().getTime()"
:item="item.upload"
:formData="item"
:isUpload="!exam.type"
></component>
<div class="result" v-if="item.check_comment">评语:{{item.check_comment}}</div>
<div class="analysis" v-if="item.analysis">
<p>解析:</p>
<div v-html="item.analysis"></div>
</div>
</div>
</template>
</template>
</template>
<div
:class="['btn', (isSubmited && 'on')]"
@click="submitExam"
:data-submit="isSubmited"
@mousedown="_SubmitMouseLeftDown()"
>{{isSubmited ? "已提交" : "提交"}}</div>
<div class="care">(注意:考试只有一次提交机会)</div>
<!-- <div :class='["btn"]' @click='repeatExam($event, true)' v-if="exam.work_contents">重做</div> -->
</template>
</div>
</template>
</div>
</template>
<template v-else>
<div class="exam">
<!-- <p>考试须知:</p> -->
<div style="text-align: left;">考试开始时间为:{{status.startTime}}</div>
<div style="text-align: left;">考试截止时间为:{{status.terminateTime}}</div>
<template
v-if="new Date(status.startTime).getTime() - new Date(status.serverTime).getTime() <= 0"
>
<div
style="width: 25%;"
:class="['btn']"
@click="beginExam(true)"
@mousedown="beginExam(true)"
>开始考试</div>
</template>
</div>
</template>
</template>
</div>
</div>
</template>
<script>
import cAction from '@action'
import Base64 from 'Base64'
import VEditor from '@/components/editor.vue'
const A_Z = (function() {
const result = []
for (let i = 0; i < 26; i++) {
result.push(String.fromCharCode(65 + i))
}
return result
})()
var getLetter = val => {
return A_Z[val]
}
export default {
props: {
sid: { type: String, require: false },
cid: { type: String, require: false },
id: { type: String, require: false }
},
components: { VEditor },
filters: {
getLetter: getLetter,
getRadioAnswer: (val, arr) => {
for (let i = 0; i < arr.length; i++) {
if (arr[i].id === val) {
return getLetter(i)
}
}
},
getCheckboxAnswer: (val, arr) => {
let str = ''
for (let i = 0; i < val.length; i++) {
const tmpId = val[i]
for (let j = 0; j < arr.length; j++) {
if (arr[j].id === tmpId) {
str += getLetter(j) + ','
break
}
}
}
return str.substr(0, str.length - 1)
}
},
data() {
return {
_time: null, // 定时器,自动化提交
exam: {},
status: {
isStart: false,
startTime: '',
terminateTime: '',
serverTime: '',
examinationStatus: '',
type: 0,
isPublished: 0
}
}
},
watch: {
id: {
handler() {
this.init()
}
}
},
computed: {
// 考试完成
isExamComplete() {
// 考试完成,批改完成并且公布成绩
return this.exam.is_published === 1 && this.exam.type === 2
},
// 是否提交
isSubmited() {
return this.exam.type === 1 || this.exam.type === 2
}
},
mounted() {
this.init()
this.$emit('changeSideBar', '')
setTimeout(() => {
if (window.document.getElementById('switch-btn')) {
window.document.getElementById('switch-btn').style.display = 'none'
}
}, 500)
},
destroyed() {
if (this._time) {
clearInterval(this._time)
this._time = null
}
if (window.document.getElementById('switch-btn')) {
window.document.getElementById('switch-btn').style.display = 'block'
}
},
methods: {
isCheckboxRight: (val, arr) => {
let flag = true
for (let i = 0; i < arr.length; i++) {
const tmpId = arr[i]
let j = 0
for (; j < val.length; j++) {
if (val[j] === tmpId) {
break
}
}
if (j === val.length) {
flag = false
break
}
}
return flag
},
isCheckboxChecked: (val, arr) => {
let i = 0
for (; i < arr.length; i++) {
if (arr[i].id === val || arr[i] === val) {
return true
}
}
return false
},
init() {
this.loadExamStatus()
this.loadExamInfo()
if (this._time) {
clearInterval(this._time)
this._time = null
}
this._time = setInterval(() => {
this.loadExamStatus()
if (!this.isSubmited && this.status.isStart) {
// console.log(11, '暂存')
this.submitExam({ submitType: true }) // 暂存, submitType: true 暂存;其他或不填为提交
}
/* 到时间 自动提交 */
if (
!this.isSubmited &&
this.status.isStart &&
new Date(this.status.terminateTime).getTime() -
new Date(this.status.serverTime).getTime() <=
5000
) {
this.submitExam({ submitType: false, currentTarget: { dataset: {} } })
}
}, 10000)
},
/* 定时调用 - 考试状态 */
loadExamStatus() {
cAction.Player.getExamStatus(this.cid, this.sid, this.id)
.then(_data => {
if (_data.status && _data.status === 200) {
this.status.startTime = this.setTime(_data.start_time)
this.status.terminateTime = _data.terminate_time
this.status.serverTime = this.setTime(_data.server_time)
this.status.examinationStatus = _data.examination_status
} else {
this.$message.error('数据异常,请联系管理员')
}
})
.catch(e => {
this.$message.error(e.message)
})
.finally(() => {})
},
/* 时间格式化(解决safari时间兼容问题); */
setTime(time) {
return time.replace(/-/g, '/')
},
/* 开始考试 */
beginExam(flag) {
this.status.isStart = true
this.loadAjax(flag)
},
/* 加载题库基本数据 */
loadExamInfo() {
const loading = this.$loading({
lock: true,
text: '',
spinner: '',
background: 'rgba(255, 255, 255, 0.9)'
})
cAction.Player.getExamInfo(this.cid, this.sid)
.then(_data => {
this.exam = _data
this.exam.id = this.id
})
.catch(e => {
this.$message.error(e.message)
})
.finally(() => {
loading.close()
/* 正在考试,考试结束 */
if (
this.status.examinationStatus === '20' ||
this.status.examinationStatus === '90'
) {
this.beginExam()
}
})
},
/**
* 生命周期函数--监听页面加载
* @param flag 通过该字段 判别是点击进入考试 还是 自动调用
*/
loadAjax(flag) {
const loading = this.$loading({
lock: true,
text: '',
spinner: '',
background: 'rgba(255, 255, 255, 0.9)'
})
cAction.Player.getExamAnswer(this.cid, this.sid, this.id)
.then(_data => {
if (_data.code === 8001) {
console.log(
'没有考试内容,认为是第一次答题,并且在答题期间,所以显示考试开始页面'
)
if (!flag) {
this.status.isStart = false
}
} else {
// this.exam.id = _data.id
this.exam.title = _data.title
this.$set(this.exam, 'type', _data.type)
this.exam.score = _data.score
this.exam.submitted_time = _data.submitted_time
this.exam.isPublished = _data.isPublished
this.status.type = _data.type
this.status.isPublished = _data.isPublished
this.exam.examination = this.exam.examination.map((exam, index) => {
const rawExam = _data.examination[index]
if (!rawExam) {
return exam
}
for (let i = 0; i < exam.radioList.length; i++) {
for (let j = 0; j < rawExam.radioList.length; j++) {
if (rawExam.radioList[j].id === exam.radioList[i].id) {
for (const k in rawExam.radioList[j]) {
exam.radioList[i][k] = rawExam.radioList[j][k]
}
}
}
}
for (let i = 0; i < exam.checkboxList.length; i++) {
for (let j = 0; j < rawExam.checkboxList.length; j++) {
if (rawExam.checkboxList[j].id === exam.checkboxList[i].id) {
for (const k in rawExam.checkboxList[j]) {
exam.checkboxList[i][k] = rawExam.checkboxList[j][k]
}
}
}
}
for (let i = 0; i < exam.shortAnswerList.length; i++) {
for (let j = 0; j < rawExam.shortAnswerList.length; j++) {
if (
rawExam.shortAnswerList[j].id === exam.shortAnswerList[i].id
) {
for (const k in rawExam.shortAnswerList[j]) {
exam.shortAnswerList[i][k] = rawExam.shortAnswerList[j][k]
}
}
}
}
return exam
})
}
})
.catch(e => {
this.$message.error(e.message)
})
.finally(() => {
// console.log(this.exam.type, this.exam.isPublished)
loading.close()
if (
this.status.isStart &&
this.exam.type !== 1 &&
this.exam.type !== 2
) {
/* 滚动到头部 */
document.querySelector('.play-paper').scrollTop = 0
}
})
},
/**
* 提交试题
*/
submitExam(e) {
if (!e.submitType && e.currentTarget.dataset.submit) {
this.$message.error('已做过,不能再提交')
return
}
const body = { answers: [], type: !e.submitType ? 1 : 0 } // type: 0 缓存;type: 1 提交
for (let k = 0; k < this.exam.examination.length; k++) {
const exam = this.exam.examination[k]
const radioList = []
for (let i = 0; i < exam.radioList.length; i++) {
const tmp = exam.radioList[i]
if (!tmp.user_answer && !e.submitType) {
this.$message.error('还有单选题未做,不能提交')
return
}
radioList.push({ id: tmp.id, user_answer: tmp.user_answer })
}
const checkboxList = []
for (let i = 0; i < exam.checkboxList.length; i++) {
const tmp = exam.checkboxList[i]
if (!tmp.user_answer.length && !e.submitType) {
this.$message.error('还有多选题未做,不能提交')
return
}
checkboxList.push({ id: tmp.id, user_answer: tmp.user_answer })
}
const shortAnswerList = []
for (let i = 0; i < exam.shortAnswerList.length; i++) {
const tmp = exam.shortAnswerList[i]
if (!tmp.user_answer && !e.submitType) {
this.$message.error('还有简答题未做,不能提交')
return
}
shortAnswerList.push({
id: tmp.id,
user_answer: Base64.encode(tmp.user_answer),
attachments: tmp.attachments
})
}
body.answers[k] = { radioList, checkboxList, shortAnswerList }
}
body.answers = JSON.stringify(body.answers)
let loading = null
if (!e.submitType) {
loading = this.$loading({
lock: true,
text: '',
spinner: '',
background: 'rgba(255, 255, 255, 0.9)'
})
}
cAction.Player.submitExam(this.cid, this.sid, this.exam.id, body)
.then(_res => {
if (e.submitType) {
// this.$message.success('暂存成功')
console.log('暂存成功')
return
}
if (_res.code === 200) {
this.$message.success('考试答卷提交成功')
// this.exam.type = 1
this.init()
console.log(111, 'this.loadAjax()')
} else {
this.$message.error(_res.data.error)
}
})
.catch(e => {
this.$message.error(e.message)
})
.finally(() => {
if (!e.submitType) {
loading.close()
}
})
},
_SubmitMouseLeftDown() {
const _fn1 = this.repeatExam.bind(this, false)
document.addEventListener('keydown', _fn1, false)
const _fn3 = function() {
document.removeEventListener('keydown', _fn1)
document.removeEventListener('mouseup', _fn3)
}
document.addEventListener('mouseup', _fn3, false)
},
/**
* 重做
*/
repeatExam(e, flag) {
let _flag = flag
/* 字母 f */
if (e.keyCode === 70) {
_flag = true
}
if (!_flag) {
return
}
const loading = this.$loading({
lock: true,
text: '',
spinner: '',
background: 'rgba(255, 255, 255, 0.9)'
})
cAction.chapterAction
.getExamDetail(this.sid, this.cid, this.id)
.then(_data => {
this.exam = {}
})
.catch(e => {
this.$message.error(e.message)
})
.finally(() => {
loading.close()
})
}
}
}
</script>
<style lang="scss" scoped>
.play {
.exam {
padding: 0;
}
.exam .topic {
display: inline-block;
margin-bottom: 0.1rem;
}
.exam .topic .tit {
margin: 0 auto;
padding: 0 0.2rem;
text-align: center;
font-size: 0.24rem;
color: #313131;
background: #fff;
box-sizing: border-box;
-webkit-box-sizing: border-box;
}
.exam .topic .cur {
text-align: center;
font-size: 0.18rem;
color: #313131;
line-height: 0.4rem;
}
/* 循环 所有选择题 */
.exam .q-group {
padding: 0.1rem 0.1rem;
border-bottom: 1px solid #c9c9c97a;
overflow: hidden;
}
.exam .q-group .q-num {
float: left;
margin-right: 0.1rem;
font-size: 0.16rem;
color: #676a6c;
}
.exam .q-group .q-title {
float: left;
width: 90%;
font-size: 0.16rem;
color: #676a6c;
text-align: justify;
}
.exam .q-group .q-type {
float: right;
font-size: 0.16rem;
color: #676a6c;
}
.exam .q-group .radio-group {
float: left;
margin-top: 0.1rem;
width: 100%;
}
.exam .q-group .radio-group .radio {
display: block;
font-size: 0.18rem;
color: #3f3b3a;
line-height: 0.3rem;
margin-bottom: 0.1rem;
}
.exam .q-group .checkbox-group {
float: left;
margin-top: 0.1rem;
width: 100%;
}
.exam .q-group .checkbox-group .checkbox {
display: block;
font-size: 0.18rem;
color: #3f3b3a;
line-height: 0.3rem;
margin-bottom: 0.1rem;
}
.exam .q-group .radio-group .radio.error,
.exam .q-group .checkbox-group .checkbox.error {
color: #d80000;
}
.exam .q-group .radio-group .radio.success,
.exam .q-group .checkbox-group .checkbox.success {
color: #090;
}
.exam .q-group .result {
clear: both;
display: flex;
justify-content: flex-end;
font-size: 0.18rem;
color: #3f3b3a;
margin-right: 0;
}
.exam .q-group .result .stu {
display: inline-block;
}
.exam .q-group .result .stu.error {
color: #d80000;
}
.exam .q-group .result .stu.success {
color: #090;
}
.exam .q-group:last-child {
border-bottom: none;
}
.exam .btn {
margin: 0.2rem auto;
width: 60%;
height: 0.5rem;
line-height: 0.5rem;
font-size: 0.16rem;
text-align: center;
font-weight: 300;
color: #fff;
border-radius: 0.1rem;
background: #b49441;
cursor: pointer;
}
.exam .btn.on {
opacity: 0.5;
}
.exam .care {
font-size: 0.16rem;
color: #d80000;
text-align: center;
}
.exam .q-sa-title {
float: left;
width: 100%;
font-size: 0.16rem;
color: #676a6c;
text-align: justify;
}
}
.no-exam {
font-size: 0.24rem;
line-height: 19;
text-align: center;
}
.analysis {
clear: both;
display: flex;
margin: 20px 0;
padding: 0 20px;
border: 1px solid #c9c9c97a;
}
</style>
.play{overflow:hidden; position: fixed;top:0; z-index: 800; width: 100%; height: 100%; background-color:#3f3f3f;color:#a0a0a0;}
.play .left-content{ position: absolute; right: 350px; top: 0; left: 0; bottom: 0; min-width: 705px;height:100%;}
.play.sidebar-hide .left-content{right:0;}
.play .play-top{ line-height: 56px;}
.play .play-top p{font-size:1.5em;text-align:center;margin:0;}
.play .play-back{position:absolute;top:6px;left:10px;width:40px;height:40px;overflow:hidden;color: #fff;font-size: 24px;line-height: 40px;text-align: center;}
.play .play-content{position:absolute;top:56px;bottom:0;left:0;right:0;}
.play .play-content-video{height:100%;}
.play .play-center .text-error{ font-size:0.875em;line-height:1.5em; }
.play .play-video-hide{visibility:hidden;overflow:hidden;width:0}
.play .play-video-init-center{position:absolute;top:50%;left:50%;margin:-180px 0 0 -275px;}
/* ppt控制 样式 */
.play .play-ppt { position: relative;width: 550px; height: 363.375px;background-color:#000;}
.play .play-ppt-img { width: 100%; height: 100%;}
.play .play-controls {position: absolute;bottom:0;left:0;right:0;height: 44px; line-height: 42px; padding: 0 14px;background-color: #000;}
.play .play-controls .fl i{ color: #8c8c8b}
.play .play-page{ position: absolute; left: 50%; margin-left: -75px; color: #fff; width: 150px; text-align: center; font-size: 0.875em;}
.play .play-page .play-now { color: #d29f29;}
.play .play-amazing { float: right; }
.play .play-amazing i{ color: #fff; margin: 0 10px; cursor: pointer; }
.play .play-amazing i.active,
.play .play-amazing i:hover{ color: #d29f29;}
.play .play-amazing .icon-rotate{ font-size: 1.125em;}
/* 整个视频 底部控制 上一章、下一章 同步、下载、跳过 */
.play .play-footer{ position: absolute; bottom: 0; left: 0;right:0; z-index: 200;padding:18px 20px 15px;}
.play .play-footer a:hover{color:#a0a0a0;}
/* 底部控制 按钮样式 */
.play .play-state{display:inline-block;color:#a0a0a0;padding-left: 25px;font-size:14px;line-height:18px;margin:0 20px;background:url(./play-icons.png) no-repeat 0 0;cursor:pointer}
.play .play-state a { color: #a0a0a0; text-decoration: none; }
.play .play-state-prev{background-position:0 2px;}
.play .play-state-prev-disable{background-position:0 -78px;color:#666;}
.play .play-state-next{background-position:0 -38px;}
.play .play-state-next-disable{background-position:0 -118px;color:#666;}
.play .play-state-check{background-position:0 -160px;}
.play .play-state-check-active{background-position:0 -200px;color: #b19241; }
.play .play-state-ppt{background-position:0 -240px;}
.play .play-state-ppt-active{background-position:0 -280px;color: #b19241; }
.play .play-state-prev-disable:hover,
.play .play-state-next-disable:hover {color:#666!important;}
/* 收起右侧,出现的 按钮样式 */
.play .switch { display: block; width: 36px; height: 125px; position: absolute; right: 0px; top: 50%; text-align: center; margin: -63px 0 0; z-index: 998; cursor: pointer;}
.play .switch a { color: #a0a0a0; text-decoration: none; font-size: 14px; line-height: 2; margin-bottom: 20px; }
.play .switch a i { font-size: 24px; padding: 5px; background: #666; border-radius: 4px; }
/*作业类页*/
.play .play-paper{position:absolute;top:0;bottom:0;left:0;right:0;overflow:auto;background-color:#e5e5e5;}
.play .play-paper-body{min-height:500px;margin:25px;padding:15px 45px 25px;color:#313131;box-shadow:0 0 2px rgba(0,0,0,.05);background-color:#f2f2f2;}
.play .play-paper-title{margin:0 10px;text-align:center;}
.play .play-paper-title div{padding-bottom:3px;display:inline-block;border-bottom:1px solid #707070;}
.play .play-paper-title h3{padding:0 0 5px;margin:0;display:inline-block;font-size:20px;border-bottom:3px solid #707070;}
.play .play-paper-body .help{color:#999;font-size:12px;}
.play .play-paper-body .help-file{margin-top:-10px;}
.play .play-paper-body .area-btns{margin:20px 0;}
.play .play-paper-body .area-btns .btn{padding:6px 25px;}
.play .play-paper-body .area-btns .help{margin-top:10px; font-size: 14px}
.play .play-paper-body .area-btns .help-info{display:inline-block;vertical-align:middle;}
.play .play-paper-body .webuploader-btn .upbtn{color:#b49441;text-decoration:underline;padding:3px 15px;font-size:.9em;display:inline-block;}
.play .play-paper-body .webuploader-btn .loading .fa-spin{font-size:1.2em!important;}
.play .play-paper-body label{font-weight:normal;}
.play .play-paper-body input{vertical-align:middle;}
.play .play-paper-check{margin-top:20px;padding:20px;border:1px solid #dedede;}
.play .play-paper-check h4{font-size:16px;margin:0 0 10px;}
.play .play-paper-check-item{padding-left:3em;}
.play .play-paper-check-item b{margin-left:-3em;margin-top:1px;display:inline-block;vertical-align:top;}
.play .play-paper-check-item .edit_html{display:inline-block;vertical-align:top;}
/*阅读材料*/
.play .play-read-files{padding:30px;margin: 0;}
.play .play-read-files li{font-size:16px;padding:20px 30px;margin-bottom:10px;background-color:#fff;list-style: none;}
.play .play-read-files li a { color: #333; text-decoration: none; }
.play .play-read-files li a:hover { color: #b49441; }
/*章节作业*/
.play .play-chapter-work{padding:25px;}
.play .play-chapter-work .work-number{margin-left:-25px;}
.play .play-chapter-work .work-title{margin-top:-20px;margin-bottom:10px;}
.play .play-chapter-work .area-btns{margin:20px -25px 0;border-top:1px solid #eaeaea;padding-top:20px;}
.play .play-chapter-exam{padding:25px;}
.play .play-chapter-exam li{position:relative;margin-top:15px;border-bottom:1px solid #b49441;}
.play .play-chapter-exam .exam-title{margin: -20px 0 10px 25px;}
.play .play-chapter-exam .wrong{color:#d80000;}
.play .play-chapter-exam .correct{color:#090;}
.play .play-chapter-exam .answer{position:absolute;right:25px;bottom:10px;}
.play .play-chapter-exam .result{float:right;margin-top:-20px;margin-right:-20px;font-size:16px;font-weight:bold;}
/* 统一默认 common样式 */
.play dd,
.play dl,
.play dt,
.play li,
.play ol,
.play ul { margin: 0; padding: 0; list-style: none; }
.play .edit_html p {padding: 0; margin: 0; margin-bottom: 15px;}
.play .play-paper-step{font-weight:bold;font-size:16px;margin:30px -20px 15px;padding-bottom:10px;border-bottom:1px dashed #cecece;}
.play .no-data {
color: #c9c9c9;
font-size: 36px;
padding: 160px 0;
text-align: center;
}
/* 视频播放样式 */
.play .hide { display: none; }
.play .play-video { float: left }
.play .play-jiangyi { float: left }
/* 视频播放 是 flash */
@media (max-width:768px){
.play .left-content {min-width:0;right:0;}
.play .play-back{margin:0;}
.play .play-chapter-work{padding:25px 0;margin-right:-20px;}
.play .play-read-files{padding:30px 0;margin:0 -20px;}
.play .switch{top:80%;}
.play .play-paper-body{ padding: 15px 25px 25px; }
.play .play-paper-step{ margin: 30px 0 15px; }
}
/* OK 样式 */
.exam .q-group .q-title p { padding: 0; margin: 0; }
.exam .el-radio + .el-radio { margin-left: 0; }
.exam .el-radio__input.is-disabled + span.el-radio__label { color: inherit; }
.exam .el-checkbox + .el-checkbox { margin-left: 0; }
.exam .el-checkbox__input.is-disabled + span.el-checkbox__label { color: inherit; }
.exam .el-radio__label, .exam .el-checkbox__label { white-space: normal; }
/* aliyun 播放器 样式修改 */
#player .prism-setting-btn { display: none; }
#player .prism-cc-btn { display: none; }
#player.prism-player .prism-progress { z-index: 99; }
<template>
<div :class="['play', (state.sideBar ? '' : 'sidebar-hide')]">
<div class="left-content">
<div class="play-top cl" :style="(state.sideBar ? {} : { marginRight: 0 })">
<router-link class="router-link-class" :to="{ path: `/app/learn/course-detail/${sid}/${cid}` }"><i class="play-back el-icon-arrow-left"></i></router-link>
<p>{{chapterList.title}}</p>
<router-link class="router-link-class" id="sys-help" :to="{ path: `/mobile/help/student` }" target="_blank">
<el-tooltip effect="light" content="帮助" placement="bottom-start">
<i class="el-icon-self-icon-test"></i>
</el-tooltip>
</router-link>
<router-link class="router-link-class" id="sys-callback" :to="{ path: `/app/account/feedbackCreate` }" target="_blank">
<el-tooltip effect="light" content="意见反馈" placement="bottom-start">
<i class="el-icon-self-fankuiyijian"></i>
</el-tooltip>
</router-link>
</div>
<div class="play-content">
<router-view
ref="comTotalChapter"
:chapters="rawResponse.chapters"
:chapterName="curChapterName"
:chapterId="chapterId"
:courseInfo="courseInfo"
:courseWork="courseWork"
:chapterRead="chapterRead"
:chapterWork="chapterWork"
:chapterExam="chapterExam"
:chapterVideo="chapterVideo"
:ppts="chapterPpts"
:videoType="videoType"
@changeVideoArr="changeVideoArr"
@handlePlayTime="handlePlayTime"
@updateProgress="updateProgress"
@changeSideBar="changeSideBar"
:key="id"
v-if="rawResponse.chapters"
></router-view>
</div>
</div>
<div class="right-ctrl" :style="{ right: (state.sideBar ? 0 : -388) + 'px' }">
<p class="ctrl-arrow" @click="changeSideBar('')"><span>&gt;</span></p>
<div class="ctrl-pl">
<ul class="pl-tab-hd">
<li :class="[(state.sideBar === SIDEBAR_CHAPTER ? 'on' : '')]"><a :href="('#' + SIDEBAR_CHAPTER)" @click="changeSideBar(SIDEBAR_CHAPTER)">章节</a></li>
<template v-if="state.isChapterVideo">
<li :class="['br-l-line', (state.sideBar === SIDEBAR_PPT ? 'on' : '')]"><a :href="('#' + SIDEBAR_PPT)" @click="changeSideBar(SIDEBAR_PPT)">讲义</a></li>
</template>
</ul>
<div class="pl-tab-bd">
<template v-if="state.sideBar === SIDEBAR_CHAPTER">
<side-chapter-list
:list="chapterList"
:sid="sid"
:cid="cid"
/>
</template>
<template v-if="state.sideBar === SIDEBAR_PPT">
<side-chapter-ppt
ref="sidePpt"
:ppt="pptList"
@handleClickPpt="handleClickSidePpt"
/>
</template>
</div>
</div>
</div>
<template v-if="!state.sideBar">
<div class="switch" id="switch-btn">
<a :href="('#' + SIDEBAR_CHAPTER)" class="switch-chapter" @click="changeSideBar(SIDEBAR_CHAPTER)">
<i class="el-icon-self-wenjian"></i>
<div>章节</div>
</a>
<template v-if="state.isChapterVideo">
<a :href="('#' + SIDEBAR_PPT)" class="switch-handout" @click="changeSideBar(SIDEBAR_PPT)">
<i class="el-icon-self-PPT"></i>
<div>讲义</div>
</a>
</template>
</div>
</template>
</div>
</template>
<script>
import cAction from '@action'
import cTool from '@tool'
import sideChapterList from './rightSide/sideChapterList.vue'
import sideChapterPpt from './rightSide/sideChapterPpt.vue'
export default {
components: { sideChapterList, sideChapterPpt },
props: {
sid: { type: String, require: false },
cid: { type: String, require: false },
id: { type: String, require: false }, // 章节id
videoType: { type: String, require: false } // 视频播放类型 // 1 是CC加密,2 是非加密,3 是阿里云
},
data () {
return {
SIDEBAR_CHAPTER: 'sidebar_chapter',
SIDEBAR_PPT: 'sidebar_ppt',
state: {
sideBar: 'sidebar_chapter',
isChapterVideo: false
},
chapterList: {
// title: '',
// currentChapterId: '11', // 当前章节id
// course: [{
// title: '第一章:重要概念',
// chapters: [
// { id: '11', time: '28:18', name: '1.1 现值(PV)和终值(FV)' },
// { id: '12', time: '19:09', name: '1.2 净现值(NPV)及实际收益率' }
// ]
// }, {
// title: '第二章:证券估值',
// chapters: [
// { id: '21', time: '27:49', name: '2.1 债券和股票的现金流贴现估值方法' },
// { id: '22', time: '16:04', name: '2.2 债券评级及债券协议' },
// { id: '23', time: '', name: '公司金融第二周测验' },
// { id: '24', time: '', name: '公司金融第二周作业' }
// ]
// }],
// nextVideo: {}, // 下一章 音视频对象
// prevVideo: {} // 上一章音视频对象
},
pptList: {
// imgUrls: [
// 'http://pd4t7ae3m.bkt.clouddn.com/imgs-test1.jpg',
// 'http://pd4t7ae3m.bkt.clouddn.com/imgs-test2.jpg',
// 'http://pd4t7ae3m.bkt.clouddn.com/imgs-test3.jpg'
// ], // 所有图片数组
// current: 0, // 当前跟着音视频走,播放的是第几个图片
// selectIndex: 0,
// timeArr: [2, 10] // 时间数组,在这个时间时,图片需要切换到对应下角标图片
},
/* 课程资料 */
courseInfo: [],
/* 课程大作业 */
courseWork: {},
/* 当前选择 - 章节名字 */
curChapterName: '',
/* 当前选择 - 章节id */
chapterId: '',
/* 章节阅读 */
chapterRead: {},
/* 章节问题、作业提交 */
chapterWork: {},
/* 章节测试 */
chapterExam: {},
/* 章节视频 */
chapterVideo: {},
chapterPpts: [],
rawResponse: {} // 接口返回的数据
}
},
beforeRouteUpdate (to, from, next) {
/* 只有 视频时 才有PPT */
if (to.name === 'video') {
this.state.isChapterVideo = true
const loading = this.$loading({ lock: true, text: '', spinner: '', background: 'rgba(255, 255, 255, 0.9)' })
const str = to.params.videoType !== '3' ? 'getCurrentChapterDetail' : 'getCurrentChapterDetailAliyun'
cAction.Player[str](to.params.id).then(json => {
this.pptList = json.image
this.chapterPpts = json.rData.ppts
}).catch(e => { this.$message.error(e.message) }).finally(() => { loading.close() })
} else {
this.state.isChapterVideo = false
}
const loading = this.$loading({ lock: true, text: '', spinner: '', background: 'rgba(255, 255, 255, 0.9)' })
if (to.params.cid === '0' && to.params.sid === '0') {
this.$message({
message: 'URL异常,重新选择课程学习!!!',
type: 'info',
duration: 10000
})
loading.close()
return
}
cAction.Player.getChapterList(to.params.cid, to.params.sid, to.params.id).then(json => {
this.rawResponse = json.rawResponse
this.chapterList = json.json
this.courseInfo = json.courseInfo
this.courseWork = json.courseWork
/* 章节选择 */
this.curChapterName = json.curJson.name
this.chapterId = json.curJson.chapterId
/* 如果 是 视频 再调用 进度信息接口 */
if (json.curJson.type === 2) {
cAction.Player.getProgress(this.id, cTool.other.getIdt(), this.sid).then(_d => {
this.chapterVideo = ((json.curJson.type === 2) && json.curJson.chapterVideo) || {}
this.chapterVideo.progress = _d
}).catch(e => { this.$message.error(e.message) })
}
this.chapterRead = ((json.curJson.type === 4) && json.curJson.chapterRead) || {}
this.chapterExam = ((json.curJson.type === 3 && json.curJson.work_type === 1) && json.curJson.homework) || {}
this.chapterWork = ((json.curJson.type === 3 && json.curJson.work_type === 2) && json.curJson.chapterWork) || {}
}).catch(e => { this.$message.error(e.message) }).finally(() => { loading.close() })
next()
},
mounted () {
/* 只有 视频时 才有PPT */
if (this.$route.name === 'video') {
this.state.isChapterVideo = true
const loading = this.$loading({ lock: true, text: '', spinner: '', background: 'rgba(255, 255, 255, 0.9)' })
const str = this.videoType !== '3' ? 'getCurrentChapterDetail' : 'getCurrentChapterDetailAliyun'
cAction.Player[str](this.id).then(json => {
this.pptList = json.image
this.chapterPpts = json.rData.ppts
}).catch(e => { this.$message.error(e.message) }).finally(() => { loading.close() })
}
const loading = this.$loading({ lock: true, text: '', spinner: '', background: 'rgba(255, 255, 255, 0.9)' })
if (this.cid === '0' && this.sid === '0') {
this.$message({
message: 'URL异常,请点击“返回首页”,重新选择课程学习!',
type: 'info',
duration: 10000
})
loading.close()
return
}
cAction.Player.getChapterList(this.cid, this.sid, this.id).then(json => {
this.rawResponse = json.rawResponse
this.chapterList = json.json
this.courseInfo = json.courseInfo
this.courseWork = json.courseWork
/* 章节选择 */
this.curChapterName = json.curJson.name
this.chapterId = json.curJson.chapterId
/* 如果 是 视频 再调用 进度信息接口 */
if (json.curJson.type === 2) {
cAction.Player.getProgress(this.id, cTool.other.getIdt(), this.sid).then(_d => {
this.chapterVideo = ((json.curJson.type === 2) && json.curJson.chapterVideo) || {}
this.chapterVideo.progress = _d
}).catch(e => { this.$message.error(e.message) })
}
this.chapterRead = ((json.curJson.type === 4) && json.curJson.chapterRead) || {}
this.chapterExam = ((json.curJson.type === 3 && json.curJson.work_type === 1) && json.curJson.homework) || {}
this.chapterWork = ((json.curJson.type === 3 && json.curJson.work_type === 2) && json.curJson.chapterWork) || {}
}).catch(e => { this.$message.error(e.message) }).finally(() => { loading.close() })
},
methods: {
changeSideBar (str) { this.state.sideBar = str },
// 视频播放时间变更调用此方法
handlePlayTime (time) {
// 侧边ppt对应位置
if (this.$refs.sidePpt) {
this.$refs.sidePpt.setIndexByPoint(time)
}
},
/* 通过 右侧 sider ppt 控制 左侧视频播放位置 */
handleClickSidePpt (index) {
const ppts = this.chapterPpts || []
if (ppts.length > index && this.$refs.comTotalChapter) {
const ppt = ppts[index]
this.$refs.comTotalChapter.setVideoTime(ppt.ppt_point)
}
},
updateProgress (_rProgress) {
if (_rProgress.cpt) {
/* 处理一下 视频帧栈,另存一个数组,防止请求事件过长,或超时,导致数据上送失败 */
let _arr = []
let _intCountPrev = 0
for (let i = 0; i < _rProgress.ps.length; i++) {
_arr[i] = _rProgress.ps[i]
/* 客户端,处理一下,统计整个 视频帧数组 都有哪些帧 播过 */
const _intCount = Math.floor(_rProgress.ps[i]) || 1
if (_intCount !== _intCountPrev) {
_rProgress.map[_intCount - 1] += 1
_intCountPrev = _intCount
}
}
/* 帧点取整 */
const _arrTmp = _arr
_intCountPrev = 0
_arr = []
for (let i = 0; i < _arrTmp.length; i++) {
if (Math.floor(_arrTmp[i]) !== _intCountPrev) {
_arr.push(Math.floor(_arrTmp[i]))
_intCountPrev = Math.floor(_arrTmp[i])
}
}
const _userInfo = window.G.UserInfo
cAction.Player.updateProgress({
sid: (_userInfo && _userInfo.student_info && _userInfo.student_info.id) || '',
uid: (_userInfo && _userInfo.id) || '',
d: cTool.other.getIdt(),
i: cTool.other.getIdt(),
c: this.cid,
s: this.sid,
v: _rProgress.vid, // this.id, // 这个不能保证退出组件时,刷新视频 从 crouse_work 切换 到 chapter_video
_p: parseInt(_rProgress.pt), // 累计时间
_m: parseInt(_rProgress.mpt), // 当前播放最大时间
_c: parseInt(_rProgress.cpt), // 当前播放位置
ps: _arr.join(',') // 播放时,播放过的 帧
// map: _rProgress.map// 播放时,统计帧
}).then(json => {
if (json.success) {
/* 将已经上传 并 成功的 帧 全部从 栈中删除 */
for (let i = 0; i < _arr.length; i++) {
_rProgress.ps.shift()
}
} else {
/* 兼容 阿里云视频、CC视频 停止播放 */
const $dom = document.getElementById('player')
const flag = !!$dom.callAction
flag ? ($dom.callAction('pause')) : ($dom.children[0].pause())
}
}).catch(e => {
this.$message.error(e.message)
/* 兼容 阿里云视频、CC视频 停止播放 */
const $dom = document.getElementById('player')
const flag = !!$dom.callAction
flag ? ($dom.callAction('pause')) : ($dom.children[0].pause())
}).finally(() => { })
}
},
changeVideoArr (obj) {
// beforeRouteUpdate 已经实现
console.log('已经实现')
obj.callback && obj.callback()
}
}
}
</script>
<style lang="scss" scoped>
@import './index.css';
/* 右侧面板结构 */
.right-ctrl {
position: absolute;
top: 0;
bottom: 0;
right: 0;
z-index: 200;
width: 350px;
background: #212121;
border-left: 19px solid #1b1b1b;
*{
box-sizing: border-box;
}
/* 箭头 */
.ctrl-arrow {
position: absolute;
top: 0;
left: -19px;
bottom: 0;
width: 19px;
height: 100%;
font-size: 14px;
color: #969696;
cursor: pointer;
span {
position: absolute;
top: 50%;
left: 0;
width: 19px;
margin-top: -10px;
text-align: center;
color: #fff;
}
}
/* 面板 */
.ctrl-pl {
position: relative;
height: 100%;
/* 头部 - 选择项 */
.pl-tab-hd {
margin: 0;
padding: 15px 0;
line-height: 1.6;
background-color: #232323;
overflow: hidden;
li {
float: left;
position: relative;
width: 50%;
padding: 0;
font-size: 16px;
color: #909090;
text-align: center;
list-style: none;
cursor: pointer;
a {
color: #909090;
text-decoration: none;
}
&.on {
a {
color: #b49441;
}
}
}
.br-l-line {
border-left: 1px solid #3f3f3f;
}
}
/* 内部 - 列表项 */
.pl-tab-bd {
height: 94%;
}
}
}
#sys-help {
display: none;
position: absolute;
top: 6px;
right: 50px;
/* width: 40px; */
height: 40px;
overflow: hidden;
color: #fff;
font-size: 16px;
line-height: 40px;
text-align: center;
text-decoration: none;
i {
font-size: 20px;
}
}
#sys-callback {
display: none;
position: absolute;
top: 6px;
right: 15px;
/* width: 40px; */
height: 40px;
overflow: hidden;
color: #fff;
font-size: 16px;
line-height: 40px;
text-align: center;
text-decoration: none;
i {
font-size: 20px;
}
}
</style>
<template>
<iframe id="myIframe" :src="live.url" frameborder="0" width="100%" height="100%" allow="autoplay;geolocation;microphone;camera;midi;encrypted-media;"></iframe>
</template>
<script>
import cAction from '@action'
export default {
props: {
sid: { type: String, require: false },
cid: { type: String, require: false },
id: { type: String, require: false }
},
data () {
return {
live: {},
ccLive: null
}
},
mounted () {
this.loadAjax()
},
destroyed () {
if (window.document.getElementById('switch-btn')) {
window.document.getElementById('switch-btn').style.display = 'block'
window.document.getElementById('sys-help').style.display = 'none'
window.document.getElementById('sys-callback').style.display = 'none'
}
if (this.ccLive) {
this.ccLive.logout({
success: function (res) {
},
error: function (res) {
}
})
}
},
methods: {
loadAjax () {
/* 只能清除本域名下的cookie,不能清除其他域名下的cookie */
// cAction.loginAction.clearCookie({
// cookies: [{
// name: 'sessionid',
// obj: { path: '/', domain: '.csslcloud.net' }
// }, {
// name: 'TGC',
// obj: { path: '/', domain: '.ezijing.com' }
// }]
// }).then().finally(() => {})
const loading = this.$loading({ lock: true, text: '', spinner: '', background: 'rgba(255, 255, 255, 0.9)' })
cAction.Player.getChapterList(this.cid, this.sid, this.id).then(json => {
this.live = (json.curJson && json.curJson.live) || {}
if (this.live.id) {
if (this.live.live_status === 2 && this.live.enable_record && this.live.record_url) {
this.live.url = this.live.record_url
} else {
this.$emit('changeSideBar', '')
setTimeout(() => {
if (window.document.getElementById('switch-btn')) {
window.document.getElementById('switch-btn').style.display = 'none'
window.document.getElementById('sys-help').style.display = 'block'
window.document.getElementById('sys-callback').style.display = 'block'
}
}, 1000)
this.live.viewer_name = window.G.UserInfo.student_info.personal_name || window.G.UserInfo.nickname
this.live.url = 'https://view.csslcloud.net/api/view/index?roomid=' + this.live.room_id + '&userid=' + this.live.user_id + '&autoLogin=true&viewername=' + this.live.viewer_name + '&viewertoken=' + this.live.viewer_token // + '&groupid=xxx'
}
this.CCLiveInit(this.live)
}
loading.close()
}).catch(e => { this.$message.error(e.message) }).finally(() => { })
},
CCLiveInit (live) {
window.DWLive.init({
userid: live.user_id, // 必须参数
roomid: live.room_id, // 必须参数
// groupid: "groupid", // 可选
viewername: live.viewer_name, // 可选
viewertoken: live.viewer_token // 如果直播间设置为密码验证,必选
// viewercustomua: 'android', // 可选
// language: 'en', // 可选
// viewercustominfo: '{"exportInfos": [ {"key": "城市", "value": "北京"}, {"key": "姓名", "value": "哈哈"}]}', // 可选
// fastMode:true // 可选参数,默认为true
})
this.ccLive = window.DWLive
}
},
watch: {
id: {
handler () {
this.loadAjax()
}
}
}
}
</script>
<style lang="scss" scoped>
</style>
<template>
<div class="tab-pane">
<ul class="chapter-list">
<template v-for="(item, index) in list.course">
<li v-bind:key="index" class="chapter-item">
<h4>{{item.title}}</h4>
<ul class="knot-list">
<template v-for="(_item, _index) in item.chapters">
<li v-bind:key="_index" :class="['knob-item', (_item.id === list.currentChapterId ? 'on' : '')]">
<a :data-vid="_item.id" :data-type="_item.video_provider" :data-hasVA='_item.time' @click='jumpToOtherVA' :data-index='index' :data-count='_index' class="knot-name">
{{_item.name + (_item.type === 5 ? ("(" + _item.live.statusStr + ")") : "") }}
</a>
<template v-if="_item.type !== 5">
<i :class="['el-icon', (_item.time ? 'el-icon-self-iconset0481' : (_item.type === 3 ? 'el-icon-edit-outline' : 'el-icon-self-cc-book'))]"></i>
</template>
</li>
</template>
</ul>
</li>
</template>
</ul>
</div>
</template>
<script>
export default {
props: {
list: { type: Object, require: false },
sid: { type: String, require: false },
cid: { type: String, require: false }
},
methods: {
/**
* 跳转到对应音视频播放页
*/
jumpToOtherVA (e) {
const _data = e.target.dataset
const sid = this.sid
const cid = this.cid
const _id = _data.vid
const type = _data.type
if (!_data.hasva) {
/* 如果存在 - 课后习题类型(chapterExam), type:3、work_type:1 */
/* 如果存在 - 课后问题类型(chapterWork), type:3、work_type:2 */
/* 如果存在 - 课后阅读类型(chapterRead), type:4 */
const i1 = _data.index
const i2 = _data.count
const _course = this.list.course[i1]
if (_course && _course.chapters[i2]) {
if (_course.chapters[i2].id === 'course_info') {
this.$router.push({ path: `/player/${sid}/${cid}/course-info/course_info` })
} else if (_course.chapters[i2].id === 'course_work') {
if (!this.list.survey) {
this.$message('请先填写教学评估,然后完成大作业。')
return
}
this.$router.push({ path: `/player/${sid}/${cid}/course-work/course_work` })
} else if (_course.chapters[i2].type === 3) {
if (_course.chapters[i2].work_type === 1) {
this.$router.push({ path: `/player/${sid}/${cid}/chapter-exam/${_id}` })
} else if (_course.chapters[i2].work_type === 2) {
this.$router.push({ path: `/player/${sid}/${cid}/chapter-work/${_id}` })
}
} else if (_course.chapters[i2].type === 4) {
this.$router.push({ path: `/player/${sid}/${cid}/chapter-read/${_id}` })
} else if (_course.chapters[i2].id === 'teach_evaluation') {
// window.localStorage.setItem('headerInfo', JSON.stringify(this.headerInfo))
this.$router.push({ path: `/survey/${sid}/${cid}` })
} else if (_course.chapters[i2].type === 'exam') {
this.$router.push({ path: `/player/${sid}/${cid}/exam/${_id}` })
} else if (_course.chapters[i2].type === 5) {
const status = _course.chapters[i2].live.live_status
const enableRecord = _course.chapters[i2].live.enable_record
if (status === 2 && enableRecord) {
this.$message.info('该直播没有回放')
return
}
this.$router.push({ path: `/player/${sid}/${cid}/live/${_id}` })
} else if (_course.chapters[i2].type === 9) {
this.$router.push({ path: `/player/${sid}/${cid}/chapter-exam2/${_course.chapters[i2].chapterId}` })
}
return
}
this.$message.error('系统未知错误,002')
return
}
this.$router.push({ path: `/player/${sid}/${cid}/chapter-video/${_id}/${type}` })
}
}
}
</script>
<style lang="scss" scoped>
.tab-pane {
display: block;
height: 100%;
overflow: auto;
/* 章列表样式 */
.chapter-list {
margin: 0;
padding: 0;
line-height: 1.6;
overflow: hidden;
.chapter-item {
h4 {
padding: 10px 22px;
margin: 0;
font-size: 15px;
color: #b0b0b0;
background-color: #2f2f2f;
}
/* 节列表样式 */
.knot-list {
margin: 0;
padding: 0;
line-height: 1.6;
overflow: hidden;
li {
position: relative;
&.on {
background: #3c3c3c;
a {
color: #b49441;
}
}
&:hover {
background: #3c3c3c;
}
&:before {
display: block;
content: "";
position: absolute;
left: 13px;
top: 16px;
z-index: 10;
width: 18px;
height: 18px;
background: #5b5b5b;
border: 2px solid #5b5b5b;
border-radius: 50%;
}
&:after {
display: block;
content: "";
position: absolute;
left: 22px;
top: 0;
z-index: 5;
width: 1px;
height: 100px;
background: #616161;
}
}
.knot-name {
display: block;
padding: 15px 35px 15px 40px;
font-size: 14px;
color: #909090;
text-decoration: none;
cursor: pointer;
}
}
/* 章节后面小图标的样式 */
.el-icon {
position: absolute;
font-size: 16px;
right: 10px;
top: 50%;
transform: translateY(-50%);
}
}
}
}
</style>
<template>
<div class="tab-pane">
<ul class="lecture-list">
<template v-for="(item, index) in ppt.imgUrls">
<li v-bind:key="index" @click="onClickPpt" :data-index="index" :class="[(index === ppt.selectIndex ? 'on' : '')]">
<img :src="item" alt=""/>
</li>
</template>
</ul>
</div>
</template>
<script>
export default {
props: {
ppt: { type: Object, require: false }
},
methods: {
// 根据播放时间同步展示ppt
// @param time 播放时间
setIndexByPoint (time) {
const ppts = this.ppt.imgUrls || []
const len = ppts.length
let i = 0
for (; i < len; i++) {
if (time < this.ppt.timeArr[i]) {
break
}
}
if (this.ppt.selectIndex !== i - 1) {
this.ppt.selectIndex = i - 1
}
},
// 点击ppt跳转对应的播放时间
// 点击某个ppt
onClickPpt (e) {
const toIndex = e.currentTarget.dataset.index - 0
if (this.ppt.selectIndex === toIndex) { return }
this.ppt.selectIndex = toIndex
this.$emit('handleClickPpt', toIndex)
}
}
}
</script>
<style lang="scss" scoped>
.tab-pane {
display: block;
height: 100%;
overflow: auto;
/* 讲义列表样式 */
.lecture-list {
padding: 8px 16px;
li {
padding: 8px 16px;
cursor: pointer;
list-style: none;
&.on {
background: #888;
}
img {
width: 100%;
}
}
}
}
</style>
...@@ -3,26 +3,6 @@ import viewerRoutes from '@/modules/viewer/routes.js' ...@@ -3,26 +3,6 @@ import viewerRoutes from '@/modules/viewer/routes.js'
export default [ export default [
{ path: '*', redirect: '/' }, { path: '*', redirect: '/' },
{ path: '/', redirect: '/app/learn/course' }, { path: '/', redirect: '/app/learn/course' },
{
path: '/login/index',
name: 'login-normal',
component: () => import('@/pages/login/index.vue'),
props: route => ({ query: route.query, params: route.params })
},
{
path: '/login/code',
name: 'login-code',
component: () => import('@/pages/login/code.vue'),
props: route => ({ query: route.query, params: route.params })
},
{
path: '/login/forget',
name: 'login-forget',
component: () => import('@/pages/login/forget.vue'),
props: route => ({ query: route.query, params: route.params })
},
/* App 内登录页面未找到时 - 指向 */
{ path: '/login/*', redirect: '/login/index' },
/* 学习系统 - 登录后,进入页面 */ /* 学习系统 - 登录后,进入页面 */
{ {
path: '/app', path: '/app',
...@@ -197,73 +177,6 @@ export default [ ...@@ -197,73 +177,6 @@ export default [
} }
] ]
}, },
/* 学习系统 - player */
{
path: '/player/:sid/:cid',
redirect: '/player/0/0/error/404',
component: () => import('@/pages/player/index.vue'),
props: true,
children: [
{
path: 'error/404',
component: () => import('@/components/errorPages/404.vue')
},
{
path: 'chapter-video/:id/:videoType',
name: 'video',
component: () => import('@/pages/player/chapterVideo/chapterVideo.vue'),
props: true
},
{
path: 'chapter-exam/:id',
name: 'chapterExam',
component: () => import('@/pages/player/chapterExam/chapterExam.vue'),
props: true
},
{
path: 'chapter-exam2/:id',
name: 'chapterExam2',
component: () => import('@/pages/player/chapterExam/chapterExam2.vue'),
props: true
},
{
path: 'chapter-read/:id',
name: 'chapterRead',
component: () => import('@/pages/player/chapterRead/chapterRead.vue'),
props: true
},
{
path: 'chapter-work/:id',
name: 'chapterWork',
component: () => import('@/pages/player/chapterWork/chapterWork.vue'),
props: true
},
{
path: 'course-info/:id',
name: 'courseInfo',
component: () => import('@/pages/player/courseInfo/courseInfo.vue'),
props: true
},
{
path: 'course-work/:id',
name: 'courseWork',
component: () => import('@/pages/player/courseWork/courseWork.vue'),
props: true
},
{
path: 'exam/:id',
name: 'exam',
component: () => import('@/pages/player/exam/exam.vue'),
props: true
},
{
path: 'live/:id',
name: 'live',
component: () => import('@/pages/player/live/live.vue'),
props: true
}
]
},
/* mobile 移动端 */ /* mobile 移动端 */
{ {
path: '/mobile', path: '/mobile',
...@@ -299,16 +212,6 @@ export default [ ...@@ -299,16 +212,6 @@ export default [
component: () => import('@/pages/survey/survey.vue'), component: () => import('@/pages/survey/survey.vue'),
props: true props: true
}, },
// /* survey 内未找到页面时 - 指向 */
// { path: '/survey/*', redirect: '/learn-error/learn-error' },
// {
// path: '/survey-phone/:sid/:cid',
// name: 'survey-phone',
// component: () => import('../../components/survey/surveyPhone.vue'),
// props: true
// },
// /* survey-phone 内未找到页面时 - 指向 */
// { path: '/survey-phone/*', redirect: '/learn-error/learn-error' },
// viewer module routes // viewer module routes
...viewerRoutes ...viewerRoutes
] ]
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论