提交 3efde1fe authored 作者: zyx's avatar zyx

暂时 提交,然后 由鹏飞和慧慧 一起修改

上级 4daddbc6
module.exports = {
demain: 'dev.ezijing.com',
url: 'http://dev.ezijing.com:4002'
url: 'http://dev.ezijing.com:4002/api',
// apiBaseURL: '//demo-login.ezijing.com/'
webpack: {
externals: {
'CKEDITOR': 'window.CKEDITOR'
}
},
ProvidePlugin: {
}
}
module.exports = {
url: 'https://api.ezijing.com',
url: '//api.ezijing.com',
DesDir: '../client-dist',
apiBaseURL: '//api.ezijing.com/'
apiBaseURL: '//api.ezijing.com/',
webpack: {
externals: {
'CKEDITOR': 'window.CKEDITOR'
}
},
ProvidePlugin: {
}
}
module.exports = {
url: 'https://login-pbcsf.ezijing.com',
url: '//api.ezijing.com',
DesDir: '../client-dist',
apiBaseURL: '//login-pbcsf.ezijing.com/'
apiBaseURL: '//api.ezijing.com/',
webpack: {
externals: {
'CKEDITOR': 'window.CKEDITOR'
}
},
ProvidePlugin: {
}
}
......@@ -48,7 +48,8 @@ $GLOBAL.BaseConfig = {
alias: {
'@': path.resolve(__dirname, '../' + $GLOBAL.ResDir),
'@api': path.resolve(__dirname, '../' + $GLOBAL.ResDir + '/api'),
'@action': path.resolve(__dirname, '../' + $GLOBAL.ResDir + '/action')
'@action': path.resolve(__dirname, '../' + $GLOBAL.ResDir + '/action'),
'@tool': path.resolve(__dirname, '../' + $GLOBAL.ResDir + '/tool')
}
},
module: {
......
......@@ -152,7 +152,38 @@ if ($GLOBAL.isDev === 'development') {
}
}
])
]
],
optimization: {
runtimeChunk: {
name: 'manifest'
},
splitChunks: {
chunks: 'async',
minSize: 30000,
maxSize: 400000, // 大于400kb 会再进行拆分,可以进行优化时,添加
minChunks: 1,
maxAsyncRequests: 5, // 按需加载块时并行请求的最大数量
maxInitialRequests: 3, // 初始页面加载时并行请求的最大数量
name: false,
cacheGroups: {
vendor: { // 将所有node_modules中模块 js打包到一起,并拆分
name: 'vendor',
chunks: 'initial',
priority: -10,
reuseExistingChunk: false,
test: /node_modules\/(.*)\.js/
},
// styles: { // 将所有node_modules中模块 css、scss打包到一起,并拆分,暂时没用,还在研究
// name: 'styles',
// test: /node_modules\/\.(sa|sc|c)ss$/,
// chunks: 'all',
// minChunks: 1,
// reuseExistingChunk: true,
// enforce: true
// }
}
}
}
})
}
......
/* 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</title>
<link rel="stylesheet" href="demo.css">
<link rel="stylesheet" href="iconfont.css">
</head>
<body>
<div class="main markdown">
<h1>IconFont 图标</h1>
<ul class="icon_lists clear">
<li>
<i class="icon selfAllIcon el-icon-self-discover"></i>
<div class="name">discover</div>
<div class="fontclass">.el-icon-self-discover</div>
</li>
<li>
<i class="icon selfAllIcon el-icon-self-settings"></i>
<div class="name">settings</div>
<div class="fontclass">.el-icon-self-settings</div>
</li>
<li>
<i class="icon selfAllIcon el-icon-self-new"></i>
<div class="name">new</div>
<div class="fontclass">.el-icon-self-new</div>
</li>
<li>
<i class="icon selfAllIcon el-icon-self-album"></i>
<div class="name">album</div>
<div class="fontclass">.el-icon-self-album</div>
</li>
<li>
<i class="icon selfAllIcon el-icon-self-cc-book"></i>
<div class="name">cc-book</div>
<div class="fontclass">.el-icon-self-cc-book</div>
</li>
<li>
<i class="icon selfAllIcon el-icon-self-iconset0481"></i>
<div class="name">播放</div>
<div class="fontclass">.el-icon-self-iconset0481</div>
</li>
<li>
<i class="icon selfAllIcon el-icon-self-13"></i>
<div class="name">image-o</div>
<div class="fontclass">.el-icon-self-13</div>
</li>
<li>
<i class="icon selfAllIcon el-icon-self-grade"></i>
<div class="name">Grade</div>
<div class="fontclass">.el-icon-self-grade</div>
</li>
<li>
<i class="icon selfAllIcon el-icon-self-nav"></i>
<div class="name">nav</div>
<div class="fontclass">.el-icon-self-nav</div>
</li>
<li>
<i class="icon selfAllIcon el-icon-self-mima"></i>
<div class="name">密码</div>
<div class="fontclass">.el-icon-self-mima</div>
</li>
<li>
<i class="icon selfAllIcon el-icon-self-character"></i>
<div class="name">人物</div>
<div class="fontclass">.el-icon-self-character</div>
</li>
<li>
<i class="icon selfAllIcon el-icon-self-wenjian"></i>
<div class="name">文件</div>
<div class="fontclass">.el-icon-self-wenjian</div>
</li>
<li>
<i class="icon selfAllIcon el-icon-self-xuexi-"></i>
<div class="name">学习</div>
<div class="fontclass">.el-icon-self-xuexi-</div>
</li>
<li>
<i class="icon selfAllIcon el-icon-self-PPT"></i>
<div class="name">PPT</div>
<div class="fontclass">.el-icon-self-PPT</div>
</li>
<li>
<i class="icon selfAllIcon el-icon-self-statistic"></i>
<div class="name">statistic</div>
<div class="fontclass">.el-icon-self-statistic</div>
</li>
</ul>
<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="lang-js hljs javascript"><span class="hljs-comment">&lt;link rel="stylesheet" type="text/css" href="./iconfont.css"&gt;</span></code></pre>
<h3 id="-">第二步:挑选相应图标并获取类名,应用于页面:</h3>
<pre><code class="lang-css hljs">&lt;<span class="hljs-selector-tag">i</span> <span class="hljs-selector-tag">class</span>="<span class="hljs-selector-tag">selfAllIcon</span> <span class="hljs-selector-tag">el-icon-self-xxx</span>"&gt;&lt;/<span class="hljs-selector-tag">i</span>&gt;</code></pre>
<blockquote>
<p>"selfAllIcon"是你项目下的font-family。可以通过编辑项目查看,默认是"iconfont"。</p>
</blockquote>
</div>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>IconFont</title>
<link rel="stylesheet" href="demo.css">
<script src="iconfont.js"></script>
<style type="text/css">
.icon {
/* 通过设置 font-size 来改变图标大小 */
width: 1em; height: 1em;
/* 图标和文字相邻时,垂直对齐 */
vertical-align: -0.15em;
/* 通过设置 color 来改变 SVG 的颜色/fill */
fill: currentColor;
/* path 和 stroke 溢出 viewBox 部分在 IE 下会显示
normalize.css 中也包含这行 */
overflow: hidden;
}
</style>
</head>
<body>
<div class="main markdown">
<h1>IconFont 图标</h1>
<ul class="icon_lists clear">
<li>
<svg class="icon" aria-hidden="true">
<use xlink:href="#el-icon-self-discover"></use>
</svg>
<div class="name">discover</div>
<div class="fontclass">#el-icon-self-discover</div>
</li>
<li>
<svg class="icon" aria-hidden="true">
<use xlink:href="#el-icon-self-settings"></use>
</svg>
<div class="name">settings</div>
<div class="fontclass">#el-icon-self-settings</div>
</li>
<li>
<svg class="icon" aria-hidden="true">
<use xlink:href="#el-icon-self-new"></use>
</svg>
<div class="name">new</div>
<div class="fontclass">#el-icon-self-new</div>
</li>
<li>
<svg class="icon" aria-hidden="true">
<use xlink:href="#el-icon-self-album"></use>
</svg>
<div class="name">album</div>
<div class="fontclass">#el-icon-self-album</div>
</li>
<li>
<svg class="icon" aria-hidden="true">
<use xlink:href="#el-icon-self-cc-book"></use>
</svg>
<div class="name">cc-book</div>
<div class="fontclass">#el-icon-self-cc-book</div>
</li>
<li>
<svg class="icon" aria-hidden="true">
<use xlink:href="#el-icon-self-iconset0481"></use>
</svg>
<div class="name">播放</div>
<div class="fontclass">#el-icon-self-iconset0481</div>
</li>
<li>
<svg class="icon" aria-hidden="true">
<use xlink:href="#el-icon-self-13"></use>
</svg>
<div class="name">image-o</div>
<div class="fontclass">#el-icon-self-13</div>
</li>
<li>
<svg class="icon" aria-hidden="true">
<use xlink:href="#el-icon-self-grade"></use>
</svg>
<div class="name">Grade</div>
<div class="fontclass">#el-icon-self-grade</div>
</li>
<li>
<svg class="icon" aria-hidden="true">
<use xlink:href="#el-icon-self-nav"></use>
</svg>
<div class="name">nav</div>
<div class="fontclass">#el-icon-self-nav</div>
</li>
<li>
<svg class="icon" aria-hidden="true">
<use xlink:href="#el-icon-self-mima"></use>
</svg>
<div class="name">密码</div>
<div class="fontclass">#el-icon-self-mima</div>
</li>
<li>
<svg class="icon" aria-hidden="true">
<use xlink:href="#el-icon-self-character"></use>
</svg>
<div class="name">人物</div>
<div class="fontclass">#el-icon-self-character</div>
</li>
<li>
<svg class="icon" aria-hidden="true">
<use xlink:href="#el-icon-self-wenjian"></use>
</svg>
<div class="name">文件</div>
<div class="fontclass">#el-icon-self-wenjian</div>
</li>
<li>
<svg class="icon" aria-hidden="true">
<use xlink:href="#el-icon-self-xuexi-"></use>
</svg>
<div class="name">学习</div>
<div class="fontclass">#el-icon-self-xuexi-</div>
</li>
<li>
<svg class="icon" aria-hidden="true">
<use xlink:href="#el-icon-self-PPT"></use>
</svg>
<div class="name">PPT</div>
<div class="fontclass">#el-icon-self-PPT</div>
</li>
<li>
<svg class="icon" aria-hidden="true">
<use xlink:href="#el-icon-self-statistic"></use>
</svg>
<div class="name">statistic</div>
<div class="fontclass">#el-icon-self-statistic</div>
</li>
</ul>
<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="lang-js hljs javascript"><span class="hljs-comment">&lt;script src="./iconfont.js"&gt;&lt;/script&gt;</span></code></pre>
<h3 id="-css-">第二步:加入通用css代码(引入一次就行):</h3>
<pre><code class="lang-js hljs javascript">&lt;style type=<span class="hljs-string">"text/css"</span>&gt;
.icon {
width: <span class="hljs-number">1</span>em; height: <span class="hljs-number">1</span>em;
vertical-align: <span class="hljs-number">-0.15</span>em;
fill: currentColor;
overflow: hidden;
}
&lt;<span class="hljs-regexp">/style&gt;</span></code></pre>
<h3 id="-">第三步:挑选相应图标并获取类名,应用于页面:</h3>
<pre><code class="lang-js hljs javascript">&lt;svg <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"icon"</span> aria-hidden=<span class="hljs-string">"true"</span>&gt;<span class="xml"><span class="hljs-tag">
&lt;<span class="hljs-name">use</span> <span class="hljs-attr">xlink:href</span>=<span class="hljs-string">"#el-icon-self-xxx"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">use</span>&gt;</span>
</span>&lt;<span class="hljs-regexp">/svg&gt;
</span></code></pre>
</div>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>IconFont</title>
<link rel="stylesheet" href="demo.css">
<style type="text/css">
@font-face {font-family: "selfAllIcon";
src: url('iconfont.eot'); /* IE9*/
src: url('iconfont.eot#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('iconfont.woff') format('woff'), /* chrome, firefox */
url('iconfont.ttf') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+*/
url('iconfont.svg#selfAllIcon') format('svg'); /* iOS 4.1- */
}
.selfAllIcon {
font-family:"selfAllIcon" !important;
font-size:16px;
font-style:normal;
-webkit-font-smoothing: antialiased;
-webkit-text-stroke-width: 0.2px;
-moz-osx-font-smoothing: grayscale;
}
</style>
</head>
<body>
<div class="main markdown">
<h1>IconFont 图标</h1>
<ul class="icon_lists clear">
<li>
<i class="icon selfAllIcon">&#xe67e;</i>
<div class="name">discover</div>
<div class="code">&amp;#xe67e;</div>
</li>
<li>
<i class="icon selfAllIcon">&#xe68a;</i>
<div class="name">settings</div>
<div class="code">&amp;#xe68a;</div>
</li>
<li>
<i class="icon selfAllIcon">&#xe71e;</i>
<div class="name">new</div>
<div class="code">&amp;#xe71e;</div>
</li>
<li>
<i class="icon selfAllIcon">&#xe734;</i>
<div class="name">album</div>
<div class="code">&amp;#xe734;</div>
</li>
<li>
<i class="icon selfAllIcon">&#xe615;</i>
<div class="name">cc-book</div>
<div class="code">&amp;#xe615;</div>
</li>
<li>
<i class="icon selfAllIcon">&#xe768;</i>
<div class="name">播放</div>
<div class="code">&amp;#xe768;</div>
</li>
<li>
<i class="icon selfAllIcon">&#xe6ce;</i>
<div class="name">image-o</div>
<div class="code">&amp;#xe6ce;</div>
</li>
<li>
<i class="icon selfAllIcon">&#xe66c;</i>
<div class="name">Grade</div>
<div class="code">&amp;#xe66c;</div>
</li>
<li>
<i class="icon selfAllIcon">&#xe66b;</i>
<div class="name">nav</div>
<div class="code">&amp;#xe66b;</div>
</li>
<li>
<i class="icon selfAllIcon">&#xe607;</i>
<div class="name">密码</div>
<div class="code">&amp;#xe607;</div>
</li>
<li>
<i class="icon selfAllIcon">&#xe62e;</i>
<div class="name">人物</div>
<div class="code">&amp;#xe62e;</div>
</li>
<li>
<i class="icon selfAllIcon">&#xe650;</i>
<div class="name">文件</div>
<div class="code">&amp;#xe650;</div>
</li>
<li>
<i class="icon selfAllIcon">&#xe609;</i>
<div class="name">学习</div>
<div class="code">&amp;#xe609;</div>
</li>
<li>
<i class="icon selfAllIcon">&#xe602;</i>
<div class="name">PPT</div>
<div class="code">&amp;#xe602;</div>
</li>
<li>
<i class="icon selfAllIcon">&#xe601;</i>
<div class="name">statistic</div>
<div class="code">&amp;#xe601;</div>
</li>
</ul>
<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">第一步:拷贝项目下面生成的font-face</h3>
<pre><code class="lang-js hljs javascript">@font-face {
font-family: <span class="hljs-string">'selfAllIcon'</span>;
src: url(<span class="hljs-string">'iconfont.eot'</span>);
src: url(<span class="hljs-string">'iconfont.eot?#iefix'</span>) format(<span class="hljs-string">'embedded-opentype'</span>),
url(<span class="hljs-string">'iconfont.woff'</span>) format(<span class="hljs-string">'woff'</span>),
url(<span class="hljs-string">'iconfont.ttf'</span>) format(<span class="hljs-string">'truetype'</span>),
url(<span class="hljs-string">'iconfont.svg#selfAllIcon'</span>) format(<span class="hljs-string">'svg'</span>);
}
</code></pre>
<h3 id="-iconfont-">第二步:定义使用iconfont的样式</h3>
<pre><code class="lang-js hljs javascript">.selfAllIcon{
font-family:<span class="hljs-string">"selfAllIcon"</span> !important;
font-size:<span class="hljs-number">16</span>px;font-style:normal;
-webkit-font-smoothing: antialiased;
-webkit-text-stroke-width: <span class="hljs-number">0.2</span>px;
-moz-osx-font-smoothing: grayscale;
}
</code></pre>
<h3 id="-">第三步:挑选相应图标并获取字体编码,应用于页面</h3>
<pre><code class="lang-js hljs javascript">&lt;i <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"selfAllIcon"</span>&gt;&amp;#x33;<span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-name">i</span>&gt;</span></span></code></pre>
<blockquote>
<p>"selfAllIcon"是你项目下的font-family。可以通过编辑项目查看,默认是"iconfont"。</p>
</blockquote>
</div>
</body>
</html>
@font-face {font-family: "selfAllIcon";
src: url('iconfont.eot?t=1557902559623'); /* IE9 */
src: url('iconfont.eot?t=1557902559623#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('data:application/x-font-woff2;charset=utf-8;base64,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') format('woff2'),
url('iconfont.woff?t=1557902559623') format('woff'),
url('iconfont.ttf?t=1557902559623') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */
url('iconfont.svg?t=1557902559623#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-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";
}
.el-icon-self-cc-book:before {
content: "\e615";
}
.el-icon-self-star_full:before {
content: "\e627";
}
.el-icon-self-iconset0481:before {
content: "\e768";
}
.el-icon-self-guanbi:before {
content: "\e611";
}
.el-icon-self-xuexiao:before {
content: "\e632";
}
.el-icon-self-13:before {
content: "\e6ce";
}
.el-icon-self-grade:before {
content: "\e66c";
}
.el-icon-self-quanping:before {
content: "\e743";
}
.el-icon-self-nav:before {
content: "\e66b";
}
.el-icon-self-mima:before {
content: "\e607";
}
.el-icon-self-shipin:before {
content: "\e60e";
}
.el-icon-self-wujiaoxing:before {
content: "\e614";
}
.el-icon-self-character:before {
content: "\e62e";
}
.el-icon-self-wenjian:before {
content: "\e650";
}
.el-icon-self-xuexi-:before {
content: "\e609";
}
.el-icon-self-PPT:before {
content: "\e602";
}
.el-icon-self-statistic:before {
content: "\e601";
}
<template>
<el-row type="flex" justify="center">
<el-col :xs="24" :sm="18" :md="12" :lg="9" :xl="6">
<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="手机号" @keyup.enter.native="onSubmitSetAccount">
</el-input>
</el-form-item>
<el-form-item prop="pwd">
<el-input v-model="setAccount.pwd" :disabled="isSendDisable" type="text" placeholder="短信验证码" @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>
<el-button type="primary" class="login-btn" @click="onSubmitSetAccount">登录</el-button>
</el-form-item>
<div class="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 }">密码登录</router-link>
</template>
<template v-else>
<router-link class="router-link-class" active-class="router-link-active-class" :to="{ name: '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 }">忘记密码</router-link>
</template>
<template v-else>
<router-link class="router-link-class" active-class="router-link-active-class" :to="{ name: 'forgetPwd' }">忘记密码</router-link>
</template>
</span>
</div>
</el-form>
</el-col>
</el-row>
</template>
<script>
import { request } from '@actions'
export default {
props: {
params: { type: Object, required: false, default: {} },
query: { type: Object, required: false, default: {} }
},
data () {
/* 账号输入正确时,才能获取验证码 */
let checkAccount = (rule, value, callback) => {
/* 手机格式 */
if (/^1[3-9]\d{9}$/.test(value)) {
this.isSendDisable = false
callback()
} else {
this.isSendDisable = true
callback(new Error('请输入正确格式的手机号'))
}
}
return {
isSendDisable: true, // 是否可以发送
isSendCode: false, // 是否已发送验证码
timeInterval: null, // 定时器,倒计时
sendBtnText: '发送验证码', // 按钮 文字
setAccount: {},
accountRules: {
'user': [
{ required: true, message: '请输入手机号', trigger: 'blur' },
{ validator: checkAccount, trigger: 'change' }
],
'pwd': [
{ required: true, message: '请输入短信验证码', 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)' })
request({
component: this,
actionName: 'loginAction',
functionName: 'sendCode',
data: {
mobile: this.setAccount.user
},
thenCallback: res => {
if (res.status === 200) {
/* 发送验证码不管是否成功,都开始倒计时 */
let time = 60
this.isSendCode = true
this.sendBtnText = '60s后重发'
this.timeInterval = setInterval(() => {
if (time-- > 0) {
this.sendBtnText = time + 's后重发'
} else {
this.isSendCode = false
this.sendBtnText = '发送验证码'
clearInterval(this.timeInterval)
}
}, 1000)
} else {
return new Error(JSON.stringify(res))
}
},
catchCallback: e => {},
finallyCallback: () => {}
})
}
},
/* 清空倒计时 */
clearTime () {
this.isSendCode = true
this.sendBtnText = '发送验证码'
clearInterval(this.timeInterval)
},
onSubmitSetAccount () {
this.$refs['setAccountform'].validate((valid) => {
if (valid) {
request({
component: this,
actionName: 'loginAction',
functionName: 'codeLogin',
data: {
mobile: this.setAccount.user,
code: this.setAccount.pwd
},
thenCallback: data => {
/* 查询上次跳转信息,并跳转回去 */
if (this.query.rd) {
this.$router.push({ path: decodeURIComponent(this.query.rd) })
} else {
this.$router.push({ path: '/app/my-learn/course' })
}
},
catchCallback: e => {},
finallyCallback: () => {}
})
} else {
this.$message.error('请根据输入框提示,检查输入项。')
return false
}
})
}
}
}
</script>
.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; }
/* forget 登录 */
.step1 { font-size: 0.16rem; width: 71%; margin: 0.6rem auto 0 auto; }
.step1 .go-back { margin-top: 0.2rem; text-align: left; }
.step2 { width: 71%; margin: 0.6rem auto 0 auto; }
.step2 .txt { margin-bottom: 0.3rem; font-size: 0.16rem; color: #ffffff; text-align: left; }
.step2 .el-form-item__label { font-size: 0.16rem; color: #ffffff; }
.step2 .operate { margin-top: 0.2rem; }
.step3 { width: 68%; margin: 0.6rem auto 0 auto; }
.step3 .el-form-item:last-child { margin-bottom: 0; }
.step3 .el-form-item__label { font-size: 0.16rem; color: #ffffff; text-align: left; }
/* Extra small devices (portrait phones, less than 576px) */
@media (max-width: 575px) {
html { font-size: 80px; }
.step3 { width: 90%; }
}
/* Small devices (landscape phones, 576px and up) */
@media (min-width: 576px) and (max-width: 767px) {
html { font-size: 80px; }
.step3 { width: 80%; }
}
/* Medium devices (tablets, 768px and up) */
@media (min-width: 768px) and (max-width: 991px) {
html { font-size: 80px; }
}
/* Large devices (desktops, 992px and up) */
@media (min-width: 992px) and (max-width: 1199px) {
html { font-size: 90px; }
}
/* Extra large devices (large desktops, 1200px and up) */
@media (min-width: 1200px) {
html { font-size: 100px; }
}
<template>
<div class="p-con">
<div class="hd">
<img src="./img/logo.png" alt="logo">
<div class="txt">在线学习系统</div>
</div>
<div class="bd">
<div class="top50 container">
<router-view></router-view>
</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>
<style lang="scss" scoped>
/* 这部分 架构 样式 基于 bootstrap - 4.1.3 栏删格系统 */
/* 由于压缩后 样式覆盖不上,直接采用 css方式 */
@import './login.css';
</style>
<template>
<div class="row">
<div class="hidden-xs-only col-md-5 col-lg-6 col-xl-6">
<img src="../img/login-left-bg.png" alt="左侧-sofia logo">
</div>
<div class="col-12 col-md-7 col-lg-5 col-xl-4">
<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="手机/邮箱" @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">
<el-input v-model="setAccount.pwd" type="password" placeholder="密码" @keyup.enter.native="onSubmitSetAccount">
<i slot="prefix" class="el-input__icon el-icon-self-mima"></i>
</el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" class="login-btn" @click="onSubmitSetAccount">登录</el-button>
</el-form-item>
<div class="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 }">验证码登录</router-link>
</template>
<template v-else>
<router-link class="router-link-class" active-class="router-link-active-class" :to="{ name: '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 }">忘记密码</router-link>
</template>
<template v-else>
<router-link class="router-link-class" active-class="router-link-active-class" :to="{ name: 'forgetPwd' }">忘记密码</router-link>
</template>
</span>
</div>
</el-form>
</div>
</div>
</template>
<script>
import { request } from '@actions'
import Base64 from 'Base64'
export default {
props: {
params: { type: Object, required: false, default: {} },
query: { type: Object, required: false, default: {} }
},
data () {
return {
setAccount: {},
accountRules: {
'user': [
{ required: true, message: '请输入账号', trigger: 'blur' },
{ pattern: /^(1[3-9]\d{9}|[\w\.]+@\w+(\.\w+)+)$/, message: '请输入正确格式的手机号/邮箱', trigger: 'change' } // eslint-disable-line
],
'pwd': [
{ required: true, message: '请输入密码', trigger: 'blur' }
]
}
}
},
methods: {
onSubmitSetAccount () {
this.$refs['setAccountform'].validate((valid) => {
if (valid) {
request({
component: this,
actionName: 'loginAction',
functionName: 'userLogin',
data: {
login_name: this.setAccount.user,
password: this.$md5('uokoaduw' + this.setAccount.pwd.split('').reverse().join('') + 'auhgniq'),
pwd: Base64.encode('uokoaduw' + this.setAccount.pwd.split('').reverse().join('') + 'auhgniq') // 追加上 密码
},
thenCallback: res => {
/* 查询上次跳转信息,并跳转回去 */
if (this.query.rd) {
this.$router.push({ path: decodeURIComponent(this.query.rd) })
} else {
window.G.pwd = Base64.encode('uokoaduw' + this.setAccount.pwd.split('').reverse().join('') + 'auhgniq')
this.$router.push({ path: '/app/my-learn/course' })
}
/* 重置账号、密码 */
// this.$refs['setAccountform'].resetFields()
},
catchCallback: () => {},
finallyCallback: () => {}
})
} else {
this.$message.error('请根据输入框提示,检查输入项。')
return false
}
})
}
}
}
</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">
<ul class="play-read-files">
<li><a :href="chapterRead.reading_attachment" target="_blank">{{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>
<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 () {
let 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 () {
let 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.
let swfVersionStr = '11.1.0'
// To use express install, set to playerProductInstall.swf, otherwise the empty string.
let xiSwfUrlStr = 'playerProductInstall.swf'
let 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模式
let params = {
quality: 'high',
bgcolor: '#000000',
allowscriptaccess: 'always',
allowfullscreen: 'true'
}
let 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 () {
let player = this.getPlayer()
if (player) {
return player.callAction('getCurrentTime')
} else {
return 0
}
},
// 设置视频跳转时间
setTimeTo (time) {
let player = this.getPlayer()
if (player) {
player.callAction('setCurrentTime', time + 2) // flash实际播放值会大概小个一两秒,因此添加偏移
}
},
// 执行“跳过片头”操作
skipBegin () {
let player = this.getPlayer()
if (player && player.callAction('getCurrentTime') < SKIP_BEGIN_TIME) {
player.callAction('setCurrentTime', SKIP_BEGIN_TIME)
}
},
// 设置视频尺寸
setSize (w, h) {
let player = this.getPlayer()
if (player) {
player.width = w
player.height = h
}
}
}
}
</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">
<template v-if="chapterWork.questions && chapterWork.questions.length" >
<ul>
<template v-for="(item, index) in chapterWork.questions">
<li v-bind:key="index">
<div class="work-number">{{index + 1}}.</div>
<div class="work-title">
<div class="edit_html" v-html="item.question_content"></div>
</div>
<textarea id="editor-chapterWork"></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> } -->
</li>
</template>
</ul>
</template>
<template v-else>
<!-- <p class="no-data">暂无数据</p> -->
</template>
<!-- <p class="text-danger">{this.state.error}</p> -->
<template v-if="this.deadLine">
<p style="color: red">请于截止日期 {{this.deadLine}} 前提交</p>
</template>
<div class="area-btns">
<el-button type="primary" @click="submitWork" :disabled="!!homeData.checker_time || deadLineFlag">{{homeData.checker_time ? '已批改' : '提交'}}</el-button>
<span class="help-info">&emsp;&emsp;在获老师批改之前,可以多次提交,将以最后一次提交为准</span>
<template v-if="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 '@actions'
import Base64 from 'Base64'
import CKEDITOR from 'CKEDITOR'
export default {
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 {
ckeditor: null,
successFileUrl: '',
filesArr: [],
file: {
id: 'WU_FILE_0',
name: '',
type: '',
lastModifiedDate: '',
size: '',
file: ''
},
homeData: {},
/* 设置是否可以初始化 ckeditor */
setTime: null,
isInit: false,
deadLine: '',
deadLineFlag: 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.chapterAction.getHomework(this.sid, this.cid, this.id).then(data => {
this.homeData = data
}).catch(e => { this.filesArr.pop(); this.$message.error(e.message) }).finally(() => {
this.setTime = setInterval(() => {
if (document.querySelector('#editor-chapterWork')) {
this.initckeditor()
if (this.homeData.work_contents) {
let json = JSON.parse(this.homeData.work_contents)
if (json[0].is_encoded) {
json[0].descreption = Base64.decode(json[0].descreption)
}
this.successFileUrl = json[0].file_url
this.ckeditor.setData(json[0].descreption)
} else {
this.successFileUrl = ''
this.ckeditor.setData('')
}
/* 滚动到头部 */
document.querySelector('.play-paper').scrollTop = 0
clearInterval(this.setTime)
}
}, 50)
loading.close()
})
setTimeout(() => {
cAction.chapterAction.getHomeworkStopTime(this.sid, this.cid, this.chapterId).then(data => {
this.deadLine = data.dead_line || ''
let deadLine = data.dead_line ? new Date(data.dead_line).getTime() : ''
// deadLine = new Date().getTime() - 100
this.deadLineFlag = ((new Date().getTime() > deadLine) && !!deadLine)
// console.log(this.deadLine)
}).catch(e => { this.$message.error(e.message) }).finally(() => {})
}, 500)
},
submitWork () {
if (!this.ckeditor.getData()) {
this.$message.error('请填写内容')
return
}
/* 只能提交 单个问题 */
const loading = this.$loading({ lock: true, text: '', spinner: '', background: 'rgba(255, 255, 255, 0.9)' })
let str = JSON.stringify([{
question_id: this.chapterWork.questions[0].id,
descreption: Base64.encode(this.ckeditor.getData()),
file_url: this.successFileUrl,
is_encoded: 1
}])
cAction.chapterAction.updateHomework({
semester_id: this.sid,
course_id: this.cid,
chapter_id: this.chapterId,
work_id: this.id,
work_contents: str,
duration: 30 + Math.floor(Math.random() * 1000)
}).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.chapterAction.uploadFile(this.file).then(data => {
this.successFileUrl = data.url
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-chapterWork', {
height: 300,
uiColor: '#eeeeee',
filebrowserImageUploadUrl: '/api/ckeditor/img/upload',
// 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' ] }
]
}))
}
},
watch: {
id: {
handler () {
this.loadAjax()
}
}
}
}
</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">
<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 '@actions'
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.chapterAction.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) {
let 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)' })
let _strContent = this.ckeditor.getData()
.replace(/<(a|b|p|em|span|strong|table|tbody|thead|th|tr|td|div).*?>/gi, '')
.replace(/<\/.*?>/gi, '')
cAction.chapterAction.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.chapterAction.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/ckeditor/img/upload',
// 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>
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论