提交 01e2e15d authored 作者: 王鹏飞's avatar 王鹏飞

merge...

差异被折叠。
......@@ -72,19 +72,22 @@
"@babel/runtime-corejs3": "^7.11.2"
},
"dependencies": {
"axios": "^0.19.2",
"cross-env": "^7.0.2",
"element-ui": "^2.13.0",
"@ckeditor/ckeditor5-build-classic": "^24.0.0",
"@ckeditor/ckeditor5-vue2": "^1.0.5",
"axios": "^0.21.0",
"core-js": "^3.8.1",
"cross-env": "^7.0.3",
"element-ui": "^2.14.1",
"js-cookie": "^2.2.1",
"lodash": "^4.17.15",
"lodash": "^4.17.20",
"qrcode.vue": "^1.7.0",
"qs": "^6.9.4",
"vue": "^2.6.11",
"vue-i18n": "^8.16.0",
"vue-loader": "^15.9.1",
"vue-meta-info": "^0.1.7",
"vue-router": "^3.1.6",
"vue-template-compiler": "^2.6.11",
"vuex": "^3.1.3",
"core-js": "^3.6.5"
"vue": "^2.6.12",
"vue-i18n": "^8.22.2",
"vue-loader": "^15.9.5",
"vue-meta": "^2.4.0",
"vue-router": "^3.4.9",
"vue-template-compiler": "^2.6.12",
"vuex": "^3.6.0"
}
}
......@@ -139,28 +139,28 @@ export default class CourseAction extends BaseACTION {
__.live.live_status = parseInt(__.live.live_status)
let str = ''
switch (__.live.live_status) {
case 1: str = '直播未开始'; break
case 2: str = '正在直播'; break
case 3: str = '直播结束'; break
case 4: str = '即将开始'; break
case 5: str = '直播结束'; break
default: str = '直播未开始'
case 1: str = _vIn.$t('live.notStarted'); break
case 2: str = _vIn.$t('live.liveStreaming'); break
case 3: str = _vIn.$t('live.liveEnd'); break
case 4: str = _vIn.$t('live.start'); break
case 5: str = _vIn.$t('live.liveEnd'); break
default: str = _vIn.$t('live.notStarted')
}
// 5分钟内显示“即将开始”,5~1小时内“N分钟后开始”,1~24小时内“N小时后开始”,1天以上“N天后开始”天就显示年月日
if (__.live.live_status === 1 && __.live.start_time) {
const time = (new Date(__.live.start_time).getTime() - new Date().getTime()) / 1000
if (time <= 5 * 60) {
str = '即将开始'
str = _vIn.$t('live.start')
} else if (time <= 1 * 60 * 60) {
str = parseInt(time / 60) + '分钟后开始'
str = _vIn.$t('live.startInMinutes', { minutes: parseInt(time / 60) })
} else if (time <= 24 * 60 * 60) {
str = parseInt(time / (60 * 60)) + '小时' + parseInt(time / 60 % 60) + '分钟后开始'
str = _vIn.$t('live.startInHours', { h: parseInt(time / (60 * 60)), min: parseInt(time / 60 % 60) })
} else {
str = parseInt(time / (24 * 60 * 60)) + '天后开始'
str = _vIn.$t('live.startInDay', { day: parseInt(time / (24 * 60 * 60)) })
}
}
if (__.live.live_status === 3 && __.live.enable_record && __.live.record_url) {
str = '观看回放'
str = _vIn.$t('live.watchReplay')
}
__.live.statusStr = str
}
......@@ -184,7 +184,7 @@ export default class CourseAction extends BaseACTION {
})
}
json.tabs1ChapterList.course.push({
title: '课程大作业',
title: _vIn.$t('action.courseAction.courseWork'),
isUp: true,
chapters: [],
id: 'course_work',
......@@ -193,7 +193,7 @@ export default class CourseAction extends BaseACTION {
type: 99
})
json.tabs1ChapterList.course.push({
title: '课程资料',
title: _vIn.$t('action.courseAction.courseData'),
isUp: true,
chapters: [],
id: 'course_info',
......@@ -202,7 +202,7 @@ export default class CourseAction extends BaseACTION {
type: 100
})
json.tabs1ChapterList.course.push({
title: '教学评估',
title: _vIn.$t('action.courseAction.teachingEvaluation'),
isUp: true,
chapters: [],
id: 'teach_evaluation',
......@@ -212,7 +212,7 @@ export default class CourseAction extends BaseACTION {
})
if (cur.course_examination) {
let courseExamChildren = []
if (data.exist_examination.length > 1) {
if (data.exist_examination && data.exist_examination.length > 1) {
courseExamChildren = data.exist_examination.map((item, index) => {
const map = ['一', '二', '三']
return {
......@@ -227,7 +227,7 @@ export default class CourseAction extends BaseACTION {
})
}
json.tabs1ChapterList.course.push({
title: '课程考试',
title: _vIn.$t('action.courseAction.courseExam'),
isUp: true,
chapters: courseExamChildren,
id: 'course_exam',
......
......@@ -122,11 +122,12 @@ export default class API {
})
})
} else if (status === 401) {
this.setConfirm('提示', '关闭', data.message).then(() => {})
_vIn.$router.push({ path: '/403' })
}
}
err = new Error(data.message || JSON.stringify(data))
err.code = data.code
err.status = data.status
} else {
err = new Error('msg:' + res.message + 'stack:' + res.stack)
err.code = 500
......
import BaseAPI from '@/api/base_api'
const httpRequest = new BaseAPI(webConf)
/**
* 上传文件
*/
export function uploadFile(data) {
return httpRequest.post('/api/lms/util/upload-file', data, {
headers: { 'Content-Type': 'multipart/form-data' }
})
}
<template>
<div style="height: 100%; width: 100%;">
<div style="height: 100%; width: 100%">
<router-view></router-view>
</div>
</template>
<script>
export default {
metaInfo() {
return {
title: this.$t('title')
}
}
}
</script>
<style lang="scss" scoped>
</style>
......@@ -5,18 +5,34 @@ export default class Before {
const UA = navigator.userAgent
this.opt = opt || {}
// 免登录列表
this.whiteList = ['login-normal', 'login-code', 'login-forget', 'studentHelp', 'teacherHelp']
this.whiteList = ['login-normal', 'login-code', 'login-forget', 'studentHelp', 'teacherHelp', '403', 'browser']
this.isMobile = /iphone/i.test(UA) || (/android/i.test(UA) && /mobile/i.test(UA))
this.isIe = window.ActiveXObject || 'ActiveXObject' in window
this.isChrome = !!window.chrome && (!!window.chrome.webstore || !!window.chrome.runtime)
// this.chromeVersion = 0
// if (this.isChrome) {
// const temp = UA.match(/Chrome\/([\d.]+)/)
// this.chromeVersion = temp ? parseFloat(temp[1]) : 0
// }
// this.notSupport = !this.isMobile && (this.isIe || (this.isChrome && this.chromeVersion < 70))
this.notSupport = !this.isMobile && this.isIe
// https://stackoverflow.com/questions/9847580/how-to-detect-safari-chrome-ie-firefox-and-opera-browser
}
async update(to, from, next) {
// 浏览器不支持
if (this.notSupport && to.name !== 'browser') {
next({ path: '/browser' })
return
}
// 免登录页面
if (this.whiteList.includes(to.name)) {
next()
return
}
// 检测登录状态
const isLogin = await this.isLogin()
const isLogin = await this.isLogin(next)
if (!isLogin) {
// next({
// path: '/login/index',
......@@ -34,7 +50,7 @@ export default class Before {
}
/* 获取用户信息 */
isLogin() {
isLogin(next) {
if (window.G.UserInfo) return true
return cAction.Other.getInfo()
.then(res => {
......@@ -45,7 +61,11 @@ export default class Before {
return false
}
})
.catch(() => {
.catch(res => {
if (res.status === 401) {
next({ path: '/403' })
return true
}
return false
})
}
......
import { uploadFile } from '@/api/common'
export default class MyUploadAdapter {
constructor(loader) {
// The file loader instance to use during the upload.
this.loader = loader
}
// Starts the upload process.
upload() {
return this.loader.file.then(
file =>
new Promise((resolve, reject) => {
this._sendRequest(resolve, reject, file)
})
)
}
_sendRequest(resolve, reject, file) {
uploadFile({ file })
.then(response => {
if (response.success) {
resolve({ default: response.url })
} else {
return reject(response.message)
}
})
.catch(response => {
return reject(response.message)
})
}
}
<template>
<div class="ckeditor">
<ckeditor
:editor="editor"
:value="value"
:disabled="disabled"
:config="editorConfig"
@ready="onEditorReady"
@input="onEditorInput"
></ckeditor>
</div>
</template>
<script>
import CKEditor from '@ckeditor/ckeditor5-vue2'
import ClassicEditor from '@ckeditor/ckeditor5-build-classic'
import '@ckeditor/ckeditor5-build-classic/build/translations/zh-cn'
import MyUploadAdapter from './MyUploadAdapter'
export default {
components: {
ckeditor: CKEditor.component
},
props: {
value: { type: String },
disabled: { type: Boolean, default: false }
},
data() {
return {
editor: ClassicEditor,
editorConfig: {
language: this.$i18n.locale.toLocaleLowerCase()
}
}
},
methods: {
onEditorReady(editor) {
const FileRepository = editor.plugins.get('FileRepository')
// 自定义上传图片插件
FileRepository.createUploadAdapter = loader => {
return new MyUploadAdapter(loader)
}
},
onEditorInput(value) {
this.$emit('input', value)
}
}
}
</script>
<style>
.ck-content {
min-height: 300px;
max-height: 500px;
word-break: break-word;
}
.ck-sticky-panel__content {
position: unset !important;
}
</style>
......@@ -54,7 +54,7 @@ export default {
data () { return { isWatch: true } },
methods: {
getList () {
const loading = this.$loading({ lock: true, text: '数据加载中,请稍后。。。', background: 'rgba(0, 0, 0, 0.7)' })
const loading = this.$loading({ lock: true, background: 'rgba(0, 0, 0, 0.7)' })
const obj = this.objFn.paramsFn(this)
while (this.tableData.length) {
this.tableData.pop()
......
......@@ -51,7 +51,7 @@ export default {
id: _data.val,
name: item.name
}
this.$emit('tapParam', param)
this.$emit('tapParam', param, item)
}
}
}
......
<template>
<div class="tap-language-switch">
<el-menu class="el-menu-demo" mode="horizontal" @select="handleSelect">
<el-submenu index="1">
<template slot="title">{{ show }}</template>
<template v-for="item in language.arr">
<template v-for="(v, k) in item">
<el-menu-item :key="k" :index="k">{{v}}</el-menu-item>
</template>
</template>
</el-submenu>
</el-menu>
</div>
<div class="language-switch">
<el-select size="medium" v-model="value" @change="handleChange">
<el-option v-for="item in languages" :key="item.value" :label="item.name" :value="item.value"> </el-option>
</el-select>
</div>
</template>
<script>
import Cookies from 'js-cookie'
import language from '@/assets/languages/language'
export default {
name: 'sLanguage',
componentName: 'sLanguage',
data () {
const _defaultLocale = 'zh-CN'
const _lang = Cookies.get('lang') || window.navigator.language || window.navigator.userLanguage || ''
if (_lang) {
if (language[_lang]) {
this.$i18n.locale = _lang
} else {
let flag = true
/* 做一下 兼容性处理 */
for (const k in language) {
const reg = new RegExp(k, 'gi')
if (reg.test(_lang)) {
this.$i18n.locale = k
flag = false
break
}
}
if (flag) {
/* 当前语言版本 - 不再我们的语言库中,那么默认 en */
this.$i18n.locale = _defaultLocale
Cookies.set('lang', _defaultLocale, { expires: 30, domain: '.ezijing.com' })
}
}
} else {
this.$i18n.locale = _defaultLocale
Cookies.set('lang', _defaultLocale, { expires: 30, domain: '.ezijing.com' })
}
let show = language[this.$i18n.locale].show
language[this.$i18n.locale].arr.forEach((item, i) => {
if (item[this.$i18n.locale]) {
show = item[this.$i18n.locale]
}
})
name: 'LanguageSwitch',
data() {
return {
show: show,
language: language[this.$i18n.locale]
value: this.$i18n.locale,
languages: [
{ name: '中文', value: 'zh-CN' },
{ name: 'English', value: 'en' }
]
}
},
mounted () {},
methods: {
handleSelect (key, val) {
Cookies.set('lang', key, { expires: 30, domain: '.ezijing.com' })
this.$i18n.locale = key
handleChange(value) {
Cookies.set('lang', value, { expires: 30, domain: '.ezijing.com' })
this.$i18n.locale = value
/* 刷新页面 */
this.$router.go(0)
}
......@@ -71,15 +32,11 @@ export default {
</script>
<style lang="scss" scoped>
.tap-language-switch {
position: absolute;
right: 100px;
.el-menu {
border: none;
.language-switch {
width: 100px;
::v-deep .el-input__inner {
background: transparent;
}
.el-menu--horizontal > .el-submenu.is-active .el-submenu__title {
border: none;
border: 0;
}
}
</style>
......@@ -4,45 +4,42 @@
<img class="logo" src="https://zws-imgs-pub.ezijing.com/pc/base/logo_white.svg" />
<div class="text-title" @click="setStatus">{{ $t('components.learnSysLayout.navigation.title') }}</div>
</div>
<!-- <s-language></s-language> -->
<div class="notify" @click="goNotify()">{{ $t('components.learnSysLayout.navigation.tip') }}
<div class="num" v-if="this.$store.getters.myMsg !=0">{{ this.$store.getters.myMsg }}</div>
<div class="nav-right">
<div class="notify" @click="goNotify()">
{{ $t('components.learnSysLayout.navigation.tip') }}
<div class="num" v-if="this.$store.getters.myMsg != 0">{{ this.$store.getters.myMsg }}</div>
</div>
<!-- <language-switch /> -->
</div>
</div>
</template>
<script>
// import sLanguage from '@/components/languageSwitch/index.vue'
import LanguageSwitch from '@/components/languageSwitch/index.vue'
import cAction from '../../action'
export default {
components: {},
data () {
components: { LanguageSwitch },
data() {
return {
num: this.$store.getters.myMsg
}
},
mounted () {
// request({
// component: this,
// actionName: 'Other',
// functionName: 'getNavMsg',
// data: {},
// thenCallback: data => {
// this.$store.commit('myMsg', data.num)
// },
// catchCallback: () => {},
// finallyCallback: () => {}
// })
cAction.Other.getNavMsg().then(data => {
mounted() {
cAction.Other.getNavMsg()
.then(data => {
this.$store.commit('myMsg', data.num)
}).catch(e => { this.$message.error(e.message) }).finally(() => { })
})
.catch(e => {
this.$message.error(e.message)
})
.finally(() => {})
},
methods: {
goNotify () {
goNotify() {
this.$router.push({ path: '/app/other/message' })
},
setStatus () {
setStatus() {
if (this.status) {
this.status = false
} else {
......@@ -56,9 +53,10 @@ export default {
<style scoped lang="scss">
.menu {
width: 100%;
height: 100%;
color: #ffffff;
display: flex;
align-items: center;
justify-content: space-between;
color: #fff;
.nav-left {
float: left;
position: relative;
......@@ -78,6 +76,10 @@ export default {
font-size: 16px;
}
}
.nav-right {
display: flex;
align-items: center;
}
.notify {
position: relative;
float: right;
......
......@@ -110,7 +110,7 @@ export default {
case '1-3': this.$router.push({ path: '/app/learn/report-active-list' }); break
case '2-1': this.$router.push({ path: '/app/grade/credit' }); break
case '3': this.$router.push({ path: '/app/feedback/feedback-list' }); break
case '4': this.$router.push({ path: '/app/affairs-hall/hall' }); break
case '4': this.$router.push({ path: '/app/offices' }); break
}
},
/* 修改头像 - 跳转方法 */
......
## 组件简介
| 字段值 | 说明 | 字段属性 | 默认值 |
| ------- | ------------------------- | ------- | ----- |
| `type` | 类型:`String`; 说明:组件类型名 | 自定义字段 | `upload-form` |
| `action` | 类型:`String`; 说明:上传请求接口path | 自定义字段 | `` |
| `deleteAction` | 类型:`String`; 说明:删除请求接口path | 自定义字段 | `` |
| `html` | 类型:`String`; 说明:上传说明,支持html | 自定义字段 | `` |
| `label` | 类型:`String`; 说明:组件左侧显示名称 | element-ui el-form-item对应字段 | `''` |
| `label-width` | 类型:`String`; 说明:组件左侧显示名称宽度(加单位),父级设置可以子级继承 | element-ui el-form-item对应字段 | `''` |
| `required` | 类型:`Boolean`; 说明:标识是否必填 | element-ui el-form-item对应字段 | `false` |
| `disabled` | 类型:`Boolean`; 说明:标识是否只读 | element-ui el-form-item对应字段 | `false` |
| `model` | 类型:`String`; 说明:表单提交name值和回显对照字段 | 自定义字段 | `''` |
| `placeholder` | 类型:`String`; 说明:组件input框中,默认提示文字 | element-ui el-input对应字段 | `''` |
| `attrs` | 类型:`Object`; 说明:定义标签上Data属性值 | element-ui对应字段 | `{}` |
| `rules` | 类型:`Array`; 说明:组件错误提示规则 | element-ui el-form-item对应字段 | `[]` |
### Demo Example:
``` js
return {
type: 'upload-form',
label: '姓名',
labeWidth: '160px',
required: true,
disabled: false,
model: 'uploadArrs',
action: '',
data: {
},
deleteAction: '',
deleteData: {
},
html: `
<div style="color: #72818c; font-size: 14px;">
<p style="margin: 0;">申请者需要将有效身份证件原件扫描或者拍照后提交。</p>
<p style="margin: 0;">请您提供有效身份证件的扫描件,身份证与台港澳居民大陆通行证应包括正反两面扫描件。</p>
<p style="margin: 0;">只上传一个文件,多份文件需合并到一个文件后打印出来检查无误后再上传。</p>
<p style="margin: 0;">上传文件仅限“jpg,jpeg,gif,png”格式,文件小于10MB。</p>
</div>
`,
attrs: {
multiple: false,
limit: 1
},
rules: [
{
required: true,
message: '请上传',
trigger: 'blur'
}
]
}
```
* 其他属性 [参考文档]([https://](https://element.eleme.cn/#/zh-CN/component/input))
import Upload from './src/uploadForm.vue'
/* istanbul ignore next */
Upload.install = function (Vue) {
Vue.component(Upload.name, Upload)
}
export default Upload
function getError (action, option, xhr) {
let msg
if (xhr.response) {
msg = `${xhr.response.error || xhr.response}`
} else if (xhr.responseText) {
msg = `${xhr.responseText}`
} else {
msg = `fail to post ${action} ${xhr.status}`
}
const err = new Error(msg)
err.status = xhr.status
err.method = 'post'
err.url = action
return err
}
function getBody (xhr) {
const text = xhr.responseText || xhr.response
if (!text) {
return text
}
try {
return JSON.parse(text)
} catch (e) {
return text
}
}
export function deleteFile (option) {
if (typeof XMLHttpRequest === 'undefined') {
return
}
// eslint-disable-next-line no-undef
const xhr = new XMLHttpRequest()
let action = option.action
xhr.onerror = function error (e) {
option.onError(e)
}
xhr.onload = function onload () {
if (xhr.status < 200 || xhr.status >= 300) {
return option.onError(getError(action, option, xhr))
}
option.onSuccess(getBody(xhr))
}
xhr.open('delete', action, true)
if (option.withCredentials && 'withCredentials' in xhr) {
xhr.withCredentials = true
}
const headers = option.headers || {}
for (let item in headers) {
if (headers.hasOwnProperty(item) && headers[item] !== null) {
xhr.setRequestHeader(item, headers[item])
}
}
xhr.send()
return xhr
}
export default function upload (option) {
if (typeof XMLHttpRequest === 'undefined') {
return
}
// eslint-disable-next-line no-undef
const xhr = new XMLHttpRequest()
const action = option.action
if (xhr.upload) {
xhr.upload.onprogress = function progress (e) {
if (e.total > 0) {
e.percent = e.loaded / e.total * 100
}
option.onProgress(e)
}
}
// eslint-disable-next-line no-undef
const formData = new FormData()
if (option.data) {
Object.keys(option.data).forEach(key => {
formData.append(key, option.data[key])
})
}
formData.append(option.filename, option.file, option.file.name)
xhr.onerror = function error (e) {
option.onError(e)
}
xhr.onload = function onload () {
if (xhr.status < 200 || xhr.status >= 300) {
return option.onError(getError(action, option, xhr))
}
option.onSuccess(getBody(xhr))
}
xhr.open('post', action, true)
if (option.withCredentials && 'withCredentials' in xhr) {
xhr.withCredentials = true
}
const headers = option.headers || {}
for (let item in headers) {
if (headers.hasOwnProperty(item) && headers[item] !== null) {
xhr.setRequestHeader(item, headers[item])
}
}
xhr.send(formData)
return xhr
}
<template>
<div class="upload-form">
<div class="u-babel">{{ item.label }}</div>
<el-upload style="display: inline-block;"
:action="item.action"
:data="item.data"
:before-upload="beforeUploadFile"
:on-success="onSuccessFile"
:with-credentials="true"
:show-file-list="false"
:disabled="(item.disabled || false) || !isUpload"
v-bind="item.attrs || {}"
>
<el-button type="primary" size="small" :disabled="!isUpload">点击上传</el-button>
<template v-if="formData[item.model] !== null && formData[item.model] !== '' && formData[item.model] !== undefined">
<div class="self-icon el-icon-circle-check" style="color: #237f00;"></div>
</template>
<div class="self-icon el-icon-circle-close" style="color: #b01c40;"></div>
</el-upload>
<div style="overflow: hidden; padding: 10px 0 0 0;">
<template v-if="filesArr.length">
<!-- 遍历显示文件 -->
<template v-for="(item, index) in filesArr">
<template v-if="/(jpeg)|(jpg)|(png)|(gif)/gi.test(item.url)">
<div v-bind:key="item.id" class="show-file">
<template v-if="!(item.disabled || false) && isUpload">
<div class="close" @click="deleteFiles(index)">X</div>
</template>
<el-avatar shape="square" :size="100" fit="contain" :src="item.url"></el-avatar>
<span class="title">{{ item.sso_file_name }}</span>
<div class="hover">
<a target="_blank" :href="item.url">下载</a>
</div>
</div>
</template>
<template v-else>
<div v-bind:key="item.id" class="show-file">
<template v-if="!(item.disabled || false) && isUpload">
<div class="close" @click="deleteFiles(index)">X</div>
</template>
<el-avatar shape="square" :size="100" fit="contain" :src="item.url"></el-avatar>
<span class="title">{{ item.sso_file_name }}</span>
<div class="hover">
<a target="_blank" :href="item.url">下载</a>
</div>
</div>
</template>
</template>
</template>
</div>
<div class='info' style="line-height: 1.5;" v-html="item.html"></div>
</div>
</template>
<script>
// import { deleteFile } from './ajax'
export default {
name: 'UploadForm',
componentName: 'UploadForm',
props: {
item: {
type: Object,
default () {
return {}
}
},
formData: {
type: Object,
default () {
return {}
}
},
isUpload: {
type: Boolean,
default () {
return true
}
}
},
data () {
const tmpArr = this.formData[this.item.model] || []
this.formData[this.item.model] = tmpArr
return {
project_id: '',
filesArr: tmpArr
}
},
methods: {
beforeUploadFile (file) {},
onSuccessFile (response, file, fileList) {
response.url = response.url || response.file || ''
response.sso_file_name = file.name
this.filesArr.push(response)
// this.$emit('onSubmit')
},
deleteFiles (index) {
this.filesArr.splice(index, 1)
// let temp = this.filesArr[index]
// deleteFile({
// action: this.item.deleteAction + '/' + temp.id + '?project_id=' + this.item.data.project_id,
// onError: () => {},
// onSuccess: (res) => {
// if (res.status === 200) {
// this.filesArr.splice(index, 1)
// }
// }
// })
}
},
watch: {
filesArr: {
immediate: true,
deep: true,
handler (value) {
if (this.formData[this.item.model].length !== value.length) {
this.formData[this.item.model] = value
}
}
}
}
}
</script>
<style lang="scss">
.u-babel {
display: inline-block;
margin-right: 10px;
}
.self-icon {
display: none !important;
vertical-align: middle;
margin-left: 10px;
font-size: 21px;
line-height: 22px;
}
.is-error .self-icon.el-icon-circle-close { display: inline-block !important; }
.is-success .self-icon.el-icon-circle-check { display: inline-block !important; }
.show-file {
position: relative;
float: left;
margin-right: 10px;
.close {
position: absolute;
z-index: 10;
right: -10px;
top: -10px;
width: 20px;
height: 20px;
color: #fff;
font-size: 12px;
line-height: 20px;
text-align: center;
background: #efefef;
border-radius: 50%;
cursor: pointer;
}
.el-avatar {
img {
width: 100%;
}
}
.title {
position: absolute;
left: 0;
bottom: 8px;
width: 100%;
padding-left: 5px;
font-size: 12px;
line-height: 20px;
background: #efefef;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
word-break: break-all;
box-sizing: border-box;
}
.hover {
display: none;
position: absolute;
z-index: 9;
top: 0;
left: 0;
height: 100px;
width: 100%;
background: rgba(0, 0, 0, 0.2);
line-height: 100px;
text-align: center;
a {
color: #f1f1f1;
}
}
&:hover {
.hover {
display: block;
}
}
}
</style>
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta content="origin" name="referrer">
<title>紫荆-Kelley金融硕士学习系统</title>
<meta name="viewport" id="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, shrink-to-fit=no">
<meta name="renderer" content="webkit" />
<meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1" />
<meta content="origin" name="referrer" />
<title></title>
<meta
name="viewport"
content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, shrink-to-fit=no"
/>
<!-- 直接引入aliyun播放插件 CSS -->
<link rel="stylesheet" href="https://g.alicdn.com/de/prismplayer/2.8.8/skins/default/aliplayer-min.css" />
</head>
<body>
<link rel="stylesheet" href="https://g.alicdn.com/de/prismplayer/2.9.3/skins/default/aliplayer-min.css" />
</head>
<body>
<div id="app"></div>
<!-- es5 兼容 新方法 -->
<!-- <script type="text/javascript" src="https://zws-imgs-pub.ezijing.com/static/build/learn-mba/static/compatible/es5-shim.min.js"></script>
<script type="text/javascript" src="https://zws-imgs-pub.ezijing.com/static/build/learn-mba/static/compatible/es5-sham.min.js"></script> -->
<!-- 三方插件引入 -->
<script type="text/javascript" src="https://zws-imgs-pub.ezijing.com/static/build/learn-mba/static/ckeditor/ckeditor.js"></script>
<script type="text/javascript" src="https://zws-imgs-pub.ezijing.com/static/build/learn-mba/static/videoJs/videoJs.js"></script>
<!-- common -->
<script type="text/javascript" src="https://zws-imgs-pub.ezijing.com/static/build/learn-mba/static/common/base64.js"></script>
<script type="text/javascript" src="https://zws-imgs-pub.ezijing.com/static/build/learn-mba/static/common/md5.js"></script>
<script type="text/javascript" src="https://zws-imgs-pub.ezijing.com/static/build/learn-mba/static/common/jQuery-2.1.4.min.js"></script>
<script type="text/javascript" src="https://zws-imgs-pub.ezijing.com/static/build/learn-mba/static/common/runtime.js"></script>
<script src="https://zws-imgs-pub.ezijing.com/static/build/learn-mba/static/common/base64.js"></script>
<script src="https://zws-imgs-pub.ezijing.com/static/build/learn-mba/static/common/jQuery-2.1.4.min.js"></script>
<script src="https://zws-imgs-pub.ezijing.com/static/build/learn-mba/static/common/runtime.js"></script>
<!-- 直接引入aliyun播放插件 JS -->
<script type="text/javascript" charset="utf-8" src="https://g.alicdn.com/de/prismplayer/2.8.8/aliplayer-min.js"></script>
<script type="text/javascript" charset="utf-8" src="https://player.alicdn.com/aliplayer/presentation/js/aliplayercomponents.min.js"></script> <!-- 解决iframe嵌套,CC视频在safri中打开免登陆兼容问题 -->
<script src="//view.csslcloud.net/js/_fix_.js"></script>
<script src="//view.csslcloud.net/js/jquery-1.9.0.min.js" type="text/javascript"></script>
<script src="//view.csslcloud.net/js/sdk/3.1.0/liveSDK.js" type="text/javascript"></script>
<script charset="utf-8" src="https://g.alicdn.com/de/prismplayer/2.9.3/aliplayer-min.js"></script>
<!-- <script type="text/javascript" src="https://zws-imgs-pub.ezijing.com/static/build/learn-mba/static/notify/notification.js"></script> -->
<!-- <script type="text/javascript" src="https://zws-imgs-pub.ezijing.com/static/build/learn-mba/static/errorCollection/collection.js"></script> -->
<!--[if lt IE 9]>
<script src="https://zws-imgs-pub.ezijing.com/static/build/learn-mba/static/compatible/console-polyfill.js"></script>
<script src="https://zws-imgs-pub.ezijing.com/static/build/learn-mba/static/compatible/html5shiv.min.js"></script>
<script src="https://zws-imgs-pub.ezijing.com/static/build/learn-mba/static/compatible/respond.min.js"></script>
<![endif]-->
<!-- 解决iframe嵌套,CC视频在safri中打开免登陆兼容问题 -->
<script src="//view.csslcloud.net/js/_fix_.js"></script>
<!-- <script src="//view.csslcloud.net/js/sdk/3.1.0/liveSDK.js" type="text/javascript"></script> -->
<!-- Matomo -->
<script type="text/javascript">
......
import Vue from 'vue' // 引入vue框架
import VueRouter from 'vue-router' // 使用 vue-router
import createRouter from './router' // router定义
import router from './router' // router定义
import VueI18n from 'vue-i18n' // 使用 国际化
import createI18n from './assets/languages' // 国际化定义
import store from './store'
import App from './app.vue' // 初始化 vue页面
import UploadForm from './components/upload-form'
import './style.scss' // 公共样式
import MetaInfo from 'vue-meta-info'
import Element from 'element-ui'
import modules from './modules'
import Modules from '@/modules'
import createBefore from './components/beforeEnter'
import store from './store'
import _ from 'lodash'
import VueMeta from 'vue-meta'
Vue.use(VueMeta)
Vue.prototype.$_ = _
Vue.use(VueRouter)
Vue.use(UploadForm)
Vue.component(UploadForm.name, UploadForm)
const router = createRouter()
Vue.use(VueI18n)
const i18n = createI18n()
Vue.use(MetaInfo)
Vue.use(Element, { i18n: (key, value) => i18n.t(key, value) })
Vue.use(modules, { i18n })
Vue.use(Modules, { i18n, router })
/* 设置全局变量 */
window.G = Vue.prototype.$GLOBAL = {
VERSION: 'PC-1.0.0'
}
// window.Promise = Promise
/**
* 定义全局变量 - 用作全局事件发布订阅
* 使用 vue自带事件 $emit 和 $on 进行发布订阅
*/
Vue.prototype.VueEvent = new Vue()
/* 创建实例之前,通过导航守卫,处理部分逻辑,如:是否直接进入系统 */
const before = createBefore()
const routerBefore = createBefore()
/* 导航守卫 */
router.beforeEach((to, from, next) => {
before.update(to, from, next)
routerBefore.update(to, from, next)
// next()
})
......
......@@ -20,7 +20,7 @@
{{ $t('pages.learn.discussDetail.discuss') }}({{ data.comments.length }})
</div>
<div class="right-txt" @click="$emit('btnlike', { tagId: data.tag ? data.tag.id : null, ansId: data.id })">
点赞({{ data.tag_count }})
{{ $t('pages.learn.discussDetail.like') }}({{ data.tag_count }})
</div>
</div>
<template v-if="commentVisible">
......
......@@ -22,7 +22,7 @@
</div>
</template>
<template v-if='!discussList.length'>
<div class='no-data'>暂无相关讨论</div>
<div class='no-data'>{{ $t('DiscussModule.DiscussList.noData') }}</div>
</template>
</div>
</template>
......
......@@ -143,7 +143,7 @@ export default {
// 通过点击不同的回复按钮 拼成所要提交不同的参数
replyComposeParam (obj, answer) {
this.$refs.focusTextarea.focus()
this.inputStatus.placeholder = obj.to !== undefined ? `回复${obj.to}:` : '回复:'
this.inputStatus.placeholder = obj.to !== undefined ? `${this.$t('DiscussModule.DiscussDetail.reply')}${obj.to}:` : `${this.$t('DiscussModule.DiscussDetail.reply')}:`
this.answer = answer || false
const commonParam = {
questionId: this.detail.id,
......
/* Automatically generated by './build/bin/build-entry.js' */
/* 模块基于 element-ui,一定在 element-ui后加载 */
import LoginModule from './login-module'
import Discuss from './discuss'
import Viewer from './viewer'
import Offices from './offices'
const components = [
LoginModule,
Discuss
]
const components = [Discuss, Viewer, Offices]
const install = function (Vue, opts = {}) {
const install = function(Vue, opts = {}) {
components.forEach(component => {
Vue.use(component, opts)
})
......@@ -20,8 +15,4 @@ if (typeof window !== 'undefined' && window.Vue) {
install(window.Vue)
}
export default {
install,
LoginModule,
Discuss
}
export default { install, ...components }
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;
}
@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,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') 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";
}
{
"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
}
]
}
{
"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>
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论