@ -0,0 +1 @@
|
||||
Subproject commit 913343522bfb20f24342454a5dba3c880914d631
|
@ -0,0 +1,21 @@
|
||||
.DS_Store
|
||||
node_modules
|
||||
/dist
|
||||
package-lock.json
|
||||
# local env files
|
||||
.env.local
|
||||
.env.*.local
|
||||
|
||||
# Log files
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
# Editor directories and files
|
||||
.idea
|
||||
.vscode
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw*
|
@ -0,0 +1,5 @@
|
||||
module.exports = {
|
||||
presets: [
|
||||
'@vue/app'
|
||||
]
|
||||
}
|
@ -0,0 +1,72 @@
|
||||
{
|
||||
"name": "pear-project",
|
||||
"version": "2.0.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"serve": "vue-cli-service serve",
|
||||
"build": "vue-cli-service build",
|
||||
"lint": "vue-cli-service lint"
|
||||
},
|
||||
"dependencies": {
|
||||
"ant-design-vue": "latest",
|
||||
"axios": "^0.18.0",
|
||||
"echarts": "^4.2.0-rc.1",
|
||||
"element-ui": "^2.7.2",
|
||||
"jquery": "^3.3.1",
|
||||
"layui-layer": "^1.0.9",
|
||||
"lodash": "^4.17.11",
|
||||
"md5": "^2.2.1",
|
||||
"moment": "^2.22.2",
|
||||
"v-charts": "^1.17.10",
|
||||
"vue": "^2.5.17",
|
||||
"vue-clipboards": "^1.2.4",
|
||||
"vue-cropper": "^0.4.7",
|
||||
"vue-router": "^3.0.1",
|
||||
"vue-simple-uploader": "^0.5.6",
|
||||
"vuedraggable": "^2.17.0",
|
||||
"vuescroll": "^4.6.24",
|
||||
"vuex": "^3.0.1",
|
||||
"wangeditor": "^3.1.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vue/cli-plugin-babel": "^3.2.0",
|
||||
"@vue/cli-plugin-eslint": "^3.2.0",
|
||||
"@vue/cli-service": "^3.2.0",
|
||||
"babel-eslint": "^10.0.1",
|
||||
"babel-plugin-import": "^1.11.0",
|
||||
"eslint": "^5.8.0",
|
||||
"eslint-plugin-vue": "^5.0.0-0",
|
||||
"less": "^3.9.0",
|
||||
"less-loader": "^4.1.0",
|
||||
"mockjs": "^1.0.1-beta3",
|
||||
"semver": "^6.0.0",
|
||||
"vue-template-compiler": "^2.5.17"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"root": true,
|
||||
"env": {
|
||||
"node": true
|
||||
},
|
||||
"extends": [
|
||||
"plugin:vue/essential",
|
||||
"eslint:recommended"
|
||||
],
|
||||
"rules": {
|
||||
"vue/no-unused-components": "off",
|
||||
"vue/no-unused-vars": "off"
|
||||
},
|
||||
"parserOptions": {
|
||||
"parser": "babel-eslint"
|
||||
}
|
||||
},
|
||||
"postcss": {
|
||||
"plugins": {
|
||||
"autoprefixer": {}
|
||||
}
|
||||
},
|
||||
"browserslist": [
|
||||
"> 1%",
|
||||
"last 2 versions",
|
||||
"not ie <= 8"
|
||||
]
|
||||
}
|
After Width: | Height: | Size: 8.8 KiB |
After Width: | Height: | Size: 4.2 KiB |
@ -0,0 +1,16 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<!--<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">-->
|
||||
<link id="icon" rel="icon" type="image/x-icon" href="bull.png">
|
||||
<title>夜未央网盘</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<!-- built files will be auto injected -->
|
||||
<!--<script src="https://webapi.amap.com/js/marker.js"></script>
|
||||
<script type="text/javascript"
|
||||
src="https://webapi.amap.com/maps?v=1.4.7&key=936c5eca7d2e763f953a0483e75637c8&plugin=AMap.Transfer,AMap.Driving,AMap.Walking,AMap.LineSearch,AMap.Geocoder"></script>-->
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,23 @@
|
||||
<template>
|
||||
<div id="app" style="height: 100%">
|
||||
<a-locale-provider :locale="zh_CN">
|
||||
<transition name="router-fades" mode="out-in">
|
||||
<router-view></router-view>
|
||||
</transition>
|
||||
</a-locale-provider>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import zh_CN from 'ant-design-vue/lib/locale-provider/zh_CN';
|
||||
import 'moment/locale/zh-cn';
|
||||
export default {
|
||||
name: 'app',
|
||||
data() {
|
||||
return {
|
||||
zh_CN
|
||||
}
|
||||
},
|
||||
watch: {},
|
||||
methods: {},
|
||||
}
|
||||
</script>
|
@ -0,0 +1,5 @@
|
||||
import $http from '../assets/js/http'
|
||||
|
||||
export function bindClientId(client_id, uid) {
|
||||
return $http.post('index/index/bindClientId', {client_id: client_id, uid: uid});
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
import $http from '../../assets/js/http'
|
||||
|
||||
export function install(data) {
|
||||
return $http.post('index/index/install', data);
|
||||
}
|
||||
|
||||
export function checkInstall() {
|
||||
return $http.post('index/index/checkInstall');
|
||||
}
|
||||
|
||||
export function inviteInfo(inviteCode) {
|
||||
return $http.post('project/invite_link/_read', {inviteCode: inviteCode});
|
||||
}
|
||||
|
||||
export function createInviteLink(data) {
|
||||
return $http.post('project/invite_link/save', data);
|
||||
}
|
||||
|
||||
|
||||
export function notifyOverview(to) {
|
||||
return $http.post('index/notify/listTypeFormat', {to: to});
|
||||
}
|
||||
|
||||
export function areasData() {
|
||||
return $http.post('index/index/getAreaData');
|
||||
}
|
||||
|
||||
export function refreshAccessToken(refreshToken) {
|
||||
return $http.post('index/index/refreshAccessToken', {refreshToken: refreshToken});
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
import $http from '@/assets/js/http'
|
||||
|
||||
|
||||
export function del(code) {
|
||||
return $http.post('project/task_tag/delete', {tagCode: code});
|
||||
}
|
||||
|
||||
|
||||
export function edit(data) {
|
||||
return $http.post('project/task_tag/edit', data);
|
||||
}
|
||||
|
||||
|
||||
export function sort(preCode, nextCode, projectCode) {
|
||||
return $http.post('project/task_stages/sort', {preCode: preCode, nextCode: nextCode, projectCode: projectCode});
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
import $http from '@/assets/js/http'
|
||||
|
||||
//
|
||||
// export function list(data) {
|
||||
// return $http.post('project/file', data);
|
||||
// }
|
||||
//
|
||||
// export function read(fileCode) {
|
||||
// return $http.post('project/file/read', {fileCode: fileCode});
|
||||
// }
|
||||
//
|
||||
// export function edit(data) {
|
||||
// return $http.post('project/file/edit', data);
|
||||
// }
|
||||
//
|
||||
|
||||
// export function recycle(fileCode) {
|
||||
// return $http.post('project/file/recycle', {fileCode: fileCode});
|
||||
// }
|
||||
//
|
||||
// export function recovery(fileCode) {
|
||||
// return $http.post('project/file/recovery', {fileCode: fileCode});
|
||||
// }
|
||||
//
|
||||
// export function del(fileCode) {
|
||||
// return $http.post('project/file/delete', {fileCode: fileCode});
|
||||
// }
|
@ -0,0 +1,28 @@
|
||||
// import $http from '@/assets/js/http'
|
||||
//
|
||||
// export function getMenuForUser() {
|
||||
// return $http.post('project/index');
|
||||
// }
|
||||
//
|
||||
// /*export function getMenu() {
|
||||
// return $http.post('project/menu/menu');
|
||||
// }*/
|
||||
//
|
||||
// export function doMenu(data) {
|
||||
// let url = 'project/menu/menuAdd';
|
||||
// if (data.id) {
|
||||
// url = 'project/menu/menuEdit';
|
||||
// }
|
||||
// return $http.post(url, data);
|
||||
// }
|
||||
// export function forbid(id, status) {
|
||||
// return $http.post('project/menu/menuForbid', {id: id, status: status});
|
||||
// }
|
||||
//
|
||||
// export function resume(id, status) {
|
||||
// return $http.post('project/menu/menuResume', {id: id, status: status});
|
||||
// }
|
||||
// export function delMenu(id) {
|
||||
// return $http.post('project/menu/menuDel', {id: id});
|
||||
// }
|
||||
//
|
@ -0,0 +1,192 @@
|
||||
import $http from '@/assets/js/http'
|
||||
import {getApiUrl} from "../assets/js/utils";
|
||||
import {getStore} from "../assets/js/storage";
|
||||
|
||||
/**---------------登陆--------------**/
|
||||
/*登陆*/
|
||||
export function Login(data) {
|
||||
return $http.post('login', data);
|
||||
}
|
||||
|
||||
/*获取验证码*/
|
||||
export function getCaptcha(mobile) {
|
||||
return $http.post('getCaptcha', {mobile: mobile});
|
||||
}
|
||||
|
||||
/*获取qq授页面*/
|
||||
export function getQqLoginUrl() {
|
||||
return $http.post('qq/login');
|
||||
}
|
||||
|
||||
/*获取qq关联url*/
|
||||
export function getQqConnUrl() {
|
||||
return $http.post('qq/conn');
|
||||
}
|
||||
|
||||
|
||||
/*获取qq登陆用户信息*/
|
||||
export function qqCallback() {
|
||||
return $http.post('qq/callback');
|
||||
}
|
||||
|
||||
/*获取微博授页面*/
|
||||
export function getSinaLoginUrl() {
|
||||
return $http.post('sina/login');
|
||||
}
|
||||
|
||||
/*忘記密碼*/
|
||||
export function forget(data) {
|
||||
return $http.post('forget', data);
|
||||
}
|
||||
|
||||
|
||||
/**---------------菜单--------------**/
|
||||
/*获取菜单*/
|
||||
export function getMenu() {
|
||||
return $http.post('getMenu');
|
||||
}
|
||||
|
||||
/*获取通知*/
|
||||
export function getNotice(data) {
|
||||
return $http.post('getNotice', data);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**---------------首页--------------**/
|
||||
/*获取操作记录*/
|
||||
export function getOperateLog(data) {
|
||||
return $http.post('/getOperateLog', data);
|
||||
}
|
||||
|
||||
|
||||
/*获取首页数据*/
|
||||
export function getIndexData(data) {
|
||||
return $http.post('/getIndexData', data);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**---------------网盘--------------**/
|
||||
/*获取文件上传日志*/
|
||||
export function getFileLog(data) {
|
||||
return $http.post('/getFileLog', data);
|
||||
}
|
||||
|
||||
/*获取文件列表*/
|
||||
export function getFiles(data) {
|
||||
return $http.post('/getFiles', data);
|
||||
}
|
||||
|
||||
|
||||
/*分享查询分享的用户*/
|
||||
export function findToShareUser(userName) {
|
||||
return $http.post('findToShareUser', {userName: userName});
|
||||
}
|
||||
|
||||
/*分享给用户*/
|
||||
export function shareToUser(userId, fileId) {
|
||||
return $http.post('/toShare', {userId: userId, fileId: fileId});
|
||||
}
|
||||
|
||||
/*创建分享链接*/
|
||||
export function createShareUrl(data) {
|
||||
return $http.post('createLink', data);
|
||||
}
|
||||
|
||||
/*文件加入网盘*/
|
||||
export function addDisk(fileId) {
|
||||
return $http.post('addDisk', {fileId: fileId});
|
||||
}
|
||||
|
||||
/*我的网盘删除文件*/
|
||||
export function delFileById(fileId) {
|
||||
return $http.post('delFileById', {fileId: fileId});
|
||||
}
|
||||
|
||||
|
||||
/**---------分享--------**/
|
||||
/*获取分享列表*/
|
||||
export function getShares(data) {
|
||||
return $http.post('getShares', data);
|
||||
}
|
||||
|
||||
export function delByShareId(data) {
|
||||
return $http.post('delByShareId', data);
|
||||
}
|
||||
|
||||
export function uploadFiles() {
|
||||
return "http://localhost:9000/front/app/uploadFile";
|
||||
}
|
||||
|
||||
export function getUserId(userId) {
|
||||
let accessToken = userId;
|
||||
return {userId: `${accessToken}`};
|
||||
}
|
||||
|
||||
export function getLinkInfo(data) {
|
||||
return $http.post('getLinkInfo', data);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**--------资源库-------**/
|
||||
/*获取网盘文件类型*/
|
||||
export function getSourceType() {
|
||||
return $http.post('getSourceType');
|
||||
}
|
||||
|
||||
/*获取资源列表*/
|
||||
export function getSource(data) {
|
||||
return $http.post('getSource', data);
|
||||
}
|
||||
|
||||
|
||||
/*获取资源列表*/
|
||||
export function fileDownload(data) {
|
||||
return $http.post('fileDownload', data);
|
||||
}
|
||||
|
||||
/*文件重命名*/
|
||||
export function fileRename(data) {
|
||||
return $http.post('/file/rename', data);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**--------关注用户-------**/
|
||||
/*获取关注用户列表*/
|
||||
export function getFollowUser(data) {
|
||||
return $http.post('getFollowUser', data);
|
||||
}
|
||||
export function getUserDetail(data) {
|
||||
return $http.post('getUserDetail', data);
|
||||
}
|
||||
|
||||
export function addOrCancleUser(data) {
|
||||
return $http.post('addOrCancelUser', data);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**--------更多-------**/
|
||||
export function editPersonal(data) {
|
||||
return $http.post('updateUserInfo', data);
|
||||
}
|
||||
|
||||
export function _bindMail(data) {
|
||||
return $http.post('bindUpdate', data);
|
||||
}
|
||||
|
||||
export function _bindMobile(data) {
|
||||
return $http.post('bindUpdate', data);
|
||||
}
|
||||
|
||||
export function editPassword(data) {
|
||||
return $http.post('bindUpdate', data);
|
||||
}
|
||||
|
||||
|
||||
|
@ -0,0 +1,29 @@
|
||||
import $http from '@/assets/js/http'
|
||||
|
||||
export function list(data) {
|
||||
return $http.post('project/notify', data);
|
||||
}
|
||||
|
||||
export function noReads() {
|
||||
return $http.post('project/notify/noReads');
|
||||
}
|
||||
|
||||
export function doData(data) {
|
||||
let url = 'project/notify/save';
|
||||
if (data.id) {
|
||||
url = 'project/notify/edit';
|
||||
}
|
||||
return $http.post(url, data);
|
||||
}
|
||||
|
||||
export function del(id) {
|
||||
return $http.post('project/notify/delete', {id: id});
|
||||
}
|
||||
|
||||
export function batchDel(ids) {
|
||||
return $http.post('project/notify/batchDel', {ids: ids});
|
||||
}
|
||||
|
||||
export function setReadied(ids) {
|
||||
return $http.post('project/notify/setReadied', {ids: ids});
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
import $ from 'jquery'
|
||||
export function getYiYan(callback, type) {
|
||||
if (type === undefined) {
|
||||
type = 'f';
|
||||
}
|
||||
let api = 'https://v1.hitokoto.cn/?c=' + type + '&encode=json';
|
||||
$.get({
|
||||
url: api,
|
||||
success: function (data) {
|
||||
callback(data);
|
||||
}
|
||||
})
|
||||
}
|
@ -0,0 +1,82 @@
|
||||
import $http from '@/assets/js/http'
|
||||
|
||||
export async function Login(data) {
|
||||
return $http.post('project/login', data);
|
||||
}
|
||||
|
||||
export function register(data) {
|
||||
return $http.post('project/login/register', data);
|
||||
}
|
||||
|
||||
export function forget(data) {
|
||||
return $http.post('project/login/forget', data);
|
||||
}
|
||||
|
||||
export function getCaptcha(mobile) {
|
||||
return $http.post('project/login/getCaptcha', {mobile: mobile});
|
||||
}
|
||||
|
||||
export function changeCurrentOrganization(organizationCode) {
|
||||
return $http.post('project/index/changeCurrentOrganization', {organizationCode: organizationCode});
|
||||
}
|
||||
|
||||
export function list(data) {
|
||||
return $http.post('project/account', data);
|
||||
}
|
||||
|
||||
export function forbid(accountCode) {
|
||||
return $http.post('project/account/forbid', {accountCode: accountCode, status: 0});
|
||||
}
|
||||
|
||||
export function resume(accountCode) {
|
||||
return $http.post('project/account/resume', {accountCode: accountCode, status: 1});
|
||||
}
|
||||
|
||||
export function doAccount(data) {
|
||||
let url = 'project/account/add';
|
||||
if (data.code) {
|
||||
url = 'project/account/edit';
|
||||
}
|
||||
return $http.post(url, data);
|
||||
}
|
||||
|
||||
export function auth(id, auth) {
|
||||
return $http.post('project/account/auth', {id: id, auth: auth});
|
||||
}
|
||||
|
||||
export function del(accountCode) {
|
||||
return $http.post('project/account/del', {accountCode: accountCode});
|
||||
}
|
||||
|
||||
export function info($id) {
|
||||
return $http.post('project/index/info', {id: $id});
|
||||
}
|
||||
|
||||
export function read(code) {
|
||||
return $http.post('project/account/read', {code: code});
|
||||
}
|
||||
|
||||
export function editAccount(data) {
|
||||
return $http.post('project/account/edit', data);
|
||||
}
|
||||
|
||||
export function editPersonal(data) {
|
||||
return $http.post('project/index/editPersonal', data);
|
||||
}
|
||||
|
||||
export function editPassword(data) {
|
||||
return $http.post('project/index/editPassword', data);
|
||||
}
|
||||
export function _bindMobile(data) {
|
||||
return $http.post('project/login/_bindMobile', data);
|
||||
}
|
||||
export function _bindMail(data) {
|
||||
return $http.post('project/login/_bindMail', data);
|
||||
}
|
||||
export function _checkBindMail(data) {
|
||||
return $http.post('project/login/_checkBindMail', data);
|
||||
}
|
||||
|
||||
export function _joinByInviteLink(inviteCode) {
|
||||
return $http.post('project/account/_joinByInviteLink', {inviteCode: inviteCode});
|
||||
}
|
@ -0,0 +1,406 @@
|
||||
body {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.pull-right {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.pull-left {
|
||||
float: left;
|
||||
}
|
||||
|
||||
//Text
|
||||
.muted {
|
||||
color: rgba(0, 0, 0, 0.45);
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.text-grey {
|
||||
color: grey;
|
||||
}
|
||||
|
||||
.text-default {
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.text-primary {
|
||||
color: @primary-color;
|
||||
}
|
||||
|
||||
.text-info {
|
||||
color: @info-color;
|
||||
}
|
||||
|
||||
.text-success {
|
||||
color: @success-color;
|
||||
}
|
||||
|
||||
.text-processing {
|
||||
color: @processing-color;
|
||||
}
|
||||
|
||||
.text-error {
|
||||
color: @error-color;
|
||||
}
|
||||
|
||||
.text-highlight {
|
||||
color: @highlight-color;
|
||||
}
|
||||
|
||||
.text-warning {
|
||||
color: @warning-color;
|
||||
}
|
||||
|
||||
.text-normal {
|
||||
color: @normal-color;
|
||||
}
|
||||
|
||||
.text-center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.text-right {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.text-left {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
//Input
|
||||
.ant-input-lg {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.ant-select-lg {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
//Button
|
||||
.action-btn {
|
||||
margin-top: 12px;
|
||||
|
||||
.cancel-text {
|
||||
margin-right: 12px;
|
||||
}
|
||||
|
||||
button {
|
||||
margin-right: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
.group-btn, .submit-set {
|
||||
.cancel-text {
|
||||
margin-right: 12px;
|
||||
}
|
||||
|
||||
button {
|
||||
margin-right: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
.middle-btn {
|
||||
min-width: 66px;
|
||||
//min-height: 42px;
|
||||
//min-width: 90px;
|
||||
//height: 35px !important;
|
||||
}
|
||||
|
||||
.ant-btn-lg {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.disabled-btn {
|
||||
background-color: #d9d9d9 !important;
|
||||
border-color: #d9d9d9 !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
//Form
|
||||
.ant-form-horizontal {
|
||||
.ant-form-item-with-help {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
//Table
|
||||
.ant-table-wrapper {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.table-list {
|
||||
.item {
|
||||
display: inline-block;
|
||||
|
||||
&.row-img {
|
||||
img {
|
||||
width: 85px;
|
||||
height: 85px;
|
||||
}
|
||||
}
|
||||
|
||||
&.row-title {
|
||||
margin-left: 12px;
|
||||
vertical-align: middle;
|
||||
width: 75%;
|
||||
|
||||
.title {
|
||||
margin-bottom: 0;
|
||||
|
||||
&.title-name {
|
||||
padding: 5px 24px 5px 5px;
|
||||
color: @primary-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.edit-content {
|
||||
.prefix {
|
||||
position: absolute;
|
||||
line-height: 2.3;
|
||||
}
|
||||
|
||||
.editable-cell {
|
||||
width: 115px;
|
||||
}
|
||||
|
||||
&.price {
|
||||
.editable-cell-input-wrapper, .editable-cell-text-wrapper {
|
||||
padding-left: 15px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Drowdown
|
||||
.ant-dropdown-menu-item {
|
||||
color: grey;
|
||||
}
|
||||
|
||||
.field-right-menu {
|
||||
width: 240px;
|
||||
|
||||
.ant-dropdown-menu-item {
|
||||
min-height: 36px;
|
||||
padding: 8px 16px;
|
||||
position: relative;
|
||||
|
||||
.menu-action {
|
||||
position: absolute;
|
||||
right: 16px;
|
||||
top: 8px;
|
||||
font-size: 12px;
|
||||
color: @primary-color;
|
||||
}
|
||||
|
||||
.menu-desc {
|
||||
padding-left: 22px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.menu-item-content {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Select
|
||||
.ant-select {
|
||||
min-width: 100px;
|
||||
}
|
||||
|
||||
.wangEditor-txt {
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
//Modal
|
||||
.ant-modal {
|
||||
top: 50px;
|
||||
}
|
||||
|
||||
//Badge
|
||||
|
||||
.badge-blue {
|
||||
.ant-badge-status-dot {
|
||||
background-color: #1890ff;
|
||||
}
|
||||
}
|
||||
|
||||
.badge-red {
|
||||
.ant-badge-status-dot {
|
||||
background-color: #f5222d;
|
||||
}
|
||||
}
|
||||
|
||||
.badge-orange {
|
||||
.ant-badge-status-dot {
|
||||
background-color: #ff9900;
|
||||
}
|
||||
}
|
||||
|
||||
.badge-green {
|
||||
.ant-badge-status-dot {
|
||||
background-color: #52c41a;
|
||||
}
|
||||
}
|
||||
|
||||
.badge-brown {
|
||||
.ant-badge-status-dot {
|
||||
background-color: #2fbdb3;
|
||||
}
|
||||
}
|
||||
|
||||
.badge-purple {
|
||||
.ant-badge-status-dot {
|
||||
background-color: #797ec9;
|
||||
}
|
||||
}
|
||||
|
||||
.scroll-modal {
|
||||
.ant-modal-body {
|
||||
padding-bottom: 24px;
|
||||
height: 70vh;
|
||||
}
|
||||
|
||||
.modal-content {
|
||||
padding: 0 24px;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.modal-footer {
|
||||
position: fixed;
|
||||
bottom: 13vh;
|
||||
background: #FFF;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.task-detail-modal {
|
||||
width: 1200px;
|
||||
|
||||
&.ant-modal {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
.ant-modal-content {
|
||||
.ant-modal-body {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.project-navigation {
|
||||
border-bottom: 1px solid #D9D9D9;
|
||||
z-index: 1;
|
||||
background-color: #F5F5F5;
|
||||
transition: right 218ms ease;
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.project-navigation .ivu-breadcrumb-item-separator {
|
||||
color: #383838;
|
||||
}
|
||||
|
||||
.project-navigation .ivu-breadcrumb > span:last-child {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.project-navigation .project-nav-header {
|
||||
position: absolute;
|
||||
z-index: 2;
|
||||
left: 0;
|
||||
height: 50px;
|
||||
margin: 0;
|
||||
padding: 15px;
|
||||
|
||||
.nav-title {
|
||||
font-size: 15px;
|
||||
margin-right: 12px;
|
||||
}
|
||||
|
||||
.actions {
|
||||
cursor: pointer;
|
||||
margin-right: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.project-navigation .nav-underscore {
|
||||
position: relative;
|
||||
height: 50px;
|
||||
border: none;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.project-navigation .nav-body {
|
||||
position: relative;
|
||||
white-space: nowrap;
|
||||
z-index: 1;
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-justify-content: center;
|
||||
-ms-flex-pack: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.project-navigation .nav-body .nav-wrapper.nav > li {
|
||||
z-index: 2;
|
||||
padding: 0 20px;
|
||||
}
|
||||
|
||||
.project-navigation .nav-underscore > li {
|
||||
list-style: none;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.project-navigation .nav-underscore > li a {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
height: 50px;
|
||||
margin: 0;
|
||||
padding: 15px 0;
|
||||
color: #383838;
|
||||
font-size: 15px;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.project-navigation .nav-body .nav-wrapper.nav > li .app[data-app=tasks] {
|
||||
position: relative;
|
||||
float: left;
|
||||
max-width: 200px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.project-navigation .nav-underscore > li > a:hover {
|
||||
background-color: inherit;
|
||||
}
|
||||
|
||||
.project-navigation .nav-underscore > li > a:after {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
height: 3px;
|
||||
width: 100%;
|
||||
border-bottom: 0 solid #3da8f5;
|
||||
content: '';
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.project-navigation .nav-underscore > li > a:hover:after, .project-navigation .nav-underscore > .actives > a:after {
|
||||
border-width: 3px;
|
||||
opacity: 1;
|
||||
}
|
@ -0,0 +1,402 @@
|
||||
/* MARGINS & PADDINGS */
|
||||
|
||||
.p-xxs {
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.p-xs {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.p-sm {
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
.p-m {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.p-md {
|
||||
padding: 25px;
|
||||
}
|
||||
|
||||
.p-lg {
|
||||
padding: 30px;
|
||||
}
|
||||
|
||||
.p-xl {
|
||||
padding: 40px;
|
||||
}
|
||||
|
||||
.p-w-xs {
|
||||
padding: 0 10px;
|
||||
}
|
||||
|
||||
.p-w-sm {
|
||||
padding: 0 15px;
|
||||
|
||||
}
|
||||
|
||||
.p-w-m {
|
||||
padding: 0 20px;
|
||||
|
||||
}
|
||||
|
||||
.p-w-md {
|
||||
padding: 0 25px;
|
||||
|
||||
}
|
||||
|
||||
.p-w-lg {
|
||||
padding: 0 30px;
|
||||
|
||||
}
|
||||
|
||||
.p-w-xl {
|
||||
padding: 0 40px;
|
||||
|
||||
}
|
||||
|
||||
.p-h-xs {
|
||||
padding: 10px 0;
|
||||
}
|
||||
|
||||
.p-h-sm {
|
||||
padding: 15px 0;
|
||||
|
||||
}
|
||||
|
||||
.p-h-m {
|
||||
padding: 20px 0;
|
||||
|
||||
}
|
||||
|
||||
.p-h-md {
|
||||
padding: 25px 0;
|
||||
|
||||
}
|
||||
|
||||
.p-h-lg {
|
||||
padding: 30px 0;
|
||||
|
||||
}
|
||||
|
||||
.p-h-xl {
|
||||
padding: 40px 0;
|
||||
|
||||
}
|
||||
|
||||
.m-xxs {
|
||||
margin: 2px 4px;
|
||||
}
|
||||
|
||||
.m {
|
||||
margin: 15px;
|
||||
}
|
||||
|
||||
.m-xs {
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
.m-sm {
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
.m-md {
|
||||
margin: 20px;
|
||||
}
|
||||
|
||||
.m-lg {
|
||||
margin: 30px;
|
||||
}
|
||||
|
||||
.m-xl {
|
||||
margin: 50px;
|
||||
}
|
||||
|
||||
.m-n {
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
.m-l-none {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.m-l-xs {
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
.m-l-sm {
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.m-l {
|
||||
margin-left: 15px;
|
||||
}
|
||||
|
||||
.m-l-md {
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
.m-l-lg {
|
||||
margin-left: 30px;
|
||||
}
|
||||
|
||||
.m-l-xl {
|
||||
margin-left: 40px;
|
||||
}
|
||||
|
||||
.m-l-n-xxs {
|
||||
margin-left: -1px;
|
||||
}
|
||||
|
||||
.m-l-n-xs {
|
||||
margin-left: -5px;
|
||||
}
|
||||
|
||||
.m-l-n-sm {
|
||||
margin-left: -10px;
|
||||
}
|
||||
|
||||
.m-l-n {
|
||||
margin-left: -15px;
|
||||
}
|
||||
|
||||
.m-l-n-md {
|
||||
margin-left: -20px;
|
||||
}
|
||||
|
||||
.m-l-n-lg {
|
||||
margin-left: -30px;
|
||||
}
|
||||
|
||||
.m-l-n-xl {
|
||||
margin-left: -40px;
|
||||
}
|
||||
|
||||
.m-t-none {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.m-t-xxs {
|
||||
margin-top: 1px;
|
||||
}
|
||||
|
||||
.m-t-xs {
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.m-t-sm {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.m-t {
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
.m-t-md {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.m-t-lg {
|
||||
margin-top: 30px;
|
||||
}
|
||||
|
||||
.m-t-xl {
|
||||
margin-top: 40px;
|
||||
}
|
||||
|
||||
.m-t-n-xxs {
|
||||
margin-top: -1px;
|
||||
}
|
||||
|
||||
.m-t-n-xs {
|
||||
margin-top: -5px;
|
||||
}
|
||||
|
||||
.m-t-n-sm {
|
||||
margin-top: -10px;
|
||||
}
|
||||
|
||||
.m-t-n {
|
||||
margin-top: -15px;
|
||||
}
|
||||
|
||||
.m-t-n-md {
|
||||
margin-top: -20px;
|
||||
}
|
||||
|
||||
.m-t-n-lg {
|
||||
margin-top: -30px;
|
||||
}
|
||||
|
||||
.m-t-n-xl {
|
||||
margin-top: -40px;
|
||||
}
|
||||
|
||||
.m-r-none {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.m-r-xxs {
|
||||
margin-right: 1px;
|
||||
}
|
||||
|
||||
.m-r-xs {
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.m-r-sm {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.m-r {
|
||||
margin-right: 15px;
|
||||
}
|
||||
|
||||
.m-r-md {
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
.m-r-lg {
|
||||
margin-right: 30px;
|
||||
}
|
||||
|
||||
.m-r-xl {
|
||||
margin-right: 40px;
|
||||
}
|
||||
|
||||
.m-r-n-xxs {
|
||||
margin-right: -1px;
|
||||
}
|
||||
|
||||
.m-r-n-xs {
|
||||
margin-right: -5px;
|
||||
}
|
||||
|
||||
.m-r-n-sm {
|
||||
margin-right: -10px;
|
||||
}
|
||||
|
||||
.m-r-n {
|
||||
margin-right: -15px;
|
||||
}
|
||||
|
||||
.m-r-n-md {
|
||||
margin-right: -20px;
|
||||
}
|
||||
|
||||
.m-r-n-lg {
|
||||
margin-right: -30px;
|
||||
}
|
||||
|
||||
.m-r-n-xl {
|
||||
margin-right: -40px;
|
||||
}
|
||||
|
||||
.m-b-none {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.m-b-xxs {
|
||||
margin-bottom: 1px;
|
||||
}
|
||||
|
||||
.m-b-xs {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.m-b-sm {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.m-b {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.m-b-md {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.m-b-lg {
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.m-b-xl {
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
|
||||
.m-b-n-xxs {
|
||||
margin-bottom: -1px;
|
||||
}
|
||||
|
||||
.m-b-n-xs {
|
||||
margin-bottom: -5px;
|
||||
}
|
||||
|
||||
.m-b-n-sm {
|
||||
margin-bottom: -10px;
|
||||
}
|
||||
|
||||
.m-b-n {
|
||||
margin-bottom: -15px;
|
||||
}
|
||||
|
||||
.m-b-n-md {
|
||||
margin-bottom: -20px;
|
||||
}
|
||||
|
||||
.m-b-n-lg {
|
||||
margin-bottom: -30px;
|
||||
}
|
||||
|
||||
.m-b-n-xl {
|
||||
margin-bottom: -40px;
|
||||
}
|
||||
|
||||
.space-15 {
|
||||
margin: 15px 0;
|
||||
}
|
||||
|
||||
.space-20 {
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.space-25 {
|
||||
margin: 25px 0;
|
||||
}
|
||||
|
||||
.space-30 {
|
||||
margin: 30px 0;
|
||||
}
|
||||
|
||||
// IMAGES SIZE
|
||||
|
||||
.img-sm {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
.img-md {
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
}
|
||||
|
||||
.img-lg {
|
||||
width: 96px;
|
||||
height: 96px;
|
||||
}
|
||||
|
||||
// BORDER RADIUS
|
||||
|
||||
// Alignment
|
||||
.text-left { text-align: left; }
|
||||
.text-right { text-align: right; }
|
||||
.text-center { text-align: center; }
|
||||
.text-justify { text-align: justify; }
|
||||
.text-nowrap { white-space: nowrap; }
|
||||
|
||||
// Transformation
|
||||
.text-lowercase { text-transform: lowercase; }
|
||||
.text-uppercase { text-transform: uppercase; }
|
||||
.text-capitalize { text-transform: capitalize; }
|
@ -0,0 +1,6 @@
|
||||
@import "commom";
|
||||
@import "base";
|
||||
@import "layout";
|
||||
@import "list";
|
||||
@import "labels";
|
||||
@import "warpperContent";
|
@ -0,0 +1,73 @@
|
||||
|
||||
//
|
||||
// Labels
|
||||
// --------------------------------------------------
|
||||
|
||||
|
||||
.label {
|
||||
display: inline;
|
||||
padding: .3em .8em;
|
||||
font-size: 75%;
|
||||
//font-weight: bold;
|
||||
line-height: 1;
|
||||
color: #FFF;
|
||||
text-align: center;
|
||||
white-space: nowrap;
|
||||
vertical-align: baseline;
|
||||
border-radius: .25em;
|
||||
background-color: #d1dade;
|
||||
//font-family: 'Open Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
|
||||
text-shadow: none;
|
||||
|
||||
// Add hover effects, but only for links
|
||||
a& {
|
||||
&:hover,
|
||||
&:focus {
|
||||
color: #FFF;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
// Empty labels collapse automatically (not available in IE8)
|
||||
&:empty {
|
||||
display: none;
|
||||
}
|
||||
|
||||
// Quick fix for labels in buttons
|
||||
.btn & {
|
||||
position: relative;
|
||||
top: -1px;
|
||||
}
|
||||
}
|
||||
|
||||
// Colors
|
||||
// Contextual variations (linked labels get darker on :hover)
|
||||
|
||||
.label-default {
|
||||
//background-color(@default-color);
|
||||
}
|
||||
|
||||
.label-primary {
|
||||
background-color:(@primary-color);
|
||||
}
|
||||
|
||||
.label-success {
|
||||
background-color:(@success-color);
|
||||
}
|
||||
|
||||
.label-info {
|
||||
background-color:(@info-color);
|
||||
}
|
||||
|
||||
.label-warning {
|
||||
background-color:(@warning-color);
|
||||
}
|
||||
|
||||
.label-danger {
|
||||
background-color:(@error-color);
|
||||
}
|
||||
.label-normal {
|
||||
color: gray;
|
||||
background-color:(@normal-color);
|
||||
}
|
@ -0,0 +1,316 @@
|
||||
#layout {
|
||||
height: 100vh;
|
||||
|
||||
.ant-layout-header {
|
||||
background: #fff;
|
||||
padding: 0;
|
||||
line-height: 85px;
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
top: 0;
|
||||
z-index: 5;
|
||||
//box-shadow: 0 1px 4px rgba(0, 21, 41, .08);
|
||||
box-shadow: 0 0 8px 0 rgba(0,0,0,.1);
|
||||
ul {
|
||||
border-bottom: none;
|
||||
}
|
||||
}
|
||||
|
||||
.logo {
|
||||
height: 32px;
|
||||
padding: 16px;
|
||||
text-align: center;
|
||||
box-sizing: content-box;
|
||||
transition: all .2s;
|
||||
width: 224px;
|
||||
float: left;
|
||||
line-height: 1.4;
|
||||
background: initial;
|
||||
color: #FFF;
|
||||
cursor: pointer;
|
||||
.logo-img {
|
||||
width: 23px;
|
||||
position: absolute;
|
||||
left: 45px;
|
||||
top: 15px;
|
||||
transition: all .2s;
|
||||
}
|
||||
|
||||
.title {
|
||||
color: inherit;
|
||||
font-size: 20px;
|
||||
position: relative;
|
||||
.version {
|
||||
color: inherit;
|
||||
position: absolute;
|
||||
right: -25px;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.right-menu {
|
||||
position: absolute;
|
||||
right: 12px;
|
||||
top: 0;
|
||||
height: 100%;
|
||||
line-height: 66px;
|
||||
color: #FFF;
|
||||
display: flex;
|
||||
|
||||
.action {
|
||||
cursor: pointer;
|
||||
//display: inline-block;
|
||||
transition: all .2s;
|
||||
padding: 0 6px;
|
||||
height: 65px;
|
||||
|
||||
.anticon {
|
||||
font-size: 16px;
|
||||
vertical-align: middle;
|
||||
color: #FFF;
|
||||
//color: rgba(0, 0, 0, .65);
|
||||
}
|
||||
|
||||
.action-item {
|
||||
padding: 0 12px;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
|
||||
&.user-info {
|
||||
padding-left: 52px;
|
||||
|
||||
.ant-avatar {
|
||||
position: absolute;
|
||||
left: 12px;
|
||||
top: 18px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: rgba(0, 0, 0, .08);
|
||||
//background: #e6f7ff;
|
||||
}
|
||||
|
||||
&.action-avatar {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
&.action-organization {
|
||||
//min-width: 200px;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ant-layout-sider {
|
||||
z-index: 2;
|
||||
overflow: auto;
|
||||
width: 256px !important;
|
||||
max-width: 256px !important;
|
||||
height: 100vh;
|
||||
position: fixed;
|
||||
left: 0;
|
||||
box-shadow: 2px 0 8px 0 rgba(29, 35, 41, .05);
|
||||
|
||||
&.ant-layout-sider-collapsed {
|
||||
width: 80px !important;
|
||||
max-width: 80px !important;
|
||||
|
||||
.ant-layout-sider-trigger {
|
||||
width: 80px !important;
|
||||
}
|
||||
|
||||
.logo {
|
||||
.title {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ant-layout-sider-trigger {
|
||||
width: 256px !important;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.maint-content{
|
||||
.ant-layout-content{
|
||||
border-top: 1px solid #e8e8e8;
|
||||
}
|
||||
}
|
||||
|
||||
.ant-layout-footer {
|
||||
margin: 0 6px;
|
||||
padding: 0 50px 12px 50px;
|
||||
}
|
||||
|
||||
.ant-layout-header.collapsed{
|
||||
.logo{
|
||||
width: 48px;
|
||||
.logo-img{
|
||||
left: 27px;
|
||||
}
|
||||
.title{
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.layout-light {
|
||||
.ant-layout-header {
|
||||
ul {
|
||||
//background-color: #2b83f9;
|
||||
//background-image: linear-gradient(143deg,#2945cb 20%,#2b83f9 81%,#3a9dff);
|
||||
//background-image: linear-gradient(143deg, #2945cb 20%, #1890ff 81%, #3a9dff);
|
||||
background-image: linear-gradient(143deg, #e12f3f 20%, #f79275 81%, #FFC107);
|
||||
border-bottom: none;
|
||||
|
||||
li {
|
||||
border-bottom: none;
|
||||
|
||||
span, i {
|
||||
color: #FFF;
|
||||
//opacity: .69;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
span, i {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
&.ant-menu-item-selected, &.ant-menu-item-active {
|
||||
color: #1890ff;
|
||||
background: rgba(0, 0, 0, 0.08);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ant-layout-sider {
|
||||
background: #FFF;
|
||||
.ant-layout-sider-children{
|
||||
.ant-menu-inline, .ant-menu-vertical, .ant-menu-vertical-left {
|
||||
border-right: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.logo {
|
||||
.title {
|
||||
color: inherit;
|
||||
|
||||
.version {
|
||||
color: inherit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ant-layout-sider-trigger {
|
||||
background: #FFF;
|
||||
color: inherit;
|
||||
}
|
||||
}
|
||||
|
||||
&.layout-dark {
|
||||
.ant-layout-header {
|
||||
ul {
|
||||
background-color: #fff;
|
||||
background-image: none;
|
||||
}
|
||||
}
|
||||
|
||||
.logo {
|
||||
background: #002140;
|
||||
border-bottom: 1px solid #002140;
|
||||
box-shadow: 2px 0 6px rgba(0, 21, 41, .35);
|
||||
}
|
||||
|
||||
.ant-layout-sider{
|
||||
box-shadow: 2px 0 6px rgba(0, 21, 41, .35);
|
||||
}
|
||||
|
||||
.right-menu {
|
||||
color: initial;
|
||||
|
||||
.action {
|
||||
.anticon {
|
||||
color: initial;
|
||||
}
|
||||
|
||||
.action-item {
|
||||
&.user-info {
|
||||
.ant-avatar {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: rgba(0,0,0,.025);
|
||||
//background: #e6f7ff;
|
||||
}
|
||||
|
||||
&.action-avatar {
|
||||
}
|
||||
|
||||
&.action-organization {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
header {
|
||||
.ant-menu {
|
||||
//-webkit-box-shadow: 0 1px 4px rgba(0,21,41,.08);
|
||||
//box-shadow: 0 1px 4px rgba(0,21,41,.08);
|
||||
}
|
||||
}
|
||||
|
||||
&.hide {
|
||||
.ant-layout-sider {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.main-content {
|
||||
padding-left: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.trigger {
|
||||
font-size: 18px;
|
||||
line-height: 64px;
|
||||
padding: 0 24px;
|
||||
cursor: pointer;
|
||||
transition: color .2s;
|
||||
|
||||
&:hover {
|
||||
color: #1890ff;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
.middle-menu {
|
||||
padding: 4px 0;
|
||||
|
||||
.ant-dropdown-menu-item-divider, .ant-dropdown-menu-submenu-title-divider {
|
||||
margin: 4px 0;
|
||||
}
|
||||
|
||||
.ant-dropdown-menu-item {
|
||||
width: 160px;
|
||||
}
|
||||
|
||||
&.organization-menu {
|
||||
.ant-dropdown-menu-item {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.__vuescroll .__rail-is-vertical {
|
||||
z-index: 3;
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
.default-list {
|
||||
.ant-list-item-meta-avatar {
|
||||
.ant-avatar {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
}
|
||||
|
||||
.ant-list-item-content {
|
||||
.other-info {
|
||||
display: flex;
|
||||
|
||||
.info-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding-left: 48px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ant-list-item-action {
|
||||
.anticon:hover {
|
||||
svg {
|
||||
color: @primary-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,146 @@
|
||||
.page-title {
|
||||
font-size: 18px;
|
||||
color: #464c5b;
|
||||
line-height: 35px;
|
||||
padding-bottom: 5px;
|
||||
font-weight: 400;
|
||||
//border-bottom: 1px solid #e5e5e5;
|
||||
}
|
||||
.content-title {
|
||||
font-size: 18px;
|
||||
color: #464c5b;
|
||||
line-height: 35px;
|
||||
padding-bottom: 12px;
|
||||
margin-bottom: 12px;
|
||||
min-height: 52px;
|
||||
font-weight: 400;
|
||||
border-bottom: 1px solid #e5e5e5;
|
||||
}
|
||||
|
||||
.content-action {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.content-action + .page-title {
|
||||
//padding-top: 55px;
|
||||
}
|
||||
.page-header{
|
||||
//margin-top: 65px;
|
||||
background: #fff;
|
||||
padding: 16px 32px 0;
|
||||
border-bottom: 1px solid #e8e8e8;
|
||||
.breadcrumb{
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
.detail{
|
||||
display: flex;
|
||||
.row {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
}
|
||||
.main{
|
||||
width: 100%;
|
||||
flex: 0 1 auto;
|
||||
.title{
|
||||
flex: auto;
|
||||
font-size: 20px;
|
||||
font-weight: 500;
|
||||
color: rgba(0,0,0,.85);
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
.logo{
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
border-radius: 4px;
|
||||
margin-right: 16px;
|
||||
}
|
||||
.content{
|
||||
margin-bottom: 16px;
|
||||
flex: auto;
|
||||
}
|
||||
.extra{
|
||||
flex: 0 1 auto;
|
||||
margin-left: 88px;
|
||||
min-width: 242px;
|
||||
text-align: right;
|
||||
}
|
||||
.action{
|
||||
margin-left: 56px;
|
||||
min-width: 266px;
|
||||
flex: 0 1 auto;
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.page-header-none{
|
||||
padding: 0;
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.wrapper-main {
|
||||
margin: 24px;
|
||||
padding: 24px 0 12px 24px;
|
||||
background: rgb(255, 255, 255);
|
||||
}
|
||||
|
||||
.wrapper-content {
|
||||
width: 100%;
|
||||
padding-right: 24px;
|
||||
transition: all 368ms;
|
||||
.action{
|
||||
padding-bottom: 12px;
|
||||
line-height: 3;
|
||||
}
|
||||
}
|
||||
|
||||
.layout-content {
|
||||
}
|
||||
|
||||
.page-search {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.has-header-content .wrapper-content {
|
||||
padding: 80px 20px 0 276px;
|
||||
margin-top: 0;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.has-header-content .layout-content {
|
||||
box-shadow: 0 2px 3px 0 rgba(0, 0, 0, .047);
|
||||
padding: 5px 30px 15px 30px;
|
||||
}
|
||||
|
||||
.wrapper-content .data-content {
|
||||
margin-top: 30px;
|
||||
}
|
||||
|
||||
.layout-content .content-header {
|
||||
height: 56px;
|
||||
z-index: 5;
|
||||
width: 100%;
|
||||
line-height: 56px;
|
||||
overflow: hidden;
|
||||
border-bottom: 1px solid #e5e5e5;
|
||||
margin-bottom: 35px;
|
||||
}
|
||||
|
||||
.layout-content .content-header h1:first-child {
|
||||
cursor: pointer;
|
||||
color: @primary-color;
|
||||
}
|
||||
|
||||
.layout-content .content-header h1 {
|
||||
font-size: 14px;
|
||||
float: left;
|
||||
line-height: 56px;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.layout-copy {
|
||||
text-align: center;
|
||||
padding: 10px 0 20px;
|
||||
color: #9ea7b4;
|
||||
}
|
||||
|
@ -0,0 +1,66 @@
|
||||
.member-menu {
|
||||
background: #fff;
|
||||
box-shadow: 0 2px 20px rgba(0, 0, 0, .1);
|
||||
padding: 12px 0;
|
||||
width: 250px;
|
||||
height: 375px;
|
||||
border-radius: 4px;
|
||||
|
||||
.header {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
padding: 12px 0;
|
||||
}
|
||||
|
||||
.search-content {
|
||||
padding: 12px;
|
||||
|
||||
.ant-input {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
.member-list {
|
||||
height: 235px;
|
||||
position: relative;
|
||||
|
||||
.list-group {
|
||||
.title {
|
||||
display: block;
|
||||
margin: 6px 12px;
|
||||
}
|
||||
|
||||
.member-list-item {
|
||||
padding: 12px;
|
||||
cursor: pointer;
|
||||
border-bottom: none;
|
||||
|
||||
.ant-list-item-meta {
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
&.owner {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ant-list-empty-text {
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
|
||||
.footer {
|
||||
border-top: 1px solid #e5e5e5;
|
||||
padding: 12px 12px 0 12px;
|
||||
position: fixed;
|
||||
width: 250px;
|
||||
height: 75px;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
@import "~ant-design-vue/dist/antd.less";
|
||||
@import "components/index";
|
||||
@import "project/memberMenu";
|
||||
|
@ -0,0 +1,831 @@
|
||||
/* 编辑器边框颜色 */
|
||||
/* 菜单颜色、上边框颜色 */
|
||||
/* 菜单选中状态的颜色 */
|
||||
/* input focus 时的颜色 */
|
||||
/* 按钮颜色 */
|
||||
/* tab selected 状态下的颜色 */
|
||||
.wangEditor-container {
|
||||
position: relative;
|
||||
background-color: #fff;
|
||||
border: 1px solid #ccc;
|
||||
z-index: 1;
|
||||
width: 100%;
|
||||
}
|
||||
.wangEditor-container a:focus,
|
||||
.wangEditor-container button:focus {
|
||||
outline: none;
|
||||
}
|
||||
.wangEditor-container,
|
||||
.wangEditor-container * {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
line-height: 1;
|
||||
}
|
||||
.wangEditor-container img {
|
||||
border: none;
|
||||
}
|
||||
.wangEditor-container .clearfix:after {
|
||||
content: '';
|
||||
display: table;
|
||||
clear: both;
|
||||
}
|
||||
.wangEditor-container .clearfix {
|
||||
*zoom: 1;
|
||||
}
|
||||
.wangEditor-container textarea {
|
||||
border: none;
|
||||
}
|
||||
.wangEditor-container textarea:focus {
|
||||
outline: none;
|
||||
}
|
||||
.wangEditor-container .height-tip {
|
||||
position: absolute;
|
||||
width: 3px;
|
||||
background-color: #ccc;
|
||||
left: 0;
|
||||
transition: top .2s;
|
||||
}
|
||||
.wangEditor-container .txt-toolbar {
|
||||
position: absolute;
|
||||
background-color: #fff;
|
||||
padding: 3px 5px;
|
||||
border-top: 2px solid #666;
|
||||
box-shadow: 1px 3px 3px #999;
|
||||
border-left: 1px\9 solid\9 #ccc\9;
|
||||
border-bottom: 1px\9 solid\9 #999\9;
|
||||
border-right: 1px\9 solid\9 #999\9;
|
||||
}
|
||||
.wangEditor-container .txt-toolbar .tip-triangle {
|
||||
display: block;
|
||||
position: absolute;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border: 5px solid;
|
||||
border-color: transparent transparent #666 transparent;
|
||||
top: -12px;
|
||||
left: 50%;
|
||||
margin-left: -5px;
|
||||
}
|
||||
.wangEditor-container .txt-toolbar a {
|
||||
color: #666;
|
||||
display: inline-block;
|
||||
margin: 0 3px;
|
||||
padding: 5px;
|
||||
text-decoration: none;
|
||||
border-radius: 3px;
|
||||
}
|
||||
.wangEditor-container .txt-toolbar a:hover {
|
||||
background-color: #f1f1f1;
|
||||
}
|
||||
.wangEditor-container .img-drag-point {
|
||||
display: block;
|
||||
position: absolute;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
border-radius: 50%;
|
||||
cursor: se-resize;
|
||||
background-color: #666;
|
||||
margin-left: -6px;
|
||||
margin-top: -6px;
|
||||
box-shadow: 1px 1px 5px #999;
|
||||
}
|
||||
.wangEditor-container .wangEditor-upload-progress {
|
||||
position: absolute;
|
||||
height: 1px;
|
||||
background: #1e88e5;
|
||||
width: 0;
|
||||
display: none;
|
||||
-webkit-transition: width .5s;
|
||||
-o-transition: width .5s;
|
||||
transition: width .5s;
|
||||
}
|
||||
.wangEditor-fullscreen {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
.wangEditor-container .code-textarea {
|
||||
resize: none;
|
||||
width: 100%;
|
||||
font-size: 14px;
|
||||
line-height: 1.5;
|
||||
font-family: 'Verdana';
|
||||
color: #333;
|
||||
padding: 0 15px 0 15px;
|
||||
}
|
||||
.wangEditor-menu-container {
|
||||
width: 100%;
|
||||
border-bottom: 1px solid #f1f1f1;
|
||||
background-color: #fff;
|
||||
}
|
||||
.wangEditor-menu-container a {
|
||||
text-decoration: none;
|
||||
}
|
||||
.wangEditor-menu-container .menu-group {
|
||||
float: left;
|
||||
padding: 0 8px;
|
||||
border-right: 1px solid #f1f1f1;
|
||||
}
|
||||
.wangEditor-menu-container .menu-item {
|
||||
float: left;
|
||||
position: relative;
|
||||
text-align: center;
|
||||
height: 31px;
|
||||
width: 35px;
|
||||
}
|
||||
.wangEditor-menu-container .menu-item:hover {
|
||||
background-color: #f1f1f1;
|
||||
}
|
||||
.wangEditor-menu-container .menu-item a {
|
||||
display: block;
|
||||
text-align: center;
|
||||
color: #666;
|
||||
width: 100%;
|
||||
padding: 8px 0;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
.wangEditor-menu-container .menu-item .selected {
|
||||
color: #1e88e5;
|
||||
}
|
||||
.wangEditor-menu-container .menu-item .active {
|
||||
background-color: #f1f1f1;
|
||||
}
|
||||
.wangEditor-menu-container .menu-item .disable {
|
||||
opacity: 0.5;
|
||||
filter: alpha(opacity=50);
|
||||
}
|
||||
.wangEditor-menu-container .menu-tip {
|
||||
display: block;
|
||||
position: absolute;
|
||||
z-index: 20;
|
||||
width: 60px;
|
||||
text-align: center;
|
||||
background-color: #666;
|
||||
color: #fff;
|
||||
padding: 7px 0;
|
||||
font-size: 12px;
|
||||
top: 100%;
|
||||
left: 50%;
|
||||
margin-left: -30px;
|
||||
border-radius: 2px;
|
||||
box-shadow: 1px 1px 5px #999;
|
||||
display: none;
|
||||
/*// 小三角
|
||||
.tip-triangle {
|
||||
display: block;
|
||||
position: absolute;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border:5px solid;
|
||||
border-color: transparent transparent @fore-color transparent;
|
||||
top: -10px;
|
||||
left: 50%;
|
||||
margin-left: -5px;
|
||||
}*/
|
||||
}
|
||||
.wangEditor-menu-container .menu-tip-40 {
|
||||
width: 40px;
|
||||
margin-left: -20px;
|
||||
}
|
||||
.wangEditor-menu-container .menu-tip-50 {
|
||||
width: 50px;
|
||||
margin-left: -25px;
|
||||
}
|
||||
.wangEditor-menu-shadow {
|
||||
/*border-bottom-width: 0;*/
|
||||
border-bottom: 1px\9 solid\9 #f1f1f1\9;
|
||||
box-shadow: 0 1px 3px #999;
|
||||
}
|
||||
.wangEditor-container .wangEditor-txt {
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
padding: 15px;
|
||||
padding-top: 0;
|
||||
margin-top: 5px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.wangEditor-container .wangEditor-txt p,
|
||||
.wangEditor-container .wangEditor-txt h1,
|
||||
.wangEditor-container .wangEditor-txt h2,
|
||||
.wangEditor-container .wangEditor-txt h3,
|
||||
.wangEditor-container .wangEditor-txt h4,
|
||||
.wangEditor-container .wangEditor-txt h5 {
|
||||
margin: 10px 0;
|
||||
line-height: 1.8;
|
||||
}
|
||||
.wangEditor-container .wangEditor-txt p *,
|
||||
.wangEditor-container .wangEditor-txt h1 *,
|
||||
.wangEditor-container .wangEditor-txt h2 *,
|
||||
.wangEditor-container .wangEditor-txt h3 *,
|
||||
.wangEditor-container .wangEditor-txt h4 *,
|
||||
.wangEditor-container .wangEditor-txt h5 * {
|
||||
line-height: 1.8;
|
||||
}
|
||||
.wangEditor-container .wangEditor-txt ul,
|
||||
.wangEditor-container .wangEditor-txt ol {
|
||||
padding-left: 20px;
|
||||
}
|
||||
.wangEditor-container .wangEditor-txt img {
|
||||
cursor: pointer;
|
||||
}
|
||||
.wangEditor-container .wangEditor-txt img.clicked {
|
||||
box-shadow: 1px 1px 10px #999;
|
||||
}
|
||||
.wangEditor-container .wangEditor-txt table.clicked {
|
||||
box-shadow: 1px 1px 10px #999;
|
||||
}
|
||||
.wangEditor-container .wangEditor-txt pre code {
|
||||
line-height: 1.5;
|
||||
}
|
||||
.wangEditor-container .wangEditor-txt:focus {
|
||||
outline: none;
|
||||
}
|
||||
.wangEditor-container .wangEditor-txt blockquote {
|
||||
display: block;
|
||||
border-left: 8px solid #d0e5f2;
|
||||
padding: 5px 10px;
|
||||
margin: 10px 0;
|
||||
line-height: 1.4;
|
||||
font-size: 100%;
|
||||
background-color: #f1f1f1;
|
||||
}
|
||||
.wangEditor-container .wangEditor-txt table {
|
||||
border: none;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
.wangEditor-container .wangEditor-txt table td,
|
||||
.wangEditor-container .wangEditor-txt table th {
|
||||
border: 1px solid #999;
|
||||
padding: 3px 5px;
|
||||
min-width: 50px;
|
||||
height: 20px;
|
||||
}
|
||||
.wangEditor-container .wangEditor-txt pre {
|
||||
border: 1px solid #ccc;
|
||||
background-color: #f8f8f8;
|
||||
padding: 10px;
|
||||
margin: 5px 0px;
|
||||
font-size: 0.8em;
|
||||
border-radius: 3px;
|
||||
}
|
||||
.wangEditor-drop-list {
|
||||
display: none;
|
||||
position: absolute;
|
||||
background-color: #fff;
|
||||
overflow: hidden;
|
||||
z-index: 10;
|
||||
transition: height .7s;
|
||||
border-top: 1px solid #f1f1f1;
|
||||
box-shadow: 1px 3px 3px #999;
|
||||
border-left: 1px\9 solid\9 #ccc\9;
|
||||
border-bottom: 1px\9 solid\9 #999\9;
|
||||
border-right: 1px\9 solid\9 #999\9;
|
||||
}
|
||||
.wangEditor-drop-list a {
|
||||
text-decoration: none;
|
||||
display: block;
|
||||
color: #666;
|
||||
padding: 3px 5px;
|
||||
}
|
||||
.wangEditor-drop-list a:hover {
|
||||
background-color: #f1f1f1;
|
||||
}
|
||||
.wangEditor-drop-panel,
|
||||
.txt-toolbar {
|
||||
display: none;
|
||||
position: absolute;
|
||||
padding: 10px;
|
||||
font-size: 14px;
|
||||
/*border: 1px\9 solid\9 #cccccc\9;*/
|
||||
background-color: #fff;
|
||||
z-index: 10;
|
||||
border-top: 2px solid #666;
|
||||
box-shadow: 1px 3px 3px #999;
|
||||
border-left: 1px\9 solid\9 #ccc\9;
|
||||
border-bottom: 1px\9 solid\9 #999\9;
|
||||
border-right: 1px\9 solid\9 #999\9;
|
||||
}
|
||||
.wangEditor-drop-panel .tip-triangle,
|
||||
.txt-toolbar .tip-triangle {
|
||||
display: block;
|
||||
position: absolute;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border: 5px solid;
|
||||
border-color: transparent transparent #666 transparent;
|
||||
top: -12px;
|
||||
left: 50%;
|
||||
margin-left: -5px;
|
||||
}
|
||||
.wangEditor-drop-panel a,
|
||||
.txt-toolbar a {
|
||||
text-decoration: none;
|
||||
}
|
||||
.wangEditor-drop-panel input[type=text],
|
||||
.txt-toolbar input[type=text] {
|
||||
border: none;
|
||||
border-bottom: 1px solid #ccc;
|
||||
font-size: 14px;
|
||||
height: 20px;
|
||||
color: #333;
|
||||
padding: 3px 0;
|
||||
}
|
||||
.wangEditor-drop-panel input[type=text]:focus,
|
||||
.txt-toolbar input[type=text]:focus {
|
||||
outline: none;
|
||||
border-bottom: 2px solid #1e88e5;
|
||||
}
|
||||
.wangEditor-drop-panel input[type=text].block,
|
||||
.txt-toolbar input[type=text].block {
|
||||
display: block;
|
||||
width: 100%;
|
||||
}
|
||||
.wangEditor-drop-panel textarea,
|
||||
.txt-toolbar textarea {
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
.wangEditor-drop-panel textarea:focus,
|
||||
.txt-toolbar textarea:focus {
|
||||
outline: none;
|
||||
border-color: #1e88e5;
|
||||
}
|
||||
.wangEditor-drop-panel button,
|
||||
.txt-toolbar button {
|
||||
font-size: 14px;
|
||||
color: #1e88e5;
|
||||
border: none;
|
||||
padding: 10px;
|
||||
background-color: #fff;
|
||||
cursor: pointer;
|
||||
border-radius: 3px;
|
||||
}
|
||||
.wangEditor-drop-panel button:hover,
|
||||
.txt-toolbar button:hover {
|
||||
background-color: #f1f1f1;
|
||||
}
|
||||
.wangEditor-drop-panel button:focus,
|
||||
.txt-toolbar button:focus {
|
||||
outline: none;
|
||||
}
|
||||
.wangEditor-drop-panel button.right,
|
||||
.txt-toolbar button.right {
|
||||
float: right;
|
||||
margin-left: 10px;
|
||||
}
|
||||
.wangEditor-drop-panel button.gray,
|
||||
.txt-toolbar button.gray {
|
||||
color: #999;
|
||||
}
|
||||
.wangEditor-drop-panel button.link,
|
||||
.txt-toolbar button.link {
|
||||
padding: 5px 10px;
|
||||
}
|
||||
.wangEditor-drop-panel button.link:hover,
|
||||
.txt-toolbar button.link:hover {
|
||||
background-color: #fff;
|
||||
text-decoration: underline;
|
||||
}
|
||||
.wangEditor-drop-panel .color-item,
|
||||
.txt-toolbar .color-item {
|
||||
display: block;
|
||||
float: left;
|
||||
width: 25px;
|
||||
height: 25px;
|
||||
text-align: center;
|
||||
padding: 2px;
|
||||
border-radius: 2px;
|
||||
text-decoration: underline;
|
||||
}
|
||||
.wangEditor-drop-panel .color-item:hover,
|
||||
.txt-toolbar .color-item:hover {
|
||||
background-color: #f1f1f1;
|
||||
}
|
||||
.wangEditor-drop-panel .list-menu-item,
|
||||
.txt-toolbar .list-menu-item {
|
||||
display: block;
|
||||
float: left;
|
||||
color: #333;
|
||||
padding: 5px 5px;
|
||||
border-radius: 2px;
|
||||
}
|
||||
.wangEditor-drop-panel .list-menu-item:hover,
|
||||
.txt-toolbar .list-menu-item:hover {
|
||||
background-color: #f1f1f1;
|
||||
}
|
||||
.wangEditor-drop-panel table.choose-table,
|
||||
.txt-toolbar table.choose-table {
|
||||
border: none;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
.wangEditor-drop-panel table.choose-table td,
|
||||
.txt-toolbar table.choose-table td {
|
||||
border: 1px solid #ccc;
|
||||
width: 16px;
|
||||
height: 12px;
|
||||
}
|
||||
.wangEditor-drop-panel table.choose-table td.active,
|
||||
.txt-toolbar table.choose-table td.active {
|
||||
background-color: #ccc;
|
||||
opacity: .5;
|
||||
filter: alpha(opacity=50);
|
||||
}
|
||||
.wangEditor-drop-panel .panel-tab .tab-container,
|
||||
.txt-toolbar .panel-tab .tab-container {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
.wangEditor-drop-panel .panel-tab .tab-container a,
|
||||
.txt-toolbar .panel-tab .tab-container a {
|
||||
display: inline-block;
|
||||
color: #999;
|
||||
text-align: center;
|
||||
margin: 0 5px;
|
||||
padding: 5px 5px;
|
||||
}
|
||||
.wangEditor-drop-panel .panel-tab .tab-container a.selected,
|
||||
.txt-toolbar .panel-tab .tab-container a.selected {
|
||||
color: #1e88e5;
|
||||
border-bottom: 2px solid #1e88e5;
|
||||
}
|
||||
.wangEditor-drop-panel .panel-tab .content-container .content,
|
||||
.txt-toolbar .panel-tab .content-container .content {
|
||||
display: none;
|
||||
}
|
||||
.wangEditor-drop-panel .panel-tab .content-container .content a,
|
||||
.txt-toolbar .panel-tab .content-container .content a {
|
||||
display: inline-block;
|
||||
margin: 2px;
|
||||
padding: 2px;
|
||||
border-radius: 2px;
|
||||
}
|
||||
.wangEditor-drop-panel .panel-tab .content-container .content a:hover,
|
||||
.txt-toolbar .panel-tab .content-container .content a:hover {
|
||||
background-color: #f1f1f1;
|
||||
}
|
||||
.wangEditor-drop-panel .panel-tab .content-container .selected,
|
||||
.txt-toolbar .panel-tab .content-container .selected {
|
||||
display: block;
|
||||
}
|
||||
.wangEditor-drop-panel .panel-tab .emotion-content-container,
|
||||
.txt-toolbar .panel-tab .emotion-content-container {
|
||||
height: 200px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.wangEditor-drop-panel .upload-icon-container,
|
||||
.txt-toolbar .upload-icon-container {
|
||||
color: #ccc;
|
||||
text-align: center;
|
||||
margin: 20px 20px 15px 20px !important;
|
||||
padding: 5px !important;
|
||||
font-size: 65px;
|
||||
cursor: pointer;
|
||||
border: 2px dotted #f1f1f1;
|
||||
display: block !important;
|
||||
}
|
||||
.wangEditor-drop-panel .upload-icon-container:hover,
|
||||
.txt-toolbar .upload-icon-container:hover {
|
||||
color: #666;
|
||||
border-color: #ccc;
|
||||
}
|
||||
.wangEditor-modal {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
background-color: #fff;
|
||||
border-top: 1px solid #f1f1f1;
|
||||
box-shadow: 1px 3px 3px #999;
|
||||
border-top: 1px\9 solid\9 #ccc\9;
|
||||
border-left: 1px\9 solid\9 #ccc\9;
|
||||
border-bottom: 1px\9 solid\9 #999\9;
|
||||
border-right: 1px\9 solid\9 #999\9;
|
||||
}
|
||||
.wangEditor-modal .wangEditor-modal-close {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
margin-top: -25px;
|
||||
margin-right: -25px;
|
||||
font-size: 1.5em;
|
||||
color: #666;
|
||||
cursor: pointer;
|
||||
}
|
||||
/*@font-face {*/
|
||||
/*font-family: 'icomoon';*/
|
||||
/*src: url('../fonts/icomoon.eot?-qdfu1s');*/
|
||||
/*src: url('../fonts/icomoon.eot?#iefix-qdfu1s') format('embedded-opentype'), url('../fonts/icomoon.ttf?-qdfu1s') format('truetype'), url('../fonts/icomoon.woff?-qdfu1s') format('woff'), url('../fonts/icomoon.svg?-qdfu1s#icomoon') format('svg');*/
|
||||
/*font-weight: normal;*/
|
||||
/*font-style: normal;*/
|
||||
/*}*/
|
||||
[class^="wangeditor-menu-img-"],
|
||||
[class*=" wangeditor-menu-img-"] {
|
||||
font-family: 'icomoon';
|
||||
speak: none;
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
font-variant: normal;
|
||||
text-transform: none;
|
||||
line-height: 1;
|
||||
/* Better Font Rendering =========== */
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
.wangeditor-menu-img-link:before {
|
||||
content: "\e800";
|
||||
}
|
||||
.wangeditor-menu-img-unlink:before {
|
||||
content: "\e801";
|
||||
}
|
||||
.wangeditor-menu-img-code:before {
|
||||
content: "\e802";
|
||||
}
|
||||
.wangeditor-menu-img-cancel:before {
|
||||
content: "\e803";
|
||||
}
|
||||
.wangeditor-menu-img-terminal:before {
|
||||
content: "\e804";
|
||||
}
|
||||
.wangeditor-menu-img-angle-down:before {
|
||||
content: "\e805";
|
||||
}
|
||||
.wangeditor-menu-img-font:before {
|
||||
content: "\e806";
|
||||
}
|
||||
.wangeditor-menu-img-bold:before {
|
||||
content: "\e807";
|
||||
}
|
||||
.wangeditor-menu-img-italic:before {
|
||||
content: "\e808";
|
||||
}
|
||||
.wangeditor-menu-img-header:before {
|
||||
content: "\e809";
|
||||
}
|
||||
.wangeditor-menu-img-align-left:before {
|
||||
content: "\e80a";
|
||||
}
|
||||
.wangeditor-menu-img-align-center:before {
|
||||
content: "\e80b";
|
||||
}
|
||||
.wangeditor-menu-img-align-right:before {
|
||||
content: "\e80c";
|
||||
}
|
||||
.wangeditor-menu-img-list-bullet:before {
|
||||
content: "\e80d";
|
||||
}
|
||||
.wangeditor-menu-img-indent-left:before {
|
||||
content: "\e80e";
|
||||
}
|
||||
.wangeditor-menu-img-indent-right:before {
|
||||
content: "\e80f";
|
||||
}
|
||||
.wangeditor-menu-img-list-numbered:before {
|
||||
content: "\e810";
|
||||
}
|
||||
.wangeditor-menu-img-underline:before {
|
||||
content: "\e811";
|
||||
}
|
||||
.wangeditor-menu-img-table:before {
|
||||
content: "\e812";
|
||||
}
|
||||
.wangeditor-menu-img-eraser:before {
|
||||
content: "\e813";
|
||||
}
|
||||
.wangeditor-menu-img-text-height:before {
|
||||
content: "\e814";
|
||||
}
|
||||
.wangeditor-menu-img-brush:before {
|
||||
content: "\e815";
|
||||
}
|
||||
.wangeditor-menu-img-pencil:before {
|
||||
content: "\e816";
|
||||
}
|
||||
.wangeditor-menu-img-minus:before {
|
||||
content: "\e817";
|
||||
}
|
||||
.wangeditor-menu-img-picture:before {
|
||||
content: "\e818";
|
||||
}
|
||||
.wangeditor-menu-img-file-image:before {
|
||||
content: "\e819";
|
||||
}
|
||||
.wangeditor-menu-img-cw:before {
|
||||
content: "\e81a";
|
||||
}
|
||||
.wangeditor-menu-img-ccw:before {
|
||||
content: "\e81b";
|
||||
}
|
||||
.wangeditor-menu-img-music:before {
|
||||
content: "\e911";
|
||||
}
|
||||
.wangeditor-menu-img-play:before {
|
||||
content: "\e912";
|
||||
}
|
||||
.wangeditor-menu-img-location:before {
|
||||
content: "\e947";
|
||||
}
|
||||
.wangeditor-menu-img-happy:before {
|
||||
content: "\e9df";
|
||||
}
|
||||
.wangeditor-menu-img-sigma:before {
|
||||
content: "\ea67";
|
||||
}
|
||||
.wangeditor-menu-img-enlarge2:before {
|
||||
content: "\e98b";
|
||||
}
|
||||
.wangeditor-menu-img-shrink2:before {
|
||||
content: "\e98c";
|
||||
}
|
||||
.wangeditor-menu-img-newspaper:before {
|
||||
content: "\e904";
|
||||
}
|
||||
.wangeditor-menu-img-camera:before {
|
||||
content: "\e90f";
|
||||
}
|
||||
.wangeditor-menu-img-video-camera:before {
|
||||
content: "\e914";
|
||||
}
|
||||
.wangeditor-menu-img-file-zip:before {
|
||||
content: "\e92b";
|
||||
}
|
||||
.wangeditor-menu-img-stack:before {
|
||||
content: "\e92e";
|
||||
}
|
||||
.wangeditor-menu-img-credit-card:before {
|
||||
content: "\e93f";
|
||||
}
|
||||
.wangeditor-menu-img-address-book:before {
|
||||
content: "\e944";
|
||||
}
|
||||
.wangeditor-menu-img-envelop:before {
|
||||
content: "\e945";
|
||||
}
|
||||
.wangeditor-menu-img-drawer:before {
|
||||
content: "\e95c";
|
||||
}
|
||||
.wangeditor-menu-img-download:before {
|
||||
content: "\e960";
|
||||
}
|
||||
.wangeditor-menu-img-upload:before {
|
||||
content: "\e961";
|
||||
}
|
||||
.wangeditor-menu-img-lock:before {
|
||||
content: "\e98f";
|
||||
}
|
||||
.wangeditor-menu-img-unlocked:before {
|
||||
content: "\e990";
|
||||
}
|
||||
.wangeditor-menu-img-wrench:before {
|
||||
content: "\e991";
|
||||
}
|
||||
.wangeditor-menu-img-eye:before {
|
||||
content: "\e9ce";
|
||||
}
|
||||
.wangeditor-menu-img-eye-blocked:before {
|
||||
content: "\e9d1";
|
||||
}
|
||||
.wangeditor-menu-img-command:before {
|
||||
content: "\ea4e";
|
||||
}
|
||||
.wangeditor-menu-img-font2:before {
|
||||
content: "\ea5c";
|
||||
}
|
||||
.wangeditor-menu-img-libreoffice:before {
|
||||
content: "\eade";
|
||||
}
|
||||
.wangeditor-menu-img-quotes-left:before {
|
||||
content: "\e977";
|
||||
}
|
||||
.wangeditor-menu-img-strikethrough:before {
|
||||
content: "\ea65";
|
||||
}
|
||||
.wangeditor-menu-img-desktop:before {
|
||||
content: "\f108";
|
||||
}
|
||||
.wangeditor-menu-img-tablet:before {
|
||||
content: "\f10a";
|
||||
}
|
||||
.wangeditor-menu-img-search-plus:before {
|
||||
content: "\f00e";
|
||||
}
|
||||
.wangeditor-menu-img-search-minus:before {
|
||||
content: "\f010";
|
||||
}
|
||||
.wangeditor-menu-img-trash-o:before {
|
||||
content: "\f014";
|
||||
}
|
||||
.wangeditor-menu-img-align-justify:before {
|
||||
content: "\f039";
|
||||
}
|
||||
.wangeditor-menu-img-arrows-v:before {
|
||||
content: "\f07d";
|
||||
}
|
||||
.wangeditor-menu-img-sigma2:before {
|
||||
content: "\ea68";
|
||||
}
|
||||
.wangeditor-menu-img-omega:before {
|
||||
content: "\e900";
|
||||
}
|
||||
.wangeditor-menu-img-cancel-circle:before {
|
||||
content: "\e901";
|
||||
}
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
padding: 0.5em;
|
||||
color: #333;
|
||||
background: #f8f8f8;
|
||||
-webkit-text-size-adjust: none;
|
||||
}
|
||||
.hljs-comment,
|
||||
.diff .hljs-header {
|
||||
color: #998;
|
||||
font-style: italic;
|
||||
}
|
||||
.hljs-keyword,
|
||||
.css .rule .hljs-keyword,
|
||||
.hljs-winutils,
|
||||
.nginx .hljs-title,
|
||||
.hljs-subst,
|
||||
.hljs-request,
|
||||
.hljs-status {
|
||||
color: #333;
|
||||
font-weight: bold;
|
||||
}
|
||||
.hljs-number,
|
||||
.hljs-hexcolor,
|
||||
.ruby .hljs-constant {
|
||||
color: #008080;
|
||||
}
|
||||
.hljs-string,
|
||||
.hljs-tag .hljs-value,
|
||||
.hljs-doctag,
|
||||
.tex .hljs-formula {
|
||||
color: #d14;
|
||||
}
|
||||
.hljs-title,
|
||||
.hljs-id,
|
||||
.scss .hljs-preprocessor {
|
||||
color: #900;
|
||||
font-weight: bold;
|
||||
}
|
||||
.hljs-list .hljs-keyword,
|
||||
.hljs-subst {
|
||||
font-weight: normal;
|
||||
}
|
||||
.hljs-class .hljs-title,
|
||||
.hljs-type,
|
||||
.vhdl .hljs-literal,
|
||||
.tex .hljs-command {
|
||||
color: #458;
|
||||
font-weight: bold;
|
||||
}
|
||||
.hljs-tag,
|
||||
.hljs-tag .hljs-title,
|
||||
.hljs-rule .hljs-property,
|
||||
.django .hljs-tag .hljs-keyword {
|
||||
color: #000080;
|
||||
font-weight: normal;
|
||||
}
|
||||
.hljs-attribute,
|
||||
.hljs-variable,
|
||||
.lisp .hljs-body,
|
||||
.hljs-name {
|
||||
color: #008080;
|
||||
}
|
||||
.hljs-regexp {
|
||||
color: #009926;
|
||||
}
|
||||
.hljs-symbol,
|
||||
.ruby .hljs-symbol .hljs-string,
|
||||
.lisp .hljs-keyword,
|
||||
.clojure .hljs-keyword,
|
||||
.scheme .hljs-keyword,
|
||||
.tex .hljs-special,
|
||||
.hljs-prompt {
|
||||
color: #990073;
|
||||
}
|
||||
.hljs-built_in {
|
||||
color: #0086b3;
|
||||
}
|
||||
.hljs-preprocessor,
|
||||
.hljs-pragma,
|
||||
.hljs-pi,
|
||||
.hljs-doctype,
|
||||
.hljs-shebang,
|
||||
.hljs-cdata {
|
||||
color: #999;
|
||||
font-weight: bold;
|
||||
}
|
||||
.hljs-deletion {
|
||||
background: #fdd;
|
||||
}
|
||||
.hljs-addition {
|
||||
background: #dfd;
|
||||
}
|
||||
.diff .hljs-change {
|
||||
background: #0086b3;
|
||||
}
|
||||
.hljs-chunk {
|
||||
color: #aaa;
|
||||
}
|
@ -0,0 +1,72 @@
|
||||
.wangEditor-txt {
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
padding: 15px;
|
||||
padding-top: 0;
|
||||
margin-top: 5px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.wangEditor-txt p,
|
||||
.wangEditor-txt h1,
|
||||
.wangEditor-txt h2,
|
||||
.wangEditor-txt h3,
|
||||
.wangEditor-txt h4,
|
||||
.wangEditor-txt h5 {
|
||||
margin: 10px 0;
|
||||
line-height: 1.8;
|
||||
}
|
||||
.wangEditor-txt p *,
|
||||
.wangEditor-txt h1 *,
|
||||
.wangEditor-txt h2 *,
|
||||
.wangEditor-txt h3 *,
|
||||
.wangEditor-txt h4 *,
|
||||
.wangEditor-txt h5 * {
|
||||
line-height: 1.8;
|
||||
}
|
||||
.wangEditor-txt ul,
|
||||
.wangEditor-txt ol {
|
||||
padding-left: 20px;
|
||||
}
|
||||
.wangEditor-txt img {
|
||||
cursor: pointer;
|
||||
}
|
||||
.wangEditor-txt img.clicked {
|
||||
box-shadow: 1px 1px 10px #999;
|
||||
}
|
||||
.wangEditor-txt table.clicked {
|
||||
box-shadow: 1px 1px 10px #999;
|
||||
}
|
||||
.wangEditor-txt pre code {
|
||||
line-height: 1.5;
|
||||
}
|
||||
.wangEditor-txt:focus {
|
||||
outline: none;
|
||||
}
|
||||
.wangEditor-txt blockquote {
|
||||
display: block;
|
||||
border-left: 8px solid #d0e5f2;
|
||||
padding: 5px 10px;
|
||||
margin: 10px 0;
|
||||
line-height: 1.4;
|
||||
font-size: 100%;
|
||||
background-color: #f1f1f1;
|
||||
}
|
||||
.wangEditor-txt table {
|
||||
border: none;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
.wangEditor-txt table td,
|
||||
.wangEditor-txt table th {
|
||||
border: 1px solid #999;
|
||||
padding: 3px 5px;
|
||||
min-width: 50px;
|
||||
height: 20px;
|
||||
}
|
||||
.wangEditor-txt pre {
|
||||
border: 1px solid #ccc;
|
||||
background-color: #f8f8f8;
|
||||
padding: 10px;
|
||||
margin: 5px 0px;
|
||||
font-size: 0.8em;
|
||||
border-radius: 3px;
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
|
||||
@font-face {font-family: "iconfont";
|
||||
src: url('iconfont.eot?t=1496642611968'); /* IE9*/
|
||||
src: url('iconfont.eot?t=1496642611968#iefix') format('embedded-opentype'), /* IE6-IE8 */
|
||||
url('iconfont.woff?t=1496642611968') format('woff'), /* chrome, firefox */
|
||||
url('iconfont.ttf?t=1496642611968') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+*/
|
||||
url('iconfont.svg?t=1496642611968#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-img:before { content: "\e657"; }
|
||||
|
||||
.icon-excel:before { content: "\e61c"; }
|
||||
|
||||
.icon-word:before { content: "\e61f"; }
|
||||
|
||||
.icon-file:before { content: "\e689"; }
|
||||
|
||||
.icon-js:before { content: "\e6b2"; }
|
||||
|
||||
.icon-MP:before { content: "\e670"; }
|
||||
|
||||
.icon-txt:before { content: "\e668"; }
|
||||
|
||||
.icon-file_csv:before { content: "\e724"; }
|
||||
|
||||
.icon-file_ppt:before { content: "\e726"; }
|
||||
|
||||
.icon-file_word:before { content: "\e729"; }
|
||||
|
||||
.icon-pdf:before { content: "\e72c"; }
|
||||
|
||||
.icon-zip:before { content: "\e661"; }
|
||||
|
||||
.icon-rar:before { content: "\e662"; }
|
||||
|
||||
.icon-file_css:before { content: "\e6bd"; }
|
||||
|
||||
.icon-file_video:before { content: "\e6bf"; }
|
||||
|
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 8.7 KiB |
After Width: | Height: | Size: 8.8 KiB |
After Width: | Height: | Size: 8.7 KiB |
After Width: | Height: | Size: 38 KiB |
After Width: | Height: | Size: 6.0 KiB |
After Width: | Height: | Size: 17 KiB |
After Width: | Height: | Size: 54 KiB |
After Width: | Height: | Size: 87 KiB |
After Width: | Height: | Size: 87 KiB |
After Width: | Height: | Size: 4.4 KiB |
After Width: | Height: | Size: 6.4 KiB |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 4.5 KiB |
@ -0,0 +1,45 @@
|
||||
import {message,notification} from 'ant-design-vue'
|
||||
|
||||
export const notice = (content, type = 'message', action = 'warning', duration = 3, placement = 'bottomLeft') => {
|
||||
destroyNotice();
|
||||
let config = {};
|
||||
config.duration = duration;
|
||||
if (type === 'message') {
|
||||
switch (action) {
|
||||
case 'info':
|
||||
return message.info(content, duration);
|
||||
case 'success':
|
||||
return message.success(content, duration);
|
||||
case 'error':
|
||||
return message.error(content, duration);
|
||||
case 'loading':
|
||||
return message.loading(content, duration);
|
||||
default:
|
||||
return message.warning(content, duration);
|
||||
}
|
||||
} else {
|
||||
config.message = content.title;
|
||||
config.description = content.msg || '';
|
||||
config.placement = placement;
|
||||
switch (action) {
|
||||
case 'open':
|
||||
return notification.open(config);
|
||||
case 'info':
|
||||
return notification.info(config);
|
||||
case 'success':
|
||||
return notification.success(config);
|
||||
case 'error':
|
||||
return notification.error(config);
|
||||
default:
|
||||
return notification.warning(config);
|
||||
}
|
||||
}
|
||||
};
|
||||
export const destroyNotice = (type = '') => {
|
||||
if (!type) {
|
||||
message.destroy();
|
||||
notification.destroy();
|
||||
}else{
|
||||
type === 'message' ? message.destroy() : notification.destroy();
|
||||
}
|
||||
};
|
@ -0,0 +1,88 @@
|
||||
/**
|
||||
* Created by vilson on 17/6/4.
|
||||
*/
|
||||
export const showMsgNotification = (title, msg, $opt = {}) => {
|
||||
let options = {
|
||||
body: msg,
|
||||
icon: $opt.icon || "http://static.vilson.xyz/preview.jpg",
|
||||
showTime: $opt.showTime || 15000,
|
||||
onclick: $opt.onclick,
|
||||
onshow: $opt.onshow,
|
||||
onerror: $opt.onerror,
|
||||
onclose: $opt.onclose,
|
||||
};
|
||||
let Notification = window.Notification || window.mozNotification || window.webkitNotification;
|
||||
console.log(Notification.permission);
|
||||
if (Notification && Notification.permission === "granted") {
|
||||
let instance = new Notification(title, options);
|
||||
instance.onclick = function () {
|
||||
// Something to do
|
||||
if (typeof options.onclick === 'function') {
|
||||
options.onclick(instance)
|
||||
}
|
||||
// window.location.href = instance.icon
|
||||
};
|
||||
instance.onerror = function () {
|
||||
// Something to do
|
||||
if (typeof options.onerror === 'function') {
|
||||
options.onerror(instance)
|
||||
}
|
||||
};
|
||||
instance.onshow = function () {
|
||||
// Something to do
|
||||
if (typeof options.onshow === 'function') {
|
||||
options.onshow(instance)
|
||||
}
|
||||
setTimeout(function () {
|
||||
instance.close();
|
||||
}, options.showTime)
|
||||
};
|
||||
instance.onclose = function () {
|
||||
// Something to do
|
||||
if (typeof options.onclose === 'function') {
|
||||
options.onclose(instance)
|
||||
}
|
||||
};
|
||||
} else if (Notification && Notification.permission !== "denied") {
|
||||
Notification.requestPermission(function (status) {
|
||||
if (Notification.permission !== status) {
|
||||
Notification.permission = status;
|
||||
}
|
||||
// If the user said okay
|
||||
if (status === "granted") {
|
||||
let instance = new Notification(title, options);
|
||||
instance.onclick = function () {
|
||||
// Something to do
|
||||
if (typeof options.onclick === 'function') {
|
||||
options.onclick(instance)
|
||||
}
|
||||
};
|
||||
instance.onerror = function () {
|
||||
// Something to do
|
||||
if (typeof options.onerror === 'function') {
|
||||
options.onerror(instance)
|
||||
}
|
||||
};
|
||||
instance.onshow = function () {
|
||||
// Something to do
|
||||
if (typeof options.onshow === 'function') {
|
||||
options.onshow(instance)
|
||||
}
|
||||
setTimeout(function () {
|
||||
instance.close();
|
||||
}, options.showTime)
|
||||
};
|
||||
instance.onclose = function () {
|
||||
// Something to do
|
||||
if (typeof options.onclose === 'function') {
|
||||
options.onclose(instance)
|
||||
}
|
||||
};
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
});
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
};
|
@ -0,0 +1,133 @@
|
||||
// 打印类属性、方法定义
|
||||
/* eslint-disable */
|
||||
const Print = function (dom, options) {
|
||||
if (!(this instanceof Print)) return new Print(dom, options);
|
||||
|
||||
this.options = this.extend({
|
||||
'noPrint': '.no-print'
|
||||
}, options);
|
||||
|
||||
if ((typeof dom) === "string") {
|
||||
this.dom = document.querySelector(dom);
|
||||
} else {
|
||||
this.isDOM(dom)
|
||||
this.dom = this.isDOM(dom) ? dom : dom.$el;
|
||||
}
|
||||
|
||||
this.init();
|
||||
};
|
||||
Print.prototype = {
|
||||
init: function () {
|
||||
var content = this.getStyle() + this.getHtml();
|
||||
this.writeIframe(content);
|
||||
},
|
||||
extend: function (obj, obj2) {
|
||||
for (var k in obj2) {
|
||||
obj[k] = obj2[k];
|
||||
}
|
||||
return obj;
|
||||
},
|
||||
|
||||
getStyle: function () {
|
||||
var str = "",
|
||||
styles = document.querySelectorAll('style,link');
|
||||
for (var i = 0; i < styles.length; i++) {
|
||||
str += styles[i].outerHTML;
|
||||
}
|
||||
str += "<style>" + (this.options.noPrint ? this.options.noPrint : '.no-print') + "{display:none;}</style>";
|
||||
|
||||
return str;
|
||||
},
|
||||
|
||||
getHtml: function () {
|
||||
var inputs = document.querySelectorAll('input');
|
||||
var textareas = document.querySelectorAll('textarea');
|
||||
var selects = document.querySelectorAll('select');
|
||||
|
||||
for (var k = 0; k < inputs.length; k++) {
|
||||
if (inputs[k].type == "checkbox" || inputs[k].type == "radio") {
|
||||
if (inputs[k].checked == true) {
|
||||
inputs[k].setAttribute('checked', "checked")
|
||||
} else {
|
||||
inputs[k].removeAttribute('checked')
|
||||
}
|
||||
} else if (inputs[k].type == "text") {
|
||||
inputs[k].setAttribute('value', inputs[k].value)
|
||||
} else {
|
||||
inputs[k].setAttribute('value', inputs[k].value)
|
||||
}
|
||||
}
|
||||
|
||||
for (var k2 = 0; k2 < textareas.length; k2++) {
|
||||
if (textareas[k2].type == 'textarea') {
|
||||
textareas[k2].innerHTML = textareas[k2].value
|
||||
}
|
||||
}
|
||||
|
||||
for (var k3 = 0; k3 < selects.length; k3++) {
|
||||
if (selects[k3].type == 'select-one') {
|
||||
var child = selects[k3].children;
|
||||
for (var i in child) {
|
||||
if (child[i].tagName == 'OPTION') {
|
||||
if (child[i].selected == true) {
|
||||
child[i].setAttribute('selected', "selected")
|
||||
} else {
|
||||
child[i].removeAttribute('selected')
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return this.dom.outerHTML;
|
||||
},
|
||||
|
||||
writeIframe: function (content) {
|
||||
var w, doc, iframe = document.createElement('iframe'),
|
||||
f = document.body.appendChild(iframe);
|
||||
iframe.id = "myIframe";
|
||||
//iframe.style = "position:absolute;width:0;height:0;top:-10px;left:-10px;";
|
||||
iframe.setAttribute('style', 'position:absolute;width:0;height:0;top:-10px;left:-10px;');
|
||||
w = f.contentWindow || f.contentDocument;
|
||||
doc = f.contentDocument || f.contentWindow.document;
|
||||
doc.open();
|
||||
doc.write(content);
|
||||
doc.close();
|
||||
this.toPrint(w);
|
||||
|
||||
setTimeout(function () {
|
||||
document.body.removeChild(iframe)
|
||||
}, 100)
|
||||
},
|
||||
|
||||
toPrint: function (frameWindow) {
|
||||
try {
|
||||
setTimeout(function () {
|
||||
frameWindow.focus();
|
||||
try {
|
||||
if (!frameWindow.document.execCommand('print', false, null)) {
|
||||
frameWindow.print();
|
||||
}
|
||||
} catch (e) {
|
||||
frameWindow.print();
|
||||
}
|
||||
frameWindow.close();
|
||||
}, 10);
|
||||
} catch (err) {
|
||||
console.log('err', err);
|
||||
}
|
||||
},
|
||||
isDOM: (typeof HTMLElement === 'object') ?
|
||||
function (obj) {
|
||||
return obj instanceof HTMLElement;
|
||||
} :
|
||||
function (obj) {
|
||||
return obj && typeof obj === 'object' && obj.nodeType === 1 && typeof obj.nodeName === 'string';
|
||||
}
|
||||
};
|
||||
const MyPlugin = {}
|
||||
MyPlugin.install = function (Vue, options) {
|
||||
// 4. 添加实例方法
|
||||
Vue.prototype.$print = Print
|
||||
}
|
||||
export default MyPlugin
|
@ -0,0 +1,3 @@
|
||||
import Trend from './Trend.vue'
|
||||
|
||||
export default Trend
|
@ -0,0 +1,42 @@
|
||||
@import "../index";
|
||||
|
||||
@trend-prefix-cls: ~"@{ant-pro-prefix}-trend";
|
||||
|
||||
.@{trend-prefix-cls} {
|
||||
display: inline-block;
|
||||
font-size: @font-size-base;
|
||||
line-height: 22px;
|
||||
|
||||
.up,
|
||||
.down {
|
||||
margin-left: 4px;
|
||||
position: relative;
|
||||
top: 1px;
|
||||
|
||||
i {
|
||||
font-size: 12px;
|
||||
transform: scale(0.83);
|
||||
}
|
||||
}
|
||||
|
||||
.item-text {
|
||||
display: inline-block;
|
||||
margin-left: 8px;
|
||||
color: rgba(0,0,0,.85);
|
||||
}
|
||||
|
||||
.up {
|
||||
color: @red-6;
|
||||
}
|
||||
.down {
|
||||
color: @green-6;
|
||||
top: -1px;
|
||||
}
|
||||
|
||||
&.reverse-color .up {
|
||||
color: @green-6;
|
||||
}
|
||||
&.reverse-color .down {
|
||||
color: @red-6;
|
||||
}
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
# Trend 趋势标记
|
||||
|
||||
趋势符号,标记上升和下降趋势。通常用绿色代表“好”,红色代表“不好”,股票涨跌场景除外。
|
||||
|
||||
|
||||
|
||||
引用方式:
|
||||
|
||||
```javascript
|
||||
import Trend from '@/components/Trend'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Trend
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
## 代码演示 [demo](https://pro.loacg.com/test/home)
|
||||
|
||||
```html
|
||||
<trend flag="up">5%</trend>
|
||||
```
|
||||
或
|
||||
```html
|
||||
<trend flag="up">
|
||||
<span slot="term">工资</span>
|
||||
5%
|
||||
</trend>
|
||||
```
|
||||
或
|
||||
```html
|
||||
<trend flag="up" term="工资">5%</trend>
|
||||
```
|
||||
|
||||
|
||||
## API
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 |
|
||||
|----------|------------------------------------------|-------------|-------|
|
||||
| flag | 上升下降标识:`up|down` | string | - |
|
||||
| reverseColor | 颜色反转 | Boolean | false |
|
||||
|
@ -0,0 +1,111 @@
|
||||
<template>
|
||||
<a-card :loading="loading" :body-style="{ padding: '20px 24px 8px' }" :bordered="false">
|
||||
<div class="chart-card-header">
|
||||
<div class="meta">
|
||||
<span class="chart-card-title">{{ title }}</span>
|
||||
<span class="chart-card-action">
|
||||
<slot name="action"></slot>
|
||||
</span>
|
||||
</div>
|
||||
<div class="total"><span>{{ total }}</span></div>
|
||||
</div>
|
||||
<div class="chart-card-content">
|
||||
<div class="content-fix">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</div>
|
||||
<div class="chart-card-footer">
|
||||
<div class="field">
|
||||
<slot name="footer"></slot>
|
||||
</div>
|
||||
</div>
|
||||
</a-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'ChartCard',
|
||||
props: {
|
||||
title: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
total: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
loading: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.chart-card-header {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
|
||||
.meta {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
color: rgba(0, 0, 0, .45);
|
||||
font-size: 14px;
|
||||
line-height: 22px;
|
||||
}
|
||||
}
|
||||
|
||||
.chart-card-action {
|
||||
cursor: pointer;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.chart-card-footer {
|
||||
border-top: 1px solid #e8e8e8;
|
||||
padding-top: 9px;
|
||||
margin-top: 8px;
|
||||
|
||||
> * {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.field {
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.chart-card-content {
|
||||
margin-bottom: 12px;
|
||||
position: relative;
|
||||
height: 46px;
|
||||
width: 100%;
|
||||
|
||||
.content-fix {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.total {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
word-break: break-all;
|
||||
white-space: nowrap;
|
||||
color: #000;
|
||||
margin-top: 4px;
|
||||
margin-bottom: 0;
|
||||
font-size: 30px;
|
||||
line-height: 38px;
|
||||
height: 38px;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,75 @@
|
||||
<template>
|
||||
<div class="chart-mini-progress">
|
||||
<div class="target" :style="{ left: target + '%'}">
|
||||
<span :style="{ backgroundColor: color }" />
|
||||
<span :style="{ backgroundColor: color }"/>
|
||||
</div>
|
||||
<div class="progress-wrapper">
|
||||
<div class="progress" :style="{ backgroundColor: color, width: percentage + '%', height: height }"></div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'MiniProgress',
|
||||
props: {
|
||||
target: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
height: {
|
||||
type: String,
|
||||
default: '10px'
|
||||
},
|
||||
color: {
|
||||
type: String,
|
||||
default: '#ffd401'
|
||||
},
|
||||
percentage: {
|
||||
type: Number,
|
||||
default: 0
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.chart-mini-progress {
|
||||
padding: 5px 0;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
|
||||
.target {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
|
||||
span {
|
||||
border-radius: 100px;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 4px;
|
||||
width: 2px;
|
||||
|
||||
&:last-child {
|
||||
top: auto;
|
||||
bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
.progress-wrapper {
|
||||
background-color: #f5f5f5;
|
||||
position: relative;
|
||||
|
||||
.progress {
|
||||
transition: all .4s cubic-bezier(.08,.82,.17,1) 0s;
|
||||
border-radius: 1px 0 0 1px;
|
||||
background-color: #1890ff;
|
||||
width: 0;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@ -0,0 +1,77 @@
|
||||
<template>
|
||||
<div class="rank">
|
||||
<h4 class="title">{{ title }}</h4>
|
||||
<ul class="list">
|
||||
<li :key="index" v-for="(item, index) in list">
|
||||
<span :class="index < 3 ? 'active' : null">{{ index + 1 }}</span>
|
||||
<span>{{ item.name }}</span>
|
||||
<span>{{ item.total }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'RankList',
|
||||
// ['title', 'list']
|
||||
props: {
|
||||
title: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
list: {
|
||||
type: Array,
|
||||
default: null
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
|
||||
.rank {
|
||||
padding: 0 32px 32px 72px;
|
||||
|
||||
.list {
|
||||
margin: 25px 0 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
|
||||
li {
|
||||
margin-top: 16px;
|
||||
|
||||
span {
|
||||
color: rgba(0, 0, 0, .65);
|
||||
font-size: 14px;
|
||||
line-height: 22px;
|
||||
|
||||
&:first-child {
|
||||
background-color: #f5f5f5;
|
||||
border-radius: 20px;
|
||||
display: inline-block;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
margin-right: 24px;
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
width: 20px;
|
||||
text-align: center;
|
||||
}
|
||||
&.active {
|
||||
background-color: #314659;
|
||||
color: #fff;
|
||||
}
|
||||
&:last-child {
|
||||
float: right;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.mobile .rank {
|
||||
padding: 0 32px 32px 32px;
|
||||
}
|
||||
|
||||
</style>
|
@ -0,0 +1,100 @@
|
||||
<template>
|
||||
<div class="error-page">
|
||||
<div class="exception">
|
||||
<div class="imgBlock">
|
||||
<div class="img-exception">
|
||||
<slot name="img"></slot>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content">
|
||||
<h1>{{code}}</h1>
|
||||
<div class="desc">{{desc}}</div>
|
||||
<div class="actions">
|
||||
<router-link :to="url">
|
||||
<Button type="primary">{{urlText}}</Button>
|
||||
</router-link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import {Button} from 'ant-design-vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Button
|
||||
},
|
||||
props: {
|
||||
code: {
|
||||
default: '500'
|
||||
},
|
||||
desc: {
|
||||
default: '抱歉,服务器出错了',
|
||||
},
|
||||
url: {
|
||||
default: '/home'
|
||||
},
|
||||
urlText: {
|
||||
default: '返回首页'
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style lang="less">
|
||||
.error-page {
|
||||
background: #f0f2f5;
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
.exception {
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
height: 70vh;
|
||||
}
|
||||
|
||||
.exception .imgBlock {
|
||||
-ms-flex: 0 0 62.5%;
|
||||
flex: 0 0 55.5%;
|
||||
width: 62.5%;
|
||||
padding-right: 60px;
|
||||
zoom: 1;
|
||||
}
|
||||
|
||||
.exception .img-exception {
|
||||
width: 100%;
|
||||
max-width: 430px;
|
||||
float: right;
|
||||
background: no-repeat 50% 50%;
|
||||
background-size: contain;
|
||||
}
|
||||
|
||||
.exception .img-exception img {
|
||||
width: 75%;
|
||||
}
|
||||
|
||||
.exception .content {
|
||||
-ms-flex: auto;
|
||||
flex: auto;
|
||||
}
|
||||
|
||||
.exception .content h1 {
|
||||
color: #434e59;
|
||||
font-size: 72px;
|
||||
font-weight: 600;
|
||||
line-height: 72px;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.exception .content .desc {
|
||||
color: rgba(0, 0, 0, .45);
|
||||
font-size: 20px;
|
||||
line-height: 28px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,200 @@
|
||||
<template>
|
||||
<div class="wrap" v-if="flag">
|
||||
<div class="my-box">
|
||||
<a-spin class="task-detail-spin" :spinning="loading">
|
||||
<div class="task-header" style="background: white;">
|
||||
<span class="head-title">
|
||||
<span>查看文件</span>
|
||||
</span>
|
||||
<span class="header-action text-right">
|
||||
<a-tooltip :mouseEnterDelay="0.5">
|
||||
<template slot="title">
|
||||
<span>最小化</span>
|
||||
</template>
|
||||
<a class="action-item muted" @click="reset()"><a-icon type="minus"/></a>
|
||||
</a-tooltip>
|
||||
<a-tooltip :mouseEnterDelay="0.5">
|
||||
<template slot="title">
|
||||
<span>最大化</span>
|
||||
</template>
|
||||
<a class="action-item muted" @click="max()"><a-icon type="plus"/></a>
|
||||
</a-tooltip>
|
||||
<a-tooltip :mouseEnterDelay="0.5">
|
||||
<template slot="title">
|
||||
<span>关闭面板</span>
|
||||
</template>
|
||||
<a class="action-item muted" @click="close()"><a-icon type="close"/></a>
|
||||
</a-tooltip>
|
||||
</span>
|
||||
</div>
|
||||
<div class="task-wrap">
|
||||
<div class="task-content">
|
||||
<iframe :src="getUrl(seeUrl)" height="700px" width="100%"></iframe>
|
||||
</div>
|
||||
</div>
|
||||
</a-spin>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import $ from 'jquery'
|
||||
import {getFileUrl} from "assets/js/utils";
|
||||
|
||||
export default {
|
||||
name: "box-detail",
|
||||
props: {
|
||||
value: {
|
||||
type: Boolean,
|
||||
default() {
|
||||
return false
|
||||
}
|
||||
},
|
||||
seeUrl: {
|
||||
type: [String],
|
||||
default() {
|
||||
return ''
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
flag: true,
|
||||
}
|
||||
},
|
||||
create: function () {
|
||||
this.flag = true;
|
||||
},
|
||||
watch: {
|
||||
value(value) {
|
||||
this.flag = value;
|
||||
},
|
||||
seeUrl(seeUrl) {
|
||||
this.seeUrl = seeUrl;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
close() {
|
||||
this.flag = false;
|
||||
this.$emit('input', this.flag);
|
||||
},
|
||||
max() {
|
||||
$(".task-detail-spin").css("width", "100%");
|
||||
$(".task-detail-spin").css("height", "100%");
|
||||
},
|
||||
reset() {
|
||||
$(".task-detail-spin").css("width", "50%");
|
||||
},
|
||||
getUrl(fileUrl) {
|
||||
return getFileUrl(fileUrl, 'local');
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
@import "~ant-design-vue/lib/style/themes/default";
|
||||
|
||||
.wrap {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
top: 0;
|
||||
left: 0;
|
||||
background: rgba(113, 111, 111, 0.5);
|
||||
width: 100%;
|
||||
|
||||
.my-box {
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-box-pack: center;
|
||||
-ms-flex-pack: center;
|
||||
justify-content: center;
|
||||
-webkit-box-flex: 1;
|
||||
-ms-flex: 1;
|
||||
flex: 1;
|
||||
min-height: 1px;
|
||||
min-width: 1px;
|
||||
margin: 100px auto;
|
||||
margin-top: 75px;
|
||||
|
||||
.task-detail-spin {
|
||||
width: 50%;
|
||||
height: 60%;
|
||||
}
|
||||
|
||||
.task-header {
|
||||
background: white;
|
||||
padding: 20px 0;
|
||||
// border: 1px solid #e5e5e5;
|
||||
background: whitesmoke;
|
||||
display: flex;
|
||||
vertical-align: middle;
|
||||
|
||||
|
||||
.head-title {
|
||||
padding: 0 20px 0 20px;
|
||||
flex: 1 1;
|
||||
|
||||
.breadcrumb {
|
||||
display: inline;
|
||||
|
||||
a {
|
||||
color: inherit;
|
||||
|
||||
&:hover {
|
||||
color: #40a9ff;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.header-action {
|
||||
font-size: 16px;
|
||||
padding: 0 20px;
|
||||
display: flex;
|
||||
max-height: 24px;
|
||||
|
||||
.action-item {
|
||||
margin-left: 10px;
|
||||
padding: 4px;
|
||||
transition: 218ms;
|
||||
transition-property: background, color;
|
||||
border-radius: 4px;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
text-align: center;
|
||||
justify-content: center;
|
||||
min-width: 32px;
|
||||
|
||||
span {
|
||||
margin-left: 6px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
&.active {
|
||||
color: #3da8f5;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: #ecf6fe;
|
||||
color: #3da8f5;
|
||||
border-radius: 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
background: #f5f5f5;
|
||||
}
|
||||
}
|
||||
|
||||
.task-wrap {
|
||||
background: white;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</style>
|
@ -0,0 +1,118 @@
|
||||
<template>
|
||||
<div>
|
||||
<a-modal
|
||||
class="file-box"
|
||||
:width="800"
|
||||
v-model="actionInfo.modalStatus"
|
||||
:title="actionInfo.modalTitle"
|
||||
:footer="null"
|
||||
@Max = "max"
|
||||
@cancel="cancel">
|
||||
<div class="search-content">
|
||||
<iframe :src="actionInfo.url" height="700px" width="100%" scrolling="no"></iframe>
|
||||
</div>
|
||||
</a-modal>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import _ from 'lodash'
|
||||
|
||||
export default {
|
||||
name: "box",
|
||||
props: {
|
||||
value: {
|
||||
type: Boolean,
|
||||
default() {
|
||||
return false
|
||||
}
|
||||
},
|
||||
projectCode: {
|
||||
type: [String, Number],
|
||||
default() {
|
||||
return ''
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
form: this.$form.createForm(this),
|
||||
actionInfo: {
|
||||
modalStatus: this.value,
|
||||
confirmLoading: false,
|
||||
modalTitle: '查看文件',
|
||||
url: 'http://193.112.27.123:8012/onlinePreview?url=http%3A%2F%2F193.112.27.123%3A8012%2Fdemo%2Ftimg.gif'
|
||||
},
|
||||
linkInfo: {
|
||||
modalStatus: false,
|
||||
confirmLoading: false,
|
||||
modalTitle: '邀请成员',
|
||||
link: '',
|
||||
overTime: '',
|
||||
},
|
||||
keyword: '',
|
||||
searching: false,
|
||||
list: [],
|
||||
// emptyText: keyword ? '没有搜索结果' : ''
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
value(value) {
|
||||
this.actionInfo.modalStatus = value;
|
||||
},
|
||||
keyword() {
|
||||
this.search();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
invite(item) {
|
||||
|
||||
},
|
||||
createInviteLink() {
|
||||
if (!this.linkInfo.link) {
|
||||
|
||||
}else{
|
||||
this.linkInfo.modalStatus = true;
|
||||
}
|
||||
},
|
||||
search: _.debounce(
|
||||
function () {
|
||||
if (!this.keyword) {
|
||||
this.list = [];
|
||||
}
|
||||
if (this.keyword.length <= 1) {
|
||||
return false;
|
||||
}
|
||||
this.searching = true;
|
||||
}, 500
|
||||
),
|
||||
cancel() {
|
||||
this.actionInfo.modalStatus = false;
|
||||
this.$emit('input', this.actionInfo.modalStatus);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.file-box {
|
||||
.ant-modal-body {
|
||||
padding-top: 0;
|
||||
padding-bottom: 24px;
|
||||
min-height: 40vh;
|
||||
}
|
||||
|
||||
.header {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
padding: 12px 0;
|
||||
}
|
||||
|
||||
.member-list {
|
||||
padding-top: 12px;
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
@ -0,0 +1,4 @@
|
||||
@import "~ant-design-vue/lib/style/index";
|
||||
|
||||
// The prefix to use on all css classes from ant-pro.
|
||||
@ant-pro-prefix : ant-pro;
|
@ -0,0 +1,157 @@
|
||||
<!--页面登录-->
|
||||
<template>
|
||||
<div class="userLayout">
|
||||
<div class="container">
|
||||
<div class="top">
|
||||
<div class="header">
|
||||
<a-badge>
|
||||
<a href="/">
|
||||
<img src="../../assets/image/common/bull.png" class="logo" alt="logo">
|
||||
<span class="title">企业网盘</span>
|
||||
</a>
|
||||
</a-badge>
|
||||
</div>
|
||||
<div class="desc">{{desc}}</div>
|
||||
</div>
|
||||
|
||||
<router-view/>
|
||||
<slot></slot>
|
||||
|
||||
<div class="footer">
|
||||
<!-- <div class="links">
|
||||
<a href="_self">帮助</a>
|
||||
<a href="_self">隐私</a>
|
||||
<a href="_self">条款</a>
|
||||
</div>-->
|
||||
<div class="copyright">
|
||||
Copyright © 2022 万振宇 潘祎铖 梁兆新 李森
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
name: 'UserLayout',
|
||||
props: {
|
||||
desc: {
|
||||
type: [String],
|
||||
default() {
|
||||
return '欢迎使用夜未央网盘系统';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.userLayout {
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
|
||||
&.mobile {
|
||||
.container {
|
||||
.main {
|
||||
max-width: 368px;
|
||||
width: 98%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.container {
|
||||
width: 100%;
|
||||
min-height: 100%;
|
||||
background: #f0f2f5 url(~@/assets/image/common/background.svg) no-repeat 50%;
|
||||
background-size: 100%;
|
||||
padding: 110px 0 144px;
|
||||
position: relative;
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.top {
|
||||
text-align: center;
|
||||
|
||||
.header {
|
||||
height: 44px;
|
||||
line-height: 44px;
|
||||
|
||||
.badge {
|
||||
position: absolute;
|
||||
display: inline-block;
|
||||
line-height: 1;
|
||||
vertical-align: middle;
|
||||
margin-left: -12px;
|
||||
margin-top: -10px;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.logo {
|
||||
height: 44px;
|
||||
vertical-align: top;
|
||||
margin-right: 12px;
|
||||
border-style: none;
|
||||
transform: rotate(-25deg);
|
||||
-ms-transform: rotate(-25deg); /* IE 9 */
|
||||
-moz-transform: rotate(-25deg); /* Firefox */
|
||||
-webkit-transform: rotate(-25deg); /* Safari 和 Chrome */
|
||||
-o-transform: rotate(-25deg);
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 33px;
|
||||
color: rgba(0, 0, 0, .85);
|
||||
font-family: "Chinese Quote", -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Helvetica Neue", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
|
||||
font-weight: 600;
|
||||
position: relative;
|
||||
top: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
.desc {
|
||||
font-size: 14px;
|
||||
color: rgba(0, 0, 0, 0.45);
|
||||
margin-top: 12px;
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
}
|
||||
|
||||
.main {
|
||||
min-width: 260px;
|
||||
width: 368px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.footer {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
bottom: 0;
|
||||
padding: 0 16px;
|
||||
margin: 48px 0 24px;
|
||||
text-align: center;
|
||||
|
||||
.links {
|
||||
margin-bottom: 8px;
|
||||
font-size: 14px;
|
||||
|
||||
a {
|
||||
color: rgba(0, 0, 0, 0.45);
|
||||
transition: all 0.3s;
|
||||
|
||||
&:not(:last-child) {
|
||||
margin-right: 40px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.copyright {
|
||||
color: rgba(0, 0, 0, 0.45);
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@ -0,0 +1,144 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="page-header" v-if="showHeader">
|
||||
<div class="breadcrumb" v-if="breadCrumbInfo.length > 0 && breadCrumb">
|
||||
<a-breadcrumb>
|
||||
<a-breadcrumb-item>
|
||||
<router-link to="/home">首页</router-link>
|
||||
</a-breadcrumb-item>
|
||||
<a-breadcrumb-item>{{breadCrumbInfo[2].title}}</a-breadcrumb-item>
|
||||
<a-breadcrumb-item>{{breadCrumbInfo[1].title}}</a-breadcrumb-item>
|
||||
<a-breadcrumb-item>{{breadCrumbInfo[0].title}}</a-breadcrumb-item>
|
||||
<!--<router-link :to="breadCrumbInfo[0].path">{{breadCrumbInfo[0].title}}</router-link>-->
|
||||
</a-breadcrumb>
|
||||
</div>
|
||||
<div class="detail">
|
||||
<div class="main">
|
||||
<div class="row">
|
||||
<h1 v-if="pageTitle.trim() != '' && showTitle" class="title">{{ pageTitle }}</h1>
|
||||
<h1 v-else-if="showTitle" class="title">{{ defaultPageTitle }}</h1>
|
||||
<div class="action">
|
||||
<slot name="action"></slot>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div v-if="this.$slots.content" class="content">
|
||||
<slot name="content"></slot>
|
||||
</div>
|
||||
<div v-if="this.$slots.extra" class="extra">
|
||||
<slot name="extra"></slot>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="page-header page-header-none" v-else></div>
|
||||
<div class="page-header page-header-none"></div>
|
||||
|
||||
<div class="wrapper-main">
|
||||
<div class="wrapper-content"
|
||||
:class="{ 'hidden':pageLoading}">
|
||||
<div class="layout-content">
|
||||
<div class="content-title" v-if="this.$slots.contentTitle || this.$slots.contentAction">
|
||||
<slot name="contentTitle"></slot>
|
||||
<div class="content-action">
|
||||
<slot name="contentAction"></slot>
|
||||
</div>
|
||||
</div>
|
||||
<slot></slot>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
<script>
|
||||
import {mapState} from 'vuex'
|
||||
import {getStore} from '@/assets/js/storage'
|
||||
import {getClassObj} from '@/assets/js/utils'
|
||||
import $ from 'jquery'
|
||||
import ABreadcrumb from 'ant-design-vue/es/breadcrumb'
|
||||
|
||||
const ABreadcrumbItem = ABreadcrumb.Item;
|
||||
|
||||
|
||||
export default {
|
||||
components: {
|
||||
ABreadcrumb,
|
||||
ABreadcrumbItem,
|
||||
},
|
||||
props: {
|
||||
pageTitle: {
|
||||
default: ''
|
||||
},
|
||||
showTitle: {
|
||||
default: true
|
||||
},
|
||||
showHeader: {
|
||||
default: true
|
||||
},
|
||||
breadCrumb: {
|
||||
default: true
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
//用户权限资源检测
|
||||
/* function TraversalObject(obj, value) {
|
||||
for (let a in obj) {
|
||||
if (typeof (obj[a]) === "object") {
|
||||
TraversalObject(obj[a], value); //递归遍历
|
||||
}
|
||||
else {
|
||||
if (a === 'name' && obj[a] === value) {
|
||||
window.permission = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const auth_list = getStore('auth_list', true);
|
||||
const permissions = $("a[permission]");
|
||||
if (permissions) {
|
||||
$.each(permissions, function (k, v) {
|
||||
let permission = $(v).attr('permission');
|
||||
window.permission = false;
|
||||
TraversalObject(auth_list, permission);
|
||||
if (!window.permission) {
|
||||
$(v).remove()
|
||||
}
|
||||
});
|
||||
}
|
||||
this.$nextTick(function () {
|
||||
// 挂载时隐藏所有父级页面的内容区
|
||||
const ClassElements = getClassObj('wrapper-main');
|
||||
if (ClassElements.length > 1) {
|
||||
for (let i = 0; i < ClassElements.length - 1; i++) {
|
||||
ClassElements[i].style.display = "none"
|
||||
}
|
||||
}
|
||||
})*/
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
pageLoading: state => state.pageLoading,
|
||||
breadCrumbInfo: state => state.menu.breadCrumbInfo,
|
||||
}),
|
||||
defaultPageTitle: {
|
||||
get() {
|
||||
return this.$route.meta.info.title
|
||||
}
|
||||
},
|
||||
wrapper_content_class: function () {
|
||||
}
|
||||
},
|
||||
destroyed: function () {
|
||||
this.$nextTick(function () {
|
||||
const ClassElements = getClassObj('wrapper-main');
|
||||
for (let i = 0; i < ClassElements.length; i++) {
|
||||
ClassElements[i].removeAttribute("style");
|
||||
}
|
||||
})
|
||||
},
|
||||
}
|
||||
</script>
|
@ -0,0 +1,61 @@
|
||||
<!--个人设置-->
|
||||
<template>
|
||||
<div class="account-setting">
|
||||
<div class="layout-item left">
|
||||
<div class="left-content">
|
||||
<div class="search-type">
|
||||
<a-menu mode="inline" :selectedKeys="keys" @click="menuClick">
|
||||
<a-menu-item key="base">
|
||||
<span>基本设置</span>
|
||||
</a-menu-item>
|
||||
<a-menu-item key="security">
|
||||
<span>安全设置</span>
|
||||
</a-menu-item>
|
||||
</a-menu>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "accountSetting",
|
||||
props: {
|
||||
keys: {
|
||||
type: Array,
|
||||
default: function () {
|
||||
return ['base'];
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
menuClick(event) {
|
||||
const key = event.key;
|
||||
let url = '';
|
||||
switch (key) {
|
||||
case "base":
|
||||
url = '/account/setting/base';
|
||||
break;
|
||||
case "security":
|
||||
url = '/account/setting/security';
|
||||
}
|
||||
this.$router.push(url);
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.account-setting {
|
||||
.left {
|
||||
height: 100%;
|
||||
width: 225px;
|
||||
border-right: 1px solid #e8e8e8;
|
||||
|
||||
.ant-menu-root {
|
||||
border-right: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@ -0,0 +1,84 @@
|
||||
<template>
|
||||
<div v-if="userInfo">
|
||||
<a-dropdown class="action-item" placement="bottomRight">
|
||||
<div class="user-info">
|
||||
<a-avatar :src="userInfo.imgPath" alt="">{{userInfo.username}}</a-avatar>
|
||||
<span>{{userInfo.username}}</span>
|
||||
</div>
|
||||
<a-menu slot="overlay" class="middle-menu" :selectable="false" @click="userAction">
|
||||
<a-menu-item key="setting">
|
||||
<a href="javascript:;">
|
||||
<a-icon type="user"></a-icon>
|
||||
个人设置</a>
|
||||
</a-menu-item>
|
||||
<a-menu-item key="theme">
|
||||
<a href="javascript:;">
|
||||
<a-icon type="swap"/>
|
||||
切换主题</a>
|
||||
</a-menu-item>
|
||||
<a-menu-divider></a-menu-divider>
|
||||
<a-menu-item key="logout">
|
||||
<a href="javascript:;">
|
||||
<a-icon type="logout"></a-icon>
|
||||
退出登录</a>
|
||||
</a-menu-item>
|
||||
</a-menu>
|
||||
</a-dropdown>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {mapState} from 'vuex'
|
||||
|
||||
export default {
|
||||
name: 'HeaderAvatar',
|
||||
data() {
|
||||
return {}
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
userInfo: state => state.userInfo,
|
||||
theme: state => state.theme,
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
userAction(action) {
|
||||
let app = this;
|
||||
if (action.key == 'logout') {
|
||||
app.$store.dispatch('SET_LOGOUT');
|
||||
} else if (action.key == 'setting') {
|
||||
app.$router.push('/account/setting/base');
|
||||
} else if (action.key == 'theme') {
|
||||
let theme = 'dark';
|
||||
if (this.theme == theme) {
|
||||
theme = 'light';
|
||||
}
|
||||
this.$store.dispatch('setTheme', theme);
|
||||
} else {
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.avatar-uploader > .ant-upload {
|
||||
width: 128px;
|
||||
height: 128px;
|
||||
}
|
||||
|
||||
.avatar-uploader img {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.ant-upload-select-picture-card i {
|
||||
font-size: 32px;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.ant-upload-select-picture-card .ant-upload-text {
|
||||
margin-top: 8px;
|
||||
color: #666;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,157 @@
|
||||
<template>
|
||||
<a-popover v-model="showNotice" overlayClassName="header-notice" trigger="click" placement="bottomRight">
|
||||
<template slot="content">
|
||||
<a-spin :spinning="loading">
|
||||
<a-tabs class="header-notice-content" :tabBarGutter="25">
|
||||
<a-tab-pane key="3">
|
||||
<span slot="tab">通知<span
|
||||
v-if="task.total && task.total">({{task.total}})</span></span>
|
||||
<template v-if="task.total && task.total">
|
||||
<a-list>
|
||||
<template v-for="item in task.list">
|
||||
<a-list-item :key="item.id">
|
||||
<a-list-item-meta>
|
||||
<a-avatar slot="avatar" :src="item.img"/>
|
||||
<span slot="title">
|
||||
<p>{{item.title}}</p>
|
||||
</span>
|
||||
</a-list-item-meta>
|
||||
</a-list-item>
|
||||
</template>
|
||||
</a-list>
|
||||
<div class="footer-action">
|
||||
<!-- <a class="item muted" @click="setRead('task')">清空通知</a>-->
|
||||
<a class="item muted" @click="showMore()">查看更多</a>
|
||||
</div>
|
||||
</template>
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
</a-spin>
|
||||
</template>
|
||||
<span>
|
||||
<a-badge :count="total">
|
||||
<a-icon class="action-item" type="bell"/>
|
||||
</a-badge>
|
||||
</span>
|
||||
</a-popover>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import moment from 'moment';
|
||||
import {getNotice} from "../../../api/mock";
|
||||
|
||||
export default {
|
||||
name: 'HeaderNotice',
|
||||
data() {
|
||||
return {
|
||||
showNotice: false,
|
||||
loading: false,
|
||||
total: 0,
|
||||
totalSum: 0,
|
||||
list: [],
|
||||
task: {
|
||||
page: 1,
|
||||
pageSize: 5,
|
||||
total: 0,
|
||||
list: [],
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.init();
|
||||
},
|
||||
methods: {
|
||||
init() {
|
||||
this.fetchNotice();
|
||||
},
|
||||
setRead(type) {
|
||||
this.total -= this.list[type].length;
|
||||
this.list[type] = [];
|
||||
},
|
||||
showMore() {
|
||||
this.showNotice = false;
|
||||
this.$router.push('/notify/notice');
|
||||
},
|
||||
fetchNotice() {
|
||||
getNotice().then(res => {
|
||||
this.task.list = res.data.list;
|
||||
this.task.total = res.data.total;
|
||||
this.total = this.task.total;
|
||||
})
|
||||
},
|
||||
formatTime(time) {
|
||||
return moment(time).format('YY年MM月DD日 HH:mm');
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.header-notice {
|
||||
.ant-popover-inner-content {
|
||||
padding: 0;
|
||||
|
||||
.ant-tabs-bar {
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
|
||||
.ant-list {
|
||||
.ant-list-item {
|
||||
padding: 12px 24px;
|
||||
transition: all .3s;
|
||||
|
||||
&:hover {
|
||||
background: #e6f7ff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.header-notice-content {
|
||||
width: 340px;
|
||||
|
||||
.ant-tabs-bar {
|
||||
text-align: center;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.ant-list-item-meta-title {
|
||||
p {
|
||||
margin-bottom: 8px;
|
||||
position: relative;
|
||||
}
|
||||
}
|
||||
|
||||
.ant-list-item-meta-description {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.ant-list-item:hover {
|
||||
/*background: #e6f7ff;*/
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.notFound {
|
||||
text-align: center;
|
||||
padding: 73px 0 88px 0;
|
||||
color: rgba(0, 0, 0, 0.45);
|
||||
height: 275px;
|
||||
|
||||
img {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.footer-action {
|
||||
border-top: 1px solid #e8e8e8;
|
||||
padding: 12px 0;
|
||||
|
||||
.item {
|
||||
width: 49%;
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@ -0,0 +1,75 @@
|
||||
<!--切换不同项目组-->
|
||||
<template>
|
||||
<!--<div v-if="currentOrganization">
|
||||
<a-dropdown class="action-item" placement="bottomCenter">
|
||||
<div class="organization-select">
|
||||
<span>{{currentOrganization.name}}</span>
|
||||
<span><a-icon type="down" /></span>
|
||||
</div>
|
||||
<a-menu slot="overlay" class="middle-menu organization-menu" :selectable="false" @click="organizationAction">
|
||||
<a-menu-item v-for="(organization,index) in organizationList" :key="index">
|
||||
<a href="javascript:;">{{organization.name}}</a>
|
||||
</a-menu-item>
|
||||
</a-menu>
|
||||
</a-dropdown>
|
||||
</div>-->
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {mapState} from 'vuex'
|
||||
import {changeCurrentOrganization} from '@/api/user';
|
||||
import {checkResponse} from "@/assets/js/utils";
|
||||
import {createRoute} from "../../../assets/js/utils";
|
||||
|
||||
export default {
|
||||
name: 'HeaderSelect',
|
||||
data() {
|
||||
return {
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
currentOrganization: state => state.currentOrganization,
|
||||
organizationList: state => state.organizationList
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
organizationAction(action) {
|
||||
let app = this;
|
||||
app.$store.dispatch('setCurrentOrganization', app.organizationList[action.key]);
|
||||
changeCurrentOrganization(app.organizationList[action.key].code).then(res=>{
|
||||
if (checkResponse(res)) {
|
||||
app.$store.dispatch('SET_MENU', res.data);
|
||||
app.$store.dispatch('windowLoading', true);
|
||||
setTimeout(function () {
|
||||
const menu = res.data;
|
||||
if (menu) {
|
||||
let routes = app.$router.options.routes;
|
||||
menu.forEach(function (v) {
|
||||
routes[0].children.push(createRoute(v));
|
||||
if (v.children) {
|
||||
v.children.forEach(function (v2) {
|
||||
routes[0].children.push(createRoute(v2));
|
||||
if (v2.children) {
|
||||
v2.children.forEach(function (v3) {
|
||||
routes[0].children.push(createRoute(v3));
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
});
|
||||
app.$router.addRoutes(routes);
|
||||
app.$store.dispatch('windowLoading', false);
|
||||
location.reload();
|
||||
}
|
||||
}, 500);
|
||||
}
|
||||
})
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
</style>
|
@ -0,0 +1,108 @@
|
||||
<template>
|
||||
<div class='editable-cell'>
|
||||
<div v-if="editable" class='editable-cell-input-wrapper'>
|
||||
<a-input
|
||||
:value="value"
|
||||
@change="handleChange"
|
||||
@pressEnter="check"
|
||||
/>
|
||||
<a-icon
|
||||
type='check'
|
||||
class='editable-cell-icon-check'
|
||||
@click="check"
|
||||
/>
|
||||
</div>
|
||||
<div v-else class='editable-cell-text-wrapper'>
|
||||
<span v-if="value">{{value}}</span>
|
||||
<span v-else-if="value == 0">{{value}}</span>
|
||||
<span v-else> </span>
|
||||
<a-icon type='edit' class='editable-cell-icon' @click="edit"/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import {Input, Icon} from 'ant-design-vue';
|
||||
|
||||
export default {
|
||||
name: 'EditableCell',
|
||||
components: {
|
||||
'a-input': Input,
|
||||
'a-icon': Icon
|
||||
},
|
||||
props: {
|
||||
text: [String,Number],
|
||||
showEdit: {
|
||||
type: [Boolean]
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
value: this.text,
|
||||
editable: false,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleChange(e) {
|
||||
const value = e.target.value;
|
||||
this.value = value
|
||||
},
|
||||
check() {
|
||||
this.editable = false;
|
||||
this.$emit('change', this.value)
|
||||
},
|
||||
edit() {
|
||||
this.editable = true
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.editable-cell {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.editable-cell-input-wrapper,
|
||||
.editable-cell-text-wrapper {
|
||||
padding-right: 24px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.editable-cell-text-wrapper {
|
||||
padding: 5px 24px 5px 5px;
|
||||
}
|
||||
|
||||
.editable-cell-icon,
|
||||
.editable-cell-icon-check {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 8px;
|
||||
width: 20px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.editable-cell-icon {
|
||||
line-height: 18px;
|
||||
display: none;
|
||||
}
|
||||
.editable-cell-icon.anticon{
|
||||
display: none;
|
||||
}
|
||||
|
||||
.editable-cell-icon-check {
|
||||
top: 0;
|
||||
line-height: 28px !important;
|
||||
}
|
||||
|
||||
.editable-cell:hover .editable-cell-icon {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.editable-cell-icon:hover,
|
||||
.editable-cell-icon-check:hover {
|
||||
color: #108ee9;
|
||||
}
|
||||
|
||||
.editable-add-btn {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,375 @@
|
||||
<template>
|
||||
<div class="v-uploader" :class="{'hidden-files': !showFiles,'hidden-uploader': !showUploader}">
|
||||
<a-card :title="uploaderTitle">
|
||||
<div class="actions" slot="extra">
|
||||
<a class="muted action-item" @click="showFiles = !showFiles">
|
||||
<a-icon type="shrink" v-show="showFiles"/>
|
||||
<a-icon type="arrows-alt" v-show="!showFiles"/>
|
||||
</a>
|
||||
<a class="muted action-item" @click="closeUploader">
|
||||
<a-icon type="close"/>
|
||||
</a>
|
||||
</div>
|
||||
<uploader ref="uploader"
|
||||
:options="options"
|
||||
:autoStart="autoStart"
|
||||
@files-submitted="filesSubmitted"
|
||||
@file-progress="fileProgress"
|
||||
@file-success="fileSuccess"
|
||||
@file-error="fileError"
|
||||
@file-complete="fileComplete"
|
||||
@complete="complete"
|
||||
class="uploader-workplace">
|
||||
<vue-scroll>
|
||||
<!-- <a-button @click="testSomeThing">测试</a-button>
|
||||
<uploader-unsupport></uploader-unsupport>
|
||||
<uploader-btn>select files</uploader-btn>
|
||||
<uploader-drop>
|
||||
<p>Drop files here to upload or</p>
|
||||
<uploader-btn>select files</uploader-btn>
|
||||
<uploader-btn :attrs="attrs">select images</uploader-btn>
|
||||
<uploader-btn :directory="true">select folder</uploader-btn>
|
||||
</uploader-drop>-->
|
||||
<uploader-list>
|
||||
<template slot-scope="files">
|
||||
<ul class="uploader-wrapper">
|
||||
<uploader-file :key="file.id" :file="file" :list="true"
|
||||
v-for="file in files.fileList">
|
||||
<template slot-scope="file">
|
||||
<li class="uploader-item">
|
||||
<div class="item-content">
|
||||
<div class="item-info">
|
||||
<div class="file-item">
|
||||
<div class="file-icon">
|
||||
<a-avatar icon="link" shape="square"
|
||||
:src="file.file.fileUrl"/>
|
||||
</div>
|
||||
<div class="file-info">
|
||||
<div class="file-content">
|
||||
<div class="file-title">
|
||||
<a-tooltip placement="top" :mouseEnterDelay="0.3"
|
||||
:title="file.file.name">
|
||||
{{file.file.name}}
|
||||
</a-tooltip>
|
||||
</div>
|
||||
<!-- <div class="file-extra">
|
||||
<span>{{file.file.projectName ? file.file.projectName : tempData.projectName}}</span>
|
||||
<span v-if="file.status == 'success'">({{file.formatedSize }})</span>
|
||||
<span v-else>({{(Number(file.uploadedSize) / (1024 * 1000)).toFixed(2) }}MB/{{file.formatedSize }})</span>
|
||||
</div>-->
|
||||
</div>
|
||||
<div class="uploader-progress"
|
||||
v-show="file.status != 'success'">
|
||||
<a-progress :strokeWidth="2" :showInfo="false"
|
||||
:percent="file.progress * 100"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item-status">
|
||||
<a class="muted" @click="cancelUpload(file)">
|
||||
<a-icon type="close" v-show="file.status != 'success'"/>
|
||||
</a>
|
||||
<a-icon class="text-success" type="check"
|
||||
v-show="file.status == 'success'"/>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</template>
|
||||
</uploader-file>
|
||||
</ul>
|
||||
</template>
|
||||
</uploader-list>
|
||||
<!--<uploader-files>
|
||||
</uploader-files>-->
|
||||
</vue-scroll>
|
||||
</uploader>
|
||||
</a-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {checkResponse} from "../../assets/js/utils";
|
||||
import {mapState} from 'vuex'
|
||||
import {getStore} from "../../assets/js/storage";
|
||||
import {notice} from "../../assets/js/notice";
|
||||
import {uploadFiles, getUserId} from "../../api/mock";
|
||||
|
||||
export default {
|
||||
name: "v-uploader",
|
||||
props: {
|
||||
code: {
|
||||
type: [String],
|
||||
default() {
|
||||
return ''
|
||||
}
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
showFiles: false, //显示上传文件
|
||||
showUploader: false,//显示上传窗口
|
||||
progressTotal: 0, //上传中的文件数
|
||||
completeTotal: 0, //已完成的文件数
|
||||
options: {
|
||||
target: uploadFiles,
|
||||
testChunks: true,
|
||||
chunkSize: 1024 * 1024 * 1024 * 8,
|
||||
query: function () {
|
||||
return getStore('tempData', true);//query暂时无法动态响应
|
||||
},
|
||||
headers: function () {
|
||||
const userInfo = getStore('userInfo', true);
|
||||
const auth = getUserId(userInfo.id);
|
||||
return auth;
|
||||
},
|
||||
},
|
||||
attrs: {
|
||||
accept: 'image/*'
|
||||
},
|
||||
autoStart: true,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
uploader: state => state.common.uploader,
|
||||
tempData: state => state.common.tempData,
|
||||
}),
|
||||
uploaderTitle() {
|
||||
if (!this.progressTotal) {
|
||||
return '上传完成';
|
||||
}
|
||||
let current = this.completeTotal + 1;
|
||||
if (current > this.progressTotal) {
|
||||
current = this.progressTotal;
|
||||
}
|
||||
return `正在上传 ${current}/${this.progressTotal}`;
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
code() {
|
||||
this.init();
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.init();
|
||||
},
|
||||
mounted() {
|
||||
this.$nextTick(() => {
|
||||
window.uploader = this.$refs.uploader.uploader;
|
||||
this.$store.dispatch('setUploader', window.uploader);
|
||||
console.log(window.uploader);
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
init() {
|
||||
|
||||
},
|
||||
closeUploader() {//关闭上传窗口
|
||||
this.showUploader = false;
|
||||
this.uploader.cancel();
|
||||
},
|
||||
filesSubmitted(files) { //添加上传文件
|
||||
//this.$refs.uploader.uploader.opts.query = 111;
|
||||
this.showUploader = true;
|
||||
this.showFiles = true;
|
||||
this.progressTotal += files.length;
|
||||
console.log('file submitted', files)
|
||||
|
||||
},
|
||||
fileProgress(rootFile, file, chunk) { //有文件上传中
|
||||
this.showUploader = true;
|
||||
this.showFiles = true;
|
||||
console.log('file progress', arguments)
|
||||
},
|
||||
fileSuccess(rootFile, file, message, chunk) { //一个文件上传成功
|
||||
const response = JSON.parse(message);
|
||||
if (!checkResponse(response)) {
|
||||
notice({title: response.msg}, 'notice', 'error');
|
||||
return false;
|
||||
}
|
||||
rootFile.fileUrl = response.data.url;
|
||||
console.log('file success', rootFile);
|
||||
this.completeTotal++;
|
||||
},
|
||||
fileError(rootFile, file, message, chunk) { //一个文件上传失败 this.progressTotal--;
|
||||
this.completeTotal--;
|
||||
const response = JSON.parse(message);
|
||||
file.cancel();
|
||||
//rootFile.projectName = response.data.projectName;
|
||||
console.log('file error', rootFile);
|
||||
notice({title: response.msg}, 'notice', 'error');
|
||||
},
|
||||
fileComplete(rootFile) { //一个文件上传完成
|
||||
console.log('file complete', rootFile);
|
||||
},
|
||||
complete() { //所有文件上传完成
|
||||
console.log('complete', arguments);
|
||||
this.progressTotal = this.completeTotal = 0;
|
||||
notice({title: '文件上传成功'}, 'notice', 'success');
|
||||
setTimeout(() => {
|
||||
this.showFiles = false;
|
||||
}, 3000);
|
||||
},
|
||||
cancelUpload(file) {
|
||||
console.log(file);
|
||||
this.progressTotal--;
|
||||
this.completeTotal--;
|
||||
file.file.cancel();
|
||||
},
|
||||
filterList(list) {
|
||||
return list;
|
||||
},
|
||||
testSomeThing() {
|
||||
console.log(this.uploader.fileList);
|
||||
this.uploader.fileList[0].resume();
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
@import "~ant-design-vue/lib/style/themes/default";
|
||||
|
||||
.v-uploader {
|
||||
position: fixed;
|
||||
bottom: 12px;
|
||||
right: 24px;
|
||||
width: 485px;
|
||||
z-index: 1001;
|
||||
box-shadow: 0 7px 21px rgba(0, 0, 0, .1);
|
||||
transition: bottom 218ms ease;
|
||||
|
||||
.ant-card {
|
||||
box-shadow: 0 7px 21px rgba(0, 0, 0, .1);
|
||||
|
||||
.ant-card-head {
|
||||
margin-bottom: 0;
|
||||
border-bottom: 1px solid #e1e1e1;
|
||||
}
|
||||
|
||||
.ant-card-head-title, .ant-card-extra {
|
||||
padding: 12px 0;
|
||||
}
|
||||
|
||||
.ant-card-body {
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&.hidden-files {
|
||||
bottom: -241px;
|
||||
}
|
||||
|
||||
&.hidden-uploader {
|
||||
bottom: -291px;
|
||||
}
|
||||
|
||||
.actions {
|
||||
.action-item {
|
||||
margin-left: 12px;
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.uploader-workplace {
|
||||
height: 240px;
|
||||
background-color: #f7f7f7;
|
||||
padding: 12px 0 0 12px;
|
||||
|
||||
.uploader-list {
|
||||
padding-right: 12px;
|
||||
|
||||
.uploader-wrapper {
|
||||
.uploader-file {
|
||||
padding: 0;
|
||||
height: auto;
|
||||
line-height: 36px;
|
||||
border-bottom: none;
|
||||
border-radius: 4px;
|
||||
|
||||
.uploader-item {
|
||||
width: 100%;
|
||||
margin-bottom: 8px;
|
||||
background: #eee;
|
||||
|
||||
.item-content {
|
||||
padding: 6px 12px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
flex: 1;
|
||||
|
||||
.item-info {
|
||||
flex: 1 1 auto;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
|
||||
.file-item {
|
||||
display: flex;
|
||||
|
||||
.file-icon {
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.file-info {
|
||||
width: 100%;
|
||||
min-width: 0;
|
||||
padding: 4px 0;
|
||||
line-height: 16px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
|
||||
.file-content {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
.file-title {
|
||||
max-width: 210px;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.file-extra {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
max-width: 200px;
|
||||
margin-left: 16px;
|
||||
color: gray;
|
||||
font-size: 12px;
|
||||
|
||||
span {
|
||||
margin-left: 3px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.uploader-progress {
|
||||
.ant-progress-outer {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.item-status {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
width: 30px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@ -0,0 +1,11 @@
|
||||
export default {
|
||||
crossDomain: false, //是否开启跨域支持
|
||||
//PROD_URL: 'https://beta.vilson.xyz/index.php/', //生产环境接口地址
|
||||
PROD_URL: 'http://localhost:8888/api', //生产环境接口地址(网关)服务器url
|
||||
MOCK_URL: 'https://result.eolinker.com/1DVzyqbab364c82aaead42f24de532c4c046e6805221c90?uri=/mock/', //mock数据url
|
||||
WS_URI: 'ws://localhost:8888/websocket', //WebSocket地址
|
||||
HOME_PAGE: '/home',//主页路由
|
||||
ERROR_PAGE_URL: 'http://ppkn5nh6t.bkt.clouddn.com/upload/20190410/dbf66652effa4b309d98b00946043690.jpeg',//404页面图片
|
||||
VIEW_FILE_SERVER_LOCAL: 'http://localhost:8012/onlinePreview?url=', //本地查看文件服务器
|
||||
VIEW_FILE_SERVER_SERVER: 'http://193.112.27.123:8012/onlinePreview?url=', //远程查看文件服务器
|
||||
};
|
@ -0,0 +1,3 @@
|
||||
export default {
|
||||
VERSION: '2.2.10',
|
||||
};
|
@ -0,0 +1,5 @@
|
||||
export const COMMON = {
|
||||
PAGE_SIZE: 20,
|
||||
PAGE_NUM: 1,
|
||||
};
|
||||
|
@ -0,0 +1,76 @@
|
||||
/* eslint-disable no-console,no-unused-vars */
|
||||
import Vue from 'vue'
|
||||
import VueRouter from 'vue-router'
|
||||
import Antd from "ant-design-vue";
|
||||
import App from './App'
|
||||
import store from './store/index'
|
||||
import router from './router/index'
|
||||
import 'ant-design-vue/dist/antd.css'
|
||||
import vuescroll from 'vuescroll';
|
||||
import 'vuescroll/dist/vuescroll.css';
|
||||
import '@/assets/css/theme.less'
|
||||
import '@/assets/icon/iconfont'
|
||||
import WrapperContent from '@/components/layout/WrapperContent'
|
||||
import {message, notification} from 'ant-design-vue'
|
||||
import {notice, destroyNotice} from './assets/js/notice'
|
||||
|
||||
import moment from 'moment';
|
||||
import 'moment/locale/zh-cn';
|
||||
|
||||
import common from "./mixins/common";
|
||||
|
||||
import '@/utils/filter' // global filter
|
||||
|
||||
|
||||
moment.locale('zh-cn');
|
||||
|
||||
Vue.use(VueRouter);
|
||||
Vue.use(store);
|
||||
|
||||
Vue.config.productionTip = false;
|
||||
Vue.use(Antd);
|
||||
Vue.component('WrapperContent', WrapperContent);
|
||||
|
||||
import VueClipboards from 'vue-clipboards';
|
||||
Vue.use(VueClipboards);
|
||||
|
||||
import uploader from 'vue-simple-uploader'
|
||||
Vue.use(uploader);
|
||||
|
||||
|
||||
//引入element ui
|
||||
import ElementUI from 'element-ui';
|
||||
import 'element-ui/lib/theme-chalk/index.css';
|
||||
Vue.use(ElementUI);
|
||||
|
||||
Vue.prototype.$message = message;
|
||||
Vue.prototype.$notification = notification;
|
||||
Vue.prototype.$notice = notice;
|
||||
Vue.prototype.$destroyNotice = destroyNotice;
|
||||
|
||||
Vue.use(vuescroll);
|
||||
Vue.prototype.$vuescrollConfig = {
|
||||
vuescroll: {
|
||||
mode: 'native'
|
||||
},
|
||||
scrollPanel: {
|
||||
scrollingX: true,
|
||||
},
|
||||
bar: {
|
||||
delayTime: 500,
|
||||
onlyShowBarOnScroll: false,
|
||||
background: "#cecece",
|
||||
keepShow: false
|
||||
}
|
||||
};
|
||||
|
||||
Vue.mixin(common);
|
||||
|
||||
|
||||
new Vue({
|
||||
el: '#app',
|
||||
store,
|
||||
router,
|
||||
template: '<App/>',
|
||||
components: {App}
|
||||
});
|
@ -0,0 +1,15 @@
|
||||
// common-mixin.vue
|
||||
export default {
|
||||
data() {
|
||||
return {}
|
||||
},
|
||||
methods: {
|
||||
routerLink(page, replace = false) {
|
||||
if (replace) {
|
||||
this.$router.replace(page);
|
||||
} else {
|
||||
this.$router.push(page);
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
// pagination-mixin.vue
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
pagination: {
|
||||
page: 1,
|
||||
pageSize: 10,
|
||||
total: 0,
|
||||
showTotal: (total, range) => `共 ${total} 条`
|
||||
},
|
||||
// requestData: {
|
||||
// page: this.pagination.page,
|
||||
// pageSize: this.pagination.pageSize,
|
||||
// },
|
||||
}
|
||||
},
|
||||
computed:{
|
||||
requestData(){
|
||||
return {
|
||||
page: this.pagination.page,
|
||||
pageSize: this.pagination.pageSize,
|
||||
};
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
init() {
|
||||
},
|
||||
pageChange(page) {
|
||||
this.pagination.page = page;
|
||||
this.requestData.page = page.current;
|
||||
this.init();
|
||||
},
|
||||
}
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
/**
|
||||
* Home 自定义路由
|
||||
*/
|
||||
export default [
|
||||
/* {
|
||||
//任务看板
|
||||
name: 'files',
|
||||
path: '/project/space/files',
|
||||
component: resolve => require(['@/views/project/space/files'], resolve),
|
||||
meta: {model: 'Project', info: {show_slider: true, is_inner: false, pid: 122, id: 152, innerText: '导航'}},
|
||||
children: [
|
||||
{
|
||||
//任务详情
|
||||
name: 'taskdetail',
|
||||
path: 'detail/:taskCode',
|
||||
component: resolve => require(['@/views/project/space/taskdetail'], resolve),
|
||||
meta: {model: 'Project', info: {show_slider: false}},
|
||||
},
|
||||
]
|
||||
},*/
|
||||
{
|
||||
//任务看板
|
||||
name: 'inviteFromLink',
|
||||
path: '/invite_from_link/:code',
|
||||
component: resolve => require(['@/views/common/inviteFromLink'], resolve),
|
||||
meta: {model: 'Common', info: {show_slider: false}},
|
||||
},
|
||||
{
|
||||
name: 'demo',
|
||||
path: '/demo',
|
||||
component: resolve => require(['@/views/member/demo'], resolve),
|
||||
meta: {model: 'diskdemo', info:{show_slider: false}},
|
||||
},
|
||||
{
|
||||
name: 'detail',
|
||||
path: '/followuser/detail',
|
||||
component: resolve => require(['@/views/followuser/detail'], resolve),
|
||||
meta: {model: 'followuser', info:{show_slider: false}},
|
||||
},
|
||||
{
|
||||
name: 'link',
|
||||
path: '/share/link',
|
||||
component: resolve => require(['@/views/share/link'], resolve),
|
||||
meta: {model: 'share', info:{show_slider: false}},
|
||||
},
|
||||
/* {
|
||||
name: 'files',
|
||||
path: '/disk/files',
|
||||
component: resolve => require(['@/views/disk/files'], resolve),
|
||||
meta: {model: 'diskdemo', info:{show_slider: false}},
|
||||
},*/
|
||||
/*{
|
||||
name: 'overview',
|
||||
path: '/disk/overview',
|
||||
component: resolve => require(['@/views/disk/overview'], resolve),
|
||||
meta: {model: 'diskdemo', info:{show_slider: false}},
|
||||
}*/
|
||||
];
|
@ -0,0 +1,140 @@
|
||||
import Vue from 'vue'
|
||||
import store from '@/store'
|
||||
import Router from 'vue-router'
|
||||
import Index from '@/views/index'
|
||||
import Home from './home';
|
||||
import {getStore, setStore} from "../assets/js/storage";
|
||||
import {createRoute, isTokenExpired} from "../assets/js/utils";
|
||||
import config from "../config/config";
|
||||
import {refreshAccessToken} from "../api/common/common";
|
||||
|
||||
Vue.use(Router);
|
||||
const routes = [].concat(
|
||||
Home
|
||||
);
|
||||
// const router = new Router({
|
||||
// routes: routers
|
||||
// });
|
||||
const menu = getStore('menu', true);
|
||||
//后台查询出来的菜单注册到路由里面
|
||||
if (menu) {
|
||||
menu.forEach(function (v) {
|
||||
routes.push(createRoute(v));
|
||||
if (v.children) {
|
||||
v.children.forEach(function (v2) {
|
||||
routes.push(createRoute(v2));
|
||||
if (v2.children) {
|
||||
v2.children.forEach(function (v3) {
|
||||
routes.push(createRoute(v3));
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
const router = new Router({
|
||||
routes: [
|
||||
{
|
||||
path: '/',
|
||||
name: 'index',
|
||||
component: Index,
|
||||
children: routes
|
||||
},
|
||||
{
|
||||
name: 'member',
|
||||
path: '/member',
|
||||
component: resolve => require(['@/components/layout/UserLayout'], resolve),
|
||||
meta: {model: 'Login'},
|
||||
children: [
|
||||
{
|
||||
path: 'login',
|
||||
name: 'login',
|
||||
component: () => import(/* webpackChunkName: "user" */ '@/views/member/login'),
|
||||
meta: {model: 'Login'},
|
||||
},
|
||||
{
|
||||
path: 'register',
|
||||
name: 'register',
|
||||
component: () => import(/* webpackChunkName: "user" */ '@/views/member/Register'),
|
||||
meta: {model: 'Login'},
|
||||
},
|
||||
{
|
||||
path: 'forget',
|
||||
name: 'forget',
|
||||
component: () => import(/* webpackChunkName: "user" */ '@/views/member/forget'),
|
||||
meta: {model: 'Login'},
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'install',
|
||||
path: '/install',
|
||||
component: resolve => require(['@/views/error/install'], resolve),
|
||||
meta: {model: 'error'},
|
||||
},
|
||||
{
|
||||
name: 'resetEmail',
|
||||
path: '/reset/email',
|
||||
component: resolve => require(['@/views/reset/email'], resolve),
|
||||
meta: {model: 'error'},
|
||||
},
|
||||
{
|
||||
name: '404',
|
||||
path: '/404',
|
||||
component: resolve => require(['@/views/error/404'], resolve),
|
||||
meta: {model: 'error'},
|
||||
},
|
||||
{
|
||||
name: '403',
|
||||
path: '/403',
|
||||
component: resolve => require(['@/views/error/403'], resolve),
|
||||
meta: {model: 'error'},
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
router.beforeEach((to, from, next) => {
|
||||
console.log(to);
|
||||
let tokenList = getStore('tokenList', true);
|
||||
if (tokenList) {
|
||||
let refreshToken = tokenList.refreshToken;
|
||||
let accessTokenExp = tokenList.accessTokenExp;
|
||||
//判断accessToken即将到期后刷新token
|
||||
if (accessTokenExp && isTokenExpired(accessTokenExp)) {
|
||||
refreshAccessToken(refreshToken).then(res => {
|
||||
tokenList.accessToken = res.data.accessToken;
|
||||
tokenList.accessTokenExp = res.data.accessTokenExp;
|
||||
setStore('tokenList', tokenList);
|
||||
});
|
||||
}
|
||||
}
|
||||
const HOME_PAGE = config.HOME_PAGE;
|
||||
//页面中转
|
||||
if (to.name === 'index' || to.path === '/index' || to.path === '/') {
|
||||
next({path: HOME_PAGE});
|
||||
return false;
|
||||
}
|
||||
//无效页面跳转至首页
|
||||
if (!to.name && from.meta.model !== 'Login' && to.path !== HOME_PAGE) {
|
||||
next({path: '/404'});
|
||||
return false;
|
||||
}
|
||||
if (to.meta.model === 'Login' && store.state.logged) {
|
||||
next({path: HOME_PAGE});
|
||||
return false;
|
||||
}
|
||||
if (!store.state.logged && to.meta.model !== 'Login' && to.meta.model !== 'error') {
|
||||
next({
|
||||
name: 'login',
|
||||
query: {redirect: to.fullPath}
|
||||
});
|
||||
return false;
|
||||
}
|
||||
next();
|
||||
});
|
||||
router.afterEach(route => {
|
||||
//预留
|
||||
// window.scrollTo(0,0)
|
||||
});
|
||||
|
||||
export default router
|
@ -0,0 +1,44 @@
|
||||
import {setStore, removeStore} from '@/assets/js/storage'
|
||||
|
||||
export default {
|
||||
SET_LOGGED({commit}, data) {
|
||||
setStore('tokenList', data.tokenList);
|
||||
setStore('userInfo', data.userInfo);
|
||||
commit('SET_LOGGED', data);
|
||||
},
|
||||
SET_USER({commit}, data) {
|
||||
setStore('userInfo', data);
|
||||
commit('SET_USER', data);
|
||||
},
|
||||
SET_LOGOUT({commit}) {
|
||||
removeStore('tokenList');
|
||||
removeStore('token');
|
||||
removeStore('userInfo');
|
||||
commit('SET_LOGOUT');
|
||||
},
|
||||
setTheme({commit}, theme) {
|
||||
setStore('theme', theme);
|
||||
commit('setTheme', theme);
|
||||
},
|
||||
pageLoading({commit}, status) {
|
||||
commit('pageLoading', status);
|
||||
},
|
||||
windowLoading({commit}, status) {
|
||||
commit('windowLoading', status);
|
||||
},
|
||||
setOrganizationList({commit}, data) {
|
||||
setStore('organizationList', data);
|
||||
commit('setOrganizationList', data);
|
||||
},
|
||||
setCurrentOrganization({commit}, data) {
|
||||
setStore('currentOrganization', data);
|
||||
commit('setCurrentOrganization', data);
|
||||
},
|
||||
setSystem({commit}, data) {
|
||||
setStore('system', data);
|
||||
commit('setSystem', data);
|
||||
},
|
||||
setBoundClient({commit}, data) {
|
||||
commit('setBoundClient', data);
|
||||
},
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
import Vue from 'vue'
|
||||
import Vuex from 'vuex'
|
||||
import state from './state'
|
||||
import mutations from './mutations'
|
||||
import actions from './actions'
|
||||
import common from './modules/common'
|
||||
import menu from './modules/menu'
|
||||
import {getStore, setStore} from '@/assets/js/storage'
|
||||
|
||||
Vue.use(Vuex);
|
||||
|
||||
const store = new Vuex.Store({
|
||||
modules: {
|
||||
common,
|
||||
menu,
|
||||
},
|
||||
state,
|
||||
mutations,
|
||||
actions
|
||||
});
|
||||
export default store
|
@ -0,0 +1,26 @@
|
||||
import {getStore, setStore} from '@/assets/js/storage';
|
||||
|
||||
const common = {
|
||||
state: {
|
||||
uploader: null,
|
||||
tempData: getStore('tempData', true)
|
||||
},
|
||||
mutations: {
|
||||
setUploader(state, data) {
|
||||
state.uploader = data;
|
||||
},
|
||||
setTempData(state, data) {
|
||||
state.tempData = data;
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
setUploader({commit}, data) {
|
||||
commit('setUploader', data);
|
||||
},
|
||||
setTempData({commit}, data) {
|
||||
setStore('tempData', data);
|
||||
commit('setTempData', data);
|
||||
}
|
||||
}
|
||||
};
|
||||
export default common
|
@ -0,0 +1,35 @@
|
||||
import {getMenuForUser} from "@/api/menu";
|
||||
import {getMenu} from "@/api/mock";
|
||||
import {getStore, setStore} from '@/assets/js/storage';
|
||||
|
||||
const common = {
|
||||
state: {
|
||||
menu: getStore('menu', true),
|
||||
breadCrumbInfo: []
|
||||
},
|
||||
mutations: {
|
||||
SET_MENU(state, data) {
|
||||
state.menu = data;
|
||||
},
|
||||
setBreadCrumbInfo(state, data) {
|
||||
state.breadCrumbInfo = data;
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
GET_MENU({commit}) {
|
||||
getMenu().then(res => {
|
||||
setStore('menu', res.data);
|
||||
commit('SET_MENU', res.data);
|
||||
});
|
||||
},
|
||||
SET_MENU({commit},data) {
|
||||
setStore('menu', data);
|
||||
commit('SET_MENU', data);
|
||||
},
|
||||
setBreadCrumbInfo({commit}, data) {
|
||||
commit('setBreadCrumbInfo', data);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
export default common
|
@ -0,0 +1,37 @@
|
||||
export default {
|
||||
SET_LOGGED(state, {tokenList, userInfo}) {
|
||||
state.logged = true;
|
||||
state.userInfo = userInfo;
|
||||
},
|
||||
SET_USER(state, data) {
|
||||
state.userInfo = data;
|
||||
},
|
||||
SET_LOGOUT(state) {
|
||||
state.logged = false;
|
||||
state.userInfo = null;
|
||||
},
|
||||
setTheme(state, theme) {
|
||||
state.theme = theme
|
||||
},
|
||||
pageLoading(state, status) {
|
||||
state.pageLoading = status
|
||||
},
|
||||
windowLoading(state, status) {
|
||||
state.windowLoading = status
|
||||
},
|
||||
setSystem(state, data) {
|
||||
state.system = data;
|
||||
},
|
||||
setOrganizationList(state, data) {
|
||||
state.organizationList = data;
|
||||
},
|
||||
setCurrentOrganization(state, data) {
|
||||
state.currentOrganization = data;
|
||||
},
|
||||
catchSocketAction(state, data) {
|
||||
state.socketAction = data;
|
||||
},
|
||||
setBoundClient(state, data) {
|
||||
state.boundClient = data;
|
||||
}
|
||||
};
|
@ -0,0 +1,17 @@
|
||||
import {getStore} from "../assets/js/storage";
|
||||
|
||||
const userInfo = getStore('userInfo', true);
|
||||
const theme = getStore('theme');
|
||||
export default {
|
||||
theme: theme ? theme : 'dark',
|
||||
logged: !!userInfo,//登录状态
|
||||
userInfo: userInfo,//用户信息
|
||||
organizationList: getStore('organizationList', true),//能查看的组织列表
|
||||
currentOrganization: getStore('currentOrganization', true),//当前组织
|
||||
system: getStore('system', true),//系统配置
|
||||
windowLoading: false, // 窗口loading
|
||||
pageLoading: false, // 页面加载loading
|
||||
socketAction: '',
|
||||
boundClient: false,//是否绑定client
|
||||
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
import Vue from 'vue'
|
||||
|
||||
Vue.filter('NumberFormat', function (value) {
|
||||
if (!value) {
|
||||
return '0'
|
||||
}
|
||||
const intPartFormat = value.toString().replace(/(\d)(?=(?:\d{3})+$)/g, '$1,'); //将整数部分逢三一断
|
||||
return intPartFormat
|
||||
});
|
||||
|
||||
//文件预览
|
||||
Vue.filter('showPreviewUrl', function (file) {
|
||||
let url = file.file_url;
|
||||
const docUrl = 'https://view.officeapps.live.com/op/view.aspx?src=https://beta.vilson.xyz/static/upload/file/default/6v7be19pwman2fird04gqu53/6v7be19pwman2fird04gqu53/20190408/20190408124525-qq%E9%9F%B3%E4%B9%90%20copy%2055.png';
|
||||
let docArr = ['doc', 'docx', 'docm', 'dotm', 'dotx', 'xlsx', 'xlsb', 'xls', 'xlsm', 'pptx', 'ppsx', 'ppt', 'pps', 'pptm', 'potm', 'ppam', 'potx', 'ppsm'];
|
||||
const extension = file.extension;
|
||||
const index = docArr.findIndex(item => item == extension);
|
||||
if (index !== -1) {
|
||||
url = docUrl + url;
|
||||
}
|
||||
return url;
|
||||
});
|
@ -0,0 +1,211 @@
|
||||
<template>
|
||||
<div class="account-setting-base">
|
||||
<wrapper-content :showHeader="false">
|
||||
<div class="setting-content">
|
||||
<account-setting></account-setting>
|
||||
<div class="layout-item right">
|
||||
<div class="setting-info-title">
|
||||
<span>基本设置</span>
|
||||
</div>
|
||||
<div class="setting-info">
|
||||
<div class="setting-info-content">
|
||||
<a-form
|
||||
layout="vertical"
|
||||
:form="form"
|
||||
hideRequiredMark
|
||||
@submit.prevent="handleSubmit">
|
||||
<a-form-item label='邮箱'>
|
||||
<a-input v-decorator="[
|
||||
'email',
|
||||
{rules: [{ required: true, message: '请输入您的邮箱' }]}
|
||||
]"/>
|
||||
</a-form-item>
|
||||
<a-form-item label='昵称'>
|
||||
<a-input
|
||||
v-decorator="[
|
||||
'name',
|
||||
{rules: [{ required: true, message: '请输入您的邮箱' }]}
|
||||
]"/>
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
label='用户 id'>
|
||||
<a-input placeholder='用户 id'
|
||||
:rows="4"
|
||||
v-decorator="['id']"
|
||||
readonly="true"
|
||||
disabled="true"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item>
|
||||
<a-button type='primary' htmlType='submit' :loading="loading">更新基本信息</a-button>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</div>
|
||||
<div class="setting-info-avatar">
|
||||
<span>头像</span>
|
||||
<a-avatar class="avatar" :size="150" :src="userInfo.imgPath">{{ userInfo.username }}
|
||||
</a-avatar>
|
||||
<a-upload
|
||||
name="avatar"
|
||||
class="avatar-uploader"
|
||||
:showUploadList="false"
|
||||
:headers="headers"
|
||||
:action="uploadAction"
|
||||
:data="{userid: userInfo.id}"
|
||||
:beforeUpload="beforeUpload"
|
||||
@change="handleChange"
|
||||
>
|
||||
<a-button icon="upload" class="upload">更换头像</a-button>
|
||||
</a-upload>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</wrapper-content>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {mapState} from 'vuex'
|
||||
import AccountSetting from "@/components/layout/account/setting"
|
||||
import {checkResponse, getBase64} from "assets/js/utils";
|
||||
import {editPersonal} from "@/api/mock";
|
||||
import {setStore} from "assets/js/storage";
|
||||
|
||||
export default {
|
||||
name: "settingBase",
|
||||
components: {
|
||||
AccountSetting
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
form: this.$form.createForm(this),
|
||||
uploadLoading: false,
|
||||
uploadAction: 'http://localhost:9000/front/app/updateImg',
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
userInfo: state => state.userInfo,
|
||||
}),
|
||||
/*headers() {
|
||||
return getAuthorization();
|
||||
}*/
|
||||
},
|
||||
mounted() {
|
||||
this.$nextTick(() => {
|
||||
this.form.setFieldsValue({
|
||||
email: this.userInfo.email,
|
||||
name: this.userInfo.username,
|
||||
id: this.userInfo.id,
|
||||
});
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
handleSubmit() {
|
||||
let app = this;
|
||||
this.form.validateFields(
|
||||
(err, values) => {
|
||||
if (!err) {
|
||||
let obj = app.form.getFieldsValue();
|
||||
obj.id = app.userInfo.id;
|
||||
obj.avatar = app.userInfo.imgPath;
|
||||
console.log(obj);
|
||||
let tmpObj = {
|
||||
id: app.userInfo.id,
|
||||
username: obj.name,
|
||||
password: null,
|
||||
email: obj.email,
|
||||
mobile: app.userInfo.mobile,
|
||||
createTime: app.userInfo.createTime,
|
||||
deptId: app.userInfo.deptId,
|
||||
deptName: app.userInfo.deptName,
|
||||
companyName: app.userInfo.companyName
|
||||
}
|
||||
setStore('userInfo', tmpObj);
|
||||
editPersonal(obj).then(res => {
|
||||
app.loading = false;
|
||||
if (!checkResponse(res)) {
|
||||
return;
|
||||
}
|
||||
app.userInfo.email = obj.email;
|
||||
app.userInfo.name = obj.username;
|
||||
app.userInfo.description = obj.description;
|
||||
});
|
||||
}
|
||||
},
|
||||
);
|
||||
},
|
||||
handleChange(info) {
|
||||
if (info.file.status === 'uploading') {
|
||||
this.uploadLoading = true;
|
||||
return
|
||||
}
|
||||
if (info.file.status === 'done') {
|
||||
getBase64(info.file.originFileObj, (imageUrl) => {
|
||||
this.userInfo.imgPath = info.file.response.url;
|
||||
this.$store.dispatch('SET_USER', this.userInfo);
|
||||
this.uploadLoading = false;
|
||||
// this.$store.dispatch('SET_USER', this.userInfo);
|
||||
})
|
||||
}
|
||||
},
|
||||
beforeUpload(file) {
|
||||
const isLt2M = file.size / 1024 / 1024 < 2;
|
||||
if (!isLt2M) {
|
||||
this.$message.error('图片不能超过2MB!')
|
||||
}
|
||||
return isLt2M
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.account-setting-base {
|
||||
|
||||
.wrapper-main {
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
.setting-content {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
||||
.right {
|
||||
flex: 1 1 0;
|
||||
padding: 8px 40px;
|
||||
|
||||
.setting-info-title {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.setting-info {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
padding-top: 12px;
|
||||
|
||||
&-content {
|
||||
width: 320px;
|
||||
}
|
||||
|
||||
&-avatar {
|
||||
padding-left: 104px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.avatar {
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
.avatar-uploader {
|
||||
width: 115px;
|
||||
margin: 24px auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@ -0,0 +1,492 @@
|
||||
<template>
|
||||
<div class="account-setting-security">
|
||||
<wrapper-content :showHeader="false">
|
||||
<div class="setting-content">
|
||||
<account-setting :keys="['security']"></account-setting>
|
||||
<div class="layout-item right">
|
||||
<div class="setting-info-title">
|
||||
<span>安全设置</span>
|
||||
</div>
|
||||
<div class="setting-info">
|
||||
<div class="setting-info-content">
|
||||
<div class="ant-list ant-list-split">
|
||||
<div class="ant-spin-nested-loading">
|
||||
<div class="ant-spin-container">
|
||||
<div class="ant-list-item">
|
||||
<div class="ant-list-item-meta">
|
||||
<div class="ant-list-item-meta-content">
|
||||
<h4 class="ant-list-item-meta-title"><a>账户密码</a></h4>
|
||||
<div class="ant-list-item-meta-description">
|
||||
<span>
|
||||
<span class="security-list-description">当前密码强度 : 强</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<ul class="ant-list-item-action">
|
||||
<li @click="editPassword"><a>修改</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="ant-list-item">
|
||||
<div class="ant-list-item-meta">
|
||||
<div class="ant-list-item-meta-content">
|
||||
<h4 class="ant-list-item-meta-title"><a>手机账号</a></h4>
|
||||
<div class="ant-list-item-meta-description">
|
||||
<span>
|
||||
<span class="security-list-description">
|
||||
<span v-if="userInfo.mobile">已绑定手机 : {{userInfo.mobile}}</span>
|
||||
<span v-else>未绑定手机</span>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<ul class="ant-list-item-action">
|
||||
<li @click="editMobile"><a>修改</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="ant-list-item">
|
||||
<div class="ant-list-item-meta">
|
||||
<div class="ant-list-item-meta-content">
|
||||
<h4 class="ant-list-item-meta-title"><a>QQ扫码登录关联</a></h4>
|
||||
<div class="ant-list-item-meta-description">
|
||||
<span>
|
||||
<span class="security-list-description">是否关联 : 是</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<ul class="ant-list-item-action">
|
||||
<li @click="editQQ()"><a>关联</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</wrapper-content>
|
||||
<a-modal
|
||||
:width="385"
|
||||
v-model="passwordInfo.modalStatus"
|
||||
:title="passwordInfo.modalTitle"
|
||||
:bodyStyle="{paddingBottom:'1px'}"
|
||||
:footer="null"
|
||||
>
|
||||
<a-alert style="margin-bottom: 12px;"
|
||||
v-show="errorTips"
|
||||
:message="errorTips"
|
||||
type="error"
|
||||
/>
|
||||
<a-form
|
||||
layout="vertical"
|
||||
:form="form"
|
||||
:autoFormCreate="(form)=>{this.form = form}"
|
||||
hideRequiredMark
|
||||
@submit.prevent="handlePasswordSubmit">
|
||||
<a-form-item
|
||||
label='原密码'
|
||||
>
|
||||
<a-input
|
||||
type="password"
|
||||
v-decorator="[
|
||||
'password',
|
||||
{rules: [{ required: true, message: '请输入原密码' }]}
|
||||
]"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
label='新密码'
|
||||
>
|
||||
<a-input
|
||||
type="password"
|
||||
v-decorator="[
|
||||
'newPassword',
|
||||
{rules: [{ required: true, message: '请输入新密码' }]}
|
||||
]"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
label='确认新密码'
|
||||
>
|
||||
<a-input
|
||||
type="password"
|
||||
v-decorator="[
|
||||
'confirmPassword',
|
||||
{rules: [{ required: true, message: '请确认新密码' }]}
|
||||
]"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
>
|
||||
<a-button type='primary' htmlType='submit' block size="large">保存</a-button>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-modal>
|
||||
<a-modal
|
||||
class="mobile-modal"
|
||||
:width="385"
|
||||
v-model="mobileInfo.modalStatus"
|
||||
:title="mobileInfo.modalTitle"
|
||||
:bodyStyle="{paddingBottom:'1px'}"
|
||||
:footer="null"
|
||||
>
|
||||
<a-alert style="margin-bottom: 12px;"
|
||||
v-show="errorTips"
|
||||
:message="errorTips"
|
||||
type="error"
|
||||
/>
|
||||
<a-form
|
||||
layout="vertical"
|
||||
:form="mobileForm"
|
||||
hideRequiredMark
|
||||
@submit.prevent="handleMobileSubmit">
|
||||
<a-form-item
|
||||
>
|
||||
<a-input size="large" type="text" placeholder="手机号"
|
||||
v-decorator="[
|
||||
'mobile',
|
||||
{rules: [{ required: true, pattern: /^1[34578]\d{9}$/, message: '请输入正确的手机号' }], validateTrigger: 'change'}
|
||||
]">
|
||||
<a-icon slot="prefix" type="mobile" :style="{ color: 'rgba(0,0,0,.25)' }"/>
|
||||
</a-input>
|
||||
</a-form-item>
|
||||
|
||||
<a-row :gutter="16">
|
||||
<a-col class="gutter-row" :span="16">
|
||||
<a-form-item
|
||||
>
|
||||
<a-input size="large" type="text" placeholder="验证码"
|
||||
v-decorator="[
|
||||
'captcha',
|
||||
{rules: [{ required: true, message: '请输入验证码' }], validateTrigger: 'blur'}
|
||||
]">
|
||||
<a-icon slot="prefix" type="mail" :style="{ color: 'rgba(0,0,0,.25)' }"/>
|
||||
</a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col class="gutter-row" :span="8">
|
||||
<a-button
|
||||
class="getCaptcha"
|
||||
size="large"
|
||||
tabindex="-1"
|
||||
:disabled="mobileInfo.state.smsSendBtn"
|
||||
@click.stop.prevent="getCaptcha"
|
||||
v-text="!mobileInfo.state.smsSendBtn && '获取验证码' || (mobileInfo.state.time+' s')"
|
||||
></a-button>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-form-item
|
||||
>
|
||||
<a-button type='primary' htmlType='submit' block size="large" :loading="mobileInfo.confirmLoading" :disabled="mobileInfo.confirmLoading">绑定</a-button>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-modal>
|
||||
<a-modal
|
||||
class="mail-modal"
|
||||
:width="385"
|
||||
v-model="mailInfo.modalStatus"
|
||||
:title="mailInfo.modalTitle"
|
||||
:bodyStyle="{paddingBottom:'1px'}"
|
||||
:footer="null"
|
||||
>
|
||||
<a-alert style="margin-bottom: 12px;"
|
||||
v-show="errorTips"
|
||||
:message="errorTips"
|
||||
type="error"
|
||||
/>
|
||||
<a-form
|
||||
layout="vertical"
|
||||
:form="mailForm"
|
||||
hideRequiredMark
|
||||
@submit.prevent="handleMailSubmit">
|
||||
<a-form-item
|
||||
>
|
||||
<a-input size="large" type="text" placeholder="邮箱地址"
|
||||
v-decorator="[
|
||||
'mail',
|
||||
{rules: [{ required: true, pattern: /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+((\.[a-zA-Z0-9_-]{2,3}){1,2})$/, message: '请输入正确的邮箱地址' }], validateTrigger: 'change'}
|
||||
]">
|
||||
<a-icon slot="prefix" type="mail" :style="{ color: 'rgba(0,0,0,.25)' }"/>
|
||||
</a-input>
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
>
|
||||
<a-button type='primary' htmlType='submit' block size="large" :loading="mailInfo.confirmLoading" :disabled="mailInfo.confirmLoading">保存</a-button>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-modal>
|
||||
<a-drawer
|
||||
title="QQ登录"
|
||||
:width="720"
|
||||
@close="onClose"
|
||||
:visible="visible"
|
||||
:wrapStyle="{height: 'calc(100% - 108px)',overflow: 'auto',paddingBottom: '108px'}"
|
||||
>
|
||||
<div>
|
||||
<iframe
|
||||
:src="currentSrc"
|
||||
frameborder="0"
|
||||
scrolling=""
|
||||
style="background-color:transparent; position: absolute; z-index: -1; width: 100%; height: 100%; top: 55px;left:0; scrolling=auto">
|
||||
</iframe>
|
||||
</div>
|
||||
</a-drawer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import md5 from 'md5'
|
||||
import {mapState} from 'vuex'
|
||||
import AccountSetting from "@/components/layout/account/setting"
|
||||
import {checkResponse} from "../../../assets/js/utils";
|
||||
import {_bindMail, _bindMobile, editPassword, getQqConnUrl} from "../../../api/mock";
|
||||
export default {
|
||||
name: "settingSecurity",
|
||||
components: {
|
||||
AccountSetting
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
form: this.$form.createForm(this),
|
||||
mobileForm: this.$form.createForm(this),
|
||||
mailForm: this.$form.createForm(this),
|
||||
errorTips: '',
|
||||
passwordInfo: {
|
||||
modalStatus: false,
|
||||
confirmLoading: false,
|
||||
modalTitle: '修改密码',
|
||||
okText: '保存',
|
||||
cancelText: '放弃',
|
||||
},
|
||||
mobileInfo: {
|
||||
modalStatus: false,
|
||||
confirmLoading: false,
|
||||
modalTitle: '修改手机',
|
||||
okText: '保存',
|
||||
cancelText: '放弃',
|
||||
state: {
|
||||
time: 60,
|
||||
smsSendBtn: false
|
||||
},
|
||||
},
|
||||
mailInfo: {
|
||||
modalStatus: false,
|
||||
confirmLoading: false,
|
||||
modalTitle: '修改邮箱',
|
||||
okText: '保存',
|
||||
cancelText: '放弃',
|
||||
state: {
|
||||
time: 60,
|
||||
smsSendBtn: false
|
||||
},
|
||||
},
|
||||
visible: false,
|
||||
currentSrc: "http://www.baidu.com/"
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
userInfo: state => state.userInfo,
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
editPassword(){
|
||||
this.passwordInfo.modalStatus = true;
|
||||
},
|
||||
editMobile(){
|
||||
this.mobileInfo.modalStatus = true;
|
||||
},
|
||||
editMail(){
|
||||
this.mailInfo.modalStatus = true;
|
||||
},
|
||||
editQQ(){
|
||||
getQqConnUrl().then(res => {
|
||||
debugger
|
||||
if (checkResponse(res, true)) {
|
||||
this.currentSrc = res.url;
|
||||
this.visible = true;
|
||||
}
|
||||
}).catch(res => {
|
||||
});
|
||||
},
|
||||
onClose() {
|
||||
this.visible = false
|
||||
},
|
||||
handlePasswordSubmit() {
|
||||
let app = this;
|
||||
this.form.validateFields(
|
||||
(err, values) => {
|
||||
if (!err) {
|
||||
let obj = app.form.getFieldsValue();
|
||||
if (obj.password.length < 6 || obj.newPassword.length < 6 || obj.confirmPassword.length < 6) {
|
||||
this.setErrorTips('密码必须包含6个字符');
|
||||
return false;
|
||||
}
|
||||
if (obj.newPassword != obj.confirmPassword) {
|
||||
this.setErrorTips('两次新密码不匹配');
|
||||
return false;
|
||||
}
|
||||
this.setErrorTips('');
|
||||
obj.id = app.userInfo.id;
|
||||
//obj.password = md5(obj.password);
|
||||
//obj.newPassword = md5(obj.newPassword);
|
||||
//obj.confirmPassword = md5(obj.confirmPassword);
|
||||
obj.type = 1;
|
||||
editPassword(obj).then(res => {
|
||||
app.loading = false;
|
||||
if (!checkResponse(res)) {
|
||||
return;
|
||||
}
|
||||
this.passwordInfo.modalStatus = false;
|
||||
app.form && app.form.resetFields();
|
||||
});
|
||||
}
|
||||
},
|
||||
);
|
||||
},
|
||||
handleMobileSubmit() {
|
||||
let app = this;
|
||||
this.mobileForm.validateFields(
|
||||
(err, values) => {
|
||||
if (!err) {
|
||||
let obj = app.mobileForm.getFieldsValue();
|
||||
this.setErrorTips('');
|
||||
obj.type = 2;
|
||||
app.mobileInfo.confirmLoading = true;
|
||||
_bindMobile(obj).then(res => {
|
||||
app.mobileInfo.confirmLoading = false;
|
||||
if (!checkResponse(res)) {
|
||||
return;
|
||||
}
|
||||
const obj = {
|
||||
userInfo: res.data.member,
|
||||
tokenList: 7033929
|
||||
};
|
||||
app.$store.dispatch('SET_LOGGED', obj);
|
||||
this.mobileInfo.modalStatus = false;
|
||||
app.mobileForm && app.mobileForm.resetFields();
|
||||
});
|
||||
}
|
||||
},
|
||||
);
|
||||
},
|
||||
handleMailSubmit() {
|
||||
let app = this;
|
||||
this.mailForm.validateFields(
|
||||
(err, values) => {
|
||||
if (!err) {
|
||||
let obj = app.mailForm.getFieldsValue();
|
||||
obj.type = 3;
|
||||
this.setErrorTips('');
|
||||
app.mailInfo.confirmLoading = true;
|
||||
_bindMail(obj).then(res => {
|
||||
app.mailInfo.confirmLoading = false;
|
||||
if (!checkResponse(res)) {
|
||||
return;
|
||||
}
|
||||
const obj = {
|
||||
userInfo: res.data.member,
|
||||
tokenList: 7033929
|
||||
};
|
||||
app.$store.dispatch('SET_LOGGED', obj);
|
||||
this.mailInfo.modalStatus = false;
|
||||
app.mailForm && app.mailForm.resetFields();
|
||||
});
|
||||
}
|
||||
},
|
||||
);
|
||||
},
|
||||
setErrorTips(content = '') {
|
||||
this.errorTips = content;
|
||||
},
|
||||
getCaptcha(e) {
|
||||
e.preventDefault();
|
||||
const app = this;
|
||||
|
||||
this.mobileForm.validateFields(['mobile'], {force: true}, (err, values) => {
|
||||
if (!err) {
|
||||
this.mobileInfo.state.smsSendBtn = true;
|
||||
|
||||
const interval = window.setInterval(() => {
|
||||
if (app.mobileInfo.state.time-- <= 0) {
|
||||
app.mobileInfo.state.time = 60;
|
||||
app.mobileInfo.state.smsSendBtn = false;
|
||||
window.clearInterval(interval)
|
||||
}
|
||||
}, 1000);
|
||||
|
||||
const hide = this.$message.loading('验证码发送中..', 0);
|
||||
getCaptcha(values.mobile)
|
||||
.then(res => {
|
||||
this.$message.destroy();
|
||||
|
||||
if (!checkResponse(res)) {
|
||||
return false;
|
||||
}
|
||||
let tips = '验证码获取成功';
|
||||
if (res.data) {
|
||||
tips += ',您的验证码为:' + res.data;
|
||||
}
|
||||
this.$notification['success']({
|
||||
message: '提示',
|
||||
description: tips,
|
||||
duration: 8,
|
||||
placement: 'bottomLeft'
|
||||
});
|
||||
})
|
||||
.catch(err => {
|
||||
// setTimeout(hide, 1);
|
||||
clearInterval(interval);
|
||||
app.mobileInfo.state.time = 60;
|
||||
app.mobileInfo.state.smsSendBtn = false;
|
||||
this.requestFailed(err)
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.account-setting-security {
|
||||
|
||||
.wrapper-main {
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
.setting-content {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
||||
.right {
|
||||
flex: 1 1 0;
|
||||
padding: 8px 40px;
|
||||
|
||||
.setting-info-title {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.setting-info {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
padding-top: 12px;
|
||||
|
||||
&-content {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.mobile-modal{
|
||||
.getCaptcha {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 40px;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -0,0 +1,93 @@
|
||||
<template>
|
||||
<div class="inviteFromLink" style="height: 100%;">
|
||||
<div class="content">
|
||||
<a-spin :spinning="loading">
|
||||
<a-card v-if="inviteLink" :title="`来自 ${inviteLink.member.name} 的邀请`">
|
||||
<div class="header">
|
||||
<span>
|
||||
{{inviteLink.member.name}} 邀请你
|
||||
<span v-if="inviteLink.invite_type == 'project'">加入项目「{{inviteLink.sourceDetail.name}}」</span>
|
||||
<span v-if="inviteLink.invite_type == 'organization'">加入组织「{{inviteLink.sourceDetail.name}}」</span>
|
||||
|
||||
</span>
|
||||
</div>
|
||||
<div class="member-info">
|
||||
<div class="avatar">
|
||||
<a-avatar size="large" :src="inviteLink.member.avatar"></a-avatar>
|
||||
</div>
|
||||
<div class="info">
|
||||
<p>{{inviteLink.member.name}}</p>
|
||||
<p class="muted">{{inviteLink.member.email}}</p>
|
||||
</div>
|
||||
</div>
|
||||
<a-button type="primary" block size="large" class="middle-btn" @click="acceptInvite">
|
||||
<span v-if="inviteLink.invite_type == 'project'">加入项目</span>
|
||||
<span v-if="inviteLink.invite_type == 'organization'">加入组织</span>
|
||||
</a-button>
|
||||
</a-card>
|
||||
</a-spin>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import {mapState} from 'vuex'
|
||||
import {checkResponse} from "@/assets/js/utils";
|
||||
import {inviteInfo} from "../../api/common/common";
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
inviteLink: undefined,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
userInfo: state => state.userInfo,
|
||||
})
|
||||
},
|
||||
created() {
|
||||
this.getInviteInfo();
|
||||
},
|
||||
methods: {
|
||||
getInviteInfo() {
|
||||
this.loading = true;
|
||||
inviteInfo(this.$route.params.code).then(res => {
|
||||
this.inviteLink = res.data;
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
acceptInvite() {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="less">
|
||||
.inviteFromLink {
|
||||
.content {
|
||||
width: 600px;
|
||||
margin: 50px auto;
|
||||
|
||||
.header {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.member-info {
|
||||
margin: 36px 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.avatar {
|
||||
margin-right: 12px;
|
||||
}
|
||||
|
||||
.info {
|
||||
p {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|