3.8.1
6
.babelrc
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"presets": [
|
||||
"@vue/app"
|
||||
],
|
||||
"plugins": ["@babel/plugin-syntax-dynamic-import"]
|
||||
}
|
||||
9
.editorconfig
Normal file
@@ -0,0 +1,9 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
0
.eslintignore
Normal file
21
.eslintrc.js
Normal file
@@ -0,0 +1,21 @@
|
||||
module.exports = {
|
||||
root: true,
|
||||
'extends': [
|
||||
'plugin:vue/essential',
|
||||
'@vue/standard'
|
||||
],
|
||||
rules: {
|
||||
// allow async-await
|
||||
'generator-star-spacing': 'off',
|
||||
// allow debugger during development
|
||||
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
|
||||
'vue/no-parsing-error': [2, {
|
||||
'x-invalid-end-tag': false
|
||||
}],
|
||||
'no-undef': 'off',
|
||||
'camelcase': 'off'
|
||||
},
|
||||
parserOptions: {
|
||||
parser: 'babel-eslint'
|
||||
}
|
||||
}
|
||||
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
.idea
|
||||
node_modules
|
||||
5
.postcssrc.js
Normal file
@@ -0,0 +1,5 @@
|
||||
module.exports = {
|
||||
plugins: {
|
||||
autoprefixer: {}
|
||||
}
|
||||
}
|
||||
5
.travis.yml
Normal file
@@ -0,0 +1,5 @@
|
||||
language: node_js
|
||||
node_js: stable
|
||||
script: npm run lint
|
||||
notifications:
|
||||
email: false
|
||||
3
cypress.json
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"pluginsFile": "tests/e2e/plugins/index.js"
|
||||
}
|
||||
20527
package-lock.json
generated
Normal file
83
package.json
Normal file
@@ -0,0 +1,83 @@
|
||||
{
|
||||
"name": "iview-admin",
|
||||
"version": "2.0.0",
|
||||
"author": "Lison<lison16new@163.com>",
|
||||
"private": false,
|
||||
"scripts": {
|
||||
"dev": "vue-cli-service serve --open",
|
||||
"build": "vue-cli-service build",
|
||||
"lint": "vue-cli-service lint",
|
||||
"test:unit": "vue-cli-service test:unit",
|
||||
"test:e2e": "vue-cli-service test:e2e"
|
||||
},
|
||||
"dependencies": {
|
||||
"axios": "^0.18.0",
|
||||
"babel-polyfill": "^6.26.0",
|
||||
"clipboard": "^2.0.0",
|
||||
"codemirror": "^5.38.0",
|
||||
"cookiejar": "^2.1.2",
|
||||
"countup": "^1.8.2",
|
||||
"cropperjs": "^1.2.2",
|
||||
"dayjs": "^1.7.7",
|
||||
"echarts": "^4.0.4",
|
||||
"html2canvas": "^1.0.0-alpha.12",
|
||||
"iview": "^3.2.2",
|
||||
"iview-area": "^1.5.17",
|
||||
"js-cookie": "^2.2.0",
|
||||
"js-md5": "^0.7.3",
|
||||
"moment": "^2.24.0",
|
||||
"quill-image-resize-module": "^3.0.0",
|
||||
"simplemde": "^1.11.2",
|
||||
"sortablejs": "^1.7.0",
|
||||
"tree-table-vue": "^1.1.0",
|
||||
"v-org-tree": "^1.0.6",
|
||||
"vue": "^2.5.10",
|
||||
"vue-circleprogressbar": "^1.3.0",
|
||||
"vue-codemirror": "^4.0.6",
|
||||
"vue-cookies": "^1.6.1",
|
||||
"vue-cropper": "^0.4.9",
|
||||
"vue-i18n": "^7.8.0",
|
||||
"vue-quill-editor": "^3.0.6",
|
||||
"vue-router": "^3.0.7",
|
||||
"vuedraggable": "^2.16.0",
|
||||
"vuex": "^3.0.1",
|
||||
"wangeditor": "^3.1.1",
|
||||
"xlsx": "^0.13.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
|
||||
"@vue/cli-plugin-babel": "^3.0.1",
|
||||
"@vue/cli-plugin-eslint": "^3.0.1",
|
||||
"@vue/cli-plugin-unit-mocha": "^3.0.1",
|
||||
"@vue/cli-service": "^3.0.1",
|
||||
"@vue/eslint-config-standard": "^3.0.0-beta.10",
|
||||
"@vue/test-utils": "^1.0.0-beta.10",
|
||||
"chai": "^4.1.2",
|
||||
"eslint-plugin-cypress": "^2.0.1",
|
||||
"less": "^2.7.3",
|
||||
"less-loader": "^4.0.5",
|
||||
"lint-staged": "^6.0.0",
|
||||
"mockjs": "^1.0.1-beta3",
|
||||
"node-sass": "^4.13.0",
|
||||
"sass-loader": "^8.0.0",
|
||||
"vue-template-compiler": "^2.5.13"
|
||||
},
|
||||
"browserslist": [
|
||||
"> 1%",
|
||||
"last 2 versions",
|
||||
"not ie <= 8"
|
||||
],
|
||||
"gitHooks": {
|
||||
"pre-commit": "lint-staged"
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.js": [
|
||||
"vue-cli-service lint",
|
||||
"git add"
|
||||
],
|
||||
"*.vue": [
|
||||
"vue-cli-service lint",
|
||||
"git add"
|
||||
]
|
||||
}
|
||||
}
|
||||
BIN
public/favicon.ico
Normal file
|
After Width: | Height: | Size: 17 KiB |
17
public/index.html
Normal file
@@ -0,0 +1,17 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||
<link rel="icon" href="/favicon.ico" type="image/x-icon">
|
||||
<title></title>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>
|
||||
<strong>We're sorry but iview-admin doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
|
||||
</noscript>
|
||||
<div id="app"></div>
|
||||
<!-- built files will be auto injected -->
|
||||
</body>
|
||||
</html>
|
||||
162
src/App.vue
Normal file
@@ -0,0 +1,162 @@
|
||||
<template>
|
||||
<div id="app">
|
||||
<router-view/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'App'
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.size{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
html,body{
|
||||
.size;
|
||||
overflow: hidden;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
#app {
|
||||
.size;
|
||||
}
|
||||
|
||||
#app .edit_container, #app .quill-editor {
|
||||
height: inherit!important;
|
||||
}
|
||||
//iview组件样式修改
|
||||
#app {
|
||||
.ivu-layout {
|
||||
background: none;
|
||||
}
|
||||
.ivu-modal-body {
|
||||
margin-top: 120px;
|
||||
}
|
||||
.ivu-layout-header {
|
||||
height: 70px;
|
||||
line-height: 80px;
|
||||
background: none;
|
||||
}
|
||||
|
||||
.ivu-form-item {
|
||||
margin-top: 10px;
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
.ivu-form-item:nth-last-child(1) {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.ivu-form-item:nth-child(1) {
|
||||
margin-top: 0;
|
||||
}
|
||||
.ivu-input, .ivu-input-number-input {
|
||||
height: 40px !important;
|
||||
font-size: 14px !important;
|
||||
color: #000 !important;
|
||||
}
|
||||
.ivu-input-with-prefix {
|
||||
padding-left: 45px !important;
|
||||
}
|
||||
|
||||
.ivu-checkbox-wrapper {
|
||||
font-size: 14px !important;
|
||||
}
|
||||
.ivu-spin-large .ivu-spin-dot {
|
||||
margin: 0 auto;
|
||||
margin-top: 200px;
|
||||
margin-bottom: 250px;
|
||||
}
|
||||
}
|
||||
|
||||
//页面间公共样式
|
||||
#product-setting, #homePageSetting, #homePageSettingH5 {
|
||||
.subtitle {
|
||||
color: #b2b2b2;
|
||||
}
|
||||
.title {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
}
|
||||
.flexbox {
|
||||
display: flex;
|
||||
// justify-content: space-between;
|
||||
|
||||
.flexLeft {
|
||||
width: 460px;
|
||||
margin-right: 60px;
|
||||
}
|
||||
.flexRight {
|
||||
width: 460px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.setting-section {
|
||||
// width: 800px;
|
||||
padding: 25px;
|
||||
background:#fff;
|
||||
.section-header {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.section-content {
|
||||
margin-top: 15px;
|
||||
|
||||
// img {
|
||||
// width: 120px;
|
||||
// height: 120px;
|
||||
// margin: 3px;
|
||||
// object-fit: cover;
|
||||
// }
|
||||
}
|
||||
|
||||
.prefix {
|
||||
line-height: 40px;
|
||||
padding-left: 8px;
|
||||
color: rgb(121, 131, 153);
|
||||
}
|
||||
.tips {
|
||||
font-size:12px;
|
||||
color: #8787af;
|
||||
margin-top: 15px;
|
||||
}
|
||||
.label {
|
||||
padding-top: 12px;
|
||||
padding-bottom: 3px;
|
||||
position: relative;
|
||||
top: 0;
|
||||
}
|
||||
}
|
||||
.setting-section:nth-child(n+2) {
|
||||
margin-top: 20px;
|
||||
}
|
||||
.header.setting-section {
|
||||
padding: 6px 12px;
|
||||
background: #6686cb;
|
||||
text-align: right;
|
||||
position: relative;
|
||||
margin-bottom: 10px;
|
||||
margin-top: -6px;
|
||||
|
||||
.ivu-btn-small {
|
||||
width: 60px;
|
||||
height: 25px;
|
||||
margin-left: 6px;
|
||||
}
|
||||
.ivu-btn-small:nth-child(1) {
|
||||
margin-right: 6px;
|
||||
}
|
||||
|
||||
.head_title {
|
||||
color: #fff;
|
||||
position: absolute;
|
||||
font-size: 16px;
|
||||
top: 5px;
|
||||
left: 14px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
89
src/api/account.js
Normal file
@@ -0,0 +1,89 @@
|
||||
import axios from '@/libs/api.request'
|
||||
|
||||
// export const GetConfigAppFrontHome = () => {
|
||||
// return axios.request({
|
||||
// method: 'get',
|
||||
// url: '?r=AjaxApiMallConfig/GetConfigAppFrontHome'
|
||||
// })
|
||||
// }
|
||||
|
||||
export const Register = (data) => {
|
||||
return axios.request({
|
||||
method: 'post',
|
||||
url: 'platform.php?s=Platform.User.Register',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export const Login = (data) => {
|
||||
return axios.request({
|
||||
method: 'post',
|
||||
url: 'platform.php?s=Platform.User.UserLogin',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 获取当前登录用户自己的个人信息
|
||||
export const GetAccountInfo = (data) => {
|
||||
return axios.request({
|
||||
method: 'post',
|
||||
url: 'platform.php?s=Platform.User.Profile',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 修改个人信息
|
||||
export const SetAccountInfo = (data) => {
|
||||
return axios.request({
|
||||
method: 'post',
|
||||
url: 'platform.php?s=Platform.User.UpdateProfile',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 获取最近登录
|
||||
|
||||
// 修改密码
|
||||
export const ResetPwd = (data) => {
|
||||
return axios.request({
|
||||
method: 'post',
|
||||
url: 'platform.php?s=Platform.User.AlterPass',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 获取用户信息
|
||||
export const GetMyPermission = (data) => {
|
||||
return axios.request({
|
||||
method: 'post',
|
||||
url: 'platform.php?s=Platform.Permission.GetMyPermission',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 获取第三方绑定信息
|
||||
export const AuthorizationBindResult = (data) => {
|
||||
return axios.request({
|
||||
method: 'post',
|
||||
url: 'platform.php?s=Platform.UserBind.AuthorizationBindResult',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 读取第三方配置
|
||||
export const AuthorizationConfig = (data) => {
|
||||
return axios.request({
|
||||
method: 'post',
|
||||
url: 'platform.php?s=Platform.Authorization_Authorization.AuthorizationConfig',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 解除绑定
|
||||
export const AuthorizationUnBind = (data) => {
|
||||
return axios.request({
|
||||
method: 'post',
|
||||
url: 'platform.php?s=Platform.UserBind.AuthorizationUnBind',
|
||||
data
|
||||
})
|
||||
}
|
||||
8
src/api/app.js
Normal file
@@ -0,0 +1,8 @@
|
||||
import axios from '@/libs/api.request'
|
||||
|
||||
// export const GetConfigAppFrontHome = () => {
|
||||
// return axios.request({
|
||||
// method: 'get',
|
||||
// url: '?r=AjaxApiMallConfig/GetConfigAppFrontHome'
|
||||
// })
|
||||
// }
|
||||
71
src/api/application.js
Normal file
@@ -0,0 +1,71 @@
|
||||
/* export function indexGetIndexData (data) {
|
||||
return axios.request({
|
||||
url: 'api/admin.php?s=Admin.Index.GetIndexData',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
} */
|
||||
import axios from '@/libs/api.request'
|
||||
|
||||
// 应用管理列表
|
||||
export const GetAppList = (data) => {
|
||||
return axios.request({
|
||||
method: 'post',
|
||||
url: 'platform.php?s=Platform.Apps.GetAppList',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 添加新应用
|
||||
export const AddApp = (data) => {
|
||||
return axios.request({
|
||||
method: 'post',
|
||||
url: 'platform.php?s=Platform.Apps.AddApp',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 根据app_key查找应用
|
||||
export const GetAppInfo = (data) => {
|
||||
return axios.request({
|
||||
method: 'post',
|
||||
url: 'platform.php?s=Platform.Apps.GetMyAppInfo',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 编辑应用
|
||||
export const EditApp = (data) => {
|
||||
return axios.request({
|
||||
method: 'post',
|
||||
url: 'platform.php?s=Platform.Apps.EditMyApp',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 注销应用
|
||||
export const CancelApp = (data) => {
|
||||
return axios.request({
|
||||
method: 'post',
|
||||
url: 'platform.php?s=Platform.Apps.CancelApp',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 获取下拉应用列表
|
||||
export const GetAppDropdownList = (data) => {
|
||||
return axios.request({
|
||||
method: 'post',
|
||||
url: 'platform.php?s=Platform.Apps.GetAppDropdownList',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 获取全部接口及权限列表
|
||||
export const GetAllAppApis = (data) => {
|
||||
return axios.request({
|
||||
method: 'post',
|
||||
url: 'platform.php?s=Platform.Rights.GetAllAppApis',
|
||||
data
|
||||
})
|
||||
}
|
||||
22
src/api/data.js
Normal file
@@ -0,0 +1,22 @@
|
||||
import axios from '@/libs/api.request'
|
||||
|
||||
// export const GetConfigAppFrontHome = () => {
|
||||
// return axios.request({
|
||||
// method: 'get',
|
||||
// url: '?r=AjaxApiMallConfig/GetConfigAppFrontHome'
|
||||
// })
|
||||
// }
|
||||
export const GetSiteData = () => {
|
||||
return axios.request({
|
||||
method: 'get',
|
||||
url: 'platform.php?s=Platform.Site.Index'
|
||||
})
|
||||
}
|
||||
|
||||
export const UploadFile = (data) => {
|
||||
return axios.request({
|
||||
method: 'post',
|
||||
url: 'platform.php?s=Platform.File.Upload',
|
||||
data
|
||||
})
|
||||
}
|
||||
18
src/api/home.js
Normal file
@@ -0,0 +1,18 @@
|
||||
import axios from '@/libs/api.request'
|
||||
|
||||
// 获取首页数据
|
||||
export const GetIndexData = (data) => {
|
||||
return axios.request({
|
||||
method: 'post',
|
||||
url: 'platform.php?s=Platform.Index_Index.GetIndexData',
|
||||
data
|
||||
})
|
||||
}
|
||||
// 获取接口数据
|
||||
export const GetDataFlow = (data) => {
|
||||
return axios.request({
|
||||
method: 'post',
|
||||
url: 'platform.php?s=Platform.Index_Index.GetDataFlow',
|
||||
data
|
||||
})
|
||||
}
|
||||
79
src/api/order.js
Normal file
@@ -0,0 +1,79 @@
|
||||
import axios from '@/libs/api.request'
|
||||
|
||||
// export const GetConfigAppFrontHome = () => {
|
||||
// return axios.request({
|
||||
// method: 'get',
|
||||
// url: '?r=AjaxApiMallConfig/GetConfigAppFrontHome'
|
||||
// })
|
||||
// }
|
||||
export const GetSiteData = () => {
|
||||
return axios.request({
|
||||
method: 'get',
|
||||
url: 'platform.php?s=Platform.Site.Index'
|
||||
})
|
||||
}
|
||||
// 创建订单
|
||||
export const CreateOrder = (data) => {
|
||||
return axios.request({
|
||||
method: 'post',
|
||||
url: 'platform.php?s=Platform.Mall_Mall.CreateOrder',
|
||||
data
|
||||
})
|
||||
}
|
||||
// 准备下单
|
||||
export const PreviewOrder = (data) => {
|
||||
return axios.request({
|
||||
method: 'post',
|
||||
url: 'platform.php?s=Platform.Mall_Mall.PreviewOrder',
|
||||
data
|
||||
})
|
||||
}
|
||||
// 在线支付
|
||||
export const PreviewPay = (data) => {
|
||||
return axios.request({
|
||||
method: 'post',
|
||||
url: 'platform.php?s=Platform.Mall_Mall.PreviewPay',
|
||||
data
|
||||
})
|
||||
}
|
||||
// 开始支付
|
||||
export const StartPay = (data) => {
|
||||
return axios.request({
|
||||
method: 'post',
|
||||
url: 'platform.php?s=Platform.Mall_Mall.StartPay',
|
||||
data
|
||||
})
|
||||
}
|
||||
// 支付成功
|
||||
export const PaySuccess = (data) => {
|
||||
return axios.request({
|
||||
method: 'post',
|
||||
url: 'platform.php?s=Platform.Mall_Mall.PaySuccess',
|
||||
data
|
||||
})
|
||||
}
|
||||
// 获取我的订单列表
|
||||
export const GetMyOrderList = (data) => {
|
||||
return axios.request({
|
||||
method: 'post',
|
||||
url: 'platform.php?s=Platform.Mall_Mall.GetMyOrderList',
|
||||
data
|
||||
})
|
||||
}
|
||||
// 获取我的流量套餐
|
||||
export const GetMyFlowList = (data) => {
|
||||
return axios.request({
|
||||
method: 'post',
|
||||
url: 'platform.php?s=Platform.Mall_Mall.GetMyFlowList',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 前台组合套餐列表
|
||||
export const GetProductMoreList = (data) => {
|
||||
return axios.request({
|
||||
method: 'post',
|
||||
url: 'platform.php?s=Platform.Mall_Mall.GetProductMoreList',
|
||||
data
|
||||
})
|
||||
}
|
||||
64
src/api/workorder.js
Normal file
@@ -0,0 +1,64 @@
|
||||
import axios from '@/libs/api.request'
|
||||
|
||||
// 获取工单列表
|
||||
export const LstWorkOrder = (data) => {
|
||||
return axios.request({
|
||||
method: 'post',
|
||||
url: 'platform.php?s=Platform.WorkOrder_WorkOrder.LstWorkOrder',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 新增工单
|
||||
export const AddWorkOrder = (data) => {
|
||||
return axios.request({
|
||||
method: 'post',
|
||||
url: 'platform.php?s=Platform.WorkOrder_WorkOrder.AddWorkOrder',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 模块列表
|
||||
export const GetModuleLst = (data) => {
|
||||
return axios.request({
|
||||
method: 'post',
|
||||
url: 'platform.php?s=Platform.WorkOrder_WorkOrder.GetModuleLst',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 工单详情
|
||||
export const DetailWorkOrder = (data) => {
|
||||
return axios.request({
|
||||
method: 'post',
|
||||
url: 'platform.php?s=Platform.WorkOrder_WorkOrder.DetailWorkOrder',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 更新工单信息
|
||||
export const UpdateChatRecodeWorkOrder = (data) => {
|
||||
return axios.request({
|
||||
method: 'post',
|
||||
url: 'platform.php?s=Platform.WorkOrder_WorkOrder.UpdateChatRecodeWorkOrder',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 上图
|
||||
export const UploadImg = (data) => {
|
||||
return axios.request({
|
||||
method: 'post',
|
||||
url: 'platform.php?s=Platform.File.Upload',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 获取上传类型UploadType
|
||||
export const UploadType = (data) => {
|
||||
return axios.request({
|
||||
method: 'post',
|
||||
url: 'platform.php?s=Platform.File.UploadType',
|
||||
data
|
||||
})
|
||||
}
|
||||
BIN
src/assets/icons/file-icon/doc_logo.jpg
Normal file
|
After Width: | Height: | Size: 27 KiB |
BIN
src/assets/icons/file-icon/html_logo.jpg
Normal file
|
After Width: | Height: | Size: 22 KiB |
BIN
src/assets/icons/file-icon/others_logo.jpg
Normal file
|
After Width: | Height: | Size: 21 KiB |
BIN
src/assets/icons/file-icon/ppt_logo.jpg
Normal file
|
After Width: | Height: | Size: 27 KiB |
BIN
src/assets/icons/file-icon/xls_logo.jpg
Normal file
|
After Width: | Height: | Size: 27 KiB |
BIN
src/assets/icons/file-icon/文件.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
src/assets/icons/file-icon/文件.psd
Normal file
37
src/assets/icons/iconfont.css
Normal file
@@ -0,0 +1,37 @@
|
||||
|
||||
@font-face {font-family: "iconfont";
|
||||
src: url('iconfont.eot?t=1541579316141'); /* IE9*/
|
||||
src: url('iconfont.eot?t=1541579316141#iefix') format('embedded-opentype'), /* IE6-IE8 */
|
||||
url('data:application/x-font-woff;charset=utf-8;base64,d09GRgABAAAAAAiEAAsAAAAADmgAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABHU1VCAAABCAAAADMAAABCsP6z7U9TLzIAAAE8AAAARAAAAFY8eUnXY21hcAAAAYAAAACjAAACLi+YJuBnbHlmAAACJAAABAgAAAcg4dRWHmhlYWQAAAYsAAAAMQAAADYTL8piaGhlYQAABmAAAAAgAAAAJAfdA4xobXR4AAAGgAAAABQAAAAsLAD//2xvY2EAAAaUAAAAGAAAABgImgpGbWF4cAAABqwAAAAfAAAAIAEcAG5uYW1lAAAGzAAAAUUAAAJtPlT+fXBvc3QAAAgUAAAAbgAAAI54roygeJxjYGRgYOBikGPQYWB0cfMJYeBgYGGAAJAMY05meiJQDMoDyrGAaQ4gZoOIAgCKIwNPAHicY2BkYWCcwMDKwMHUyXSGgYGhH0IzvmYwYuRgYGBiYGVmwAoC0lxTGByeMTx/ytzwv4EhhrmBoRkozAiSAwDuUwzMeJzlkUEKwkAMRd/YabXFhQvxFF6qPYPrUujGY7jyIr1JoZNjtMnEhag3MOEN5MMk8D9QAoVyVSKEJwGrh6oh6wVN1iM3nc+cVImJVKdOehlklElmWdYVstp+ql8VdIv15a1NLW0zFXsO7Kjz3erH/3+rY37vr6kxnx1LKNWOJZlaxxJNnWOpSu+ot8jgqMvI6KjfyOSo88jsaAbI4tBsig89rQB4nLVUTWwbRRSeNzO767i2g7N/FP9s7MRrE5ON4/V6rSZyU0PiINSSNImES4IUoapWz6hEiqiMBDQqEojkAkiFStyKRC+9VSoFCeUEyqESVUAqEkcu3OAQb3hrJxAXwSGI3X0/szPz5vvm2x0i7O/vf8IJe5VkSJnUyUtklRBQJE1VIjRtUafkmk6pSu2ipleh4+xikkKxSksWTUeo8m8NoagpYtoslTmxrLl37z64e33esuJjU8P5Wd262LxoPVnPZ06Pxfe+C0YjkhSJygPhQCA8ABPOykwuN7NyuRvgUnAgLEnhATkaCQQiUe/7XKUyV6nQz+t2o7l66+rs7NVbq82GXTdrdjxjRGU5amTids2bUDMFtzCsqsMYMqr3IDY6OT05GjsI8Exv/6CSkOWEQigh+y3clxY5QVTcEZFIGtHLxDUJs6WsHR1y9SFKdr1HggCp3V1ICYL36OOpVmvKN9bC1u6R3vZ0qwWtVovgJfqOfUvfIYxIWL+fyETHNVJqSkIT1JTjW8ZWh3yDJDz0ctvsyt51etvrg9/QHhqGlzMM+vbmizPnDWPLMNbW19e7tffvsBzL99aWEfBRY46t+tbe3PypXv/IMDYN43WsQBe9HL2NC33RuxABrPsG+xH3o4bVRE2KgCRqulbWNf8W/UYVHM129aKra24VshZkq+CWD/Oy6Xt8cGYEthgHVlVliCfynAlqjo6oysTKlYUAD4docMI5/1ZioN+GwZNBcTwWUmTdBUqhTwX29QebXzF4An4JJMzwfMl+WQ01+IlQZVR4yhie53ycA16pOI/ODiYNGK4MChdCgXNnX5gIJXPCSYnf2OF850aQ+zJIyOs+u8+mMO8jQdwtg1TIWVRjKAnFcslMi8KfGUPoSUCergUyUk77dMyS69Ms6tijKZKYwUGKbpfdzu+iYeZYAHMFiOVi+MD7h9mb99qC0L7X8c+XatMfTj97KZ5IxJt/pd43tYYQKEjAnXMOB6kQEBrwg+LPjindAPOHNdC3q3ait0I3/ZIunZEARLNYNEUA6czSP3N/7j9wz6ZESdX0VNl1zGNS/szbQaQSIGk4DtVPcZf8AgXpf9A2OyTit5s2syZmand46bhEe2WtodLHkvaoqtTXuXN2/c42WADP9HGfbUcUW7JgqHss4xHtlMys679FqUomdP9VJBQBdnlPABBubpuNwqnmQj6/0HwNQzKxDUJFgKiXurBG6dqFjmeBzsvtRPJgGIZThYa5fdOvsReOticPh6JHHXxsv7ItJpOniYPYsmZ/x0QD/o5P105DeQwF6MH33ogoLi+KQp7zpY3HQV5bFMURzheXeds7gpP+jKNXljjHuYvXHke7cdCxLLZf6YX7B63UcCV4nGNgZGBgAOKAN2ZR8fw2Xxm4WRhA4AbHYRMY/f///1oWBuYGIJeDgQkkCgAvWgs2AAAAeJxjYGRgYG7438AQw8Lw/z8DAwsDA1AEBXADAHXiBHJ4nGNhYGBgYfj/nwVM48cATwECKwAAAAAAjAC6AOgBFAGAAf4CbgLqAzgDkHicY2BkYGDgZkhiYGcAASYg5gJCBob/YD4DABOmAYsAeJxlj01OwzAQhV/6B6QSqqhgh+QFYgEo/RGrblhUavdddN+mTpsqiSPHrdQDcB6OwAk4AtyAO/BIJ5s2lsffvHljTwDc4Acejt8t95E9XDI7cg0XuBeuU38QbpBfhJto41W4Rf1N2MczpsJtdGF5g9e4YvaEd2EPHXwI13CNT+E69S/hBvlbuIk7/Aq30PHqwj7mXle4jUcv9sdWL5xeqeVBxaHJIpM5v4KZXu+Sha3S6pxrW8QmU4OgX0lTnWlb3VPs10PnIhVZk6oJqzpJjMqt2erQBRvn8lGvF4kehCblWGP+tsYCjnEFhSUOjDFCGGSIyujoO1Vm9K+xQ8Jee1Y9zed0WxTU/3OFAQL0z1xTurLSeTpPgT1fG1J1dCtuy56UNJFezUkSskJe1rZUQuoBNmVXjhF6XNGJPyhnSP8ACVpuyAAAAHicbYhdDoIwEAb3a6k/YIIX8VArWewmdJFWJOnpJTG+OQ+TzJCjLy39p4ODR4OAA4444YwWHS7U3IVzn6Voldtb8ksHnvohrlqjjmw1rmzXsvdT7fEbblnCmOfNfJIYStJJfGIL27yb6AOCGR89AAA=') format('woff'),
|
||||
url('iconfont.ttf?t=1541579316141') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+*/
|
||||
url('iconfont.svg?t=1541579316141#iconfont') format('svg'); /* iOS 4.1- */
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
font-family:"iconfont" !important;
|
||||
font-size:16px;
|
||||
font-style:normal;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.icon-bear:before { content: "\e600"; }
|
||||
|
||||
.icon-resize-vertical:before { content: "\e7c3"; }
|
||||
|
||||
.icon-chuizhifanzhuan:before { content: "\e661"; }
|
||||
|
||||
.icon-shuipingfanzhuan:before { content: "\e662"; }
|
||||
|
||||
.icon-qq:before { content: "\e609"; }
|
||||
|
||||
.icon-frown:before { content: "\e77e"; }
|
||||
|
||||
.icon-meh:before { content: "\e780"; }
|
||||
|
||||
.icon-smile:before { content: "\e783"; }
|
||||
|
||||
.icon-man:before { content: "\e7e2"; }
|
||||
|
||||
.icon-woman:before { content: "\e7e5"; }
|
||||
|
||||
BIN
src/assets/icons/iconfont.eot
Normal file
56
src/assets/icons/iconfont.svg
Normal file
@@ -0,0 +1,56 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
|
||||
<!--
|
||||
2013-9-30: Created.
|
||||
-->
|
||||
<svg>
|
||||
<metadata>
|
||||
Created by iconfont
|
||||
</metadata>
|
||||
<defs>
|
||||
|
||||
<font id="iconfont" horiz-adv-x="1024" >
|
||||
<font-face
|
||||
font-family="iconfont"
|
||||
font-weight="500"
|
||||
font-stretch="normal"
|
||||
units-per-em="1024"
|
||||
ascent="896"
|
||||
descent="-128"
|
||||
/>
|
||||
<missing-glyph />
|
||||
|
||||
<glyph glyph-name="bear" unicode="" d="M1024 683.008q0-70.656-46.08-121.856 46.08-89.088 46.08-193.536 0-96.256-39.936-181.248t-109.568-147.968-162.816-99.328-199.68-36.352-199.68 36.352-162.304 99.328-109.568 147.968-40.448 181.248q0 104.448 46.08 193.536-46.08 51.2-46.08 121.856 0 37.888 13.824 71.168t37.376 58.368 55.808 39.424 68.096 14.336q43.008 0 78.848-18.432t59.392-50.176q46.08 17.408 96.256 26.624t102.4 9.216 102.4-9.216 96.256-26.624q24.576 31.744 59.904 50.176t78.336 18.432q36.864 0 68.608-14.336t55.296-39.424 37.376-58.368 13.824-71.168zM205.824 268.288q10.24 0 18.944 10.24t15.36 28.672 10.24 42.496 3.584 51.712-3.584 51.712-10.24 41.984-15.36 28.16-18.944 10.24q-9.216 0-17.92-10.24t-15.36-28.16-10.752-41.984-4.096-51.712 4.096-51.712 10.752-42.496 15.36-28.672 17.92-10.24zM512-31.744000000000028q53.248 0 99.84 13.312t81.408 35.84 54.784 52.736 19.968 65.024q0 33.792-19.968 64t-54.784 52.736-81.408 35.84-99.84 13.312-99.84-13.312-81.408-35.84-54.784-52.736-19.968-64q0-34.816 19.968-65.024t54.784-52.736 81.408-35.84 99.84-13.312zM818.176 268.288q10.24 0 18.944 10.24t15.36 28.672 10.24 42.496 3.584 51.712-3.584 51.712-10.24 41.984-15.36 28.16-18.944 10.24q-9.216 0-17.92-10.24t-15.36-28.16-10.752-41.984-4.096-51.712 4.096-51.712 10.752-42.496 15.36-28.672 17.92-10.24zM512 235.51999999999998q39.936 0 68.096-9.728t28.16-24.064-28.16-24.064-68.096-9.728-68.096 9.728-28.16 24.064 28.16 24.064 68.096 9.728z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="resize-vertical" unicode="" d="M512 896C229.248 896 0 666.752 0 384s229.248-512 512-512 512 229.248 512 512S794.752 896 512 896zM576 192l64 0-128-128-128 128 64 0L448 576l-64 0 128 128 128-128-64 0L576 192z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="chuizhifanzhuan" unicode="" d="M286.01856 645.08416l472.4224 0 0-146.2784-472.4224 0 0 146.2784ZM87.19872 420.37248l885.80096 0 0-70.87104-885.80096 0 0 70.87104ZM773.55008 268.05248l0-31.0016L270.6688 237.05088l0 31.0016L773.55008 268.05248zM773.55008 121.4208l0-31.0016L270.6688 90.4192l0 31.0016L773.55008 121.4208zM742.54848 240.75776l31.0016 0 0-123.04896-31.0016 0L742.54848 240.75776zM270.70464 240.57856l31.0016 0 0-123.04896-31.0016 0L270.70464 240.57856z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="shuipingfanzhuan" unicode="" d="M252.76928 596.096l146.2784 0 0-472.42752-146.2784 0 0 472.42752ZM477.48096 810.65472l70.87104 0 0-885.80608-70.87104 0 0 885.80608ZM629.80096 611.2l31.0016 0 0-502.88128-31.0016 0L629.80096 611.2zM776.42752 611.2l31.0016 0 0-502.88128-31.0016 0L776.42752 611.2zM657.09056 580.1984l0 31.0016 123.04896 0 0-31.0016L657.09056 580.1984zM657.27488 108.35456l0 31.0016 123.04896 0 0-31.0016L657.27488 108.35456z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="qq" unicode="" d="M147.372058 491.394284c-5.28997-13.909921 2.431986-22.698872 0-75.732573-0.682996-14.25092-62.165649-78.762555-86.569511-145.791177-24.192863-66.517625-27.519845-135.978232 9.811944-163.285078 37.419789-27.305846 72.191593 90.879487 76.757567 73.685584 1.961989-7.509958 4.436975-15.317914 7.423958-23.338868a331.945126 331.945126 0 0 1 61.140655-101.162429c5.929967-6.783962-36.009797-19.199892-61.140655-61.99365-25.173858-42.751759 7.209959-120.49032 132.223254-120.49032 161.27909 0 197.288886 56.70368 200.574868 56.447681 12.031932-0.895995 12.841928 0 25.599855 0 15.572912 0 9.129948-1.279993 23.593867 0 7.807956 0.682996 86.186514-67.839617 194.686901-56.447681 184.873956 19.45589 156.586116 81.40754 142.079198 120.48932-15.103915 40.83277-68.692612 59.946662-66.303626 62.549647 44.28775 48.938724 51.285711 79.018554 66.346626 123.9463 6.143965 18.473896 49.066723-101.674426 82.089537-73.685584 13.781922 11.690934 41.301767 60.24566 13.781922 163.285078-27.519845 102.996419-80.767544 126.505286-79.615551 145.791177 2.389987 40.191773 1.023994 68.436614-1.023994 75.732573-9.812945 35.4128-30.378829 27.604844-30.378829 35.4128C858.450044 730.752933 705.10691 896 515.966978 896s-342.398067-165.289067-342.398068-369.192916c0-16.169909-14.378919-4.223976-26.154852-35.4128z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="frown" unicode="" d="M336 475m-48 0a48 48 0 1 1 96 0 48 48 0 1 1-96 0ZM688 475m-48 0a48 48 0 1 1 96 0 48 48 0 1 1-96 0ZM512 832C264.6 832 64 631.4 64 384s200.6-448 448-448 448 200.6 448 448S759.4 832 512 832z m263-711c-34.2-34.2-74-61-118.3-79.8C611 21.8 562.3 12 512 12c-50.3 0-99 9.8-144.8 29.2-44.3 18.7-84.1 45.6-118.3 79.8-34.2 34.2-61 74-79.8 118.3C149.8 285 140 333.7 140 384s9.8 99 29.2 144.8c18.7 44.3 45.6 84.1 79.8 118.3 34.2 34.2 74 61 118.3 79.8C413 746.2 461.7 756 512 756c50.3 0 99-9.8 144.8-29.2 44.3-18.7 84.1-45.6 118.3-79.8 34.2-34.2 61-74 79.8-118.3C874.2 483 884 434.3 884 384s-9.8-99-29.2-144.8c-18.7-44.3-45.6-84.1-79.8-118.2zM512 363c-85.5 0-155.6-67.3-160-151.6-0.2-4.6 3.4-8.4 8-8.4h48.1c4.2 0 7.8 3.2 8.1 7.4C420 259.9 461.5 299 512 299s92.1-39.1 95.8-88.6c0.3-4.2 3.9-7.4 8.1-7.4H664c4.6 0 8.2 3.8 8 8.4-4.4 84.3-74.5 151.6-160 151.6z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="meh" unicode="" d="M336 475m-48 0a48 48 0 1 1 96 0 48 48 0 1 1-96 0ZM688 475m-48 0a48 48 0 1 1 96 0 48 48 0 1 1-96 0ZM512 832C264.6 832 64 631.4 64 384s200.6-448 448-448 448 200.6 448 448S759.4 832 512 832z m263-711c-34.2-34.2-74-61-118.3-79.8C611 21.8 562.3 12 512 12c-50.3 0-99 9.8-144.8 29.2-44.3 18.7-84.1 45.6-118.3 79.8-34.2 34.2-61 74-79.8 118.3C149.8 285 140 333.7 140 384s9.8 99 29.2 144.8c18.7 44.3 45.6 84.1 79.8 118.3 34.2 34.2 74 61 118.3 79.8C413 746.2 461.7 756 512 756c50.3 0 99-9.8 144.8-29.2 44.3-18.7 84.1-45.6 118.3-79.8 34.2-34.2 61-74 79.8-118.3C874.2 483 884 434.3 884 384s-9.8-99-29.2-144.8c-18.7-44.3-45.6-84.1-79.8-118.2zM664 331H360c-4.4 0-8-3.6-8-8v-48c0-4.4 3.6-8 8-8h304c4.4 0 8 3.6 8 8v48c0 4.4-3.6 8-8 8z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="smile" unicode="" d="M336 475m-48 0a48 48 0 1 1 96 0 48 48 0 1 1-96 0ZM688 475m-48 0a48 48 0 1 1 96 0 48 48 0 1 1-96 0ZM512 832C264.6 832 64 631.4 64 384s200.6-448 448-448 448 200.6 448 448S759.4 832 512 832z m263-711c-34.2-34.2-74-61-118.3-79.8C611 21.8 562.3 12 512 12c-50.3 0-99 9.8-144.8 29.2-44.3 18.7-84.1 45.6-118.3 79.8-34.2 34.2-61 74-79.8 118.3C149.8 285 140 333.7 140 384s9.8 99 29.2 144.8c18.7 44.3 45.6 84.1 79.8 118.3 34.2 34.2 74 61 118.3 79.8C413 746.2 461.7 756 512 756c50.3 0 99-9.8 144.8-29.2 44.3-18.7 84.1-45.6 118.3-79.8 34.2-34.2 61-74 79.8-118.3C874.2 483 884 434.3 884 384s-9.8-99-29.2-144.8c-18.7-44.3-45.6-84.1-79.8-118.2zM664 363h-48.1c-4.2 0-7.8-3.2-8.1-7.4C604 306.1 562.5 267 512 267s-92.1 39.1-95.8 88.6c-0.3 4.2-3.9 7.4-8.1 7.4H360c-4.6 0-8.2-3.8-8-8.4 4.4-84.3 74.5-151.6 160-151.6s155.6 67.3 160 151.6c0.2 4.6-3.4 8.4-8 8.4z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="man" unicode="" d="M874 776H622c-3.3 0-6-2.7-6-6v-56c0-3.3 2.7-6 6-6h160.4L583.1 508.7c-50 38.5-111 59.3-175.1 59.3-76.9 0-149.3-30-203.6-84.4S120 356.9 120 280s30-149.3 84.4-203.6C258.7 22 331.1-8 408-8s149.3 30 203.6 84.4C666 130.7 696 203.1 696 280c0 64.1-20.8 124.9-59.2 174.9L836 654.1V494c0-3.3 2.7-6 6-6h56c3.3 0 6 2.7 6 6V746c0 16.5-13.5 30-30 30zM408 68c-116.9 0-212 95.1-212 212s95.1 212 212 212 212-95.1 212-212-95.1-212-212-212z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="woman" unicode="" d="M909.7 739.4l-42.2 42.2c-3.1 3.1-8.2 3.1-11.3 0L764 689.4l-84.2 84.2c-3.1 3.1-8.2 3.1-11.3 0l-42.1-42.1c-3.1-3.1-3.1-8.1 0-11.3l84.2-84.2-135.5-135.3c-50 38.5-111 59.3-175.1 59.3-76.9 0-149.3-30-203.6-84.4S112 348.9 112 272s30-149.3 84.4-203.6C250.7 14 323.1-16 400-16s149.3 30 203.6 84.4C658 122.7 688 195.1 688 272c0 64.2-20.9 125.1-59.3 175.1l135.4 135.4 84.2-84.2c3.1-3.1 8.2-3.1 11.3 0l42.1 42.1c3.1 3.1 3.1 8.1 0 11.3l-84.2 84.2 92.2 92.2c3.1 3.1 3.1 8.2 0 11.3zM400 60c-116.9 0-212 95.1-212 212s95.1 212 212 212 212-95.1 212-212-95.1-212-212-212z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
|
||||
|
||||
</font>
|
||||
</defs></svg>
|
||||
|
After Width: | Height: | Size: 8.2 KiB |
BIN
src/assets/icons/iconfont.ttf
Normal file
BIN
src/assets/icons/iconfont.woff
Normal file
BIN
src/assets/images/accomplish.png
Normal file
|
After Width: | Height: | Size: 3.0 KiB |
BIN
src/assets/images/alarmclock.png
Normal file
|
After Width: | Height: | Size: 6.2 KiB |
BIN
src/assets/images/alipay.png
Normal file
|
After Width: | Height: | Size: 6.0 KiB |
BIN
src/assets/images/cash.png
Normal file
|
After Width: | Height: | Size: 9.3 KiB |
1
src/assets/images/error-page/error-401.svg
Normal file
|
After Width: | Height: | Size: 31 KiB |
1
src/assets/images/error-page/error-404.svg
Normal file
|
After Width: | Height: | Size: 26 KiB |
1
src/assets/images/error-page/error-500.svg
Normal file
|
After Width: | Height: | Size: 33 KiB |
BIN
src/assets/images/headImg.jpg
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
src/assets/images/icon-qr-qq-wechat.png
Normal file
|
After Width: | Height: | Size: 42 KiB |
1
src/assets/images/icon-social-bilibili.svg
Normal file
|
After Width: | Height: | Size: 6.4 KiB |
1
src/assets/images/icon-social-juejin.svg
Normal file
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1547543883733" class="icon" style="" viewBox="0 0 1272 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="16831" xmlns:xlink="http://www.w3.org/1999/xlink" width="496.875" height="400"><defs><style type="text/css"></style></defs><path d="M729.64116345 165.27693991L634.32650881 90.125l-99.5625 78.52693991-5.17887981 4.16056009 104.74137981 83.50215546 105.09051682-83.50215546-9.77586218-7.53556009z m361.21228445 291.47198236l-456.78879245 360.19396555-456.49784537-359.99030128L110.125 511.12715547l523.93965546 413.11745671 524.23060335-413.35021555-67.44181091-54.14547436z m-456.78879245 29.21120673L385.4784479 290.00646554 318.06573237 344.12284454l315.96982771 249.16810336 316.28987101-249.40086136-67.41271555-54.14547436-248.84806008 196.21551682z" fill="#006cff" p-id="16832"></path></svg>
|
||||
|
After Width: | Height: | Size: 955 B |
1
src/assets/images/icon-social-twitter.svg
Normal file
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1547543874130" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="16498" xmlns:xlink="http://www.w3.org/1999/xlink" width="400" height="400"><defs><style type="text/css"></style></defs><path d="M511.8 0.6C229.2 0.6 0.1 229.7 0.1 512.3S229.2 1024 511.8 1024s511.7-229.1 511.7-511.7S794.4 0.6 511.8 0.6z m264.9 375.3c-0.1 0.1-0.1 0.2-0.2 0.3h0.2c-9 14.3-21.2 28.8-34.2 39.2-5.2 4.2-10.5 8.3-15.7 12.5v0.5c0.3 22.9-0.3 44.9-4.7 64.2-25.2 113.1-91.9 189.9-197.4 222.8-37.9 11.8-99.1 16.7-142.6 5.9-21.5-5.4-41-11.4-59.3-19.3-10.2-4.5-19.6-9.3-28.5-14.7l-8.8-5.3h0.5l-0.5-0.3c9.8 0.2 21.3 2.9 32.2 1.2 9.8-1.6 19.6-1.2 28.7-3.2 22.7-5 43-11.6 60.4-21.8 8.3-4.8 20.9-10.6 27-17.6-11.2 0.2-21.4-2.4-29.7-5.4-32.6-11.5-51.6-32.7-63.9-64.4h0.1c0-0.1-0.1-0.2-0.1-0.3 9.7 1.1 37.3 3.5 44.6-1.7-12.3-0.8-24.1-7.9-32.5-13.2-26.2-16.4-47.6-43.9-47.4-86.2v-0.3c3.5 1.7 6.9 3.3 10.4 4.9 6.6 2.8 13.3 4.3 21.1 5.9 3.1 0.7 9.3 2.4 13.2 1.4-5.1-5.8-13.2-9.7-18.4-16-14.7-18.3-28.7-45.3-25.2-77.4 0.5-4.7 1.3-9.4 2.6-14.3 2.5-9.7 6.5-18.3 10.8-26.2 0.2 0.1 0.4 0.2 0.5 0.3 2 4.2 6.4 7.2 9.1 10.6 8.6 10.7 19.2 20.3 30 28.7 36.7 28.7 69.9 46.4 123.1 59.5 13.5 3.3 29 5.9 45.1 5.9-1.9-5.8-2.7-13-2.7-20.5 0-9.7 1.3-19.6 3.3-26.8 9-32.1 28.5-55.2 57-67.6 6.9-3 14.4-5.2 22.4-6.9 4.1-0.6 8.2-1.1 12.3-1.6 39-0.7 59.8 13.5 79.6 31.6 16.8-1.4 38.7-10.8 51.6-17.4l12.6-6.9c0 0.1-0.1 0.3-0.1 0.4l0.1-0.1c-7.3 19.9-17.4 35.5-32.7 47.3-3.1 2.4-6.3 5.6-10 7.4 21.5-0.4 39.3-10 56.1-15.4v0.3z" fill="#2EB1EB" p-id="16499"></path><path d="M719.7 391.1s0.1 0 0.1-0.1c0 0-0.1 0-0.1 0.1zM726.8 428.4v-0.5 0.5zM336.4 479.9c3.3 0.7 9.9 2.7 13.8 1.2h-0.5l-0.1-0.1c-3.9 1-10.1-0.7-13.2-1.4-7.8-1.6-14.5-3.1-21.1-5.9-3.5-1.6-6.9-3.2-10.4-4.9v0.3c3.4 1.6 6.9 3.2 10.4 4.9 6.6 2.8 13.3 4.3 21.1 5.9zM719.6 391.4v0.2c21.9-0.2 39.8-10.1 56.9-15.4 0.1-0.1 0.1-0.2 0.2-0.3v-0.3c-16.9 5.3-34.6 14.9-56.1 15.4-0.4 0.1-0.7 0.3-1 0.4zM584.8 337.5c6.9-3 14.4-5.1 22.4-6.9 4.1-0.6 8.2-1 12.3-1.6 39-0.7 59.8 13.5 79.6 31.6 16.8-1.4 38.7-10.8 51.6-17.4 4.2-2.3 8.3-4.5 12.5-6.8 0-0.1 0.1-0.3 0.1-0.4l-12.6 6.9c-12.9 6.6-34.8 16-51.6 17.4-19.8-18.1-40.6-32.3-79.6-31.6-4.1 0.5-8.2 1-12.3 1.6-8 1.7-15.5 3.9-22.4 6.9-28.5 12.4-48 35.5-57 67.6-2 7.2-3.4 17.2-3.3 26.8 0-9.6 1.3-19.4 3.3-26.5 9-32.1 28.5-55.2 57-67.6zM385.2 568.5h-0.4c-7.3 5.2-34.9 2.8-44.6 1.7 0 0.1 0.1 0.2 0.1 0.3 10 1.1 38.2 3.6 44.9-2zM319.4 347.4c0.1 0.1 0.3 0.1 0.5 0.3 2 4.1 6.3 7.1 9.1 10.6 8.6 10.6 19.2 20.2 30 28.7 36.8 28.7 69.9 46.4 123.1 59.5 13.5 3.3 29.1 5.9 45.2 5.9 0-0.1-0.1-0.2-0.1-0.3-16.1 0-31.6-2.6-45.1-5.9-53.2-13.1-86.4-30.8-123.1-59.5-10.8-8.4-21.4-18-30-28.7-2.7-3.4-7.1-6.4-9.1-10.6-0.1-0.1-0.3-0.2-0.5-0.3-4.3 7.9-8.3 16.5-10.8 26.2-1.3 4.9-2.1 9.6-2.6 14.3 0.5-4.6 1.3-9.2 2.6-14 2.5-9.7 6.5-18.3 10.8-26.2zM317.7 683.2c9.9-1.6 19.6-1.2 28.7-3.2 22.8-5 43-11.6 60.4-21.8 8.4-4.9 21.3-10.8 27.3-17.9h-0.3c-6.1 7-18.7 12.8-27 17.6-17.4 10.2-37.7 16.8-60.4 21.8-9.1 2-18.9 1.6-28.7 3.2-10.9 1.7-22.4-1-32.2-1.2l0.5 0.3c9.7 0.4 21 2.9 31.7 1.2z" fill="#FFFFFF" p-id="16500"></path></svg>
|
||||
|
After Width: | Height: | Size: 3.1 KiB |
1
src/assets/images/icon-social-zhihu.svg
Normal file
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1547543863835" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="16165" xmlns:xlink="http://www.w3.org/1999/xlink" width="400" height="400"><defs><style type="text/css"></style></defs><path d="M512 1024C229.236364 1024 0 794.763636 0 512S229.236364 0 512 0s512 229.236364 512 512-229.236364 512-512 512z m-129.861818-756.48s-36.212364 2.094545-48.989091 24.482909c-12.8 22.365091-54.318545 137.378909-54.318546 137.378909s13.847273 6.376727 37.28291-10.658909c23.435636-17.035636 30.882909-46.848 30.882909-46.848l42.589091-2.117818 1.070545 121.390545s-73.495273-1.070545-88.413091 0c-14.894545 1.047273-23.412364 40.448-23.412364 40.448h111.825455s-9.588364 67.095273-38.353455 116.084364c-28.741818 48.989091-83.060364 87.319273-83.060363 87.319273s39.424 15.965091 77.730909-6.4c38.353455-22.341818 66.629818-120.692364 66.629818-120.692364l89.925818 110.056727s8.192-52.386909-1.466182-67.188363c-9.658182-14.778182-62.208-74.286545-62.208-74.286546l-22.946909 20.247273 16.337455-65.117091h97.954909s0-38.353455-19.153455-40.494545c-19.176727-2.094545-78.801455 0-78.801454 0V371.898182h88.389818s-1.070545-39.400727-18.106182-39.400727h-143.755636l22.341818-64.954182z m169.984 61.184v358.562909h36.002909l13.102545 45.009455 63.348364-45.009455h89.064727V328.704h-201.518545z" fill="#0f84fd" p-id="16166"></path><path d="M594.781091 368.64h117.899636v277.876364h-41.890909l-53.364363 40.261818-11.636364-40.261818h-11.008V368.64z" fill="#0f84fd" p-id="16167"></path></svg>
|
||||
|
After Width: | Height: | Size: 1.6 KiB |
BIN
src/assets/images/left.png
Normal file
|
After Width: | Height: | Size: 3.1 KiB |
BIN
src/assets/images/login-bg.jpg
Normal file
|
After Width: | Height: | Size: 144 KiB |
BIN
src/assets/images/logo-min.jpg
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
src/assets/images/logo-min.png
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
BIN
src/assets/images/logo.png
Normal file
|
After Width: | Height: | Size: 84 KiB |
BIN
src/assets/images/logo_new.png
Normal file
|
After Width: | Height: | Size: 3.3 KiB |
BIN
src/assets/images/money.png
Normal file
|
After Width: | Height: | Size: 5.3 KiB |
BIN
src/assets/images/paypal.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
BIN
src/assets/images/pic_bg.png
Normal file
|
After Width: | Height: | Size: 83 KiB |
BIN
src/assets/images/pic_illustration.png
Normal file
|
After Width: | Height: | Size: 66 KiB |
BIN
src/assets/images/pro_logo.png
Normal file
|
After Width: | Height: | Size: 21 KiB |
BIN
src/assets/images/right.png
Normal file
|
After Width: | Height: | Size: 3.1 KiB |
BIN
src/assets/images/talkingdata.png
Normal file
|
After Width: | Height: | Size: 2.7 MiB |
BIN
src/assets/images/wenjian.png
Normal file
|
After Width: | Height: | Size: 3.0 KiB |
BIN
src/assets/images/yasuobao.png
Normal file
|
After Width: | Height: | Size: 3.1 KiB |
156
src/components/ProgressBar/index.vue
Normal file
@@ -0,0 +1,156 @@
|
||||
<template>
|
||||
<div class="percentloop">
|
||||
<div class="circle-left">
|
||||
<div ref="leftcontent"></div>
|
||||
</div>
|
||||
<div class="circle-right">
|
||||
<div ref="rightcontent"></div>
|
||||
</div>
|
||||
<div class="number">
|
||||
{{ percent }} %
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
percentNum: {
|
||||
type: [String, Number],
|
||||
default: 0
|
||||
},
|
||||
speed: { // 建议取值为0-3
|
||||
type: [String, Number],
|
||||
default: 1
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
percent: 0,
|
||||
initDeg: 0,
|
||||
timeId: null,
|
||||
animationing: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
transformToDeg (percent) {
|
||||
let deg = 0
|
||||
if (percent >= 100) {
|
||||
deg = 360
|
||||
} else {
|
||||
deg = parseInt(360 * percent / 100)
|
||||
}
|
||||
return deg
|
||||
},
|
||||
transformToPercent (deg) {
|
||||
let percent = 0
|
||||
if (deg >= 360) {
|
||||
percent = 100
|
||||
} else {
|
||||
percent = parseInt(100 * deg / 360)
|
||||
}
|
||||
return percent
|
||||
},
|
||||
rotateLeft (deg) { // 大于180时,执行的动画
|
||||
this.$refs.leftcontent.style.transform = 'rotate(' + (deg - 180) + 'deg)'
|
||||
},
|
||||
rotateRight (deg) { // 小于180时,执行的动画
|
||||
this.$refs.rightcontent.style.transform = 'rotate(' + deg + 'deg)'
|
||||
},
|
||||
goRotate (deg) {
|
||||
this.animationing = true
|
||||
this.timeId = setInterval(() => {
|
||||
if (deg > this.initDeg) { // 递增动画
|
||||
this.initDeg += Number(this.speed)
|
||||
if (this.initDeg >= 180) {
|
||||
this.rotateLeft(this.initDeg)
|
||||
this.rotateRight(180) // 为避免前后两次传入的百分比转换为度数后的值不为步距的整数,可能出现的左右转动不到位的情况。
|
||||
} else {
|
||||
this.rotateRight(this.initDeg)
|
||||
}
|
||||
} else { // 递减动画
|
||||
this.initDeg -= Number(this.speed)
|
||||
if (this.initDeg >= 180) {
|
||||
this.rotateLeft(this.initDeg)
|
||||
} else {
|
||||
this.rotateLeft(180) // 为避免前后两次传入的百分比转换为度数后的值不为步距的整数,可能出现的左右转动不到位的情况。
|
||||
this.rotateRight(this.initDeg)
|
||||
}
|
||||
}
|
||||
this.percent = this.transformToPercent(this.initDeg) // 百分比数据滚动动画
|
||||
const remainer = Number(deg) - this.initDeg
|
||||
if (Math.abs(remainer) < this.speed) {
|
||||
this.initDeg += remainer
|
||||
if (this.initDeg > 180) {
|
||||
this.rotateLeft(deg)
|
||||
} else {
|
||||
this.rotateRight(deg)
|
||||
}
|
||||
this.animationFinished()
|
||||
}
|
||||
}, 10)
|
||||
},
|
||||
animationFinished () {
|
||||
this.percent = this.percentNum // 百分比数据滚动动画
|
||||
this.animationing = false
|
||||
clearInterval(this.timeId)
|
||||
this.$emit('animationFinished') // 动画完成的回调
|
||||
}
|
||||
},
|
||||
created () {
|
||||
this.goRotate(this.transformToDeg(this.percentNum))
|
||||
},
|
||||
watch: {
|
||||
'percentNum': function (val) {
|
||||
if (this.animationing) return
|
||||
this.goRotate(this.transformToDeg(val))
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.percentloop {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 50%;
|
||||
overflow: hidden;
|
||||
.circle-left, .circle-right {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 50%;
|
||||
height: 100%;
|
||||
background-color: red;
|
||||
overflow: hidden;
|
||||
&>div {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #8a8a8a;
|
||||
transform-origin: right center;
|
||||
/*transition: all .5s linear;*/
|
||||
}
|
||||
}
|
||||
.circle-right {
|
||||
left: 50%;
|
||||
&>div {
|
||||
transform-origin: left center;
|
||||
}
|
||||
}
|
||||
.number {
|
||||
position: absolute;
|
||||
top: 9%;
|
||||
bottom: 9%;
|
||||
left: 9%;
|
||||
right: 9%;
|
||||
background-color: #fff;
|
||||
border-radius: 50%;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: #000;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
284
src/components/assets-libs/assets-libs.vue
Normal file
@@ -0,0 +1,284 @@
|
||||
<template>
|
||||
<div>
|
||||
<Modal
|
||||
id="assets-libs"
|
||||
class="img-lib"
|
||||
v-model="showLibs"
|
||||
title="素材库"
|
||||
width='1055px'
|
||||
@on-ok="ok"
|
||||
@on-cancel="cancel">
|
||||
<CheckboxGroup v-if="this.fileList.length" v-model="selected" @on-change="checkboxChange" class="assets-collection" >
|
||||
<item-card
|
||||
:class="['assets-collection-item', {'selected':is_selected(item)}]"
|
||||
v-for="item in fileList"
|
||||
:key="item.id"
|
||||
:fileData="item"
|
||||
@del_item="delImg">
|
||||
</item-card>
|
||||
</CheckboxGroup>
|
||||
<div v-else class="empty-libs">
|
||||
<Icon type="md-images" />
|
||||
<p>素材库内容目前还是空的。</p>
|
||||
</div>
|
||||
<div class="flexbox" slot="footer">
|
||||
<div class="pagination">
|
||||
<Page :page-size-opts="pageSizeOpts" :page-size="20" :total="total" show-sizer @on-page-size-change='changeSize' @on-change='changePage'/>
|
||||
</div>
|
||||
<div class="buttons">
|
||||
<Upload
|
||||
:action="uploadApi"
|
||||
:format="['jpg','jpeg','png']"
|
||||
:max-size="2048"
|
||||
:before-upload="handleUpload"
|
||||
:on-format-error="handleFormatError"
|
||||
:on-exceeded-size="handleMaxSize"
|
||||
:on-success="uploadSuccess"
|
||||
>
|
||||
<Button :loading="loadingStatus" size="large"><Icon type="ios-cloud-upload-outline" /> 上传图片 </Button>
|
||||
</Upload>
|
||||
|
||||
<Button type="primary" size="large" @click="ok">确定选择</Button>
|
||||
</div>
|
||||
</div>
|
||||
</Modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { GetImgList, DocsRecordDelete } from '@/api/data'
|
||||
import ItemCard from './item-card.vue'
|
||||
export default {
|
||||
components: {
|
||||
ItemCard
|
||||
},
|
||||
name: 'assets-libs',
|
||||
props: {
|
||||
// 可选,最大选择数量
|
||||
maxSelected: {
|
||||
type: Number,
|
||||
default: 1
|
||||
},
|
||||
uploadApi: {
|
||||
type: String,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
showLibs: false,
|
||||
total: 0,
|
||||
fileList: [],
|
||||
fileName: '', // 查询名字
|
||||
fileType: '', // 文件类型
|
||||
currentOrder: 'desc', // 升序降序
|
||||
page: 1, // 分页
|
||||
perpage: 20,
|
||||
orderType: '降序', // 下拉框默认,
|
||||
selected: [],
|
||||
pageSizeOpts: [20, 30, 40],
|
||||
loadingStatus: false,
|
||||
bindName: '' // 可传入绑定的字段,再emit事件时带出
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
||||
},
|
||||
methods: {
|
||||
is_selected (item) {
|
||||
let is_selected = this.selected.findIndex((value) => {
|
||||
return value === item.file_url
|
||||
})
|
||||
if (is_selected >= 0) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
},
|
||||
_initOption () { // 筛选条件初始化
|
||||
let file_name = this.fileName
|
||||
let file_type = this.fileType
|
||||
let order_type = this.currentOrder
|
||||
let page = this.page
|
||||
let perpage = this.perpage
|
||||
|
||||
// post 参数为空的时候不加入
|
||||
let data = { order_type, page, perpage }
|
||||
if (file_name) {
|
||||
data.file_name = file_name
|
||||
}
|
||||
if (file_type) {
|
||||
data.file_name = file_type
|
||||
}
|
||||
|
||||
return data
|
||||
},
|
||||
_reset () {
|
||||
let {
|
||||
fileName,
|
||||
fileType,
|
||||
currentOrder,
|
||||
page,
|
||||
perpage,
|
||||
orderType,
|
||||
bindName,
|
||||
selected
|
||||
} = this.$options.data()
|
||||
const originData = {
|
||||
fileName,
|
||||
fileType,
|
||||
currentOrder,
|
||||
page,
|
||||
perpage,
|
||||
orderType,
|
||||
bindName,
|
||||
selected
|
||||
}
|
||||
Object.assign(this.$data, originData)
|
||||
this.getImgs()
|
||||
},
|
||||
checkboxChange (value) {
|
||||
if (this.maxSelected === 1 && this.selected.length > 1) {
|
||||
this.selected.shift()
|
||||
} else if (this.selected.length > this.maxSelected) {
|
||||
this.selected.pop()
|
||||
this.$Message.info(`当前选项不得超过${this.maxSelected}个。`)
|
||||
}
|
||||
},
|
||||
show (bindName) {
|
||||
if (bindName) {
|
||||
this.bindName = bindName
|
||||
}
|
||||
this.showLibs = true
|
||||
},
|
||||
hide () {
|
||||
this._reset()
|
||||
this.showLibs = false
|
||||
},
|
||||
delImg (id) {
|
||||
DocsRecordDelete({ id }).then(res => {
|
||||
this.getImgs()
|
||||
this.$Message.success('图片已删除。')
|
||||
})
|
||||
},
|
||||
ok () {
|
||||
if (this.bindName) {
|
||||
let params = {
|
||||
bindName: this.bindName,
|
||||
value: this.selected
|
||||
}
|
||||
this.$emit('selected', params)
|
||||
} else {
|
||||
this.$emit('selected', this.selected)
|
||||
}
|
||||
this.hide()
|
||||
},
|
||||
cancel () {
|
||||
this._reset()
|
||||
},
|
||||
getImgs () {
|
||||
let data = this._initOption()
|
||||
const formdata = new FormData()
|
||||
// formdata.append('access_token', this.token)
|
||||
if (data.file_name) {
|
||||
formdata.append('file_name', data.file_name)
|
||||
}
|
||||
if (data.file_type) {
|
||||
formdata.append('sort', data.orderType)
|
||||
}
|
||||
formdata.append('by', data.order_type)
|
||||
formdata.append('page', this.page)
|
||||
formdata.append('perpage', this.perpage)
|
||||
GetImgList(formdata).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.total = res.totalCount
|
||||
this.fileList = res.recordList
|
||||
} else {
|
||||
this.$Message.error(res.msg)
|
||||
}
|
||||
})
|
||||
},
|
||||
changeSize (size) {
|
||||
this.perpage = size
|
||||
this.getImgs()
|
||||
},
|
||||
changePage (page) {
|
||||
this.page = page
|
||||
this.getImgs()
|
||||
},
|
||||
handleUpload (file) {
|
||||
this.loadingStatus = true
|
||||
},
|
||||
handleFormatError (file) {
|
||||
this.$Message.warning({
|
||||
content: '请上传正确的图片格式文件。'
|
||||
})
|
||||
this.loadingStatus = false
|
||||
},
|
||||
handleMaxSize (file) {
|
||||
this.$Message.warning({
|
||||
content: '请将上传的图片控制在2M以内。'
|
||||
})
|
||||
this.loadingStatus = false
|
||||
},
|
||||
uploadSuccess (response, file, fileList) {
|
||||
this.loadingStatus = false
|
||||
this.getImgs()
|
||||
}
|
||||
},
|
||||
created () {
|
||||
this.getImgs()
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.selected {
|
||||
box-shadow: rgb(217, 233, 247) 1px 1px 6px 2px;
|
||||
}
|
||||
.assets-collection {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
.ivu-modal{
|
||||
top: 20px;
|
||||
height: 80%;
|
||||
|
||||
}
|
||||
.img-lib {
|
||||
.ivu-modal-body {
|
||||
overflow-y: scroll;
|
||||
height: 560px;
|
||||
padding-top: 0;
|
||||
}
|
||||
.ivu-modal-footer .flexbox {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
.buttons {
|
||||
display: flex;
|
||||
|
||||
.ivu-btn-large {
|
||||
height: 36px;
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
.ivu-upload-list {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
.empty-libs {
|
||||
width: 250px;
|
||||
margin: 0 auto;
|
||||
margin-top: 20px;
|
||||
font-size: 250px;
|
||||
color: #7485a9;
|
||||
p {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
221
src/components/assets-libs/item-card.vue
Normal file
@@ -0,0 +1,221 @@
|
||||
<template>
|
||||
<div class="item-card">
|
||||
<div class="hover-card">
|
||||
<div class="img-container">
|
||||
<img :src="file_logo" alt="">
|
||||
</div>
|
||||
<div class="item-headline" :title="fileData.file_name" @click="showPic">
|
||||
<p class="item-name">{{fileData.file_name}}</p><Icon class="item-delet" @click.stop="del_item(fileData.id)" type="md-close" />
|
||||
</div>
|
||||
</div>
|
||||
<Checkbox :label="fileData.file_url" ></Checkbox>
|
||||
|
||||
<div v-show="false" class="item-info">
|
||||
<!-- <span>{{fileData.file_type}}</span> -->
|
||||
<span style="margin-right: 15px;">大小:<span>{{fileSize}}</span></span>
|
||||
<span>上传于:<span>{{fileAddTime}}</span></span>
|
||||
</div>
|
||||
<Input v-show="false" v-model="fileData.file_url" readonly>
|
||||
<a href="javascript:void(0);" class="copyButton" v-clipboard="copyLink" slot="append">复制</a>
|
||||
</Input>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { DelFile } from '@/api/data'
|
||||
import { getToken } from '@/libs/util'
|
||||
export default {
|
||||
props: {
|
||||
fileData: {
|
||||
type: Object
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
showPic () {
|
||||
window.open(this.fileData.file_url, '_blank')
|
||||
},
|
||||
del_item (id) {
|
||||
this.$Modal.confirm({
|
||||
title: '提示',
|
||||
content: '<p>是否确定删除?</p>',
|
||||
className: 'vertical-center-modal',
|
||||
onOk: () => {
|
||||
this.$emit('delItem', id)
|
||||
},
|
||||
onCancel: () => {
|
||||
return false
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
fileSize () {
|
||||
let size = this.fileData.file_size / 1024
|
||||
if (size > 1024) {
|
||||
size = size / 1024
|
||||
size = Math.floor(size * 100) / 100 + 'MB'
|
||||
} else {
|
||||
size = Math.floor(size * 100) / 100 + 'KB'
|
||||
}
|
||||
return size
|
||||
},
|
||||
fileAddTime () {
|
||||
let data_time = this.fileData.add_time
|
||||
let time = data_time.slice(0, 10)
|
||||
return time
|
||||
},
|
||||
copyLink () {
|
||||
return {
|
||||
value: this.fileData.file_url,
|
||||
success: (e) => {
|
||||
this.$Message.success('复制成功')
|
||||
},
|
||||
error: () => {
|
||||
this.$Message.error('复制失败')
|
||||
}
|
||||
}
|
||||
},
|
||||
file_logo () {
|
||||
// todo 扩展其他文件的logo 使用swtich方式
|
||||
if (/\.(jpe?g|png|gif)$/i.test(this.fileData.file_url)) {
|
||||
return this.fileData.file_url
|
||||
} else if (/\.(xlsx?)$/i.test(this.fileData.file_url)) {
|
||||
let logo = require('@/assets/icons/file-icon/xls_logo.jpg')
|
||||
return logo
|
||||
} else if (/\.(docx?)$/i.test(this.fileData.file_url)) {
|
||||
let logo = require('@/assets/icons/file-icon/doc_logo.jpg')
|
||||
return logo
|
||||
} else if (/\.(pptx?)$/i.test(this.fileData.file_url)) {
|
||||
let logo = require('@/assets/icons/file-icon/ppt_logo.jpg')
|
||||
return logo
|
||||
} else if (/\.(html)$/i.test(this.fileData.file_url)) {
|
||||
let logo = require('@/assets/icons/file-icon/html_logo.jpg')
|
||||
return logo
|
||||
} else {
|
||||
let logo = require('@/assets/icons/file-icon/others_logo.jpg')
|
||||
return logo
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.item-card {
|
||||
width: 170px;
|
||||
font-size: 14px;
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
justify-content: space-between;
|
||||
margin-top: 15px;
|
||||
padding-bottom: 25px;
|
||||
position: relative;
|
||||
margin: 5px 15px;
|
||||
|
||||
label {
|
||||
position: absolute;
|
||||
top: 3px;
|
||||
right: -3px;
|
||||
}
|
||||
|
||||
.hover-card {
|
||||
border-radius: 3px;
|
||||
}
|
||||
.img-container {
|
||||
width: 100%;
|
||||
height: 168px;
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: contain;
|
||||
}
|
||||
}
|
||||
|
||||
.item-headline {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
cursor: pointer;
|
||||
position: absolute;
|
||||
bottom: 0px;
|
||||
width:170px;
|
||||
background: #fff;
|
||||
padding: 2px 3px 3px;
|
||||
|
||||
.item-name {
|
||||
font-weight: 600;
|
||||
color: #57a3f3;
|
||||
overflow: hidden;
|
||||
text-overflow:ellipsis;
|
||||
white-space:nowrap;
|
||||
width: 280px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.item-delet {
|
||||
display: none;
|
||||
padding-right: 5px;
|
||||
padding-top: 5px;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
.item-info {
|
||||
display: flex;
|
||||
justify-content: start;
|
||||
color: #838383;
|
||||
margin: 5px 0;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.copyButton {
|
||||
color: #515a6e;
|
||||
}
|
||||
|
||||
.copyButton:hover {
|
||||
color: #57a3f3;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.item-card:hover {
|
||||
box-shadow: rgb(223, 223, 223) 1px 1px 6px 2px;
|
||||
|
||||
.item-headline {
|
||||
background: rgb(25, 92, 146);
|
||||
}
|
||||
.item-name {
|
||||
color: #fff;
|
||||
}
|
||||
.item-delet {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.item-delet:hover {
|
||||
display: inline-block;
|
||||
color: rgb(255, 60, 0);
|
||||
}
|
||||
}
|
||||
|
||||
.ivu-modal-wrap .ivu-modal {
|
||||
margin-top: 200px;
|
||||
}
|
||||
|
||||
.ivu-checkbox:nth-child(1) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.assets-collection label /deep/ span:nth-child(2) {
|
||||
display: none;
|
||||
}
|
||||
.assets-collection label /deep/ .ivu-checkbox-inner {
|
||||
border: 2px solid #41a0ff82;
|
||||
height: 17px;
|
||||
width: 17px;
|
||||
box-shadow: #cdd2ff 0px 0px 5px 0px;
|
||||
}
|
||||
|
||||
.ivu-checkbox-inner:after {
|
||||
left: 5px!important;
|
||||
}
|
||||
</style>
|
||||
58
src/components/charts/bar.vue
Normal file
@@ -0,0 +1,58 @@
|
||||
<template>
|
||||
<div ref="dom" class="charts chart-bar"></div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import echarts from 'echarts'
|
||||
import tdTheme from './theme.json'
|
||||
import { on, off } from '@/libs/tools'
|
||||
echarts.registerTheme('tdTheme', tdTheme)
|
||||
export default {
|
||||
name: 'ChartBar',
|
||||
props: {
|
||||
value: Object,
|
||||
text: String,
|
||||
subtext: String
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
dom: null
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
resize () {
|
||||
this.dom.resize()
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
this.$nextTick(() => {
|
||||
let xAxisData = Object.keys(this.value)
|
||||
let seriesData = Object.values(this.value)
|
||||
let option = {
|
||||
title: {
|
||||
text: this.text,
|
||||
subtext: this.subtext,
|
||||
x: 'center'
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: xAxisData
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value'
|
||||
},
|
||||
series: [{
|
||||
data: seriesData,
|
||||
type: 'bar'
|
||||
}]
|
||||
}
|
||||
this.dom = echarts.init(this.$refs.dom, 'tdTheme')
|
||||
this.dom.setOption(option)
|
||||
on(window, 'resize', this.resize)
|
||||
})
|
||||
},
|
||||
beforeDestroy () {
|
||||
off(window, 'resize', this.resize)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
3
src/components/charts/index.js
Normal file
@@ -0,0 +1,3 @@
|
||||
import ChartPie from './pie.vue'
|
||||
import ChartBar from './bar.vue'
|
||||
export { ChartPie, ChartBar }
|
||||
70
src/components/charts/pie.vue
Normal file
@@ -0,0 +1,70 @@
|
||||
<template>
|
||||
<div ref="dom" class="charts chart-pie"></div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import echarts from 'echarts'
|
||||
import tdTheme from './theme.json'
|
||||
import { on, off } from '@/libs/tools'
|
||||
echarts.registerTheme('tdTheme', tdTheme)
|
||||
export default {
|
||||
name: 'ChartPie',
|
||||
props: {
|
||||
value: Array,
|
||||
text: String,
|
||||
subtext: String
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
dom: null
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
resize () {
|
||||
this.dom.resize()
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
this.$nextTick(() => {
|
||||
let legend = this.value.map(_ => _.name)
|
||||
let option = {
|
||||
title: {
|
||||
text: this.text,
|
||||
subtext: this.subtext,
|
||||
x: 'center'
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'item',
|
||||
formatter: '{a} <br/>{b} : {c} ({d}%)'
|
||||
},
|
||||
legend: {
|
||||
orient: 'vertical',
|
||||
left: 'left',
|
||||
data: legend
|
||||
},
|
||||
series: [
|
||||
{
|
||||
type: 'pie',
|
||||
radius: '55%',
|
||||
center: ['50%', '60%'],
|
||||
data: this.value,
|
||||
itemStyle: {
|
||||
emphasis: {
|
||||
shadowBlur: 10,
|
||||
shadowOffsetX: 0,
|
||||
shadowColor: 'rgba(0, 0, 0, 0.5)'
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
this.dom = echarts.init(this.$refs.dom, 'tdTheme')
|
||||
this.dom.setOption(option)
|
||||
on(window, 'resize', this.resize)
|
||||
})
|
||||
},
|
||||
beforeDestroy () {
|
||||
off(window, 'resize', this.resize)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
491
src/components/charts/theme.json
Normal file
@@ -0,0 +1,491 @@
|
||||
|
||||
{
|
||||
"color": [
|
||||
"#2d8cf0",
|
||||
"#19be6b",
|
||||
"#ff9900",
|
||||
"#E46CBB",
|
||||
"#9A66E4",
|
||||
"#ed3f14"
|
||||
],
|
||||
"backgroundColor": "rgba(0,0,0,0)",
|
||||
"textStyle": {},
|
||||
"title": {
|
||||
"textStyle": {
|
||||
"color": "#516b91"
|
||||
},
|
||||
"subtextStyle": {
|
||||
"color": "#93b7e3"
|
||||
}
|
||||
},
|
||||
"line": {
|
||||
"itemStyle": {
|
||||
"normal": {
|
||||
"borderWidth": "2"
|
||||
}
|
||||
},
|
||||
"lineStyle": {
|
||||
"normal": {
|
||||
"width": "2"
|
||||
}
|
||||
},
|
||||
"symbolSize": "6",
|
||||
"symbol": "emptyCircle",
|
||||
"smooth": true
|
||||
},
|
||||
"radar": {
|
||||
"itemStyle": {
|
||||
"normal": {
|
||||
"borderWidth": "2"
|
||||
}
|
||||
},
|
||||
"lineStyle": {
|
||||
"normal": {
|
||||
"width": "2"
|
||||
}
|
||||
},
|
||||
"symbolSize": "6",
|
||||
"symbol": "emptyCircle",
|
||||
"smooth": true
|
||||
},
|
||||
"bar": {
|
||||
"itemStyle": {
|
||||
"normal": {
|
||||
"barBorderWidth": 0,
|
||||
"barBorderColor": "#ccc"
|
||||
},
|
||||
"emphasis": {
|
||||
"barBorderWidth": 0,
|
||||
"barBorderColor": "#ccc"
|
||||
}
|
||||
}
|
||||
},
|
||||
"pie": {
|
||||
"itemStyle": {
|
||||
"normal": {
|
||||
"borderWidth": 0,
|
||||
"borderColor": "#ccc"
|
||||
},
|
||||
"emphasis": {
|
||||
"borderWidth": 0,
|
||||
"borderColor": "#ccc"
|
||||
}
|
||||
}
|
||||
},
|
||||
"scatter": {
|
||||
"itemStyle": {
|
||||
"normal": {
|
||||
"borderWidth": 0,
|
||||
"borderColor": "#ccc"
|
||||
},
|
||||
"emphasis": {
|
||||
"borderWidth": 0,
|
||||
"borderColor": "#ccc"
|
||||
}
|
||||
}
|
||||
},
|
||||
"boxplot": {
|
||||
"itemStyle": {
|
||||
"normal": {
|
||||
"borderWidth": 0,
|
||||
"borderColor": "#ccc"
|
||||
},
|
||||
"emphasis": {
|
||||
"borderWidth": 0,
|
||||
"borderColor": "#ccc"
|
||||
}
|
||||
}
|
||||
},
|
||||
"parallel": {
|
||||
"itemStyle": {
|
||||
"normal": {
|
||||
"borderWidth": 0,
|
||||
"borderColor": "#ccc"
|
||||
},
|
||||
"emphasis": {
|
||||
"borderWidth": 0,
|
||||
"borderColor": "#ccc"
|
||||
}
|
||||
}
|
||||
},
|
||||
"sankey": {
|
||||
"itemStyle": {
|
||||
"normal": {
|
||||
"borderWidth": 0,
|
||||
"borderColor": "#ccc"
|
||||
},
|
||||
"emphasis": {
|
||||
"borderWidth": 0,
|
||||
"borderColor": "#ccc"
|
||||
}
|
||||
}
|
||||
},
|
||||
"funnel": {
|
||||
"itemStyle": {
|
||||
"normal": {
|
||||
"borderWidth": 0,
|
||||
"borderColor": "#ccc"
|
||||
},
|
||||
"emphasis": {
|
||||
"borderWidth": 0,
|
||||
"borderColor": "#ccc"
|
||||
}
|
||||
}
|
||||
},
|
||||
"gauge": {
|
||||
"itemStyle": {
|
||||
"normal": {
|
||||
"borderWidth": 0,
|
||||
"borderColor": "#ccc"
|
||||
},
|
||||
"emphasis": {
|
||||
"borderWidth": 0,
|
||||
"borderColor": "#ccc"
|
||||
}
|
||||
}
|
||||
},
|
||||
"candlestick": {
|
||||
"itemStyle": {
|
||||
"normal": {
|
||||
"color": "#edafda",
|
||||
"color0": "transparent",
|
||||
"borderColor": "#d680bc",
|
||||
"borderColor0": "#8fd3e8",
|
||||
"borderWidth": "2"
|
||||
}
|
||||
}
|
||||
},
|
||||
"graph": {
|
||||
"itemStyle": {
|
||||
"normal": {
|
||||
"borderWidth": 0,
|
||||
"borderColor": "#ccc"
|
||||
}
|
||||
},
|
||||
"lineStyle": {
|
||||
"normal": {
|
||||
"width": 1,
|
||||
"color": "#aaa"
|
||||
}
|
||||
},
|
||||
"symbolSize": "6",
|
||||
"symbol": "emptyCircle",
|
||||
"smooth": true,
|
||||
"color": [
|
||||
"#2d8cf0",
|
||||
"#19be6b",
|
||||
"#f5ae4a",
|
||||
"#9189d5",
|
||||
"#56cae2",
|
||||
"#cbb0e3"
|
||||
],
|
||||
"label": {
|
||||
"normal": {
|
||||
"textStyle": {
|
||||
"color": "#eee"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"map": {
|
||||
"itemStyle": {
|
||||
"normal": {
|
||||
"areaColor": "#f3f3f3",
|
||||
"borderColor": "#516b91",
|
||||
"borderWidth": 0.5
|
||||
},
|
||||
"emphasis": {
|
||||
"areaColor": "rgba(165,231,240,1)",
|
||||
"borderColor": "#516b91",
|
||||
"borderWidth": 1
|
||||
}
|
||||
},
|
||||
"label": {
|
||||
"normal": {
|
||||
"textStyle": {
|
||||
"color": "#000"
|
||||
}
|
||||
},
|
||||
"emphasis": {
|
||||
"textStyle": {
|
||||
"color": "rgb(81,107,145)"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"geo": {
|
||||
"itemStyle": {
|
||||
"normal": {
|
||||
"areaColor": "#f3f3f3",
|
||||
"borderColor": "#516b91",
|
||||
"borderWidth": 0.5
|
||||
},
|
||||
"emphasis": {
|
||||
"areaColor": "rgba(165,231,240,1)",
|
||||
"borderColor": "#516b91",
|
||||
"borderWidth": 1
|
||||
}
|
||||
},
|
||||
"label": {
|
||||
"normal": {
|
||||
"textStyle": {
|
||||
"color": "#000"
|
||||
}
|
||||
},
|
||||
"emphasis": {
|
||||
"textStyle": {
|
||||
"color": "rgb(81,107,145)"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"categoryAxis": {
|
||||
"axisLine": {
|
||||
"show": true,
|
||||
"lineStyle": {
|
||||
"color": "#cccccc"
|
||||
}
|
||||
},
|
||||
"axisTick": {
|
||||
"show": false,
|
||||
"lineStyle": {
|
||||
"color": "#333"
|
||||
}
|
||||
},
|
||||
"axisLabel": {
|
||||
"show": true,
|
||||
"textStyle": {
|
||||
"color": "#999999"
|
||||
}
|
||||
},
|
||||
"splitLine": {
|
||||
"show": true,
|
||||
"lineStyle": {
|
||||
"color": [
|
||||
"#eeeeee"
|
||||
]
|
||||
}
|
||||
},
|
||||
"splitArea": {
|
||||
"show": false,
|
||||
"areaStyle": {
|
||||
"color": [
|
||||
"rgba(250,250,250,0.05)",
|
||||
"rgba(200,200,200,0.02)"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"valueAxis": {
|
||||
"axisLine": {
|
||||
"show": true,
|
||||
"lineStyle": {
|
||||
"color": "#cccccc"
|
||||
}
|
||||
},
|
||||
"axisTick": {
|
||||
"show": false,
|
||||
"lineStyle": {
|
||||
"color": "#333"
|
||||
}
|
||||
},
|
||||
"axisLabel": {
|
||||
"show": true,
|
||||
"textStyle": {
|
||||
"color": "#999999"
|
||||
}
|
||||
},
|
||||
"splitLine": {
|
||||
"show": true,
|
||||
"lineStyle": {
|
||||
"color": [
|
||||
"#eeeeee"
|
||||
]
|
||||
}
|
||||
},
|
||||
"splitArea": {
|
||||
"show": false,
|
||||
"areaStyle": {
|
||||
"color": [
|
||||
"rgba(250,250,250,0.05)",
|
||||
"rgba(200,200,200,0.02)"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"logAxis": {
|
||||
"axisLine": {
|
||||
"show": true,
|
||||
"lineStyle": {
|
||||
"color": "#cccccc"
|
||||
}
|
||||
},
|
||||
"axisTick": {
|
||||
"show": false,
|
||||
"lineStyle": {
|
||||
"color": "#333"
|
||||
}
|
||||
},
|
||||
"axisLabel": {
|
||||
"show": true,
|
||||
"textStyle": {
|
||||
"color": "#999999"
|
||||
}
|
||||
},
|
||||
"splitLine": {
|
||||
"show": true,
|
||||
"lineStyle": {
|
||||
"color": [
|
||||
"#eeeeee"
|
||||
]
|
||||
}
|
||||
},
|
||||
"splitArea": {
|
||||
"show": false,
|
||||
"areaStyle": {
|
||||
"color": [
|
||||
"rgba(250,250,250,0.05)",
|
||||
"rgba(200,200,200,0.02)"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"timeAxis": {
|
||||
"axisLine": {
|
||||
"show": true,
|
||||
"lineStyle": {
|
||||
"color": "#cccccc"
|
||||
}
|
||||
},
|
||||
"axisTick": {
|
||||
"show": false,
|
||||
"lineStyle": {
|
||||
"color": "#333"
|
||||
}
|
||||
},
|
||||
"axisLabel": {
|
||||
"show": true,
|
||||
"textStyle": {
|
||||
"color": "#999999"
|
||||
}
|
||||
},
|
||||
"splitLine": {
|
||||
"show": true,
|
||||
"lineStyle": {
|
||||
"color": [
|
||||
"#eeeeee"
|
||||
]
|
||||
}
|
||||
},
|
||||
"splitArea": {
|
||||
"show": false,
|
||||
"areaStyle": {
|
||||
"color": [
|
||||
"rgba(250,250,250,0.05)",
|
||||
"rgba(200,200,200,0.02)"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"toolbox": {
|
||||
"iconStyle": {
|
||||
"normal": {
|
||||
"borderColor": "#999"
|
||||
},
|
||||
"emphasis": {
|
||||
"borderColor": "#666"
|
||||
}
|
||||
}
|
||||
},
|
||||
"legend": {
|
||||
"textStyle": {
|
||||
"color": "#999999"
|
||||
}
|
||||
},
|
||||
"tooltip": {
|
||||
"axisPointer": {
|
||||
"lineStyle": {
|
||||
"color": "#ccc",
|
||||
"width": 1
|
||||
},
|
||||
"crossStyle": {
|
||||
"color": "#ccc",
|
||||
"width": 1
|
||||
}
|
||||
}
|
||||
},
|
||||
"timeline": {
|
||||
"lineStyle": {
|
||||
"color": "#8fd3e8",
|
||||
"width": 1
|
||||
},
|
||||
"itemStyle": {
|
||||
"normal": {
|
||||
"color": "#8fd3e8",
|
||||
"borderWidth": 1
|
||||
},
|
||||
"emphasis": {
|
||||
"color": "#8fd3e8"
|
||||
}
|
||||
},
|
||||
"controlStyle": {
|
||||
"normal": {
|
||||
"color": "#8fd3e8",
|
||||
"borderColor": "#8fd3e8",
|
||||
"borderWidth": 0.5
|
||||
},
|
||||
"emphasis": {
|
||||
"color": "#8fd3e8",
|
||||
"borderColor": "#8fd3e8",
|
||||
"borderWidth": 0.5
|
||||
}
|
||||
},
|
||||
"checkpointStyle": {
|
||||
"color": "#8fd3e8",
|
||||
"borderColor": "rgba(138,124,168,0.37)"
|
||||
},
|
||||
"label": {
|
||||
"normal": {
|
||||
"textStyle": {
|
||||
"color": "#8fd3e8"
|
||||
}
|
||||
},
|
||||
"emphasis": {
|
||||
"textStyle": {
|
||||
"color": "#8fd3e8"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"visualMap": {
|
||||
"color": [
|
||||
"#516b91",
|
||||
"#59c4e6",
|
||||
"#a5e7f0"
|
||||
]
|
||||
},
|
||||
"dataZoom": {
|
||||
"backgroundColor": "rgba(0,0,0,0)",
|
||||
"dataBackgroundColor": "rgba(255,255,255,0.3)",
|
||||
"fillerColor": "rgba(167,183,204,0.4)",
|
||||
"handleColor": "#a7b7cc",
|
||||
"handleSize": "100%",
|
||||
"textStyle": {
|
||||
"color": "#333"
|
||||
}
|
||||
},
|
||||
"markPoint": {
|
||||
"label": {
|
||||
"normal": {
|
||||
"textStyle": {
|
||||
"color": "#eee"
|
||||
}
|
||||
},
|
||||
"emphasis": {
|
||||
"textStyle": {
|
||||
"color": "#eee"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
42
src/components/common-icon/common-icon.vue
Normal file
@@ -0,0 +1,42 @@
|
||||
<template>
|
||||
<component :is="iconType" :type="iconName" :color="iconColor" :size="iconSize"/>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Icons from '_c/icons'
|
||||
export default {
|
||||
name: 'CommonIcon',
|
||||
components: { Icons },
|
||||
props: {
|
||||
type: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
color: String,
|
||||
size: Number
|
||||
},
|
||||
computed: {
|
||||
iconType () {
|
||||
return this.type.indexOf('_') === 0 ? 'Icons' : 'Icon'
|
||||
},
|
||||
iconName () {
|
||||
return this.iconType === 'Icons' ? this.getCustomIconName(this.type) : this.type
|
||||
},
|
||||
iconSize () {
|
||||
return this.size || (this.iconType === 'Icons' ? 12 : undefined)
|
||||
},
|
||||
iconColor () {
|
||||
return this.color || ''
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getCustomIconName (iconName) {
|
||||
return iconName.slice(1)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
||||
2
src/components/common-icon/index.js
Normal file
@@ -0,0 +1,2 @@
|
||||
import CommonIcon from './common-icon.vue'
|
||||
export default CommonIcon
|
||||
8
src/components/common/common.less
Normal file
@@ -0,0 +1,8 @@
|
||||
.no-select{
|
||||
-webkit-touch-callout: none;
|
||||
-webkit-user-select: none;
|
||||
-khtml-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
3
src/components/common/util.js
Normal file
@@ -0,0 +1,3 @@
|
||||
export const showTitle = (item, vm) => {
|
||||
return vm.$config.useI18n ? vm.$t(item.name) : ((item.meta && item.meta.title) || item.name)
|
||||
}
|
||||
174
src/components/count-to/count-to.vue
Normal file
@@ -0,0 +1,174 @@
|
||||
<template>
|
||||
<div class="count-to-wrapper">
|
||||
<slot name="left"/>
|
||||
<p class="content-outer"><span :class="['count-to-count-text', countClass]" :id="counterId">{{ init }}</span><i :class="['count-to-unit-text', unitClass]">{{ unitText }}</i></p>
|
||||
<slot name="right"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import CountUp from 'countup'
|
||||
import './index.less'
|
||||
export default {
|
||||
name: 'CountTo',
|
||||
props: {
|
||||
init: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
/**
|
||||
* @description 起始值,即动画开始前显示的数值
|
||||
*/
|
||||
startVal: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
/**
|
||||
* @description 结束值,即动画结束后显示的数值
|
||||
*/
|
||||
end: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
/**
|
||||
* @description 保留几位小数
|
||||
*/
|
||||
decimals: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
/**
|
||||
* @description 分隔整数和小数的符号,默认是小数点
|
||||
*/
|
||||
decimal: {
|
||||
type: String,
|
||||
default: '.'
|
||||
},
|
||||
/**
|
||||
* @description 动画持续的时间,单位是秒
|
||||
*/
|
||||
duration: {
|
||||
type: Number,
|
||||
default: 2
|
||||
},
|
||||
/**
|
||||
* @description 动画延迟开始的时间,单位是秒
|
||||
*/
|
||||
delay: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
/**
|
||||
* @description 是否禁用easing动画效果
|
||||
*/
|
||||
uneasing: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
/**
|
||||
* @description 是否使用分组,分组后每三位会用一个符号分隔
|
||||
*/
|
||||
usegroup: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
/**
|
||||
* @description 用于分组(usegroup)的符号
|
||||
*/
|
||||
separator: {
|
||||
type: String,
|
||||
default: ','
|
||||
},
|
||||
/**
|
||||
* @description 是否简化显示,设为true后会使用unit单位来做相关省略
|
||||
*/
|
||||
simplify: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
/**
|
||||
* @description 自定义单位,如[3, 'K+'], [6, 'M+']即大于3位数小于6位数的用k+来做省略
|
||||
* 1000即显示为1K+
|
||||
*/
|
||||
unit: {
|
||||
type: Array,
|
||||
default () {
|
||||
return [[3, 'K+'], [6, 'M+'], [9, 'B+']]
|
||||
}
|
||||
},
|
||||
countClass: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
unitClass: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
counter: null,
|
||||
unitText: ''
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
counterId () {
|
||||
return `count_to_${this._uid}`
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getHandleVal (val, len) {
|
||||
return {
|
||||
endVal: parseInt(val / Math.pow(10, this.unit[len - 1][0])),
|
||||
unitText: this.unit[len - 1][1]
|
||||
}
|
||||
},
|
||||
transformValue (val) {
|
||||
let len = this.unit.length
|
||||
let res = {
|
||||
endVal: 0,
|
||||
unitText: ''
|
||||
}
|
||||
if (val < Math.pow(10, this.unit[0][0])) res.endVal = val
|
||||
else {
|
||||
for (let i = 1; i < len; i++) {
|
||||
if (val >= Math.pow(10, this.unit[i - 1][0]) && val < Math.pow(10, this.unit[i][0])) res = this.getHandleVal(val, i)
|
||||
}
|
||||
}
|
||||
if (val > Math.pow(10, this.unit[len - 1][0])) res = this.getHandleVal(val, len)
|
||||
return res
|
||||
},
|
||||
getValue (val) {
|
||||
let res = 0
|
||||
if (this.simplify) {
|
||||
let { endVal, unitText } = this.transformValue(val)
|
||||
this.unitText = unitText
|
||||
res = endVal
|
||||
} else {
|
||||
res = val
|
||||
}
|
||||
return res
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
this.$nextTick(() => {
|
||||
let endVal = this.getValue(this.end)
|
||||
this.counter = new CountUp(this.counterId, this.startVal, endVal, this.decimals, this.duration, {
|
||||
useEasing: !this.uneasing,
|
||||
useGrouping: this.useGroup,
|
||||
separator: this.separator,
|
||||
decimal: this.decimal
|
||||
})
|
||||
setTimeout(() => {
|
||||
if (!this.counter.error) this.counter.start()
|
||||
}, this.delay)
|
||||
})
|
||||
},
|
||||
watch: {
|
||||
end (newVal) {
|
||||
let endVal = this.getValue(newVal)
|
||||
this.counter.update(endVal)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
2
src/components/count-to/index.js
Normal file
@@ -0,0 +1,2 @@
|
||||
import countTo from './count-to.vue'
|
||||
export default countTo
|
||||
10
src/components/count-to/index.less
Normal file
@@ -0,0 +1,10 @@
|
||||
@prefix: ~"count-to";
|
||||
|
||||
.@{prefix}-wrapper{
|
||||
.content-outer{
|
||||
display: inline-block;
|
||||
.@{prefix}-unit-text{
|
||||
font-style: normal;
|
||||
}
|
||||
}
|
||||
}
|
||||
2
src/components/cropper/index.js
Normal file
@@ -0,0 +1,2 @@
|
||||
import Cropper from './index.vue'
|
||||
export default Cropper
|
||||
45
src/components/cropper/index.less
Normal file
@@ -0,0 +1,45 @@
|
||||
.bg{
|
||||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC")
|
||||
}
|
||||
.cropper-wrapper{
|
||||
min-height: 500px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-flow: column;
|
||||
align-items: center;
|
||||
.cropper-box {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-top: 20px;
|
||||
}
|
||||
.img-box{
|
||||
margin: 0 auto;
|
||||
height: 540px;
|
||||
width: 960px;
|
||||
border: 1px solid #ebebeb;
|
||||
display: inline-block;
|
||||
.bg;
|
||||
img{
|
||||
max-width: 100%;
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
.button-box{
|
||||
padding: 10px 0 0;
|
||||
margin-bottom: 25px;
|
||||
button {
|
||||
margin: 0 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.file_logo{
|
||||
.file_name{
|
||||
text-align: center;
|
||||
padding-bottom: 15px;
|
||||
}
|
||||
}
|
||||
.underline {
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
180
src/components/cropper/index.vue
Normal file
@@ -0,0 +1,180 @@
|
||||
<template>
|
||||
<div class="cropper-wrapper">
|
||||
<!-- 上传图片时出现cropper -->
|
||||
<div class="cropper-box" v-show="isImage == 1">
|
||||
<div class="img-box">
|
||||
<img class="cropper-image" :id="imgId">
|
||||
</div>
|
||||
</div>
|
||||
<div class="button-box">
|
||||
<div v-show="isImage == 1">
|
||||
<Button type="primary" @click="rotate">
|
||||
<Icon type="md-refresh" :size="18"/>
|
||||
</Button>
|
||||
<Button type="primary" @click="scale('X')">
|
||||
<Icon custom="iconfont icon-shuipingfanzhuan" :size="18"/>
|
||||
</Button>
|
||||
<Button type="primary" @click="scale('Y')">
|
||||
<Icon custom="iconfont icon-chuizhifanzhuan" :size="18"/>
|
||||
</Button>
|
||||
<Button type="primary" @click="startCrop">
|
||||
<Icon type="md-crop" :size="18"/>
|
||||
</Button>
|
||||
<Button type="primary" @click="cancelCrop">
|
||||
{{$t('use_origin_size')}}}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 其他文件时出现文件类型图片 -->
|
||||
<div class="file_logo" v-show="isImage == 2">
|
||||
<img :src="fileLogo">
|
||||
<div class="file_name">{{fileName}}</div>
|
||||
</div>
|
||||
<div class="underline">
|
||||
|
||||
<Upload
|
||||
type="drag"
|
||||
:before-upload="beforeUpload"
|
||||
action="image/upload"
|
||||
v-show="!insideSrc">
|
||||
<div style="padding: 30px 180px">
|
||||
<Icon type="ios-cloud-upload" size="52" style="color: #ffa000"></Icon>
|
||||
<p>{{$t('select_or_drag_img')}}</p>
|
||||
</div>
|
||||
</Upload>
|
||||
|
||||
<Upload action="image/upload" :before-upload="beforeUpload" v-show="insideSrc">
|
||||
<Button icon="ios-cloud-upload-outline" style="width: 150px;">{{$t('reupload')}}</Button>
|
||||
</Upload>
|
||||
<Button style="width: 150px;margin-left: 10px;height: 31.9px" type="primary" @click="comfirm" v-show="insideSrc">{{ cropButtonText }}</Button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Cropper from 'cropperjs'
|
||||
import './index.less'
|
||||
import 'cropperjs/dist/cropper.min.css'
|
||||
export default {
|
||||
name: 'Cropper',
|
||||
props: {
|
||||
cropButtonText: {
|
||||
type: String,
|
||||
default: '确定'
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
cropper: null,
|
||||
fileSize: 0,
|
||||
updataFile: {},
|
||||
insideSrc: '', // 文件内容
|
||||
infoFile: '', // 文件信息
|
||||
fileName: '',
|
||||
fileType: '',
|
||||
isImage: '', // 0表示无文件 1表示文件为图片 2表示其他类型文件
|
||||
fileLogo: ''
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
imgId () {
|
||||
return `cropper${this._uid}`
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
insideSrc (src) {
|
||||
this.replace(src)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
beforeUpload (file) {
|
||||
// 使用html5的fileReader将图片转换成base64编码
|
||||
// var fileSize = 0
|
||||
this.updataFile = file
|
||||
this.fileSize = file.size
|
||||
const reader = new FileReader()
|
||||
reader.readAsDataURL(file)
|
||||
reader.onload = (event) => {
|
||||
this.insideSrc = event.srcElement.result
|
||||
this.fileName = file.name
|
||||
this.fileType = file.type
|
||||
}
|
||||
this.fileName = file.name
|
||||
this.fileType = file.type
|
||||
// 判断文件类型是否为图片 0无 1为图片 2其他类型文件
|
||||
if (/\.(jpe?g|png|gif)$/i.test(file.name)) {
|
||||
this.isImage = 1
|
||||
} else if (/\.(xlsx?)$/i.test(file.name)) {
|
||||
this.isImage = 2
|
||||
this.fileLogo = require('@/assets/icons/file-icon/xls_logo.jpg')
|
||||
} else if (/\.(docx?)$/i.test(file.name)) {
|
||||
this.isImage = 2
|
||||
this.fileLogo = require('@/assets/icons/file-icon/doc_logo.jpg')
|
||||
} else if (/\.(pptx?)$/i.test(file.name)) {
|
||||
this.isImage = 2
|
||||
this.fileLogo = require('@/assets/icons/file-icon/ppt_logo.jpg')
|
||||
} else if (/\.(html)$/i.test(file.name)) {
|
||||
this.isImage = 2
|
||||
this.fileLogo = require('@/assets/icons/file-icon/html_logo.jpg')
|
||||
} else {
|
||||
this.isImage = 2
|
||||
this.fileLogo = require('@/assets/icons/file-icon/others_logo.jpg')
|
||||
}
|
||||
|
||||
return false
|
||||
},
|
||||
replace (src) {
|
||||
this.cropper.replace(src)
|
||||
this.insideSrc = src
|
||||
},
|
||||
rotate () {
|
||||
this.cropper.rotate(90)
|
||||
},
|
||||
scale (d) {
|
||||
this.cropper[`scale${d}`](-this.cropper.getData()[`scale${d}`])
|
||||
},
|
||||
move (...argu) {
|
||||
this.cropper.move(...argu)
|
||||
},
|
||||
startCrop () {
|
||||
this.cropper.crop()
|
||||
},
|
||||
cancelCrop () {
|
||||
this.cropper.clear()
|
||||
},
|
||||
comfirm () {
|
||||
// let dataUrl = this.insideSrc
|
||||
let dataUrl
|
||||
if (this.isImage === 1) {
|
||||
dataUrl = this.cropper.getCroppedCanvas().toDataURL()
|
||||
} else if (this.isImage === 2) {
|
||||
dataUrl = this.insideSrc
|
||||
}
|
||||
let name = this.fileName
|
||||
let type = this.fileType
|
||||
let fileSize = this.fileSize
|
||||
let updataFile = this.updataFile
|
||||
let fileData = {
|
||||
fileSize,
|
||||
updataFile,
|
||||
dataUrl,
|
||||
name,
|
||||
type
|
||||
}
|
||||
this.$emit('transmitInfo', fileData)
|
||||
this.insideSrc = ''
|
||||
this.isImage = 0
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
this.$nextTick(() => {
|
||||
let dom = document.getElementById(this.imgId)
|
||||
this.cropper = new Cropper(dom, {
|
||||
checkCrossOrigin: true,
|
||||
autoCrop: false
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
</script>
|
||||
BIN
src/components/cropper/xls_logo.jpg
Normal file
|
After Width: | Height: | Size: 29 KiB |
18
src/components/drag-drawer/drag-drawer-trigger.vue
Normal file
@@ -0,0 +1,18 @@
|
||||
<template>
|
||||
<div :class="`${prefix}-move-trigger`">
|
||||
<div :class="`${prefix}-move-trigger-point`">
|
||||
<i></i><i></i><i></i><i></i><i></i>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Mixin from './mixin'
|
||||
export default {
|
||||
name: 'DragDrawerTrigger',
|
||||
mixins: [Mixin]
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
||||
156
src/components/drag-drawer/drag-drawer.vue
Normal file
@@ -0,0 +1,156 @@
|
||||
<template>
|
||||
<Drawer ref="drawerWrapper"
|
||||
:value="value"
|
||||
@input="handleInput"
|
||||
:width="width"
|
||||
:class-name="outerClasses"
|
||||
v-bind="$attrs"
|
||||
v-on="$listeners">
|
||||
<!-- 所有插槽内容显示在这里 ↓ -->
|
||||
|
||||
<template v-for="(slots, slotsName) in $slots">
|
||||
<template v-if="slotsName !== 'default'">
|
||||
<render-dom v-for="(render, index) in slots"
|
||||
:key="`b_drawer_${slotsName}_${index}`"
|
||||
:render="() => render"
|
||||
:slot="slotsName">
|
||||
</render-dom>
|
||||
</template>
|
||||
<template v-else>
|
||||
<div :class="`${prefix}-body-wrapper`"
|
||||
:key="`b_drawer_${slotsName}`">
|
||||
<render-dom v-for="(render, index) in slots"
|
||||
:key="`b_drawer_${slotsName}_${index}`"
|
||||
:render="() => render"
|
||||
:slot="slotsName">
|
||||
</render-dom>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
<!-- 所有插槽内容显示在这里 ↑ -->
|
||||
<div v-if="draggable"
|
||||
:style="triggerStyle"
|
||||
:class="`${prefix}-trigger-wrapper`"
|
||||
@mousedown="handleTriggerMousedown">
|
||||
<slot name="trigger">
|
||||
<drag-drawer-trigger></drag-drawer-trigger>
|
||||
</slot>
|
||||
</div>
|
||||
<div v-if="$slots.footer"
|
||||
:class="`${prefix}-footer`">
|
||||
<slot name="footer"></slot>
|
||||
</div>
|
||||
</Drawer>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import RenderDom from '@/libs/render-dom'
|
||||
import DragDrawerTrigger from './drag-drawer-trigger.vue'
|
||||
import Mixin from './mixin'
|
||||
import { on, off } from '@/libs/tools'
|
||||
import './index.less'
|
||||
export default {
|
||||
name: 'BDrawer',
|
||||
components: {
|
||||
RenderDom,
|
||||
DragDrawerTrigger
|
||||
},
|
||||
mixins: [Mixin],
|
||||
props: {
|
||||
value: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
width: {
|
||||
type: [String, Number],
|
||||
default: 256
|
||||
},
|
||||
// 是否可拖动修改宽度
|
||||
draggable: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
// 最小拖动宽度
|
||||
minWidth: {
|
||||
type: [String, Number],
|
||||
default: 256
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
canMove: false,
|
||||
wrapperWidth: 0,
|
||||
wrapperLeft: 0
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
outerClasses () {
|
||||
const classesArray = [
|
||||
`${this.prefix}-wrapper`,
|
||||
this.canMove ? 'no-select pointer-events-none' : ''
|
||||
]
|
||||
return classesArray.join(' ')
|
||||
},
|
||||
placement () {
|
||||
return this.$attrs.placement
|
||||
},
|
||||
innerWidth () {
|
||||
const width = this.width
|
||||
return width <= 100 ? (this.wrapperWidth * width) / 100 : width
|
||||
},
|
||||
triggerStyle () {
|
||||
return {
|
||||
[this.placement]: `${this.innerWidth}px`,
|
||||
position: this.$attrs.inner ? 'absolute' : 'fixed'
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleInput (status) {
|
||||
this.$emit('input', status)
|
||||
},
|
||||
handleTriggerMousedown (event) {
|
||||
this.canMove = true
|
||||
this.$emit('on-resize-start')
|
||||
// 防止鼠标选中抽屉中文字,造成拖动trigger触发浏览器原生拖动行为
|
||||
window.getSelection().removeAllRanges()
|
||||
},
|
||||
handleMousemove (event) {
|
||||
if (!this.canMove) return
|
||||
// 更新容器宽度和距离左侧页面距离,如果是window则距左侧距离为0
|
||||
this.setWrapperWidth()
|
||||
const left = event.pageX - this.wrapperLeft
|
||||
// 如果抽屉方向为右边,宽度计算需用容器宽度减去left
|
||||
let width = this.placement === 'right' ? this.wrapperWidth - left : left
|
||||
// 限定做小宽度
|
||||
width = Math.max(width, parseFloat(this.minWidth))
|
||||
event.atMin = width === parseFloat(this.minWidth)
|
||||
// 如果当前width不大于100,视为百分比
|
||||
if (width <= 100) width = (width / this.wrapperWidth) * 100
|
||||
this.$emit('update:width', parseInt(width))
|
||||
this.$emit('on-resize', event)
|
||||
},
|
||||
handleMouseup (event) {
|
||||
this.canMove = false
|
||||
this.$emit('on-resize-end')
|
||||
},
|
||||
setWrapperWidth () {
|
||||
const {
|
||||
width,
|
||||
left
|
||||
} = this.$refs.drawerWrapper.$el.getBoundingClientRect()
|
||||
this.wrapperWidth = width
|
||||
this.wrapperLeft = left
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
on(document, 'mousemove', this.handleMousemove)
|
||||
on(document, 'mouseup', this.handleMouseup)
|
||||
this.setWrapperWidth()
|
||||
},
|
||||
beforeDestroy () {
|
||||
off(document, 'mousemove', this.handleMousemove)
|
||||
off(document, 'mouseup', this.handleMouseup)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
2
src/components/drag-drawer/index.js
Normal file
@@ -0,0 +1,2 @@
|
||||
import DragDrawer from './drag-drawer.vue'
|
||||
export default DragDrawer
|
||||
70
src/components/drag-drawer/index.less
Normal file
@@ -0,0 +1,70 @@
|
||||
@prefix: ~"drag-drawer";
|
||||
@drag-drawer-trigger-height: 100px;
|
||||
@drag-drawer-trigger-width: 8px;
|
||||
|
||||
.@{prefix}-wrapper{
|
||||
&.no-select{
|
||||
user-select: none;
|
||||
}
|
||||
&.pointer-events-none{
|
||||
pointer-events: none;
|
||||
& .@{prefix}-trigger-wrapper{
|
||||
pointer-events: all;
|
||||
}
|
||||
}
|
||||
.ivu-drawer{
|
||||
&-header{
|
||||
overflow: hidden !important;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
&-body{
|
||||
padding: 0;
|
||||
overflow: visible;
|
||||
position: static;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
.@{prefix}-body-wrapper{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 16px;
|
||||
overflow: auto;
|
||||
}
|
||||
.@{prefix}-trigger-wrapper{
|
||||
top: 0;
|
||||
height: 100%;
|
||||
width: 0;
|
||||
.@{prefix}-move-trigger{
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
height: @drag-drawer-trigger-height;
|
||||
width: @drag-drawer-trigger-width;
|
||||
background: rgb(243, 243, 243);
|
||||
transform: translate(-50%, -50%);
|
||||
border-radius: ~"4px / 6px";
|
||||
box-shadow: 0 0 1px 1px rgba(0, 0, 0, .2);
|
||||
line-height: @drag-drawer-trigger-height;
|
||||
cursor: col-resize;
|
||||
&-point{
|
||||
display: inline-block;
|
||||
width: 50%;
|
||||
transform: translateX(50%);
|
||||
i{
|
||||
display: block;
|
||||
border-bottom: 1px solid rgb(192, 192, 192);
|
||||
padding-bottom: 2px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.@{prefix}-footer{
|
||||
flex-grow: 1;
|
||||
width: 100%;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
border-top: 1px solid #e8e8e8;
|
||||
padding: 10px 16px;
|
||||
background: #fff;
|
||||
}
|
||||
}
|
||||
7
src/components/drag-drawer/mixin.js
Normal file
@@ -0,0 +1,7 @@
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
prefix: 'drag-drawer'
|
||||
}
|
||||
}
|
||||
}
|
||||
92
src/components/drag-list/drag-list.vue
Normal file
@@ -0,0 +1,92 @@
|
||||
<template>
|
||||
<div class="drag-list-wrapper">
|
||||
<div class="drag-list-con con1">
|
||||
<slot name="left-title"></slot>
|
||||
<draggable class="drop-box1" :class="dropConClass.left" :options="options" :value="list1" @input="handleListChange($event, 'left')" @end="handleEnd($event, 'left')">
|
||||
<div class="drag-list-item" v-for="(itemLeft, index) in list1" :key="`drag_li1_${index}`">
|
||||
<slot name="left" :itemLeft="itemLeft">{{ itemLeft }}</slot>
|
||||
</div>
|
||||
</draggable>
|
||||
</div>
|
||||
<div class="drag-list-con con2">
|
||||
<slot name="right-title"></slot>
|
||||
<draggable class="drop-box2" :class="dropConClass.right" :options="options" :value="list2" @input="handleListChange($event, 'right')" @end="handleEnd($event, 'right')">
|
||||
<div class="drag-list-item" v-for="(itemRight, index) in list2" :key="`drag_li2_${index}`">
|
||||
<slot name="right" :itemRight="itemRight">{{ itemRight }}</slot>
|
||||
</div>
|
||||
</draggable>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import draggable from 'vuedraggable'
|
||||
export default {
|
||||
name: 'DragList',
|
||||
components: {
|
||||
draggable
|
||||
},
|
||||
props: {
|
||||
list1: {
|
||||
type: Array,
|
||||
required: true
|
||||
},
|
||||
list2: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
dropConClass: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
options: { group: 'drag_list' }
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleListChange (value, type) {
|
||||
if (type === 'left') this.$emit('update:list1', value)
|
||||
else this.$emit('update:list2', value)
|
||||
},
|
||||
handleEnd (event, type) {
|
||||
const srcClassName = (event.srcElement || event.target).classList[0]
|
||||
const targetClassName = event.to.classList[0]
|
||||
let src = ''
|
||||
let target = ''
|
||||
if (srcClassName === targetClassName) {
|
||||
if (type === 'left') {
|
||||
src = 'left'
|
||||
target = 'left'
|
||||
} else {
|
||||
src = 'right'
|
||||
target = 'right'
|
||||
}
|
||||
} else {
|
||||
if (type === 'left') {
|
||||
src = 'left'
|
||||
target = 'right'
|
||||
} else {
|
||||
src = 'right'
|
||||
target = 'left'
|
||||
}
|
||||
}
|
||||
this.$emit('on-change', {
|
||||
src: src,
|
||||
target: target,
|
||||
oldIndex: event.oldIndex,
|
||||
newIndex: event.newIndex
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="less">
|
||||
.drag-list-wrapper{
|
||||
height: 100%;
|
||||
.drag-list-con{
|
||||
width: 50%;
|
||||
float: left;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
2
src/components/drag-list/index.js
Normal file
@@ -0,0 +1,2 @@
|
||||
import DragList from './drag-list.vue'
|
||||
export default DragList
|
||||
75
src/components/editor/editor.vue
Normal file
@@ -0,0 +1,75 @@
|
||||
<template>
|
||||
<div class="editor-wrapper">
|
||||
<div :id="editorId"></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Editor from 'wangeditor'
|
||||
import 'wangeditor/release/wangEditor.min.css'
|
||||
import { oneOf } from '@/libs/tools'
|
||||
export default {
|
||||
name: 'Editor',
|
||||
props: {
|
||||
value: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
/**
|
||||
* 绑定的值的类型, enum: ['html', 'text']
|
||||
*/
|
||||
valueType: {
|
||||
type: String,
|
||||
default: 'html',
|
||||
validator: (val) => {
|
||||
return oneOf(val, ['html', 'text'])
|
||||
}
|
||||
},
|
||||
/**
|
||||
* @description 设置change事件触发时间间隔
|
||||
*/
|
||||
changeInterval: {
|
||||
type: Number,
|
||||
default: 200
|
||||
},
|
||||
/**
|
||||
* @description 是否开启本地存储
|
||||
*/
|
||||
cache: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
editorId () {
|
||||
return `editor${this._uid}`
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
setHtml (val) {
|
||||
this.editor.txt.html(val)
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
this.editor = new Editor(`#${this.editorId}`)
|
||||
this.editor.customConfig.onchange = (html) => {
|
||||
let text = this.editor.txt.text()
|
||||
if (this.cache) localStorage.editorCache = html
|
||||
this.$emit('input', this.valueType === 'html' ? html : text)
|
||||
this.$emit('on-change', html, text)
|
||||
}
|
||||
this.editor.customConfig.onchangeTimeout = this.changeInterval
|
||||
// create这个方法一定要在所有配置项之后调用
|
||||
this.editor.create()
|
||||
// 如果本地有存储加载本地存储内容
|
||||
let html = this.value || localStorage.editorCache
|
||||
if (html) this.editor.txt.html(html)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.editor-wrapper *{
|
||||
z-index: 100 !important;
|
||||
}
|
||||
</style>
|
||||
2
src/components/editor/index.js
Normal file
@@ -0,0 +1,2 @@
|
||||
import Editor from './editor.vue'
|
||||
export default Editor
|
||||
35
src/components/icons/icons.vue
Normal file
@@ -0,0 +1,35 @@
|
||||
<template>
|
||||
<i :class="`iconfont icon-${type}`" :style="styles"></i>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'Icons',
|
||||
props: {
|
||||
type: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
color: {
|
||||
type: String,
|
||||
default: '#5c6b77'
|
||||
},
|
||||
size: {
|
||||
type: Number,
|
||||
default: 16
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
styles () {
|
||||
return {
|
||||
fontSize: `${this.size}px`,
|
||||
color: this.color
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
||||
2
src/components/icons/index.js
Normal file
@@ -0,0 +1,2 @@
|
||||
import Icons from './icons.vue'
|
||||
export default Icons
|
||||
2
src/components/info-card/index.js
Normal file
@@ -0,0 +1,2 @@
|
||||
import InforCard from './infor-card.vue'
|
||||
export default InforCard
|
||||
94
src/components/info-card/infor-card.vue
Normal file
@@ -0,0 +1,94 @@
|
||||
<template>
|
||||
<Card :shadow="shadow" class="info-card-wrapper" :padding="0">
|
||||
<div class="content-con">
|
||||
<div class="left-area" :style="{width: leftWidth}">
|
||||
<common-icon class="icon" :type="icon" :size="iconSize" :color="color"/>
|
||||
</div>
|
||||
<div class="right-area" :style="{width: rightWidth}">
|
||||
<div>
|
||||
<slot></slot>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import CommonIcon from '_c/common-icon'
|
||||
export default {
|
||||
name: 'InforCard',
|
||||
components: {
|
||||
CommonIcon
|
||||
},
|
||||
props: {
|
||||
left: {
|
||||
type: Number,
|
||||
default: 45
|
||||
},
|
||||
color: {
|
||||
type: String,
|
||||
default: '#2d8cf0'
|
||||
},
|
||||
icon: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
iconSize: {
|
||||
type: Number,
|
||||
default: 20
|
||||
},
|
||||
shadow: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
leftWidth () {
|
||||
return `${this.left}%`
|
||||
},
|
||||
rightWidth () {
|
||||
return `${100 - this.left}%`
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.common{
|
||||
float: left;
|
||||
height: 100%;
|
||||
display: table;
|
||||
text-align: center;
|
||||
}
|
||||
.size{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.middle-center{
|
||||
display: table-cell;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.info-card-wrapper{
|
||||
.size;
|
||||
overflow: hidden;
|
||||
.ivu-card-body{
|
||||
.size;
|
||||
}
|
||||
.content-con{
|
||||
.size;
|
||||
position: relative;
|
||||
.left-area{
|
||||
.common;
|
||||
& > .icon{
|
||||
.middle-center;
|
||||
}
|
||||
}
|
||||
.right-area{
|
||||
.common;
|
||||
& > div{
|
||||
.middle-center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
2
src/components/login-form/index.js
Normal file
@@ -0,0 +1,2 @@
|
||||
import LoginForm from './login-form.vue'
|
||||
export default LoginForm
|
||||
204
src/components/login-form/login-form.vue
Normal file
@@ -0,0 +1,204 @@
|
||||
<template>
|
||||
<Form class="login-form" ref="loginForm" :model="form" :rules="rules" @keydown.enter.native="handleSubmit">
|
||||
<FormItem prop="username">
|
||||
<Input v-model="form.username" :placeholder="$t('developer_account_tips')">
|
||||
<span slot="prepend">
|
||||
<Icon :size="16" type="ios-person"></Icon>
|
||||
</span>
|
||||
</Input>
|
||||
</FormItem>
|
||||
<FormItem prop="password">
|
||||
<Input type="password" v-model="form.password" :placeholder="$t('developer_pwd_tips')">
|
||||
<span slot="prepend">
|
||||
<Icon :size="14" type="md-lock"></Icon>
|
||||
</span>
|
||||
</Input>
|
||||
</FormItem>
|
||||
<FormItem v-if="logincaptcha">
|
||||
<div style="display: flex;align-items: center;">
|
||||
<Input clearable style="width:310px;margin-right:10px" v-model="form.verification" :placeholder="$t('input_captcha_case_sensitive')">
|
||||
<span slot="prepend">
|
||||
<Icon :size="14" type="md-barcode"></Icon>
|
||||
</span>
|
||||
</Input>
|
||||
<img style="height:40px;" :src="codeImg" @click="changeSrc" alt="">
|
||||
</div>
|
||||
</FormItem>
|
||||
<FormItem>
|
||||
<div class="flexbox">
|
||||
<Checkbox class="label" @on-change="toggle">{{$t('keep_login')}}</Checkbox>
|
||||
<router-link v-if="canRegister" :to="{path:'/register'}">{{$t('login_tips')}}>></router-link>
|
||||
</div>
|
||||
<Button class="flexbox-btn" @click="handleSubmit" type="primary" long>{{$t('login')}}</Button>
|
||||
</FormItem>
|
||||
|
||||
<div class="thirdParty_login" v-if="isShowThirdParty">
|
||||
<div class="title-line">
|
||||
<div class="line"></div>
|
||||
<div class="text">第三方登录</div>
|
||||
<div class="line"></div>
|
||||
</div>
|
||||
<div class="select-list">
|
||||
<a @click="thirdpartyLogin" :href="item.callback_url" target="_blank" v-for="(item,index) in thirdPartyList" :key="index">
|
||||
<img :src="item.icon" alt="" srcset="">
|
||||
<div class="text">{{item.desc}}</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</Form>
|
||||
</template>
|
||||
<script>
|
||||
import config from '@/config'
|
||||
|
||||
import { AuthorizationConfig } from '@/api/account'
|
||||
const { cookieExpires_long, cookieExpires_short } = config
|
||||
|
||||
export default {
|
||||
name: 'LoginForm',
|
||||
props: {
|
||||
logincaptcha: {
|
||||
type: Boolean
|
||||
}
|
||||
// usernameRules: {
|
||||
// type: Array,
|
||||
// default: () => {
|
||||
// return [
|
||||
// // { required: true, message: this.$i18n.tc('account_empty'), trigger: 'blur' }
|
||||
// { required: true, message: '账号不得为空', trigger: 'blur' }
|
||||
// ]
|
||||
// }
|
||||
// },
|
||||
// passwordRules: {
|
||||
// type: Array,
|
||||
// default: () => {
|
||||
// return [
|
||||
// // { required: true, message: this.$t('developer_pwd_tips'), trigger: 'blur' }
|
||||
// { required: true, message: '密码不得为空', trigger: 'blur' }
|
||||
// ]
|
||||
// }
|
||||
// }
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
codeImg: '/api/platform.php?service=Platform.Captcha.Create',
|
||||
form: {
|
||||
username: '',
|
||||
password: '',
|
||||
verification: ''
|
||||
},
|
||||
cookiesExp: 1,
|
||||
usernameRules: [
|
||||
{ required: true, message: this.$i18n.tc('account_empty'), trigger: 'blur' }
|
||||
// { required: true, message: '账号不得为空', trigger: 'blur' }
|
||||
],
|
||||
passwordRules: [
|
||||
{ required: true, message: this.$t('developer_pwd_tips'), trigger: 'blur' }
|
||||
// { required: true, message: '密码不得为空', trigger: 'blur' }
|
||||
],
|
||||
isShowThirdParty: false,
|
||||
thirdPartyList: []
|
||||
}
|
||||
},
|
||||
created () {
|
||||
// console.log('i18n', this.$t('welcome'))
|
||||
this.thirdpartyLogin()
|
||||
},
|
||||
computed: {
|
||||
rules () {
|
||||
return {
|
||||
username: this.usernameRules,
|
||||
password: this.passwordRules
|
||||
}
|
||||
},
|
||||
canRegister () {
|
||||
return this.$store.state.user.is_dev_register
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
thirdpartyLogin () {
|
||||
let _this = this
|
||||
AuthorizationConfig().then(res => {
|
||||
if (res.ret == 200) {
|
||||
_this.isShowThirdParty = true
|
||||
_this.thirdPartyList = res.data.quick_login
|
||||
}
|
||||
})
|
||||
},
|
||||
handleSubmit () {
|
||||
this.$refs.loginForm.validate((valid) => {
|
||||
if (valid) {
|
||||
this.$emit('on-success-valid', {
|
||||
username: this.form.username,
|
||||
password: this.form.password,
|
||||
captcha: this.form.verification,
|
||||
cookiesExp: this.cookiesExp
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
toggle (value) {
|
||||
this.cookiesExp = value ? cookieExpires_long : cookieExpires_short
|
||||
},
|
||||
changeSrc () {
|
||||
let timestamp = Date.parse(new Date())
|
||||
this.codeImg = '/api/platform.php?service=Platform.Captcha.Create&t=' + timestamp
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scope>
|
||||
.login-form {
|
||||
.flexbox {
|
||||
margin-top: 10px;
|
||||
width: 400px;
|
||||
display: flex;
|
||||
flex-flow: row;
|
||||
justify-content: space-between;
|
||||
|
||||
&-btn {
|
||||
width: 100%;
|
||||
height: 40px;
|
||||
}
|
||||
}
|
||||
.thirdParty_login {
|
||||
|
||||
.title-line {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 10px;
|
||||
.line {
|
||||
flex:1;
|
||||
background: #ECECEC;
|
||||
height: 1px;
|
||||
}
|
||||
.text {
|
||||
color: #666;
|
||||
padding: 0 15px;
|
||||
}
|
||||
}
|
||||
.select-list {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
|
||||
a {
|
||||
margin: 0 40px;
|
||||
line-height: 1;
|
||||
display: flex;
|
||||
min-width: 60px;
|
||||
flex-flow: column;
|
||||
align-items: center;
|
||||
|
||||
img {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.text {
|
||||
color: #666 !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
2
src/components/main/components/a-back-top/index.js
Normal file
@@ -0,0 +1,2 @@
|
||||
import ABackTop from './index.vue'
|
||||
export default ABackTop
|
||||
97
src/components/main/components/a-back-top/index.vue
Normal file
@@ -0,0 +1,97 @@
|
||||
<!--
|
||||
* @Description:
|
||||
* @Author: Wang Minjie
|
||||
* @Date: 2020-01-04 11:48:55
|
||||
* @LastEditTime: 2020-01-10 16:16:02
|
||||
* @LastEditors: Wang Minjie
|
||||
-->
|
||||
<template>
|
||||
<div :class="classes" :style="styles" @click="back">
|
||||
<slot>
|
||||
<div :class="innerClasses">
|
||||
<i class="ivu-icon ivu-icon-ios-arrow-up"></i>
|
||||
</div>
|
||||
</slot>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { scrollTo } from '@/libs/util'
|
||||
import { on, off } from '@/libs/tools'
|
||||
const prefixCls = 'ivu-back-top'
|
||||
|
||||
export default {
|
||||
name: 'ABackTop',
|
||||
props: {
|
||||
height: {
|
||||
type: Number,
|
||||
default: 400
|
||||
},
|
||||
bottom: {
|
||||
type: Number,
|
||||
default: 30
|
||||
},
|
||||
right: {
|
||||
type: Number,
|
||||
default: 30
|
||||
},
|
||||
duration: {
|
||||
type: Number,
|
||||
default: 1000
|
||||
},
|
||||
container: {
|
||||
type: null,
|
||||
default: window
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
backTop: false
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
// window.addEventListener('scroll', this.handleScroll, false)
|
||||
// window.addEventListener('resize', this.handleScroll, false)
|
||||
on(this.containerEle, 'scroll', this.handleScroll)
|
||||
on(this.containerEle, 'resize', this.handleScroll)
|
||||
},
|
||||
beforeDestroy () {
|
||||
// window.removeEventListener('scroll', this.handleScroll, false)
|
||||
// window.removeEventListener('resize', this.handleScroll, false)
|
||||
off(this.containerEle, 'scroll', this.handleScroll)
|
||||
off(this.containerEle, 'resize', this.handleScroll)
|
||||
},
|
||||
computed: {
|
||||
classes () {
|
||||
return [
|
||||
`${prefixCls}`,
|
||||
{
|
||||
[`${prefixCls}-show`]: this.backTop
|
||||
}
|
||||
]
|
||||
},
|
||||
styles () {
|
||||
return {
|
||||
bottom: `${this.bottom}px`,
|
||||
right: `${this.right}px`
|
||||
}
|
||||
},
|
||||
innerClasses () {
|
||||
return `${prefixCls}-inner`
|
||||
},
|
||||
containerEle () {
|
||||
return this.container === window ? window : document.querySelector(this.container)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleScroll () {
|
||||
this.backTop = this.containerEle.scrollTop >= this.height
|
||||
},
|
||||
back () {
|
||||
let target = typeof this.container === 'string' ? this.containerEle : (document.documentElement || document.body)
|
||||
const sTop = target.scrollTop
|
||||
scrollTo(this.containerEle, sTop, 0, this.duration)
|
||||
this.$emit('on-click')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
49
src/components/main/components/error-store/error-store.vue
Normal file
@@ -0,0 +1,49 @@
|
||||
<template>
|
||||
<div class="error-store">
|
||||
<Badge dot :count="countComputed">
|
||||
<Button type="text" @click="openErrorLoggerPage">
|
||||
<Icon :size="20" type="ios-bug"/>
|
||||
</Button>
|
||||
</Badge>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'ErrorStore',
|
||||
props: {
|
||||
count: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
hasRead: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
countComputed () {
|
||||
return this.hasRead ? 0 : this.count
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
openErrorLoggerPage () {
|
||||
this.$router.push({
|
||||
name: 'error_logger_page'
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.error-store{
|
||||
margin-right: 12px;
|
||||
.ivu-badge-dot{
|
||||
top: 20px;
|
||||
}
|
||||
.ivu-btn.ivu-btn-text{
|
||||
padding: 5px 1px 6px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
2
src/components/main/components/error-store/index.js
Normal file
@@ -0,0 +1,2 @@
|
||||
import ErrorStore from './error-store.vue'
|
||||
export default ErrorStore
|
||||
83
src/components/main/components/fullscreen/fullscreen.vue
Normal file
@@ -0,0 +1,83 @@
|
||||
<template>
|
||||
<div v-if="showFullScreenBtn" class="full-screen-btn-con">
|
||||
<Tooltip :content="value ? $t('exit_fullscreen') : $t('fullscreen')" placement="bottom">
|
||||
<Icon @click.native="handleChange" :type="value ? 'md-contract' : 'md-expand'" :size="23"></Icon>
|
||||
</Tooltip>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'Fullscreen',
|
||||
computed: {
|
||||
showFullScreenBtn () {
|
||||
return window.navigator.userAgent.indexOf('MSIE') < 0
|
||||
}
|
||||
},
|
||||
props: {
|
||||
value: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleFullscreen () {
|
||||
let main = document.body
|
||||
if (this.value) {
|
||||
if (document.exitFullscreen) {
|
||||
document.exitFullscreen()
|
||||
} else if (document.mozCancelFullScreen) {
|
||||
document.mozCancelFullScreen()
|
||||
} else if (document.webkitCancelFullScreen) {
|
||||
document.webkitCancelFullScreen()
|
||||
} else if (document.msExitFullscreen) {
|
||||
document.msExitFullscreen()
|
||||
}
|
||||
} else {
|
||||
if (main.requestFullscreen) {
|
||||
main.requestFullscreen()
|
||||
} else if (main.mozRequestFullScreen) {
|
||||
main.mozRequestFullScreen()
|
||||
} else if (main.webkitRequestFullScreen) {
|
||||
main.webkitRequestFullScreen()
|
||||
} else if (main.msRequestFullscreen) {
|
||||
main.msRequestFullscreen()
|
||||
}
|
||||
}
|
||||
},
|
||||
handleChange () {
|
||||
this.handleFullscreen()
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
let isFullscreen = document.fullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement || document.fullScreen || document.mozFullScreen || document.webkitIsFullScreen
|
||||
isFullscreen = !!isFullscreen
|
||||
document.addEventListener('fullscreenchange', () => {
|
||||
this.$emit('input', !this.value)
|
||||
this.$emit('on-change', !this.value)
|
||||
})
|
||||
document.addEventListener('mozfullscreenchange', () => {
|
||||
this.$emit('input', !this.value)
|
||||
this.$emit('on-change', !this.value)
|
||||
})
|
||||
document.addEventListener('webkitfullscreenchange', () => {
|
||||
this.$emit('input', !this.value)
|
||||
this.$emit('on-change', !this.value)
|
||||
})
|
||||
document.addEventListener('msfullscreenchange', () => {
|
||||
this.$emit('input', !this.value)
|
||||
this.$emit('on-change', !this.value)
|
||||
})
|
||||
this.$emit('input', isFullscreen)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.full-screen-btn-con .ivu-tooltip-rel{
|
||||
line-height: 30px;
|
||||
i{
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
2
src/components/main/components/fullscreen/index.js
Normal file
@@ -0,0 +1,2 @@
|
||||
import Fullscreen from './fullscreen.vue'
|
||||
export default Fullscreen
|
||||