网盘web界面:

一、已完成:
			1.完成文件列表的展示、预览、删除、下载(多文件、多目录打包下载)
			2.文件、文件夹的上传,大文件、多文件上传、断点续传(在另一台电脑的浏览器可以继续)
			二、待完成:
			* 移动复制文件和文件夹(可拖动)
			* 文件和文件夹的分享,可设置连接时效
			* 文件的收藏和打标签(方便筛选)
			* 适配手机界面
This commit is contained in:
jmal 2020-02-09 16:02:02 +08:00
parent a0e60e903d
commit 8d34f727bc
143 changed files with 7123 additions and 0 deletions

14
.editorconfig Normal file
View File

@ -0,0 +1,14 @@
# http://editorconfig.org
root = true
[*]
charset = utf-8
indent_style = space
indent_size = 2
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
[*.md]
insert_final_newline = false
trim_trailing_whitespace = false

15
.env.development Normal file
View File

@ -0,0 +1,15 @@
# just a flag
ENV = 'development'
# base api
VUE_APP_BASE_API = '/dev-api'
FILE_SERVER_URL = 'http://localhost:10010/'
# vue-cli uses the VUE_CLI_BABEL_TRANSPILE_MODULES environment variable,
# to control whether the babel-plugin-dynamic-import-node plugin is enabled.
# It only does one thing by converting all import() to require().
# This configuration can significantly increase the speed of hot updates,
# when you have a large number of pages.
# Detail: https://github.com/vuejs/vue-cli/blob/dev/packages/@vue/babel-preset-app/index.js
VUE_CLI_BABEL_TRANSPILE_MODULES = true

6
.env.production Normal file
View File

@ -0,0 +1,6 @@
# just a flag
ENV = 'production'
# base api
VUE_APP_BASE_API = '/prod-api'

8
.env.staging Normal file
View File

@ -0,0 +1,8 @@
NODE_ENV = production
# just a flag
ENV = 'staging'
# base api
VUE_APP_BASE_API = '/stage-api'

4
.eslintignore Normal file
View File

@ -0,0 +1,4 @@
build/*.js
src/assets
public
dist

207
.eslintrc.js Normal file
View File

@ -0,0 +1,207 @@
module.exports = {
root: true,
parserOptions: {
parser: 'babel-eslint',
sourceType: 'module'
},
env: {
browser: true,
node: true,
es6: true,
},
extends: ['plugin:vue/recommended', 'eslint:recommended'],
// add your custom rules here
//it is base on https://github.com/vuejs/eslint-config-vue
rules: {
"vue/html-self-closing": ["error",{
"html": {
"void": "never",
"normal": "any",
"component": "any"
},
"svg": "always",
"math": "always"
}],
"vue/max-attributes-per-line": [2, {
"singleline": 10,
"multiline": {
"max": 1,
"allowFirstLine": false
}
}],
"vue/singleline-html-element-content-newline": "off",
"vue/multiline-html-element-content-newline":"off",
"vue/name-property-casing": ["error", "PascalCase"],
"vue/no-v-html": "off",
'accessor-pairs': 2,
'arrow-spacing': [2, {
'before': true,
'after': true
}],
'block-spacing': [2, 'always'],
'brace-style': [2, '1tbs', {
'allowSingleLine': true
}],
'camelcase': [0, {
'properties': 'always'
}],
'comma-dangle': [2, 'never'],
'comma-spacing': [2, {
'before': false,
'after': true
}],
'comma-style': [2, 'last'],
'constructor-super': 2,
'curly': [2, 'multi-line'],
'dot-location': [2, 'property'],
'eol-last': 2,
'eqeqeq': ["error", "always", {"null": "ignore"}],
'generator-star-spacing': [2, {
'before': true,
'after': true
}],
'handle-callback-err': [2, '^(err|error)$'],
'indent': [2, 2, {
'SwitchCase': 1
}],
'jsx-quotes': [2, 'prefer-single'],
'key-spacing': [2, {
'beforeColon': false,
'afterColon': true
}],
'keyword-spacing': [2, {
'before': true,
'after': true
}],
'new-cap': [2, {
'newIsCap': true,
'capIsNew': false
}],
'new-parens': 2,
'no-array-constructor': 2,
'no-caller': 2,
'no-console': 'off',
'no-class-assign': 2,
'no-cond-assign': 2,
'no-const-assign': 2,
'no-control-regex': 0,
'no-delete-var': 2,
'no-dupe-args': 2,
'no-dupe-class-members': 2,
'no-dupe-keys': 2,
'no-duplicate-case': 2,
'no-empty-character-class': 2,
'no-empty-pattern': 2,
'no-eval': 2,
'no-ex-assign': 2,
'no-extend-native': 2,
'no-extra-bind': 2,
'no-extra-boolean-cast': 2,
'no-extra-parens': [2, 'functions'],
'no-fallthrough': 2,
'no-floating-decimal': 2,
'no-func-assign': 2,
'no-implied-eval': 2,
'no-inner-declarations': [2, 'functions'],
'no-invalid-regexp': 2,
'no-irregular-whitespace': 2,
'no-iterator': 2,
'no-label-var': 2,
'no-labels': [2, {
'allowLoop': false,
'allowSwitch': false
}],
'no-lone-blocks': 2,
'no-mixed-spaces-and-tabs': 2,
'no-multi-spaces': 2,
'no-multi-str': 2,
'no-multiple-empty-lines': [2, {
'max': 1
}],
'no-native-reassign': 2,
'no-negated-in-lhs': 2,
'no-new-object': 2,
'no-new-require': 2,
'no-new-symbol': 2,
'no-new-wrappers': 2,
'no-obj-calls': 2,
'no-octal': 2,
'no-octal-escape': 2,
'no-path-concat': 2,
'no-proto': 2,
'no-redeclare': 2,
'no-regex-spaces': 2,
'no-return-assign': [2, 'except-parens'],
'no-self-assign': 2,
'no-self-compare': 2,
'no-sequences': 2,
'no-shadow-restricted-names': 2,
'no-spaced-func': 2,
'no-sparse-arrays': 2,
'no-this-before-super': 2,
'no-throw-literal': 2,
'no-trailing-spaces': 2,
'no-undef': 2,
'no-undef-init': 2,
'no-unexpected-multiline': 2,
'no-unmodified-loop-condition': 2,
'no-unneeded-ternary': [2, {
'defaultAssignment': false
}],
'no-unreachable': 2,
'no-unsafe-finally': 2,
'no-unused-vars': [2, {
'vars': 'all',
'args': 'none'
}],
'no-useless-call': 2,
'no-useless-computed-key': 2,
'no-useless-constructor': 2,
'no-useless-escape': 0,
'no-whitespace-before-property': 2,
'no-with': 2,
'one-var': [2, {
'initialized': 'never'
}],
'operator-linebreak': [2, 'after', {
'overrides': {
'?': 'before',
':': 'before'
}
}],
'padded-blocks': [2, 'never'],
'quotes': [2, 'single', {
'avoidEscape': true,
'allowTemplateLiterals': true
}],
'semi': [2, 'never'],
'semi-spacing': [2, {
'before': false,
'after': true
}],
'space-before-blocks': [2, 'always'],
'space-before-function-paren': [2, 'never'],
'space-in-parens': [2, 'never'],
'space-infix-ops': 2,
'space-unary-ops': [2, {
'words': true,
'nonwords': false
}],
'spaced-comment': [2, 'always', {
'markers': ['global', 'globals', 'eslint', 'eslint-disable', '*package', '!', ',']
}],
'template-curly-spacing': [2, 'never'],
'use-isnan': 2,
'valid-typeof': 2,
'wrap-iife': [2, 'any'],
'yield-star-spacing': [2, 'both'],
'yoda': [2, 'never'],
'prefer-const': 2,
'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0,
'object-curly-spacing': [2, 'always', {
objectsInObjects: false
}],
'array-bracket-spacing': [2, 'never']
}
}

16
.gitignore vendored Normal file
View File

@ -0,0 +1,16 @@
.DS_Store
node_modules/
dist/
npm-debug.log*
yarn-debug.log*
yarn-error.log*
package-lock.json
tests/**/coverage/
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln

5
.travis.yml Normal file
View File

@ -0,0 +1,5 @@
language: node_js
node_js: 10
script: npm run test
notifications:
email: false

View File

@ -1,2 +1,35 @@
# jmal-cloud-view
网盘web端
基于 [vue-element-admin](https://github.com/PanJiaChen/vue-admin-template)
```bash
# clone the project
git clone https://github.com/PanJiaChen/vue-admin-template.git
# enter the project directory
cd vue-admin-template
# install dependency
npm install
# develop
npm run dev
```
This will automatically open http://localhost:9528
## Browsers support
Modern browsers and Internet Explorer 10+.
| [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt="IE / Edge" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>IE / Edge | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png" alt="Firefox" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Firefox | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png" alt="Chrome" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Chrome | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png" alt="Safari" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Safari |
| --------- | --------- | --------- | --------- |
| IE10, IE11, Edge| last 2 versions| last 2 versions| last 2 versions
## License
[MIT](https://github.com/PanJiaChen/vue-admin-template/blob/master/LICENSE) license.
Copyright (c) 2017-present PanJiaChen

5
babel.config.js Normal file
View File

@ -0,0 +1,5 @@
module.exports = {
presets: [
'@vue/app'
]
}

35
build/index.js Normal file
View File

@ -0,0 +1,35 @@
const { run } = require('runjs')
const chalk = require('chalk')
const config = require('../vue.config.js')
const rawArgv = process.argv.slice(2)
const args = rawArgv.join(' ')
if (process.env.npm_config_preview || rawArgv.includes('--preview')) {
const report = rawArgv.includes('--report')
run(`vue-cli-service build ${args}`)
const port = 9526
const publicPath = config.publicPath
var connect = require('connect')
var serveStatic = require('serve-static')
const app = connect()
app.use(
publicPath,
serveStatic('./dist', {
index: ['index.html', '/']
})
)
app.listen(port, function () {
console.log(chalk.green(`> Preview at http://localhost:${port}${publicPath}`))
if (report) {
console.log(chalk.green(`> Report at http://localhost:${port}${publicPath}report.html`))
}
})
} else {
run(`vue-cli-service build ${args}`)
}

8
config/dev.env.js Normal file
View File

@ -0,0 +1,8 @@
// 'use strict'
// const merge = require('webpack-merge')
// const prodEnv = require('./prod.env')
//
// module.exports = merge(prodEnv, {
// NODE_ENV: '"development"',
// BASE_API: '"http://localhost:8088"'
// })

77
config/index.js Normal file
View File

@ -0,0 +1,77 @@
// 'use strict'
// // Template version: 1.3.1
// // see http://vuejs-templates.github.io/webpack for documentation.
//
// const path = require('path')
// module.exports = {
// dev: {
//
// // Paths
// assetsSubDirectory: 'static',
// assetsPublicPath: '/',
// proxyTable: {
// '/api': {
// target: 'http://localhost:8088',
// // target: 'http://www.twioes.com:18888',
// changeOrigin: true,
// pathRewrite: {
// '^/api': ''
// }
// }
//
// },
//
// // Various Dev Server settings
// host: 'localhost', // can be overwritten by process.env.HOST
// port: 8080, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined
// autoOpenBrowser: false,
// errorOverlay: true,
// notifyOnErrors: true,
// poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions-
//
// /**
// * Source Maps
// */
//
// // https://webpack.js.org/configuration/devtool/#development
// devtool: 'cheap-module-eval-source-map',
//
// // If you have problems debugging vue-files in devtools,
// // set this to false - it *may* help
// // https://vue-loader.vuejs.org/en/options.html#cachebusting
// cacheBusting: true,
//
// cssSourceMap: true
// },
//
// build: {
// // Template for index.html
// index: path.resolve(__dirname, '../dist/index.html'),
//
// // Paths
// assetsRoot: path.resolve(__dirname, '../dist'),
// assetsSubDirectory: 'static',
// assetsPublicPath: '/',
//
// /**
// * Source Maps
// */
//
// productionSourceMap: true,
// // https://webpack.js.org/configuration/devtool/#production
// devtool: '#source-map',
//
// // Gzip off by default as many popular static hosts such as
// // Surge or Netlify already gzip all static assets for you.
// // Before setting to `true`, make sure to:
// // npm install --save-dev compression-webpack-plugin
// productionGzip: false,
// productionGzipExtensions: ['js', 'css'],
//
// // Run the build command with an extra argument to
// // View the bundle analyzer report after build finishes:
// // `npm run build --report`
// // Set to `true` or `false` to always turn it on or off
// bundleAnalyzerReport: process.env.npm_config_report
// }
// }

5
config/prod.env.js Normal file
View File

@ -0,0 +1,5 @@
// 'use strict'
// module.exports = {
// NODE_ENV: '"production"',
// BASE_API:'"http://10.10.1.130:10000"'
// }

24
jest.config.js Normal file
View File

@ -0,0 +1,24 @@
module.exports = {
moduleFileExtensions: ['js', 'jsx', 'json', 'vue'],
transform: {
'^.+\\.vue$': 'vue-jest',
'.+\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2)$':
'jest-transform-stub',
'^.+\\.jsx?$': 'babel-jest'
},
moduleNameMapper: {
'^@/(.*)$': '<rootDir>/src/$1'
},
snapshotSerializers: ['jest-serializer-vue'],
testMatch: [
'**/tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)'
],
collectCoverageFrom: ['src/utils/**/*.{js,vue}', '!src/utils/auth.js', '!src/utils/request.js', 'src/components/**/*.{js,vue}'],
coverageDirectory: '<rootDir>/tests/unit/coverage',
// 'collectCoverage': true,
'coverageReporters': [
'lcov',
'text-summary'
],
testURL: 'http://localhost/'
}

9
jsconfig.json Normal file
View File

@ -0,0 +1,9 @@
{
"compilerOptions": {
"baseUrl": "./",
"paths": {
"@/*": ["src/*"]
}
},
"exclude": ["node_modules", "dist"]
}

67
mock/index.js Normal file
View File

@ -0,0 +1,67 @@
import Mock from 'mockjs'
import { param2Obj } from '../src/utils'
import user from './user'
import table from './table'
const mocks = [
...user,
...table
]
// for front mock
// please use it cautiously, it will redefine XMLHttpRequest,
// which will cause many of your third-party libraries to be invalidated(like progress event).
export function mockXHR() {
// mock patch
// https://github.com/nuysoft/Mock/issues/300
Mock.XHR.prototype.proxy_send = Mock.XHR.prototype.send
Mock.XHR.prototype.send = function() {
if (this.custom.xhr) {
this.custom.xhr.withCredentials = this.withCredentials || false
if (this.responseType) {
this.custom.xhr.responseType = this.responseType
}
}
this.proxy_send(...arguments)
}
function XHR2ExpressReqWrap(respond) {
return function(options) {
let result = null
if (respond instanceof Function) {
const { body, type, url } = options
// https://expressjs.com/en/4x/api.html#req
result = respond({
method: type,
body: JSON.parse(body),
query: param2Obj(url)
})
} else {
result = respond
}
return Mock.mock(result)
}
}
for (const i of mocks) {
Mock.mock(new RegExp(i.url), i.type || 'get', XHR2ExpressReqWrap(i.response))
}
}
// for mock server
const responseFake = (url, type, respond) => {
return {
url: new RegExp(`${process.env.VUE_APP_BASE_API}${url}`),
type: type || 'get',
response(req, res) {
console.log('request invoke:' + req.path)
res.json(Mock.mock(respond instanceof Function ? respond(req, res) : respond))
}
}
}
export default mocks.map(route => {
return responseFake(route.url, route.type, route.response)
})

68
mock/mock-server.js Normal file
View File

@ -0,0 +1,68 @@
const chokidar = require('chokidar')
const bodyParser = require('body-parser')
const chalk = require('chalk')
const path = require('path')
const mockDir = path.join(process.cwd(), 'mock')
function registerRoutes(app) {
let mockLastIndex
const { default: mocks } = require('./index.js')
for (const mock of mocks) {
app[mock.type](mock.url, mock.response)
mockLastIndex = app._router.stack.length
}
const mockRoutesLength = Object.keys(mocks).length
return {
mockRoutesLength: mockRoutesLength,
mockStartIndex: mockLastIndex - mockRoutesLength
}
}
function unregisterRoutes() {
Object.keys(require.cache).forEach(i => {
if (i.includes(mockDir)) {
delete require.cache[require.resolve(i)]
}
})
}
module.exports = app => {
// es6 polyfill
require('@babel/register')
// parse app.body
// https://expressjs.com/en/4x/api.html#req.body
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({
extended: true
}))
const mockRoutes = registerRoutes(app)
var mockRoutesLength = mockRoutes.mockRoutesLength
var mockStartIndex = mockRoutes.mockStartIndex
// watch files, hot reload mock server
chokidar.watch(mockDir, {
ignored: /mock-server/,
ignoreInitial: true
}).on('all', (event, path) => {
if (event === 'change' || event === 'add') {
try {
// remove mock routes stack
app._router.stack.splice(mockStartIndex, mockRoutesLength)
// clear routes cache
unregisterRoutes()
const mockRoutes = registerRoutes(app)
mockRoutesLength = mockRoutes.mockRoutesLength
mockStartIndex = mockRoutes.mockStartIndex
console.log(chalk.magentaBright(`\n > Mock Server hot reload success! changed ${path}`))
} catch (error) {
console.log(chalk.redBright(error))
}
}
})
}

29
mock/table.js Normal file
View File

@ -0,0 +1,29 @@
import Mock from 'mockjs'
const data = Mock.mock({
'items|30': [{
id: '@id',
title: '@sentence(10, 20)',
'status|1': ['published', 'draft', 'deleted'],
author: 'name',
display_time: '@datetime',
pageviews: '@integer(300, 5000)'
}]
})
export default [
{
url: '/vue-admin-template/table/list',
type: 'get',
response: config => {
const items = data.items
return {
code: 20000,
data: {
total: items.length,
items: items
}
}
}
}
]

84
mock/user.js Normal file
View File

@ -0,0 +1,84 @@
const tokens = {
admin: {
token: 'admin-token'
},
editor: {
token: 'editor-token'
}
}
const users = {
'admin-token': {
roles: ['admin'],
introduction: 'I am a super administrator',
avatar: 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif',
name: 'Super Admin'
},
'editor-token': {
roles: ['editor'],
introduction: 'I am an editor',
avatar: 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif',
name: 'Normal Editor'
}
}
export default [
// user login
{
url: '/vue-admin-template/user/login',
type: 'post',
response: config => {
const { username } = config.body
const token = tokens[username]
// mock error
if (!token) {
return {
code: 60204,
message: 'Account and password are incorrect.'
}
}
return {
code: 20000,
data: token
}
}
},
// get user info
{
url: '/vue-admin-template/user/info\.*',
type: 'get',
response: config => {
const { token } = config.query
const info = users[token]
// mock error
if (!info) {
return {
code: 50008,
message: 'Login failed, unable to get user details.'
}
}
return {
code: 20000,
data: info
}
}
},
// user logout
{
url: '/vue-admin-template/user/logout',
type: 'post',
response: _ => {
return {
code: 20000,
data: 'success'
}
}
}
]

77
package.json Normal file
View File

@ -0,0 +1,77 @@
{
"name": "vue-admin-template",
"version": "4.2.1",
"description": "A vue admin template with Element UI & axios & iconfont & permission control & lint",
"author": "Pan <panfree23@gmail.com>",
"license": "MIT",
"scripts": {
"dev": "vue-cli-service serve",
"build:prod": "vue-cli-service build",
"build:stage": "vue-cli-service build --mode staging",
"preview": "node build/index.js --preview",
"lint": "eslint --ext .js,.vue src",
"test:unit": "jest --clearCache && vue-cli-service test:unit",
"test:ci": "npm run lint && npm run test:unit",
"svgo": "svgo -f src/icons/svg --config=src/icons/svgo.yml"
},
"dependencies": {
"@ionic/core": "^4.11.10",
"@ionic/vue": "0.0.4",
"axios": "0.18.1",
"e-vue-contextmenu": "^0.1.3",
"element-ui": "2.13.0",
"jquery": "^1.12.4",
"js-cookie": "2.2.0",
"lib-flexible": "^0.3.2",
"normalize.css": "7.0.0",
"nprogress": "0.2.0",
"path-to-regexp": "2.4.0",
"sortablejs": "^1.10.2",
"spark-md5": "^3.0.0",
"vonic": "^1.1.3",
"vue": "2.6.10",
"vue-router": "3.0.6",
"vue-simple-uploader": "^0.7.4",
"vuex": "3.1.0",
"we-vue": "^2.3.3",
"webuploader": "^0.1.8",
"weui": "^2.1.4",
"weui.js": "^1.2.1"
},
"devDependencies": {
"@babel/core": "7.0.0",
"@babel/register": "7.0.0",
"@vue/cli-plugin-babel": "3.6.0",
"@vue/cli-plugin-eslint": "^3.9.1",
"@vue/cli-plugin-unit-jest": "3.6.3",
"@vue/cli-service": "3.6.0",
"@vue/test-utils": "1.0.0-beta.29",
"autoprefixer": "^9.5.1",
"babel-core": "7.0.0-bridge.0",
"babel-eslint": "10.0.1",
"babel-jest": "23.6.0",
"chalk": "2.4.2",
"connect": "3.6.6",
"eslint": "5.15.3",
"eslint-plugin-vue": "5.2.2",
"html-webpack-plugin": "3.2.0",
"mockjs": "1.0.1-beta3",
"node-sass": "^4.9.0",
"runjs": "^4.3.2",
"sass-loader": "^7.1.0",
"script-ext-html-webpack-plugin": "2.1.3",
"script-loader": "0.7.2",
"serve-static": "^1.13.2",
"svg-sprite-loader": "4.1.3",
"svgo": "1.2.2",
"vue-template-compiler": "2.6.10"
},
"engines": {
"node": ">=8.9",
"npm": ">= 3.0.0"
},
"browserslist": [
"> 1%",
"last 2 versions"
]
}

8
postcss.config.js Normal file
View File

@ -0,0 +1,8 @@
// https://github.com/michael-ciniawsky/postcss-load-config
module.exports = {
'plugins': {
// to edit target browsers: use "browserslist" field in package.json
'autoprefixer': {}
}
}

BIN
public/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

17
public/index.html Normal file
View File

@ -0,0 +1,17 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<link rel="icon" href="<%= BASE_URL %>netdisk.png">
<title><%= webpackConfig.name %></title>
</head>
<body>
<noscript>
<strong>We're sorry but <%= webpackConfig.name %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>

BIN
public/netdisk.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

31
src/App.vue Normal file
View File

@ -0,0 +1,31 @@
<template>
<div id="app">
<router-view />
<!-- 将上传组件全局注册 -->
<global-uploader></global-uploader>
</div>
</template>
<script>
import globalUploader from '@/components/SimpleUploader/globalUploader.vue'
export default {
name: 'App',
components: {
globalUploader
},
watch: {
$route: function(to, from) {
const path = to.path
if (path.indexOf('/login') < 0) {
if (path.indexOf('_m') > 0 && this.$pc) {
this.$router.push(path.split('_m')[0])
} else if (path.indexOf('_m') < 0 && !this.$pc) {
this.$router.push(path + '_m')
}
}
}
}
}
</script>

9
src/api/table.js Normal file
View File

@ -0,0 +1,9 @@
import request from '@/utils/request'
export function getList(params) {
return request({
url: '/vue-admin-template/table/list',
method: 'get',
params
})
}

62
src/api/upload-api.js Normal file
View File

@ -0,0 +1,62 @@
import request from '@/utils/request'
const qs = require('qs')
export default {
// 上传
simpleUploadURL: process.env.VUE_APP_BASE_API + '/upload',
// 合并
mergeSimpleUpload: function(params) {
return request({
url: 'merge',
method: 'post',
params
})
},
uploadFolder: function(params) {
return request({
url: 'upload-folder',
method: 'post',
params,
paramsSerializer: function(params) {
return qs.stringify(params, { arrayFormat: 'repeat' })
}
})
},
// 文件列表
fileList: function(params) {
return request({
url: 'list',
method: 'get',
params
})
},
// 收藏/取消收藏
favoriteUrl: function(params) {
const isFavorite = params.isFavorite
if (isFavorite) {
return request({
url: 'favorite',
method: 'post',
params
})
} else {
return request({
url: 'unFavorite',
method: 'post',
params
})
}
},
// 删除
delete: function(params) {
return request({
url: 'delete',
method: 'delete',
params,
paramsSerializer: function(params) {
return qs.stringify(params, { arrayFormat: 'repeat' })
}
})
}
}

24
src/api/user.js Normal file
View File

@ -0,0 +1,24 @@
import request from '@/utils/request'
export function login(data) {
return request({
url: 'login',
method: 'post',
data
})
}
export function getInfo(token) {
return request({
url: 'user/userInfo',
method: 'get',
params: { token }
})
}
export function logout() {
return request({
url: 'logout',
method: 'get'
})
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

3
src/assets/js/bus.js Executable file
View File

@ -0,0 +1,3 @@
import Vue from 'vue';
export default new Vue();

10
src/assets/js/config.js Executable file
View File

@ -0,0 +1,10 @@
export const ACCEPT_CONFIG = {
image: ['.png', '.jpg', '.jpeg', '.gif', '.bmp'],
video: ['.mp4', '.rmvb', '.mkv', '.wmv', '.flv'],
document: ['.doc', '.docx', '.xls', '.xlsx', '.ppt', '.pptx', '.pdf', '.txt', '.tif', '.tiff'],
audio: ['.mp3'],
application: ['.zip', '.rar'],
getAll(){
return [...this.image, ...this.video, ...this.document, ...this.audio, ...this.application]
},
};

View File

@ -0,0 +1,77 @@
<template>
<el-breadcrumb class="app-breadcrumb" separator="/">
<transition-group name="breadcrumb">
<el-breadcrumb-item v-for="(item,index) in levelList" :key="item.path">
<span v-if="item.redirect==='noRedirect'||index==levelList.length-1" class="no-redirect">{{ item.meta.title }}</span>
<a v-else @click.prevent="handleLink(item)">{{ item.meta.title }}</a>
</el-breadcrumb-item>
</transition-group>
</el-breadcrumb>
</template>
<script>
import pathToRegexp from 'path-to-regexp'
export default {
data() {
return {
levelList: null
}
},
watch: {
$route() {
this.getBreadcrumb()
}
},
created() {
this.getBreadcrumb()
},
methods: {
getBreadcrumb() {
// only show routes with meta.title
let matched = this.$route.matched.filter(item => item.meta && item.meta.title)
const first = matched[0]
if (!this.isDashboard(first)) {
matched = [{ path: '/_m', meta: { title: '' }}].concat(matched)
}
this.levelList = matched.filter(item => item.meta && item.meta.title && item.meta.breadcrumb !== false)
},
isDashboard(route) {
const name = route && route.name
if (!name) {
return false
}
return name.trim().toLocaleLowerCase() === 'Dashboard'.toLocaleLowerCase()
},
pathCompile(path) {
// To solve this problem https://github.com/PanJiaChen/vue-element-admin/issues/561
const { params } = this.$route
var toPath = pathToRegexp.compile(path)
return toPath(params)
},
handleLink(item) {
const { redirect, path } = item
if (redirect) {
this.$router.push(redirect)
return
}
this.$router.push(this.pathCompile(path))
}
}
}
</script>
<style lang="scss" scoped>
.app-breadcrumb.el-breadcrumb {
display: inline-block;
font-size: 14px;
line-height: 50px;
margin-left: 8px;
.no-redirect {
color: #97a8be;
cursor: text;
}
}
</style>

View File

@ -0,0 +1,44 @@
<template>
<div style="padding: 0 15px;" @click="toggleClick">
<svg
:class="{'is-active':isActive}"
class="hamburger"
viewBox="0 0 1024 1024"
xmlns="http://www.w3.org/2000/svg"
width="64"
height="64"
>
<path d="M408 442h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8zm-8 204c0 4.4 3.6 8 8 8h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56zm504-486H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 632H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM142.4 642.1L298.7 519a8.84 8.84 0 0 0 0-13.9L142.4 381.9c-5.8-4.6-14.4-.5-14.4 6.9v246.3a8.9 8.9 0 0 0 14.4 7z" />
</svg>
</div>
</template>
<script>
export default {
name: 'Hamburger',
props: {
isActive: {
type: Boolean,
default: false
}
},
methods: {
toggleClick() {
this.$emit('toggleClick')
}
}
}
</script>
<style scoped>
.hamburger {
display: inline-block;
vertical-align: middle;
width: 20px;
height: 20px;
}
.hamburger.is-active {
transform: rotate(180deg);
}
</style>

View File

@ -0,0 +1,489 @@
<template>
<div id="global-uploader">
<!-- 上传 -->
<uploader
ref="uploader"
:options="options"
:auto-start="false"
class="uploader-app"
@files-added="onFilesAdded"
@file-success="onFileSuccess"
@file-progress="onFileProgress"
@file-error="onFileError"
>
<uploader-unsupport></uploader-unsupport>
<uploader-btn id="global-uploader-btn" ref="uploadBtn" :attrs="attrs">选择文件</uploader-btn>
<uploader-btn id="folder-uploader-btn" ref="folderBtn" :directory="true">选择文件夹</uploader-btn>
<uploader-list v-show="panelShow">
<div slot-scope="props" class="file-panel" :class="{'collapse': collapse}">
<div class="file-title">
<h2 class="files-title">文件列表</h2>
<div class="operate">
<el-button type="text" class="button-collapse" :title="collapse ? '展开':'折叠' " @click="fileListShow">
<i class="iconfont" :class="collapse ? 'el-icon-circle-plus-outline': 'el-icon-remove-outline'"></i>
</el-button>
<el-button type="text" class="button-collapse" title="关闭" @click="close">
<i class="iconfont el-icon-circle-close"></i>
</el-button>
</div>
</div>
<ul class="file-list">
<li v-for="file in props.fileList" :key="file.id">
<uploader-file ref="files" :class="'file_' + file.id" :file="file" :list="true"></uploader-file>
</li>
<div v-if="!props.fileList.length" class="no-file"><i class="iconfont icon-empty-file"></i> 暂无待上传文件</div>
</ul>
</div>
</uploader-list>
</uploader>
</div>
</template>
<script>
/**
* 全局上传插件
* 调用方法:Bus.$emit('openUploader', {}) 打开文件选择框,参数为需要传递的额外参数
* 监听函数:Bus.$on('fileAdded', fn); 文件选择后的回调
* Bus.$on('fileSuccess', fn); 文件上传成功的回调
*/
// import { ACCEPT_CONFIG } from '@/assets/js/config'
import Bus from '@/assets/js/bus'
import $ from 'jquery'
import SparkMD5 from 'spark-md5'
import api from '@/api/upload-api'
export default {
components: {},
data($this) {
return {
username: this.$store.state.user.name,
options: {
target: api.simpleUploadURL,
chunkSize: 5 * 1024 * 1024,
maxChunkRetries: 1, // 最大重试次数
simultaneousUploads: 6, // 并发上传数
testChunks: true, // 是否开启服务器分片校验
// 服务器分片校验函数,秒传及断点续传基础
checkChunkUploadedByResponse: function(chunk, message) {
const objMessage = JSON.parse(message)
const res = objMessage.data
if (res.pass) {
// 秒传
return true
}
// 断点续传
return (res.resume || []).indexOf(chunk.offset + 1) >= 0
},
headers: {
'jmal-token': $this.$store.state.user.token
},
query() {}
},
attrs: {
// accept: ACCEPT_CONFIG.getAll()
accept: '*'
},
panelShow: false, // 选择文件后,展示上传panel
collapse: false
}
},
computed: {
// Uploader实例
uploader() {
return this.$refs.uploader.uploader
}
},
watch: {},
mounted() {
Bus.$on('openUploader', query => {
this.params = query || {}
if (this.$refs.uploadBtn) {
$('#global-uploader-btn').click()
}
})
Bus.$on('uploadFolder', query => {
this.params = query || {}
if (this.$refs.folderBtn) {
$('#folder-uploader-btn').click()
}
})
},
destroyed() {
Bus.$off('openUploader')
Bus.$off('uploadFolder')
},
methods: {
// onFileAdded(file) {
// console.log('file', file)
// console.log(this.uploader.filePaths)
// this.panelShow = true
// this.computeMD5(file)
// Bus.$emit('fileAdded')
// },
onFilesAdded(files) {
console.log('files', files)
const filePaths = this.uploader.filePaths
const paths = Object.keys(filePaths)
if (paths.length > 0) {
paths.forEach(path => {
const folder = filePaths[path]
// 上传文件夹
api.uploadFolder({
isFolder: true,
folderPath: folder.parent.path,
filename: folder.name,
currentDirectory: this.params.currentDirectory,
username: this.params.username,
userId: this.params.userId
}).then(() => {
console.log('上传文件' + folder.name + '夹成功!', folder)
this.getFileList()
}).catch(e => {})
})
}
files.forEach(file => {
// 上传文件
console.log('上传->', file.name)
this.panelShow = true
this.computeMD5(file)
Bus.$emit('fileAdded')
})
},
onFileProgress(rootFile, file, chunk) {
// console.log(`上传中 ${file.name},chunk:${chunk.startByte / 1024 / 1024} ~ ${chunk.endByte / 1024 / 1024}`)
},
onFileSuccess(rootFile, file, response) {
const res = JSON.parse(response)
const data = res.data
// 服务器自定义的错误(即虽返回200,但是是错误的情况),这种错误是Uploader无法拦截的
if (!data.upload) {
// this.$message({ message: res.message, type: 'error' })
// 文件状态设为“失败”
this.statusSet(file.id, 'failed')
return
} else {
this.statusSet(file.id, 'success')
}
// 如果服务端返回需要合并
if (data.merge) {
// 文件状态设为“合并中”
this.statusSet(file.id, 'merging')
api.mergeSimpleUpload({
filename: file.name,
relativePath: file.relativePath,
identifier: file.uniqueIdentifier,
currentDirectory: this.params.currentDirectory,
username: this.params.username,
userId: this.params.userId,
totalSize: file.size,
isFolder: file.isFolder
}).then(() => {
// console.log('文件合并成功', res)
// 文件合并成功
Bus.$emit('fileSuccess')
this.statusRemove(file.id)
this.statusSet(file.id, 'success')
// file.removeFile(file)
}).catch(e => {})
// 不需要合并
} else {
Bus.$emit('fileSuccess')
// 完成后从文件列表移除
// file.removeFile(file)
// console.log('上传成功')
}
if (file.parent == null) {
this.close()
}
},
onFileError(rootFile, file, response) {
this.$message({
message: response,
type: 'error'
})
},
/**
* 计算md5,实现断点续传及秒传
* @param file
*/
computeMD5(file) {
const fileReader = new FileReader()
// const time = new Date().getTime()
const blobSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice
let currentChunk = 0
const chunkSize = 10 * 1024 * 1024
const chunks = Math.ceil(file.size / chunkSize)
const spark = new SparkMD5.ArrayBuffer()
// 文件状态设为"计算MD5"
this.statusSet(file.id, 'md5')
file.pause()
loadNext()
fileReader.onload = e => {
spark.append(e.target.result)
if (currentChunk < chunks) {
currentChunk++
loadNext()
// 实时展示MD5的计算进度
this.$nextTick(() => {
$(`.myStatus_${file.id}`).text('校验MD5 ' + ((currentChunk / chunks) * 100).toFixed(0) + '%')
})
} else {
const md5 = spark.end()
this.computeMD5Success(md5, file)
// console.log(`MD5计算完毕:${file.name} \nMD5:${md5} \n分片:${chunks} 大小:${file.size} 用时:${new Date().getTime() - time} ms`)
}
}
fileReader.onerror = function() {
this.error(`文件${file.name}读取出错,请检查该文件`)
file.cancel()
}
function loadNext() {
const start = currentChunk * chunkSize
const end = ((start + chunkSize) >= file.size) ? file.size : start + chunkSize
fileReader.readAsArrayBuffer(blobSlice.call(file.file, start, end))
}
},
computeMD5Success(md5, file) {
// 将自定义参数直接加载uploader实例的opts上
// const fileName = file.name
// const suffix = fileName.substring(fileName.lastIndexOf('.'), fileName.length)// 后缀名
Object.assign(this.uploader.opts, {
query: {
isFolder: false,
...this.params
}
})
file.uniqueIdentifier = md5
file.resume()
this.statusRemove(file.id)
},
fileListShow() {
const $list = $('#global-uploader .file-list')
if ($list.is(':visible')) {
$list.slideUp()
this.collapse = true
} else {
$list.slideDown()
this.collapse = false
}
},
close() {
this.uploader.cancel()
this.panelShow = false
},
/**
* 新增的自定义的状态: 'md5'、'transcoding'、'failed'
* @param id
* @param status
*/
statusSet(id, status) {
const statusMap = {
md5: {
text: '校验MD5',
bgc: '#fff'
},
merging: {
text: '合并中',
bgc: '#e2eeff'
},
transcoding: {
text: '转码中',
bgc: '#e2eeff'
},
failed: {
text: '上传失败',
bgc: '#e2eeff'
},
success: {
text: '上传成功',
bgc: '#e2eeff'
}
}
this.$nextTick(() => {
$(`<p class="myStatus_${id}"></p>`).appendTo(`.file_${id} .uploader-file-status`).css({
'position': 'absolute',
'top': '-14px',
'font-size': '13px',
'left': '0',
'right': '0',
'bottom': '0',
'zIndex': '1',
'backgroundColor': statusMap[status].bgc
}).text(statusMap[status].text)
})
},
statusRemove(id) {
this.$nextTick(() => {
$(`.myStatus_${id}`).remove()
})
},
error(msg) {
this.$notify({
title: '错误',
message: msg,
type: 'error',
duration: 2000
})
}
}
}
</script>
<style scoped lang="scss">
#global-uploader {
position: fixed;
z-index: 20;
right: 15px;
bottom: 15px;
.uploader-app {
width: 720px;
}
.file-panel {
background-color: #fff;
border: 1px solid #e2e2e2;
border-radius: 7px 7px 0 0;
box-shadow: 0 0 10px rgba(0, 0, 0, .2);
ul{
white-space: nowrap;
-webkit-overflow-scrolling: touch;
overflow-x: auto;
overflow-y: hidden;
padding: 0 0.1rem;
margin-bottom: -.2rem;
overflow: -moz-scrollbars-none;
overflow: -moz-scrollbars-none;
}
ul::-webkit-scrollbar{
display: none;
}
.file-title {
display: flex;
/*line-height: 8px;*/
padding: 0 10px;
border-bottom: 1px solid #ddd;
.files-title {
margin-left: 3%;
height: 20px;
line-height: 20px;
}
.operate {
flex: 1;
text-align: right;
.button-collapse {
padding: 16px 5px;
font-size: 25px;
margin-left: 0;
}
}
}
.file-list {
position: relative;
max-height: 300px;
/*height: 49px;*/
overflow-x: hidden;
list-style-type: none;
overflow-y: auto;
background-color: #fff;
padding: 0;
margin: 0;
> li {
background-color: #fff;
}
}
&.collapse {
.file-title {
background-color: #E7ECF2;
}
}
}
.no-file {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-size: 16px;
}
/deep/.uploader-file-icon {
&:before {
content: '' !important;
}
background: url(./images/file.svg);
&[icon=image] {
background: url(./images/image.svg);
}
&[icon=video] {
background: url(./images/video.svg);
}
&[icon=document] {
background: url(./images/docment.svg);
}
&[icon=audio] {
background: url(./images/audio.svg);
}
}
/deep/.uploader-file-actions > span {
margin-right: 6px;
}
}
/deep/.uploader-file-status {
width: 32%;
text-indent: 20px;
}
/deep/.uploader-file-meta {
width: 0%;
}
/deep/.uploader-file-icon {
width: 32px;
height: 32px;
display: inline-block;
vertical-align: top;
margin-top: 8px;
margin-right: 8px;
}
/deep/.uploader-file-actions>span {
margin-right: 6px;
margin-left: 8px;
}
/* 隐藏上传按钮 */
#global-uploader-btn {
position: absolute;
clip: rect(0, 0, 0, 0);
}
#folder-uploader-btn {
position: absolute;
clip: rect(0, 0, 0, 0);
}
</style>

View File

@ -0,0 +1 @@
<svg t="1580291103597" class="icon" viewBox="0 0 1179 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="19622" width="32" height="32"><path d="M846.057944 0H347.481672c-52.474576 0-95.186441 46.779661-95.18644 104.40678v708.474576c-24.40678-36.338983-65.898305-60.338983-112.81356-60.338983-74.847458 0-135.728814 60.881356-135.728813 135.728813 0 74.847458 60.881356 135.728814 135.728813 135.728814 69.423729 0 126.915254-52.474576 134.779661-119.864407h0.949153V294.644068h643.118644v518.101695c-24.40678-36.338983-65.898305-60.338983-112.813559-60.338983-74.847458 0-135.728814 60.881356-135.728814 135.728813 0 74.847458 60.881356 135.728814 135.728814 135.728814 69.423729 0 126.915254-52.474576 134.779661-119.864407h0.949152V104.40678c0-57.491525-42.711864-104.40678-95.18644-104.40678zM139.481672 1001.084746c-62.237288 0-112.813559-50.576271-112.813559-112.81356 0-62.237288 50.576271-112.813559 112.813559-112.813559 62.237288 0 112.813559 50.576271 112.81356 112.813559 0 62.101695-50.576271 112.813559-112.81356 112.81356z m666.033899 0c-62.237288 0-112.813559-50.576271-112.81356-112.81356 0-62.237288 50.711864-112.813559 112.81356-112.813559 62.237288 0 112.813559 50.576271 112.813559 112.813559 0 62.101695-50.576271 112.813559-112.813559 112.81356zM275.210486 265.627119V104.40678c0-44.881356 32.40678-81.491525 72.271186-81.491526h498.576272c39.864407 0 72.271186 36.610169 72.271186 81.491526v161.220339H275.210486z" fill="#040000" p-id="19623"></path><path d="M920.363028 265.627119V126.508475c0-57.762712-34.847458-104.542373-77.830508-104.542373H378.53252c-42.983051 0-77.830508 46.779661-77.830509 104.542373v139.118644h619.661017z" fill="#E35F3D" p-id="19624"></path><path d="M256.363028 895.050847c0 60.745763-49.220339 109.966102-109.966101 109.966102S36.430825 955.79661 36.430825 895.050847c0-60.610169 49.220339-109.966102 109.966102-109.966101s109.966102 49.355932 109.966101 109.966101zM920.363028 895.322034c0 58.847458-47.59322 106.440678-106.440678 106.440678-58.711864 0-106.305085-47.59322-106.305084-106.440678 0-58.711864 47.59322-106.305085 106.305084-106.305085 58.847458-0.135593 106.440678 47.59322 106.440678 106.305085z" fill="#EEBF2F" p-id="19625"></path><path d="M857.71896 24c-91.79661 145.084746-253.559322 241.627119-437.830508 241.627119h500.610169V126.508475c4.338983-53.423729-20.610169-93.288136-62.779661-102.508475z" fill="#BD3A1F" p-id="19626"></path></svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

@ -0,0 +1 @@
<svg t="1580291492423" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="29799" width="32" height="32"><path d="M281.086 0l-175.08 117.562v831.146h734.34V0h-559.26z m545.648 935.096H119.62V124.82l165.614-111.208h541.5v921.484z" fill="#4B555F" p-id="29800"></path><path d="M279.366 1.156L109.02 115.542l3.558 12.454 115.656 3.996 6.412-3.948 54.69-118.38-9.97-8.508z m-55.182 117.07l-90.112-3.11L266.8 25.994l-42.616 92.232z" fill="#4B555F" p-id="29801"></path><path d="M207.626 658.778h191.498v177.038h-191.498z" fill="#F58E70" p-id="29802"></path><path d="M473.178 651.97h279.444v13.614H473.178zM473.178 707.886h279.444v13.614H473.178zM473.178 763.804h279.444v13.614H473.178zM473.178 819.722h279.444v13.614H473.178z" fill="#4B555F" p-id="29803"></path><path d="M207.626 262.022h544.998v58.442H207.626z" fill="#FFD351" p-id="29804"></path><path d="M207.628 381.704h544.996v13.614H207.628zM207.628 447.77h544.996v13.614H207.628zM207.628 513.836h544.996v13.614H207.628zM207.628 579.902h544.996v13.614H207.628zM207.628 195.23h544.996v13.614H207.628zM599.316 139.876h13.614v-13.614h-13.614v13.614z m-81.684 0h13.614v-13.614h-13.614v13.614z m27.228 0h13.614v-13.614h-13.614v13.614z m-81.684 0h13.614v-13.614h-13.614v13.614z m27.228 0h13.614v-13.614h-13.614v13.614z m81.684 0h13.614v-13.614h-13.614v13.614z m136.14 0h13.614v-13.614h-13.614v13.614z m27.228-13.612v13.614h13.614v-13.614h-13.614zM681 139.876h13.614v-13.614H681v13.614z m-54.456 0h13.614v-13.614h-13.614v13.614z m27.228 0h13.614v-13.614h-13.614v13.614z" fill="#4B555F" p-id="29805"></path><path d="M911.186 89.63h-77.644v852.258H191.272v75.306h719.916z" fill="#FFD351" p-id="29806"></path><path d="M826.734 82.822v852.26H184.468V1024h733.526V82.822h-91.26z m77.646 927.564H198.082v-61.69h642.266V96.436h64.032v913.95z" fill="#4B555F" p-id="29807"></path></svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -0,0 +1 @@
<svg t="1580292196629" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="34484" width="32" height="32"><path d="M114 226m19.96 0l184.08 0q19.96 0 19.96 19.96l0 660.08q0 19.96-19.96 19.96l-184.08 0q-19.96 0-19.96-19.96l0-660.08q0-19.96 19.96-19.96Z" fill="#20C997" p-id="34485"></path><path d="M159.24 354.6a66.84 66.76 90 1 0 133.52 0 66.84 66.76 90 1 0-133.52 0Z" fill="#0CA678" p-id="34486"></path><path d="M159.24 790.88m13.64 0l106.26 0q13.64 0 13.64 13.64l0 0.04q0 13.64-13.64 13.64l-106.26 0q-13.64 0-13.64-13.64l0-0.04q0-13.64 13.64-13.64Z" fill="#0CA678" p-id="34487"></path><path d="M159.24 844.78m13.64 0l106.26 0q13.64 0 13.64 13.64l0 0.04q0 13.64-13.64 13.64l-106.26 0q-13.64 0-13.64-13.64l0-0.04q0-13.64 13.64-13.64Z" fill="#0CA678" p-id="34488"></path><path d="M402 118m19.96 0l184.08 0q19.96 0 19.96 19.96l0 660.08q0 19.96-19.96 19.96l-184.08 0q-19.96 0-19.96-19.96l0-660.08q0-19.96 19.96-19.96Z" fill="#FF6B6B" p-id="34489"></path><path d="M447.24 246.6a66.84 66.76 90 1 0 133.52 0 66.84 66.76 90 1 0-133.52 0Z" fill="#FA5252" p-id="34490"></path><path d="M447.24 682.88m13.64 0l106.26 0q13.64 0 13.64 13.64l0 0.04q0 13.64-13.64 13.64l-106.26 0q-13.64 0-13.64-13.64l0-0.04q0-13.64 13.64-13.64Z" fill="#FA5252" p-id="34491"></path><path d="M447.24 736.78m13.64 0l106.26 0q13.64 0 13.64 13.64l0 0.04q0 13.64-13.64 13.64l-106.26 0q-13.64 0-13.64-13.64l0-0.04q0-13.64 13.64-13.64Z" fill="#FA5252" p-id="34492"></path><path d="M688 184m19.96 0l184.08 0q19.96 0 19.96 19.96l0 660.08q0 19.96-19.96 19.96l-184.08 0q-19.96 0-19.96-19.96l0-660.08q0-19.96 19.96-19.96Z" fill="#329AF0" p-id="34493"></path><path d="M733.24 312.6a66.84 66.76 90 1 0 133.52 0 66.84 66.76 90 1 0-133.52 0Z" fill="#1C7CD6" p-id="34494"></path><path d="M733.24 748.88m13.64 0l106.26 0q13.64 0 13.64 13.64l0 0.04q0 13.64-13.64 13.64l-106.26 0q-13.64 0-13.64-13.64l0-0.04q0-13.64 13.64-13.64Z" fill="#1C7CD6" p-id="34495"></path><path d="M733.24 802.78m13.64 0l106.26 0q13.64 0 13.64 13.64l0 0.04q0 13.64-13.64 13.64l-106.26 0q-13.64 0-13.64-13.64l0-0.04q0-13.64 13.64-13.64Z" fill="#1C7CD6" p-id="34496"></path></svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@ -0,0 +1 @@
<svg t="1580359741005" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="37821" width="32" height="32"><path d="M853.333333 256H469.333333l-85.333333-85.333333H170.666667c-46.933333 0-85.333333 38.4-85.333334 85.333333v170.666667h853.333334v-85.333334c0-46.933333-38.4-85.333333-85.333334-85.333333z" fill="#FFA000" p-id="37822"></path><path d="M853.333333 256H170.666667c-46.933333 0-85.333333 38.4-85.333334 85.333333v426.666667c0 46.933333 38.4 85.333333 85.333334 85.333333h682.666666c46.933333 0 85.333333-38.4 85.333334-85.333333V341.333333c0-46.933333-38.4-85.333333-85.333334-85.333333z" fill="#FFCA28" p-id="37823"></path></svg>

After

Width:  |  Height:  |  Size: 680 B

View File

@ -0,0 +1 @@
<svg t="1580291384841" class="icon" viewBox="0 0 1280 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="26151" width="32" height="32"><path d="M466.346667 658.346667l63.146666 58.453333 285.866667-263.68a148.053333 148.053333 0 0 1 196.693333 0l267.946667 247.466667V42.666667a42.666667 42.666667 0 0 0-42.666667-42.666667H42.666667a42.666667 42.666667 0 0 0-42.666667 42.666667v848.213333l251.306667-232.533333a161.706667 161.706667 0 0 1 215.04 0z" fill="#FFFFFF" p-id="26152"></path><path d="M42.666667 1024h154.453333l332.373333-307.2-63.146666-58.453333a161.706667 161.706667 0 0 0-213.333334 0L0 890.88V981.333333a42.666667 42.666667 0 0 0 42.666667 42.666667zM815.36 453.12l-285.866667 263.68 332.8 307.2H1237.333333a42.666667 42.666667 0 0 0 42.666667-42.666667v-280.746666l-267.946667-247.466667a148.053333 148.053333 0 0 0-196.693333 0z" fill="#99BF87" p-id="26153"></path><path d="M197.12 1024h665.173333l-332.8-307.2L197.12 1024z" fill="#99BF87" p-id="26154"></path><path d="M1237.333333 42.666667v938.666666H42.666667V42.666667h1194.666666m0-42.666667H42.666667a42.666667 42.666667 0 0 0-42.666667 42.666667v938.666666a42.666667 42.666667 0 0 0 42.666667 42.666667h1194.666666a42.666667 42.666667 0 0 0 42.666667-42.666667V42.666667a42.666667 42.666667 0 0 0-42.666667-42.666667z" fill="#4D4D4D" p-id="26155"></path><path d="M277.333333 277.333333m-128 0a128 128 0 1 0 256 0 128 128 0 1 0-256 0Z" fill="#F4CB5A" p-id="26156"></path></svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -0,0 +1 @@
<svg t="1580291445065" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="29001" width="32" height="32"><path d="M957.38 50.708l-82.814 98.53h-168.908l82.812-98.53h-142.548l-82.814 98.53H394.2l82.814-98.53h-142.5l-82.812 98.53H82.792l82.812-98.53H32.308v233.518h133.296L82.792 185.696h168.91l82.812 98.53h142.5L394.2 185.696h168.908l82.814 98.53h142.548l-82.812-98.53h168.908l82.814 98.53h34.27V50.708z" fill="#F58E70" p-id="29002"></path><path d="M0 18.398v859.204c0 70.58 57.422 128 128.002 128h767.996c70.58 0 128.002-57.42 128.002-128V18.398H0z m1009.078 859.204c0 62.352-50.728 113.078-113.08 113.078H128.002c-62.352 0-113.08-50.726-113.08-113.078V33.32H1009.08v844.282z" fill="#4B555F" p-id="29003"></path><path d="M0 301.624v50.8h1024v-50.8H0z m1009.078 35.878H14.922v-20.956H1009.08v20.956z" fill="#4B555F" p-id="29004"></path><path d="M255.158 178.25H66.768l116.252 138.294h188.386l-116.248-138.294z m-156.352 14.922h149.408l91.154 108.452H189.964L98.806 193.172zM183.02 18.398L66.768 156.692h188.392l116.248-138.294H183.02z m65.192 123.372H98.806l91.16-108.452h149.402l-91.156 108.452zM566.588 178.25h-188.386l116.248 138.294h188.386l-116.248-138.294z m-156.348 14.922h149.402l91.156 108.452h-149.402L410.24 193.172zM494.448 18.398L378.2 156.692h188.386l116.248-138.294h-188.386z m65.194 123.372H410.24l91.156-108.452h149.402l-91.156 108.452zM878.022 178.25h-188.386l116.248 138.294h188.386l-116.248-138.294z m-156.348 14.922h149.402l91.156 108.452h-149.402l-91.156-108.452zM805.882 18.398l-116.248 138.294h188.386l116.248-138.294h-188.386z m65.194 123.372h-149.402l91.154-108.452h149.402l-91.154 108.452zM381.78 447.384v423.602l338.794-211.8L381.78 447.384z m14.922 26.922l295.72 184.878-295.72 184.878V474.306z" fill="#4B555F" p-id="29005"></path><path d="M414.11 505.72v306.928l245.474-153.466z" fill="#F58E70" p-id="29006"></path><path d="M0 18.398v298.146h1024V18.398H0z m1009.078 283.226H14.922V33.32H1009.08v268.304z" fill="#4B555F" p-id="29007"></path></svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -0,0 +1 @@
<svg t="1580291823744" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="31150" width="32" height="32"><path d="M944 944H80c-26.4 0-48-18.4-48-40.8V656h960v247.2c0 22.4-21.6 40.8-48 40.8z" fill="#5ACC9B" p-id="31151"></path><path d="M80 80h864c26.4 0 48 18.4 48 40.8V368H32V120.8c0-22.4 21.6-40.8 48-40.8z" fill="#6CCBFF" p-id="31152"></path><path d="M32 368h960v288H32z" fill="#FFD766" p-id="31153"></path><path d="M352 80h320v864H352z" fill="#FF5562" p-id="31154"></path><path d="M444 128h64v48h-64zM508 80h64v48h-64zM508 176h64v48h-64zM444 224h64v48h-64zM508 272h64v48h-64zM444 320h64v48h-64zM508 368h64v48h-64zM444 416h64v48h-64zM508 464h64v48h-64zM444 512h64v48h-64zM508 560h64v48h-64zM444 608h64v48h-64zM508 656h64v48h-64zM444 704h64v48h-64zM508 752h64v48h-64zM444 800h64v48h-64zM444 896h64v48h-64zM508 848h64v48h-64z" fill="#FFFFFF" p-id="31155"></path></svg>

After

Width:  |  Height:  |  Size: 909 B

View File

@ -0,0 +1,62 @@
<template>
<div v-if="isExternal" :style="styleExternalIcon" class="svg-external-icon svg-icon" v-on="$listeners" />
<svg v-else :class="svgClass" aria-hidden="true" v-on="$listeners">
<use :href="iconName" />
</svg>
</template>
<script>
// doc: https://panjiachen.github.io/vue-element-admin-site/feature/component/svg-icon.html#usage
import { isExternal } from '@/utils/validate'
export default {
name: 'SvgIcon',
props: {
iconClass: {
type: String,
required: true
},
className: {
type: String,
default: ''
}
},
computed: {
isExternal() {
return isExternal(this.iconClass)
},
iconName() {
return `#icon-${this.iconClass}`
},
svgClass() {
if (this.className) {
return 'svg-icon ' + this.className
} else {
return 'svg-icon'
}
},
styleExternalIcon() {
return {
mask: `url(${this.iconClass}) no-repeat 50% 50%`,
'-webkit-mask': `url(${this.iconClass}) no-repeat 50% 50%`
}
}
}
}
</script>
<style scoped>
.svg-icon {
width: 1em;
height: 1em;
vertical-align: -0.15em;
fill: currentColor;
overflow: hidden;
}
.svg-external-icon {
background-color: currentColor;
mask-size: cover!important;
display: inline-block;
}
</style>

View File

@ -0,0 +1,119 @@
<template>
<!-- 组件代码 -->
<span>
<!--<el-popover ref="popover5" v-model="visible" placement="top" width="160">-->
<!--<p>{{ content }}</p>-->
<!--<div style="text-align: right; margin: 0">-->
<!--<el-button size="mini" type="text" @click="visible = false">取消</el-button>-->
<!--<el-button type="danger" size="mini" @click="deleteItem(id)">确定</el-button>-->
<!--</div>-->
<!--</el-popover>-->
<!--<el-button v-popover:popover5 type="text" icon-class="more">fff</el-button>-->
<el-popover
ref="popover"
class="popover-content"
style="padding: 0"
placement="bottom"
@show="showMenu(row,selects)"
>
<div class="newFileMenu" style="display: block;">
<ul v-for="(item,index) in data" :key="item.label">
<li
v-if="item.operation === 'favorite'"
@click="item.click(item.operation)"
@mouseover.prevent="item.mouseover(index)"
@mouseleave.prevent="item.mouseleave(index)"
>
<label class="menuitem"><svg-icon :icon-class="item.iconClass" /><span class="menuitem text">{{ item.label }}</span>
</label>
</li>
<li
v-else
@click="item.click(item.operation)"
>
<label class="menuitem"><svg-icon :icon-class="item.iconClass" /><span class="menuitem text">{{ item.label }}</span>
</label>
</li>
</ul>
</div>
</el-popover>
<svg-icon v-popover:popover class="button-class" icon-class="more" />
</span>
</template>
<script>
import Bus from '@/assets/js/bus'
export default {
name: 'MenuPopover',
props: {
data: {
type: Array,
default: () => []
},
disabled: {
type: Boolean,
default: true
},
row: {
type: Object,
default: function() {
return {}
}
},
selects: {
type: Array,
default: () => []
}
},
data() {
return {
}
},
methods: {
showMenu(row, selects) {
selects[0] = row
Bus.$emit('clickMore', selects)
},
test() {
console.log(8769)
}
}
}
</script>
<style lang="scss" scoped>
.newFileMenu ul {
list-style: none;
padding-inline-start: 0px;
margin-top: 0;
margin-bottom: 0;
}
.newFileMenu li {
cursor: pointer;
margin: 0;
padding: 0;
font-size: 16px;
}
.newFileMenu li:hover {
cursor: pointer;
border-radius: 5px;
background-color: #409eff14;
}
.newFileMenu li > .menuitem {
cursor: pointer;
line-height: 44px;
margin-left: 10%;
}
.newFileMenu li > .menuitem > .text {
cursor: pointer;
margin-left: 8%;font-weight: normal;
}
.newFileMenu li > .menuitem > .svg-icon {
cursor: pointer;
font-size: 20px;
}
/deep/ .el-popover {
padding: 0;
}
</style>

View File

@ -0,0 +1,307 @@
<template>
<!-- 列表 -->
<div class="commonTable">
<el-table
ref="refTable"
v-loading="options.loading"
stripe
:border="options.border"
:data="dataSource"
:height="options.height"
:max-height="tableHeight"
element-loading-text="拼命加载中"
element-loading-spinner="el-icon-loading"
element-loading-background="rgba(0, 0, 0, 0.5)"
:row-style="rowClass"
:cell-style="options.cellstyle"
:cell-class-name="options.cellClassName"
:header-cell-style="options.headerCellStyle"
@selection-change="handleSelectionChange"
@row-click="handleRowClick"
>
<!--selection选择框-->
<el-table-column v-if="options.mutiSelect" type="selection" style="width:50px" align="center"></el-table-column>
<!--数据源-->
<template v-for="(column, index) in columnsList">
<!-- sortable 对应列是否可以排序 -->
<el-table-column
v-if="!column.button&&!column.type"
:key="index"
:sortable="column.hasSort"
:prop="column.prop"
:label="column.label"
:align="column.align"
:width="column.width"
>
<template slot-scope="scope">
<span v-if="column.render">
{{ column.render(scope.row) }}
</span>
<span v-else>{{ scope.row[column.prop] }}</span>
</template>
</el-table-column>
<el-table-column
v-if="column.button"
:key="index"
header-align="center"
:sortable="column.hasSort"
:prop="column.prop"
:label="column.label"
:align="column.align"
:width="column.width"
>
<template slot-scope="scope">
<!-- render button -->
<template v-for="(btn, i) in column.group">
<el-button
:key="i"
class="theme-btn"
:type="btn.type"
:size="btn.size || 'mini'"
:icon="btn.icon"
:disabled="btn.disabled"
:plain="btn.plain"
:class=" btn.class"
@click.stop="btn.onClick(scope.row, scope.$index)"
>{{ btn.name }}</el-button>
</template>
</template>
</el-table-column>
<!-- 多级表头 -->
<el-table-column
v-if="column.type === 'column'"
:key="index"
:label="column.label"
:align="column.align"
:width="column.width"
>
<div v-for="(item, i) in column.multistage" :key="i">
<el-table-column
:prop="item.prop"
:label="item.label"
:align="item.align"
:width="item.width"
>
</el-table-column>
</div>
</el-table-column>
</template>
</el-table>
<!-- 分页 -->
<el-pagination
v-if="pagination"
ref="commonPage"
background
:total="pagination.total"
:current-page.sync="pagination.pageIndex"
:page-sizes="pagination.pageSizes||[5, 10, 20, 50, 100, 500]"
layout="total, sizes, prev, pager, next, jumper"
class="commonPagination"
@size-change="handleSizeChange"
@current-change="handleIndexChange"
></el-pagination>
</div>
<!-- style="margin-top: 20px;text-align: center" -->
</template>
<script>
export default {
name: 'Tables',
components: {
//
},
props: {
dataSource: {// 表格数据源 默认为空数组
type: Array,
default: () => []
},
options: {
mutiSelect: false, // 是否显示复选框
index: true,
indexWidth: 70,
initTable: true, // 是否一挂载就加载数据
border: false
}, // // 表格参数控制 maxHeight、stripe 等等...
columns: {// 表格的字段展示 默认为空数组
type: Array,
default: () => []
},
fetch: Function, // 获取数据的函数
pagination: Object // 分页,不传则不显示
},
data() {
return {
selectRow: [],
selectData: [],
tableHeight: null
}
},
computed: {
columnsList() {
const columns = this.columns
const columnsList = []
columns.forEach((item, index) => {
if (item.isShow) {
columnsList.push(item)
}
})
return columnsList
}
},
watch: {
//
selectData(data) { // 存储选中的row
this.selectRow = []
if (data.length > 0) {
data.forEach((item, index) => {
this.selectRow.push(this.dataSource.indexOf(item))
})
}
},
tableHeight(oldData, newData) {
// console.log(oldData);
// console.log(newData);
}
},
created() {
// 传入的options覆盖默认设置
this.$parent.options = Object.assign({
maxHeight: 500,
stripe: true, // 是否为斑马纹
border: true
}, this.options)
this.options.initTable && this.fetch()
},
mounted() {
this.$nextTick(function() {
if (this.$refs.commonPage) {
this.tableHeight = window.innerHeight - this.$refs.refTable.$el.getBoundingClientRect().top - this.$refs.commonPage.$el.offsetHeight - 10
} else {
this.tableHeight = window.innerHeight - this.$refs.refTable.$el.getBoundingClientRect().top - 10
console.log(this.$refs.refTable)
}
// 监听窗口大小变化
const self = this
window.onresize = function() {
if (self.$refs.commonPage) {
self.tableHeight = window.innerHeight - self.$refs.refTable.$el.getBoundingClientRect().top - self.$refs.commonPage.$el.offsetHeight - 10
} else {
self.tableHeight = window.innerHeight - self.$refs.refTable.$el.getBoundingClientRect().top - 10
// console.log(self.$refs.refTable)
}
}
})
// console.log(this.tableHeight);
// console.log(window.innerHeight);
// console.log(this.$refs.refTable.$el.getBoundingClientRect().top);
},
methods: {
onClick(row, index) {
this.$emit('click', row, index)
},
table_index(index) {
return (this.pagination.noIndex - 1) * this.pagination.pageSize + index + 1
},
handleSizeChange(size) { // 切换每页显示的数量
this.pagination.pageSize = size
this.fetch()
},
handleIndexChange(current) { // 切换页码
this.pagination.pageIndex = current
this.fetch()
},
handleSelectionChange(selection) {
this.$emit('selection-change', selection)
this.selectData = selection
},
handleRowClick(row, event, column) {
this.$emit('row-click', row, event, column)
if (this.options.mutiSelect) {
this.$refs.refTable.toggleRowSelection(row)
}
// console.log(row,event,column);
},
btn_click() {
},
rowClass({ row, rowIndex }) {
if (this.selectRow.includes(rowIndex)) {
return { 'color': '#F5F5F5' }
}
}
}
}
</script>
<style lang="scss" scoped>
.dashboard {
&-container {
margin: 30px;
}
&-text {
font-size: 30px;
line-height: 46px;
}
}
.redirect {
color: #97a8be;
}
.no-redirect {
color: #000000;
cursor: text;
}
.el-breadcrumb {
font-size: 20px;
line-height: 46px;
}
.newFileMenu ul {
list-style: none;
padding-inline-start: 0px;
margin-top: 0;
margin-bottom: 0;
}
.button-class {
cursor: pointer;
}
.button-class:hover {
border-radius: 5px;
background-color: #409eff14;
}
.newFileMenu li {
margin: 0;
padding: 0;
font-size: 16px;
}
.newFileMenu li:hover {
border-radius: 5px;
background-color: #409eff14;
}
.newFileMenu li > .menuitem {
cursor: pointer;
line-height: 44px;
margin-left: 10%;
}
.newFileMenu li > .menuitem > .text {
margin-left: 5%;font-weight: normal;
}
.el-button.is-circle {
border-radius: 50%;
padding: 9px;
}
/deep/.svg-icon {
font-size: 28px;
}
/deep/.el-table th>.cell {
padding-left: 15px;
}
</style>

9
src/icons/index.js Normal file
View File

@ -0,0 +1,9 @@
import Vue from 'vue'
import SvgIcon from '@/components/SvgIcon'// svg component
// register globally
Vue.component('svg-icon', SvgIcon)
const req = require.context('./svg', false, /\.svg$/)
const requireAll = requireContext => requireContext.keys().map(requireContext)
requireAll(req)

View File

@ -0,0 +1 @@
<svg t="1579936422968" class="icon" viewBox="0 0 1025 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6955" width="200" height="200"><path d="M512.824885 39.121c-12.944 0-23.188 3.834-30.594 11.67-7.543 7.669-13.38 17.057-17.354 27.728L347.367885 349.82 31.960885 378.135c-7.406 1.419-14.228 4.699-20.344 10.085-6.123 5.42-9.975 12.809-11.253 22.342-1.418 9.388 0.866 18.648 6.558 27.755 5.839 9.088 12.799 17.34 20.898 24.899l11.253 9.533 26.039 22.339c10.67 9.085 22.476 19.199 35.845 30.289l40.259 33.868c32.012 27.009 67.995 57.739 108.262 92.164l-34.706 141.708c-4.833 18.199-9.393 35.982-13.798 53.631-4.403 17.503-8.406 33.56-11.811 48.094-3.416 14.506-6.403 26.87-9.098 37.4l-5.124 19.781c-1.434 5.979-0.709 11.949 1.987 17.643 2.707 5.698 6.971 10.673 12.809 14.646 5.694 4.139 12.224 6.558 19.337 7.695 1.584 0.224 3.154 0.307 4.72 0.307 5.476 0 10.886-1.334 16.204-3.861 3.416-1.444 10.103-4.832 19.922-10.113 9.951-5.39 21.617-12.228 35.276-20.337 13.518-8.116 28.75-16.784 45.396-26.316 16.637-9.389 33.561-18.922 50.485-28.315 39.566-22.197 83.377-47.514 131.754-75.824l266.461 153.792 14.813 5.53c6.394 2.416 11.364 3.555 14.782 3.555 10.254 0 19.351-2.278 27.606-6.529 8.098-4.415 11.245-13.361 9.1-26.896-0.71-2.699-1.985-9.248-3.976-19.781l-7.695-37.814c-3.129-14.954-6.39-31.458-9.668-49.659-3.416-18.223-7.25-36.425-11.241-54.624-8.961-43.263-19.061-91.502-30.716-144.679l211.407-188.228c8.818-10.253 16.074-18.787 21.908-25.897 5.833-7.112 8.682-15.367 8.682-24.759 0-10.085-2.705-17.504-8.116-22.338-5.555-4.7-15.083-8.668-28.592-12.09l-315.546-29.312-114.261-271.3c-1.418-2.697-3.265-5.973-5.684-10.085-2.415-3.974-5.262-8.116-8.684-12.089-3.415-4.137-7.668-7.692-12.652-10.667C525.624885 40.678 519.649885 39.121 512.824885 39.121" p-id="6956"></path></svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

1
src/icons/svg/audio.svg Normal file
View File

@ -0,0 +1 @@
<svg t="1580291103597" class="icon" viewBox="0 0 1179 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="19622" width="32" height="32"><path d="M846.057944 0H347.481672c-52.474576 0-95.186441 46.779661-95.18644 104.40678v708.474576c-24.40678-36.338983-65.898305-60.338983-112.81356-60.338983-74.847458 0-135.728814 60.881356-135.728813 135.728813 0 74.847458 60.881356 135.728814 135.728813 135.728814 69.423729 0 126.915254-52.474576 134.779661-119.864407h0.949153V294.644068h643.118644v518.101695c-24.40678-36.338983-65.898305-60.338983-112.813559-60.338983-74.847458 0-135.728814 60.881356-135.728814 135.728813 0 74.847458 60.881356 135.728814 135.728814 135.728814 69.423729 0 126.915254-52.474576 134.779661-119.864407h0.949152V104.40678c0-57.491525-42.711864-104.40678-95.18644-104.40678zM139.481672 1001.084746c-62.237288 0-112.813559-50.576271-112.813559-112.81356 0-62.237288 50.576271-112.813559 112.813559-112.813559 62.237288 0 112.813559 50.576271 112.81356 112.813559 0 62.101695-50.576271 112.813559-112.81356 112.81356z m666.033899 0c-62.237288 0-112.813559-50.576271-112.81356-112.81356 0-62.237288 50.711864-112.813559 112.81356-112.813559 62.237288 0 112.813559 50.576271 112.813559 112.813559 0 62.101695-50.576271 112.813559-112.813559 112.81356zM275.210486 265.627119V104.40678c0-44.881356 32.40678-81.491525 72.271186-81.491526h498.576272c39.864407 0 72.271186 36.610169 72.271186 81.491526v161.220339H275.210486z" fill="#040000" p-id="19623"></path><path d="M920.363028 265.627119V126.508475c0-57.762712-34.847458-104.542373-77.830508-104.542373H378.53252c-42.983051 0-77.830508 46.779661-77.830509 104.542373v139.118644h619.661017z" fill="#E35F3D" p-id="19624"></path><path d="M256.363028 895.050847c0 60.745763-49.220339 109.966102-109.966101 109.966102S36.430825 955.79661 36.430825 895.050847c0-60.610169 49.220339-109.966102 109.966102-109.966101s109.966102 49.355932 109.966101 109.966101zM920.363028 895.322034c0 58.847458-47.59322 106.440678-106.440678 106.440678-58.711864 0-106.305085-47.59322-106.305084-106.440678 0-58.711864 47.59322-106.305085 106.305084-106.305085 58.847458-0.135593 106.440678 47.59322 106.440678 106.305085z" fill="#EEBF2F" p-id="19625"></path><path d="M857.71896 24c-91.79661 145.084746-253.559322 241.627119-437.830508 241.627119h500.610169V126.508475c4.338983-53.423729-20.610169-93.288136-62.779661-102.508475z" fill="#BD3A1F" p-id="19626"></path></svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

@ -0,0 +1 @@
<svg t="1581134231072" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1851" width="32" height="32"><path d="M673.714 495.219q-85.098-85.098-341.118-341.118-5.091-5.819-5.091-10.91 0-5.091 5.091-10.183 5.091-5.091 10.183-5.091 5.091 0 10.91 5.091 119.282 119.282 357.119 357.119 5.091 5.091 5.091 10.91 0 5.091-5.091 10.183-0.727 0.727-1.455 1.455-88.734 88.734-355.665 354.937-5.819 5.091-10.91 5.091-5.091 0-10.183-5.091-5.091-5.091-5.091-10.183 0-5.091 5.091-10.91 113.464-113.464 341.118-341.118 5.091-5.091 0-10.183z" p-id="1852"></path></svg>

After

Width:  |  Height:  |  Size: 593 B

View File

@ -0,0 +1 @@
<svg width="128" height="100" xmlns="http://www.w3.org/2000/svg"><path d="M27.429 63.638c0-2.508-.893-4.65-2.679-6.424-1.786-1.775-3.94-2.662-6.464-2.662-2.524 0-4.679.887-6.465 2.662-1.785 1.774-2.678 3.916-2.678 6.424 0 2.508.893 4.65 2.678 6.424 1.786 1.775 3.94 2.662 6.465 2.662 2.524 0 4.678-.887 6.464-2.662 1.786-1.775 2.679-3.916 2.679-6.424zm13.714-31.801c0-2.508-.893-4.65-2.679-6.424-1.785-1.775-3.94-2.662-6.464-2.662-2.524 0-4.679.887-6.464 2.662-1.786 1.774-2.679 3.916-2.679 6.424 0 2.508.893 4.65 2.679 6.424 1.785 1.774 3.94 2.662 6.464 2.662 2.524 0 4.679-.888 6.464-2.662 1.786-1.775 2.679-3.916 2.679-6.424zM71.714 65.98l7.215-27.116c.285-1.23.107-2.378-.536-3.443-.643-1.064-1.56-1.762-2.75-2.094-1.19-.33-2.333-.177-3.429.462-1.095.639-1.81 1.573-2.143 2.804l-7.214 27.116c-2.857.237-5.405 1.266-7.643 3.088-2.238 1.822-3.738 4.152-4.5 6.992-.952 3.644-.476 7.098 1.429 10.364 1.905 3.265 4.69 5.37 8.357 6.317 3.667.947 7.143.474 10.429-1.42 3.285-1.892 5.404-4.66 6.357-8.305.762-2.84.619-5.607-.429-8.305-1.047-2.697-2.762-4.85-5.143-6.46zm47.143-2.342c0-2.508-.893-4.65-2.678-6.424-1.786-1.775-3.94-2.662-6.465-2.662-2.524 0-4.678.887-6.464 2.662-1.786 1.774-2.679 3.916-2.679 6.424 0 2.508.893 4.65 2.679 6.424 1.786 1.775 3.94 2.662 6.464 2.662 2.524 0 4.679-.887 6.465-2.662 1.785-1.775 2.678-3.916 2.678-6.424zm-45.714-45.43c0-2.509-.893-4.65-2.679-6.425C68.68 10.01 66.524 9.122 64 9.122c-2.524 0-4.679.887-6.464 2.661-1.786 1.775-2.679 3.916-2.679 6.425 0 2.508.893 4.65 2.679 6.424 1.785 1.774 3.94 2.662 6.464 2.662 2.524 0 4.679-.888 6.464-2.662 1.786-1.775 2.679-3.916 2.679-6.424zm32 13.629c0-2.508-.893-4.65-2.679-6.424-1.785-1.775-3.94-2.662-6.464-2.662-2.524 0-4.679.887-6.464 2.662-1.786 1.774-2.679 3.916-2.679 6.424 0 2.508.893 4.65 2.679 6.424 1.785 1.774 3.94 2.662 6.464 2.662 2.524 0 4.679-.888 6.464-2.662 1.786-1.775 2.679-3.916 2.679-6.424zM128 63.638c0 12.351-3.357 23.78-10.071 34.286-.905 1.372-2.19 2.058-3.858 2.058H13.93c-1.667 0-2.953-.686-3.858-2.058C3.357 87.465 0 76.037 0 63.638c0-8.613 1.69-16.847 5.071-24.703C8.452 31.08 13 24.312 18.714 18.634c5.715-5.68 12.524-10.199 20.429-13.559C47.048 1.715 55.333.035 64 .035c8.667 0 16.952 1.68 24.857 5.04 7.905 3.36 14.714 7.88 20.429 13.559 5.714 5.678 10.262 12.446 13.643 20.301 3.38 7.856 5.071 16.09 5.071 24.703z"/></svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@ -0,0 +1 @@
<svg t="1580291492423" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="29799" width="32" height="32"><path d="M281.086 0l-175.08 117.562v831.146h734.34V0h-559.26z m545.648 935.096H119.62V124.82l165.614-111.208h541.5v921.484z" fill="#4B555F" p-id="29800"></path><path d="M279.366 1.156L109.02 115.542l3.558 12.454 115.656 3.996 6.412-3.948 54.69-118.38-9.97-8.508z m-55.182 117.07l-90.112-3.11L266.8 25.994l-42.616 92.232z" fill="#4B555F" p-id="29801"></path><path d="M207.626 658.778h191.498v177.038h-191.498z" fill="#F58E70" p-id="29802"></path><path d="M473.178 651.97h279.444v13.614H473.178zM473.178 707.886h279.444v13.614H473.178zM473.178 763.804h279.444v13.614H473.178zM473.178 819.722h279.444v13.614H473.178z" fill="#4B555F" p-id="29803"></path><path d="M207.626 262.022h544.998v58.442H207.626z" fill="#FFD351" p-id="29804"></path><path d="M207.628 381.704h544.996v13.614H207.628zM207.628 447.77h544.996v13.614H207.628zM207.628 513.836h544.996v13.614H207.628zM207.628 579.902h544.996v13.614H207.628zM207.628 195.23h544.996v13.614H207.628zM599.316 139.876h13.614v-13.614h-13.614v13.614z m-81.684 0h13.614v-13.614h-13.614v13.614z m27.228 0h13.614v-13.614h-13.614v13.614z m-81.684 0h13.614v-13.614h-13.614v13.614z m27.228 0h13.614v-13.614h-13.614v13.614z m81.684 0h13.614v-13.614h-13.614v13.614z m136.14 0h13.614v-13.614h-13.614v13.614z m27.228-13.612v13.614h13.614v-13.614h-13.614zM681 139.876h13.614v-13.614H681v13.614z m-54.456 0h13.614v-13.614h-13.614v13.614z m27.228 0h13.614v-13.614h-13.614v13.614z" fill="#4B555F" p-id="29805"></path><path d="M911.186 89.63h-77.644v852.258H191.272v75.306h719.916z" fill="#FFD351" p-id="29806"></path><path d="M826.734 82.822v852.26H184.468V1024h733.526V82.822h-91.26z m77.646 927.564H198.082v-61.69h642.266V96.436h64.032v913.95z" fill="#4B555F" p-id="29807"></path></svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -0,0 +1 @@
<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M96.258 57.462h31.421C124.794 27.323 100.426 2.956 70.287.07v31.422a32.856 32.856 0 0 1 25.971 25.97zm-38.796-25.97V.07C27.323 2.956 2.956 27.323.07 57.462h31.422a32.856 32.856 0 0 1 25.97-25.97zm12.825 64.766v31.421c30.46-2.885 54.507-27.253 57.713-57.712H96.579c-2.886 13.466-13.146 23.726-26.292 26.291zM31.492 70.287H.07c2.886 30.46 27.253 54.507 57.713 57.713V96.579c-13.466-2.886-23.726-13.146-26.291-26.292z"/></svg>

After

Width:  |  Height:  |  Size: 497 B

View File

@ -0,0 +1 @@
<svg class="icon" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="128" height="128"><defs><style/></defs><path d="M512 128q69.675 0 135.51 21.163t115.498 54.997 93.483 74.837 73.685 82.006 51.67 74.837 32.17 54.827L1024 512q-2.347 4.992-6.315 13.483T998.87 560.17t-31.658 51.669-44.331 59.99-56.832 64.34-69.504 60.16-82.347 51.5-94.848 34.687T512 896q-69.675 0-135.51-21.163t-115.498-54.826-93.483-74.326-73.685-81.493-51.67-74.496-32.17-54.997L0 513.707q2.347-4.992 6.315-13.483t18.816-34.816 31.658-51.84 44.331-60.33 56.832-64.683 69.504-60.331 82.347-51.84 94.848-34.816T512 128.085zm0 85.333q-46.677 0-91.648 12.331t-81.152 31.83-70.656 47.146-59.648 54.485-48.853 57.686-37.675 52.821-26.325 43.99q12.33 21.674 26.325 43.52t37.675 52.351 48.853 57.003 59.648 53.845T339.2 767.02t81.152 31.488T512 810.667t91.648-12.331 81.152-31.659 70.656-46.848 59.648-54.186 48.853-57.344 37.675-52.651T927.957 512q-12.33-21.675-26.325-43.648t-37.675-52.65-48.853-57.345-59.648-54.186-70.656-46.848-81.152-31.659T512 213.334zm0 128q70.656 0 120.661 50.006T682.667 512 632.66 632.661 512 682.667 391.339 632.66 341.333 512t50.006-120.661T512 341.333zm0 85.334q-35.328 0-60.33 25.002T426.666 512t25.002 60.33T512 597.334t60.33-25.002T597.334 512t-25.002-60.33T512 426.666z"/></svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

1
src/icons/svg/eye.svg Normal file
View File

@ -0,0 +1 @@
<svg width="128" height="64" xmlns="http://www.w3.org/2000/svg"><path d="M127.072 7.994c1.37-2.208.914-5.152-.914-6.87-2.056-1.717-4.797-1.226-6.396.982-.229.245-25.586 32.382-55.74 32.382-29.24 0-55.74-32.382-55.968-32.627-1.6-1.963-4.57-2.208-6.397-.49C-.17 3.086-.399 6.275 1.2 8.238c.457.736 5.94 7.36 14.62 14.72L4.17 35.96c-1.828 1.963-1.6 5.152.228 6.87.457.98 1.6 1.471 2.742 1.471s2.284-.49 3.198-1.472l12.564-13.983c5.94 4.416 13.021 8.587 20.788 11.53l-4.797 17.418c-.685 2.699.686 5.397 3.198 6.133h1.37c2.057 0 3.884-1.472 4.341-3.68L52.6 42.83c3.655.736 7.538 1.227 11.422 1.227 3.883 0 7.767-.49 11.422-1.227l4.797 17.173c.457 2.208 2.513 3.68 4.34 3.68.457 0 .914 0 1.143-.246 2.513-.736 3.883-3.434 3.198-6.133l-4.797-17.172c7.767-2.944 14.848-7.114 20.788-11.53l12.336 13.738c.913.981 2.056 1.472 3.198 1.472s2.284-.49 3.198-1.472c1.828-1.963 1.828-4.906.228-6.87l-11.65-13.001c9.366-7.36 14.849-14.474 14.849-14.474z"/></svg>

After

Width:  |  Height:  |  Size: 944 B

1
src/icons/svg/file.svg Normal file
View File

@ -0,0 +1 @@
<svg t="1580292196629" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="34484" width="32" height="32"><path d="M114 226m19.96 0l184.08 0q19.96 0 19.96 19.96l0 660.08q0 19.96-19.96 19.96l-184.08 0q-19.96 0-19.96-19.96l0-660.08q0-19.96 19.96-19.96Z" fill="#20C997" p-id="34485"></path><path d="M159.24 354.6a66.84 66.76 90 1 0 133.52 0 66.84 66.76 90 1 0-133.52 0Z" fill="#0CA678" p-id="34486"></path><path d="M159.24 790.88m13.64 0l106.26 0q13.64 0 13.64 13.64l0 0.04q0 13.64-13.64 13.64l-106.26 0q-13.64 0-13.64-13.64l0-0.04q0-13.64 13.64-13.64Z" fill="#0CA678" p-id="34487"></path><path d="M159.24 844.78m13.64 0l106.26 0q13.64 0 13.64 13.64l0 0.04q0 13.64-13.64 13.64l-106.26 0q-13.64 0-13.64-13.64l0-0.04q0-13.64 13.64-13.64Z" fill="#0CA678" p-id="34488"></path><path d="M402 118m19.96 0l184.08 0q19.96 0 19.96 19.96l0 660.08q0 19.96-19.96 19.96l-184.08 0q-19.96 0-19.96-19.96l0-660.08q0-19.96 19.96-19.96Z" fill="#FF6B6B" p-id="34489"></path><path d="M447.24 246.6a66.84 66.76 90 1 0 133.52 0 66.84 66.76 90 1 0-133.52 0Z" fill="#FA5252" p-id="34490"></path><path d="M447.24 682.88m13.64 0l106.26 0q13.64 0 13.64 13.64l0 0.04q0 13.64-13.64 13.64l-106.26 0q-13.64 0-13.64-13.64l0-0.04q0-13.64 13.64-13.64Z" fill="#FA5252" p-id="34491"></path><path d="M447.24 736.78m13.64 0l106.26 0q13.64 0 13.64 13.64l0 0.04q0 13.64-13.64 13.64l-106.26 0q-13.64 0-13.64-13.64l0-0.04q0-13.64 13.64-13.64Z" fill="#FA5252" p-id="34492"></path><path d="M688 184m19.96 0l184.08 0q19.96 0 19.96 19.96l0 660.08q0 19.96-19.96 19.96l-184.08 0q-19.96 0-19.96-19.96l0-660.08q0-19.96 19.96-19.96Z" fill="#329AF0" p-id="34493"></path><path d="M733.24 312.6a66.84 66.76 90 1 0 133.52 0 66.84 66.76 90 1 0-133.52 0Z" fill="#1C7CD6" p-id="34494"></path><path d="M733.24 748.88m13.64 0l106.26 0q13.64 0 13.64 13.64l0 0.04q0 13.64-13.64 13.64l-106.26 0q-13.64 0-13.64-13.64l0-0.04q0-13.64 13.64-13.64Z" fill="#1C7CD6" p-id="34495"></path><path d="M733.24 802.78m13.64 0l106.26 0q13.64 0 13.64 13.64l0 0.04q0 13.64-13.64 13.64l-106.26 0q-13.64 0-13.64-13.64l0-0.04q0-13.64 13.64-13.64Z" fill="#1C7CD6" p-id="34496"></path></svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@ -0,0 +1 @@
<svg t="1580359893005" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="37945" width="128" height="128"><path d="M853.333333 256H469.333333l-85.333333-85.333333H170.666667c-46.933333 0-85.333333 38.4-85.333334 85.333333v170.666667h853.333334v-85.333334c0-46.933333-38.4-85.333333-85.333334-85.333333z" fill="#FFA000" p-id="37946"></path><path d="M853.333333 256H170.666667c-46.933333 0-85.333333 38.4-85.333334 85.333333v426.666667c0 46.933333 38.4 85.333333 85.333334 85.333333h682.666666c46.933333 0 85.333333-38.4 85.333334-85.333333V341.333333c0-46.933333-38.4-85.333333-85.333334-85.333333z" fill="#FFCA28" p-id="37947"></path></svg>

After

Width:  |  Height:  |  Size: 682 B

1
src/icons/svg/folder.svg Normal file
View File

@ -0,0 +1 @@
<svg t="1580359741005" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="37821" width="32" height="32"><path d="M853.333333 256H469.333333l-85.333333-85.333333H170.666667c-46.933333 0-85.333333 38.4-85.333334 85.333333v170.666667h853.333334v-85.333334c0-46.933333-38.4-85.333333-85.333334-85.333333z" fill="#FFA000" p-id="37822"></path><path d="M853.333333 256H170.666667c-46.933333 0-85.333333 38.4-85.333334 85.333333v426.666667c0 46.933333 38.4 85.333333 85.333334 85.333333h682.666666c46.933333 0 85.333333-38.4 85.333334-85.333333V341.333333c0-46.933333-38.4-85.333333-85.333334-85.333333z" fill="#FFCA28" p-id="37823"></path></svg>

After

Width:  |  Height:  |  Size: 680 B

1
src/icons/svg/form.svg Normal file
View File

@ -0,0 +1 @@
<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M84.068 23.784c-1.02 0-1.877-.32-2.572-.96a8.588 8.588 0 0 1-1.738-2.237 11.524 11.524 0 0 1-1.042-2.621c-.232-.895-.348-1.641-.348-2.238V0h.278c.834 0 1.622.085 2.363.256.742.17 1.645.575 2.711 1.214 1.066.64 2.363 1.535 3.892 2.686 1.53 1.15 3.453 2.664 5.77 4.54 2.502 2.045 4.494 3.771 5.977 5.178 1.483 1.406 2.618 2.6 3.406 3.58.787.98 1.274 1.812 1.46 2.494.185.682.277 1.278.277 1.79v2.046H84.068zM127.3 84.01c.278.682.464 1.535.556 2.558.093 1.023-.37 2.003-1.39 2.94-.463.427-.88.832-1.25 1.215-.372.384-.696.704-.974.96a6.69 6.69 0 0 1-.973.767l-11.816-10.741a44.331 44.331 0 0 0 1.877-1.535 31.028 31.028 0 0 1 1.737-1.406c1.112-.938 2.317-1.343 3.615-1.215 1.297.128 2.363.405 3.197.83.927.427 1.923 1.173 2.989 2.239 1.065 1.065 1.876 2.195 2.432 3.388zM78.23 95.902c2.038 0 3.752-.511 5.143-1.534l-26.969 25.83H18.037c-1.761 0-3.684-.47-5.77-1.407a24.549 24.549 0 0 1-5.838-3.709 21.373 21.373 0 0 1-4.518-5.306c-1.204-2.003-1.807-4.07-1.807-6.202V16.495c0-1.79.44-3.665 1.32-5.626A18.41 18.41 0 0 1 5.04 5.562a21.798 21.798 0 0 1 5.213-3.964C12.198.533 14.237 0 16.37 0h53.24v15.984c0 1.62.278 3.367.834 5.242a16.704 16.704 0 0 0 2.572 5.179c1.159 1.577 2.665 2.898 4.518 3.964 1.853 1.066 4.078 1.598 6.673 1.598h20.295v42.325L85.458 92.45c1.02-1.364 1.529-2.856 1.529-4.476 0-2.216-.857-4.113-2.572-5.69-1.714-1.577-3.776-2.366-6.186-2.366H26.1c-2.409 0-4.448.789-6.116 2.366-1.668 1.577-2.502 3.474-2.502 5.69 0 2.217.834 4.092 2.502 5.626 1.668 1.535 3.707 2.302 6.117 2.302h52.13zM26.1 47.951c-2.41 0-4.449.789-6.117 2.366-1.668 1.577-2.502 3.473-2.502 5.69 0 2.216.834 4.092 2.502 5.626 1.668 1.534 3.707 2.302 6.117 2.302h52.13c2.409 0 4.47-.768 6.185-2.302 1.715-1.534 2.572-3.41 2.572-5.626 0-2.217-.857-4.113-2.572-5.69-1.714-1.577-3.776-2.366-6.186-2.366H26.1zm52.407 64.063l1.807-1.663 3.476-3.196a479.75 479.75 0 0 0 4.587-4.284 500.757 500.757 0 0 1 5.004-4.667c3.985-3.666 8.48-7.758 13.485-12.276l11.677 10.741-13.485 12.404-5.004 4.603-4.587 4.22a179.46 179.46 0 0 0-3.267 3.068c-.88.853-1.367 1.322-1.46 1.407-.463.341-.973.703-1.529 1.087-.556.383-1.112.703-1.668.959-.556.256-1.413.575-2.572.959a83.5 83.5 0 0 1-3.545 1.087 72.2 72.2 0 0 1-3.475.895c-1.112.256-1.946.426-2.502.511-1.112.17-1.854.043-2.224-.383-.371-.426-.464-1.151-.278-2.174.092-.511.278-1.279.556-2.302.278-1.023.602-2.067.973-3.132l1.042-3.005c.325-.938.58-1.577.765-1.918a10.157 10.157 0 0 1 2.224-2.941z"/></svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="200px" height="199.80px" viewBox="0 0 1025 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M765.635944 509.492976a254.300682 254.300682 0 0 1-209.783733-110.496289l-111.005782 55.471048A213.222811 213.222811 0 0 1 447.202834 477.649665a222.011564 222.011564 0 0 1-21.016585 93.237215l297.352838 148.708262a156.732777 156.732777 0 0 1 73.940168-19.105986 161.76402 161.76402 0 1 1-153.421072 118.77555l-302.893575-152.847893a222.903177 222.903177 0 1 1 54.515749-330.024076l117.565504-58.782752A230.991378 230.991378 0 0 1 510.889456 254.746488a254.746488 254.746488 0 1 1 254.746488 254.746488zM224.299657 382.119732A95.529933 95.529933 0 1 0 319.82959 477.649665 95.529933 95.529933 0 0 0 224.299657 382.119732zM765.635944 127.373244a127.373244 127.373244 0 1 0 127.373244 127.373244 127.373244 127.373244 0 0 0-127.373244-127.373244z" /></svg>

After

Width:  |  Height:  |  Size: 1021 B

1
src/icons/svg/home.svg Normal file
View File

@ -0,0 +1 @@
<svg t="1580047428057" class="icon" viewBox="0 0 1044 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2512" width="200" height="200"><path d="M898.477419 383.174194 898.477419 158.554839l-105.703226 0 0 125.522581L521.909677 0 0 535.122581l138.735484 0 0 402.993548c0 46.245161 39.63871 79.277419 79.277419 79.277419l198.193548 0 0-244.43871c0-19.819355 19.819355-59.458065 46.245161-66.064516 52.851613 0 59.458065 0 112.309677 0 26.425806 6.606452 46.245161 46.245161 46.245161 66.064516l0 244.43871 191.587097 0c46.245161 0 79.277419-39.63871 79.277419-79.277419L891.870968 535.122581l145.341935 0L898.477419 383.174194 898.477419 383.174194z" p-id="2513"></path></svg>

After

Width:  |  Height:  |  Size: 686 B

1
src/icons/svg/image.svg Normal file
View File

@ -0,0 +1 @@
<svg t="1580291384841" class="icon" viewBox="0 0 1280 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="26151" width="32" height="32"><path d="M466.346667 658.346667l63.146666 58.453333 285.866667-263.68a148.053333 148.053333 0 0 1 196.693333 0l267.946667 247.466667V42.666667a42.666667 42.666667 0 0 0-42.666667-42.666667H42.666667a42.666667 42.666667 0 0 0-42.666667 42.666667v848.213333l251.306667-232.533333a161.706667 161.706667 0 0 1 215.04 0z" fill="#FFFFFF" p-id="26152"></path><path d="M42.666667 1024h154.453333l332.373333-307.2-63.146666-58.453333a161.706667 161.706667 0 0 0-213.333334 0L0 890.88V981.333333a42.666667 42.666667 0 0 0 42.666667 42.666667zM815.36 453.12l-285.866667 263.68 332.8 307.2H1237.333333a42.666667 42.666667 0 0 0 42.666667-42.666667v-280.746666l-267.946667-247.466667a148.053333 148.053333 0 0 0-196.693333 0z" fill="#99BF87" p-id="26153"></path><path d="M197.12 1024h665.173333l-332.8-307.2L197.12 1024z" fill="#99BF87" p-id="26154"></path><path d="M1237.333333 42.666667v938.666666H42.666667V42.666667h1194.666666m0-42.666667H42.666667a42.666667 42.666667 0 0 0-42.666667 42.666667v938.666666a42.666667 42.666667 0 0 0 42.666667 42.666667h1194.666666a42.666667 42.666667 0 0 0 42.666667-42.666667V42.666667a42.666667 42.666667 0 0 0-42.666667-42.666667z" fill="#4D4D4D" p-id="26155"></path><path d="M277.333333 277.333333m-128 0a128 128 0 1 0 256 0 128 128 0 1 0-256 0Z" fill="#F4CB5A" p-id="26156"></path></svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

1
src/icons/svg/link.svg Normal file
View File

@ -0,0 +1 @@
<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M115.625 127.937H.063V12.375h57.781v12.374H12.438v90.813h90.813V70.156h12.374z"/><path d="M116.426 2.821l8.753 8.753-56.734 56.734-8.753-8.745z"/><path d="M127.893 37.982h-12.375V12.375H88.706V0h39.187z"/></svg>

After

Width:  |  Height:  |  Size: 285 B

View File

@ -0,0 +1 @@
<svg t="1580454680514" class="icon" viewBox="0 0 1025 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2186" width="32" height="32"><path d="M89.087 992c-31.478 0-57.087-25.591-57.087-57.062l0-725.015c0-31.478 25.612-57.09 57.087-57.09l330.922 0 239.715 239.713 0 542.364c0 31.476-25.614 57.09-57.09 57.09l-513.546-0.001zM85.744 938.292l520.233 0 0-490.04-241.673 0 0-241.672-278.559 0 0 731.711zM418.019 394.508l167.658 0-167.658-167.655 0 167.655zM726.82 871.191l0-53.742 211.466 0 0-490.03-241.676 0 0-241.672-332.208 0c1.734-29.932 26.62-53.747 56.962-53.747l330.917 0 239.747 239.715 0 542.395c0 31.48-25.61 57.081-57.09 57.081l-208.118 0zM750.328 273.674l167.62 0-167.62-167.664 0 167.664z" p-id="2187"></path></svg>

After

Width:  |  Height:  |  Size: 735 B

View File

@ -0,0 +1 @@
<svg t="1581231805740" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="14283" width="32" height="32"><path d="M704 288h-281.6l177.6-202.88a32 32 0 0 0-48.32-42.24l-224 256a30.08 30.08 0 0 0-2.24 3.84 32 32 0 0 0-2.88 4.16v1.92a32 32 0 0 0 0 5.12A32 32 0 0 0 320 320a32 32 0 0 0 0 4.8 32 32 0 0 0 0 5.12v1.92a32 32 0 0 0 2.88 4.16 30.08 30.08 0 0 0 2.24 3.84l224 256a32 32 0 1 0 48.32-42.24L422.4 352H704a224 224 0 0 1 224 224v128a224 224 0 0 1-224 224H320a232 232 0 0 1-28.16-1.6 32 32 0 0 0-35.84 27.84 32 32 0 0 0 27.84 35.52A295.04 295.04 0 0 0 320 992h384a288 288 0 0 0 288-288v-128a288 288 0 0 0-288-288zM103.04 760a32 32 0 0 0-62.08 16A289.92 289.92 0 0 0 140.16 928a32 32 0 0 0 40-49.92 225.6 225.6 0 0 1-77.12-118.08zM64 672a32 32 0 0 0 22.72-9.28 37.12 37.12 0 0 0 6.72-10.56A32 32 0 0 0 96 640a33.6 33.6 0 0 0-9.28-22.72 32 32 0 0 0-10.56-6.72 32 32 0 0 0-34.88 6.72A32 32 0 0 0 32 640a32 32 0 0 0 2.56 12.16 37.12 37.12 0 0 0 6.72 10.56A32 32 0 0 0 64 672z" fill="#231815" p-id="14284"></path></svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -0,0 +1 @@
<svg t="1580454538273" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1114" width="32" height="32"><path d="M896 426.666667a21.333333 21.333333 0 1 1 42.666667 0v469.333333a85.333333 85.333333 0 0 1-85.333334 85.333333H170.666667a85.333333 85.333333 0 0 1-85.333334-85.333333V128a85.333333 85.333333 0 0 1 85.333334-85.333333h384a21.333333 21.333333 0 1 1 0 42.666666H170.666667a42.666667 42.666667 0 0 0-42.666667 42.666667v768a42.666667 42.666667 0 0 0 42.666667 42.666667h682.666666a42.666667 42.666667 0 0 0 42.666667-42.666667V426.666667z m-211.157333-85.333334C660.096 341.333333 640 321.28 640 296.490667V67.114667c0-0.554667 0-1.066667 0.085333-1.536a21.333333 21.333333 0 0 1 36.394667-15.658667l255.872 255.018667a21.290667 21.290667 0 0 1-16.170667 36.394666h-231.338666z m-3.114667-225.92v184.490667h185.130667l-185.130667-184.490667zM277.333333 298.666667h256a21.333333 21.333333 0 1 1 0 42.666666h-256a21.333333 21.333333 0 0 1 0-42.666666z m0 213.333333h469.333334a21.333333 21.333333 0 1 1 0 42.666667h-469.333334a21.333333 21.333333 0 1 1 0-42.666667z m0 213.333333h469.333334a21.333333 21.333333 0 1 1 0 42.666667h-469.333334a21.333333 21.333333 0 1 1 0-42.666667z" p-id="1115"></path></svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -0,0 +1 @@
<svg t="1580454761642" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3628" width="32" height="32"><path d="M793.6 358.4C768 227.2 652.8 128 512 128s-256 99.2-281.6 230.4C134.4 384 64 473.6 64 576c0 124.8 99.2 224 224 224h32v-64h-32c-89.6 0-160-70.4-160-160s70.4-160 160-160c0-124.8 99.2-224 224-224s224 99.2 224 224c89.6 0 160 70.4 160 160s-70.4 160-160 160h-32v64h32c124.8 0 224-99.2 224-224 0-102.4-70.4-192-166.4-217.6z" fill="" p-id="3629"></path><path d="M588.8 748.8L550.4 784V512c0-19.2-16-32-32-32-19.2 0-32 16-32 32v272L448 748.8c-12.8-12.8-35.2-12.8-48 0-12.8 12.8-12.8 32 0 44.8l96 92.8c3.2 3.2 6.4 6.4 9.6 6.4 12.8 6.4 25.6 3.2 35.2-6.4l92.8-92.8c12.8-12.8 12.8-32 0-44.8-9.6-12.8-32-12.8-44.8 0z" fill="" p-id="3630"></path></svg>

After

Width:  |  Height:  |  Size: 790 B

View File

@ -0,0 +1 @@
<svg t="1580456423628" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="17397" width="32" height="32"><path d="M512 6.4l-160 320-352 51.2 256 249.6-57.6 352L512 812.8l313.6 166.4-57.6-352 256-249.6-352-51.2L512 6.4z" p-id="17398" fill="#d81e06"></path></svg>

After

Width:  |  Height:  |  Size: 302 B

View File

@ -0,0 +1 @@
<svg t="1580455045716" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5783" width="32" height="32"><path d="M739.332181 637.364219l53.626512 328.45059L511.999488 810.674427 231.041307 965.813786l53.626512-328.45059L58.167108 405.470755l313.090289-47.780213L511.999488 58.18519 652.742603 357.690542l313.090289 47.780213L739.332181 637.364219zM617.563988 407.548066 511.999488 180.503027 405.494532 407.548066l-245.391717 31.908734 181.405852 185.16521-40.220651 238.374062 210.712496-118.134561 208.052814 119.021767-37.559946-238.374062 179.63239-183.281303L617.563988 407.548066z" p-id="5784"></path></svg>

After

Width:  |  Height:  |  Size: 654 B

View File

@ -0,0 +1 @@
<svg t="1581143686674" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2667" width="32" height="32"><path d="M512.7 813.2h-0.6c-79.1-0.1-160.8-26.3-242.8-77.8-38.7-24.3-98.3-67.7-162.9-136.8-20.7-22.1-32.5-54.6-32.5-89 0.1-34.4 12-66.8 32.8-88.9 35.8-38 93.2-92.5 163.4-136.3 81.9-51.1 163.5-77 242.5-77h0.6c79.1 0.1 160.8 26.3 242.8 77.8 38.7 24.3 98.3 67.7 162.9 136.8 20.7 22.1 32.5 54.6 32.5 89s-12 66.8-32.8 88.9c-35.8 38-93.2 92.5-163.4 136.3-82 51.1-163.6 77-242.5 77z m-0.2-529.2C362.9 284 229 402.5 162.4 473.2c-7.3 7.8-11.9 21.8-11.9 36.5s4.5 28.7 11.8 36.5c66.4 71 200.2 190.1 349.9 190.4h0.5c149.5 0 283.5-118.5 350.1-189.2 7.3-7.8 11.9-21.8 12-36.5 0-14.7-4.5-28.7-11.8-36.5-66.5-71-200.3-190.1-350-190.4h-0.5z" p-id="2668"></path><path d="M512.6 646h-0.2c-36.2-0.1-70.3-14.2-95.9-39.9-25.6-25.7-39.6-59.8-39.6-96 0.1-74.7 61-135.5 135.7-135.5h0.2c36.2 0.1 70.3 14.2 95.9 39.9s39.6 59.8 39.6 96l-32.6-0.1 32.6 0.1c-0.1 74.8-61 135.5-135.7 135.5z m0-206.2c-38.9 0-70.5 31.6-70.6 70.4 0 18.8 7.3 36.6 20.6 49.9 13.3 13.3 31 20.7 49.9 20.8h0.1c18.8 0 36.5-7.3 49.8-20.6 13.3-13.3 20.7-31 20.8-49.9 0-18.8-7.3-36.6-20.6-49.9-13.3-13.3-31-20.7-49.9-20.8 0 0.1-0.1 0.1-0.1 0.1z" p-id="2669"></path></svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -0,0 +1 @@
<svg t="1580454842221" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4508" width="32" height="32"><path d="M873.11 123.11H703.64C690.73 59.8 634.62 12 567.56 12H456.44c-67.07 0-123.17 47.8-136.08 111.11H150.89C74.31 123.11 12 185.42 12 262a27.76 27.76 0 0 0 27.78 27.78h111.11v611.11A111.22 111.22 0 0 0 262 1012h500a111.22 111.22 0 0 0 111.11-111.11V289.78h111.11A27.76 27.76 0 0 0 1012 262c0-76.58-62.31-138.89-138.89-138.89zM456.44 67.56h111.12a83.51 83.51 0 0 1 78.59 55.56H377.86a83.51 83.51 0 0 1 78.58-55.56z m361.12 833.33A55.63 55.63 0 0 1 762 956.44H262a55.63 55.63 0 0 1-55.56-55.56v-611.1h611.12z m55.56-666.67H72.3a83.51 83.51 0 0 1 78.59-55.56h722.22a83.51 83.51 0 0 1 78.59 55.56z" p-id="4509"></path><path d="M512 845.33a27.76 27.76 0 0 0 27.78-27.78V428.67a27.78 27.78 0 1 0-55.56 0v388.89A27.76 27.76 0 0 0 512 845.33zM345.33 845.33a27.76 27.76 0 0 0 27.78-27.78V428.67a27.78 27.78 0 1 0-55.56 0v388.89a27.76 27.76 0 0 0 27.78 27.77zM678.67 845.33a27.76 27.76 0 0 0 27.78-27.78V428.67a27.78 27.78 0 1 0-55.56 0v388.89a27.76 27.76 0 0 0 27.78 27.77z" p-id="4510"></path></svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -0,0 +1 @@
<svg t="1580454938893" class="icon" viewBox="0 0 1026 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5043" width="32" height="32"><path d="M785.459067 690.328142C810.008816 580.800301 872.898939 501.633478 947.617907 449.950533 958.073212 442.718621 965.748762 438.163038 969.580614 436.183735 987.177002 427.094503 990.847549 403.514431 976.846513 389.506647L662.792374 75.301147C648.78716 61.289183 625.197263 64.955438 616.105319 82.557077 614.126015 86.38893 609.570432 94.06448 602.338521 104.519785 550.655575 179.238753 471.488753 242.128877 361.96091 266.678624 323.663691 275.262624 282.745817 278.641528 239.065568 276.265413 220.796811 275.271631 206.108004 291.100916 208.462536 309.244545 208.934292 312.879813 209.621584 320.719112 210.132275 332.528648 211.004519 352.698935 210.916618 376.374966 209.477 403.324341 205.332587 480.906963 191.08296 568.808066 163.591773 665.193747 135.033631 765.320213 93.663966 868.918643 37.724798 974.985036 24.307503 1000.4256 51.80564 1027.927626 77.248099 1014.513923 183.240284 958.633022 286.761824 917.295234 386.812243 888.747293 483.239269 861.233234 571.174257 846.969369 648.783825 842.817513 675.742499 841.375315 699.426275 841.285857 719.602817 842.157343 731.415982 842.667592 739.257541 843.354795 742.893769 843.826599 761.037193 846.180709 776.866046 831.491988 775.87228 813.223486 773.496164 769.543236 776.875066 728.625361 785.459067 690.328142ZM448.918022 562.838898 160.479225 851.277696C184.253449 793.738045 203.957586 737.004916 219.861984 681.24318 248.582783 580.546428 263.53465 488.313419 267.907972 406.445686 269.449561 377.587436 269.544455 352.027572 268.591922 330.000621 268.007747 316.491814 267.174286 306.985289 266.490244 301.714179L235.887212 334.693311C284.915293 337.360336 331.209218 333.537491 374.758854 323.776205 500.501049 295.592147 591.11163 223.611103 650.462239 137.806855 659.182362 125.200014 665.008522 115.383712 668.093616 109.411093L621.406561 116.667023 935.460701 430.872524 942.726599 384.195437C936.75398 387.280532 926.937678 393.106691 914.330838 401.826815 828.526589 461.177424 756.545544 551.788004 728.361486 677.530199 718.600201 721.079836 714.777355 767.37376 717.444382 816.401842L750.422892 785.79873C745.150251 785.114604 735.640885 784.281239 722.127882 783.697572 700.094146 782.745867 674.52602 782.842441 645.657977 784.386784 563.76265 788.767912 471.495235 803.734537 370.756837 832.478783 316.045559 848.089855 260.397894 867.358252 203.969374 890.539244L490.642894 603.865723C524.581196 619.747904 566.778577 612.940617 595.320675 584.398519 631.444709 548.274484 632.752928 490.276793 597.309898 454.833763 561.866869 419.390734 503.869177 420.698952 467.745143 456.822986 438.8267 485.741429 432.22002 528.677634 448.918022 562.838898ZM54.034097 960.610544C52.676004 961.32234 51.317555 962.036427 49.958753 962.75281L52.470091 965.264511C52.857538 963.681123 53.378872 962.123797 54.034097 960.610544ZM87.864243 1000.663659 89.482053 1002.281697C89.921828 1001.44784 90.360736 1000.61412 90.798776 999.780536 89.83371 1000.127229 88.854063 1000.421607 87.864243 1000.663659ZM975.299042 335.443671 969.015949 303.417997 928.982665 398.651909 976.641604 389.301737 662.618323 75.278456 653.191756 122.969382 748.649269 83.1597 716.699991 76.84462 975.299042 335.443671ZM726.126558 29.153694 630.669045 68.963376C611.452395 76.977504 606.519946 101.93177 621.242478 116.654302L935.265758 430.677582C949.963217 445.375042 974.869943 440.48861 982.924697 421.327411L1022.957981 326.093498C1027.565314 315.13326 1025.08186 302.474797 1016.674888 294.067825L758.075837 35.468774C749.690194 27.083132 737.071954 24.589016 726.126558 29.153694Z" p-id="5044"></path></svg>

After

Width:  |  Height:  |  Size: 3.6 KiB

1
src/icons/svg/more.svg Normal file
View File

@ -0,0 +1 @@
<svg t="1580453410476" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="56890" width="32" height="32"><path d="M779.535731 510.304382c0 50.520627 40.056298 91.486644 89.447195 91.486644 49.408293 0 89.455381-40.966017 89.455381-91.486644 0-50.52779-40.047088-91.485621-89.455381-91.485621C819.592029 418.818761 779.535731 459.775568 779.535731 510.304382L779.535731 510.304382zM600.625992 510.304382c0-50.52779-40.049135-91.485621-89.448218-91.485621-49.400107 0-89.455381 40.957831-89.455381 91.485621 0 50.520627 40.055275 91.486644 89.455381 91.486644C560.57788 601.791026 600.625992 560.825009 600.625992 510.304382L600.625992 510.304382zM242.819816 510.304382c0-50.52779-40.008202-91.485621-89.454358-91.485621-49.400107 0-89.448218 40.957831-89.448218 91.485621 0 50.520627 40.048111 91.486644 89.448218 91.486644C202.81059 601.791026 242.819816 560.825009 242.819816 510.304382L242.819816 510.304382zM242.819816 510.304382" p-id="56891"></path></svg>

After

Width:  |  Height:  |  Size: 1001 B

1
src/icons/svg/nested.svg Normal file
View File

@ -0,0 +1 @@
<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M.002 9.2c0 5.044 3.58 9.133 7.998 9.133 4.417 0 7.997-4.089 7.997-9.133 0-5.043-3.58-9.132-7.997-9.132S.002 4.157.002 9.2zM31.997.066h95.981V18.33H31.997V.066zm0 45.669c0 5.044 3.58 9.132 7.998 9.132 4.417 0 7.997-4.088 7.997-9.132 0-3.263-1.524-6.278-3.998-7.91-2.475-1.63-5.524-1.63-7.998 0-2.475 1.632-4 4.647-4 7.91zM63.992 36.6h63.986v18.265H63.992V36.6zm-31.995 82.2c0 5.043 3.58 9.132 7.998 9.132 4.417 0 7.997-4.089 7.997-9.132 0-5.044-3.58-9.133-7.997-9.133s-7.998 4.089-7.998 9.133zm31.995-9.131h63.986v18.265H63.992V109.67zm0-27.404c0 5.044 3.58 9.133 7.998 9.133 4.417 0 7.997-4.089 7.997-9.133 0-3.263-1.524-6.277-3.998-7.909-2.475-1.631-5.524-1.631-7.998 0-2.475 1.632-4 4.646-4 7.91zm31.995-9.13h31.991V91.4H95.987V73.135z"/></svg>

After

Width:  |  Height:  |  Size: 821 B

View File

@ -0,0 +1 @@
<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M108.8 44.322H89.6v-5.36c0-9.04-3.308-24.163-25.6-24.163-23.145 0-25.6 16.881-25.6 24.162v5.361H19.2v-5.36C19.2 15.281 36.798 0 64 0c27.202 0 44.8 15.281 44.8 38.961v5.361zm-32 39.356c0-5.44-5.763-9.832-12.8-9.832-7.037 0-12.8 4.392-12.8 9.832 0 3.682 2.567 6.808 6.407 8.477v11.205c0 2.718 2.875 4.962 6.4 4.962 3.524 0 6.4-2.244 6.4-4.962V92.155c3.833-1.669 6.393-4.795 6.393-8.477zM128 64v49.201c0 8.158-8.645 14.799-19.2 14.799H19.2C8.651 128 0 121.359 0 113.201V64c0-8.153 8.645-14.799 19.2-14.799h89.6c10.555 0 19.2 6.646 19.2 14.799z"/></svg>

After

Width:  |  Height:  |  Size: 623 B

1
src/icons/svg/share.svg Normal file
View File

@ -0,0 +1 @@
<svg t="1580453295915" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="52816" width="32" height="32"><path d="M928 480c-17.664 0-32 14.336-32 32l0 320c0 17.664-14.336 32-32 32L160 864c-17.664 0-32-14.336-32-32L128 288c0-17.664 14.336-32 32-32l224 0 0 0c0 0 0 0 0 0 17.664 0 32-14.336 32-32s-14.336-32-32-32c-1.024 0-1.888 0.48-2.88 0.576L160.384 192.576c-52.96 0-95.904 43.008-95.904 96.064l0 543.872c0 53.056 42.944 96.064 95.904 96.064l704.224 0c52.96 0 95.904-43.008 95.904-96.064L960.512 512 960 512C960 494.336 945.664 480 928 480zM402.688 620.768c-1.92 4.128-3.168 8.608-3.168 13.44 0 17.664 14.336 32 32 32 15.456 0 27.744-11.168 30.752-25.76l0.64 0c37.12-189.696 193.984-336.256 388.672-358.272l-67.776 67.776c-12.512 12.512-12.512 32.768 0 45.248 12.512 12.512 32.768 12.512 45.248 0l122.528-122.528c12.512-12.512 12.512-32.768 0-45.248l-122.528-122.528c-12.512-12.512-32.768-12.512-45.248 0-12.512 12.512-12.512 32.768 0 45.248l67.52 67.52C628.256 239.872 448.224 405.408 402.688 620.768z" p-id="52817"></path></svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

1
src/icons/svg/table.svg Normal file
View File

@ -0,0 +1 @@
<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M.006.064h127.988v31.104H.006V.064zm0 38.016h38.396v41.472H.006V38.08zm0 48.384h38.396v41.472H.006V86.464zM44.802 38.08h38.396v41.472H44.802V38.08zm0 48.384h38.396v41.472H44.802V86.464zM89.598 38.08h38.396v41.472H89.598zm0 48.384h38.396v41.472H89.598z"/><path d="M.006.064h127.988v31.104H.006V.064zm0 38.016h38.396v41.472H.006V38.08zm0 48.384h38.396v41.472H.006V86.464zM44.802 38.08h38.396v41.472H44.802V38.08zm0 48.384h38.396v41.472H44.802V86.464zM89.598 38.08h38.396v41.472H89.598zm0 48.384h38.396v41.472H89.598z"/></svg>

After

Width:  |  Height:  |  Size: 597 B

1
src/icons/svg/tree.svg Normal file
View File

@ -0,0 +1 @@
<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M126.713 90.023c.858.985 1.287 2.134 1.287 3.447v29.553c0 1.423-.429 2.6-1.287 3.53-.858.93-1.907 1.395-3.146 1.395H97.824c-1.145 0-2.146-.465-3.004-1.395-.858-.93-1.287-2.107-1.287-3.53V93.47c0-.875.19-1.696.572-2.462.382-.766.906-1.368 1.573-1.806a3.84 3.84 0 0 1 2.146-.657h9.725V69.007a3.84 3.84 0 0 0-.43-1.806 3.569 3.569 0 0 0-1.143-1.313 2.714 2.714 0 0 0-1.573-.492h-36.47v23.149h9.725c1.144 0 2.145.492 3.004 1.478.858.985 1.287 2.134 1.287 3.447v29.553c0 .876-.191 1.696-.573 2.463-.38.766-.905 1.368-1.573 1.806a3.84 3.84 0 0 1-2.145.656H51.915a3.84 3.84 0 0 1-2.145-.656c-.668-.438-1.216-1.04-1.645-1.806a4.96 4.96 0 0 1-.644-2.463V93.47c0-1.313.43-2.462 1.288-3.447.858-.986 1.907-1.478 3.146-1.478h9.582v-23.15h-37.9c-.953 0-1.74.356-2.359 1.068-.62.711-.93 1.56-.93 2.544v19.538h9.726c1.239 0 2.264.492 3.074 1.478.81.985 1.216 2.134 1.216 3.447v29.553c0 1.423-.405 2.6-1.216 3.53-.81.93-1.835 1.395-3.074 1.395H4.29c-.476 0-.93-.082-1.358-.246a4.1 4.1 0 0 1-1.144-.657 4.658 4.658 0 0 1-.93-1.067 5.186 5.186 0 0 1-.643-1.395 5.566 5.566 0 0 1-.215-1.56V93.47c0-.437.048-.875.143-1.313a3.95 3.95 0 0 1 .429-1.15c.19-.328.429-.656.715-.984.286-.329.572-.602.858-.821.286-.22.62-.383 1.001-.493.382-.11.763-.164 1.144-.164h9.726V61.619c0-.985.31-1.833.93-2.544.619-.712 1.358-1.068 2.216-1.068h44.335V39.62h-9.582c-1.24 0-2.288-.492-3.146-1.477a5.09 5.09 0 0 1-1.287-3.448V5.14c0-1.423.429-2.627 1.287-3.612.858-.985 1.907-1.477 3.146-1.477h25.743c.763 0 1.478.246 2.145.739a5.17 5.17 0 0 1 1.573 1.888c.382.766.573 1.587.573 2.462v29.553c0 1.313-.43 2.463-1.287 3.448-.859.985-1.86 1.477-3.004 1.477h-9.725v18.389h42.762c.954 0 1.74.355 2.36 1.067.62.711.93 1.56.93 2.545v26.925h9.582c1.239 0 2.288.492 3.146 1.478z"/></svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

1
src/icons/svg/txt.svg Normal file
View File

@ -0,0 +1 @@
<svg t="1581162761983" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="13375" width="32" height="32"><path d="M789.4 223.4h177.4v732.2c0 37.8-28.8 66.6-66.6 66.6H190.4c-37.8 0-66.6-28.8-66.6-66.6V68.4c0-37.8 28.8-66.6 66.6-66.6h554.7v177.4h44.5v44.2h-0.2z m-66.7-22.1V23.9H190.4c-24.5 0-44.5 20-44.5 44.5v887.2c0 24.5 20 44.5 44.5 44.5h709.8c24.5 0 44.5-20 44.5-44.5V245.5H767.3V201h-44.5l-0.1 0.3z" fill="#9FA0A6" p-id="13376"></path><path d="M212.5 889H878v44.5H212.5zM212.5 778.2H878v44.5H212.5zM212.5 667H878v44.5H212.5z" fill="#9FA0A6" p-id="13377"></path><path d="M101.7 112.6h354.9c24.5 0 44.5 20 44.5 44.5V512c0 24.5-20 44.5-44.5 44.5H101.7c-24.5 0-44.5-20-44.5-44.5V156.8c0-24.2 20-44.2 44.5-44.2z" fill="#05C1E0" p-id="13378"></path><path d="M254.3 459.9V271c0-3.9-3-7-7-7h-58.7c-3.9 0-7-3-7-7v-27.6c0-3.9 3-7 7-7h180.2c3.9 0 7 3 7 7V257c0 3.9-3 7-7 7h-58.4c-3.9 0-7 3-7 7v188.9c0 3.9-3 7-7 7H261c-3.7-0.3-6.7-3.3-6.7-7z" fill="#FFFFFF" p-id="13379"></path></svg>

After

Width:  |  Height:  |  Size: 1018 B

1
src/icons/svg/user.svg Normal file
View File

@ -0,0 +1 @@
<svg width="130" height="130" xmlns="http://www.w3.org/2000/svg"><path d="M63.444 64.996c20.633 0 37.359-14.308 37.359-31.953 0-17.649-16.726-31.952-37.359-31.952-20.631 0-37.36 14.303-37.358 31.952 0 17.645 16.727 31.953 37.359 31.953zM80.57 75.65H49.434c-26.652 0-48.26 18.477-48.26 41.27v2.664c0 9.316 21.608 9.325 48.26 9.325H80.57c26.649 0 48.256-.344 48.256-9.325v-2.663c0-22.794-21.605-41.271-48.256-41.271z" stroke="#979797"/></svg>

After

Width:  |  Height:  |  Size: 440 B

1
src/icons/svg/video.svg Normal file
View File

@ -0,0 +1 @@
<svg t="1580291445065" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="29001" width="32" height="32"><path d="M957.38 50.708l-82.814 98.53h-168.908l82.812-98.53h-142.548l-82.814 98.53H394.2l82.814-98.53h-142.5l-82.812 98.53H82.792l82.812-98.53H32.308v233.518h133.296L82.792 185.696h168.91l82.812 98.53h142.5L394.2 185.696h168.908l82.814 98.53h142.548l-82.812-98.53h168.908l82.814 98.53h34.27V50.708z" fill="#F58E70" p-id="29002"></path><path d="M0 18.398v859.204c0 70.58 57.422 128 128.002 128h767.996c70.58 0 128.002-57.42 128.002-128V18.398H0z m1009.078 859.204c0 62.352-50.728 113.078-113.08 113.078H128.002c-62.352 0-113.08-50.726-113.08-113.078V33.32H1009.08v844.282z" fill="#4B555F" p-id="29003"></path><path d="M0 301.624v50.8h1024v-50.8H0z m1009.078 35.878H14.922v-20.956H1009.08v20.956z" fill="#4B555F" p-id="29004"></path><path d="M255.158 178.25H66.768l116.252 138.294h188.386l-116.248-138.294z m-156.352 14.922h149.408l91.154 108.452H189.964L98.806 193.172zM183.02 18.398L66.768 156.692h188.392l116.248-138.294H183.02z m65.192 123.372H98.806l91.16-108.452h149.402l-91.156 108.452zM566.588 178.25h-188.386l116.248 138.294h188.386l-116.248-138.294z m-156.348 14.922h149.402l91.156 108.452h-149.402L410.24 193.172zM494.448 18.398L378.2 156.692h188.386l116.248-138.294h-188.386z m65.194 123.372H410.24l91.156-108.452h149.402l-91.156 108.452zM878.022 178.25h-188.386l116.248 138.294h188.386l-116.248-138.294z m-156.348 14.922h149.402l91.156 108.452h-149.402l-91.156-108.452zM805.882 18.398l-116.248 138.294h188.386l116.248-138.294h-188.386z m65.194 123.372h-149.402l91.154-108.452h149.402l-91.154 108.452zM381.78 447.384v423.602l338.794-211.8L381.78 447.384z m14.922 26.922l295.72 184.878-295.72 184.878V474.306z" fill="#4B555F" p-id="29005"></path><path d="M414.11 505.72v306.928l245.474-153.466z" fill="#F58E70" p-id="29006"></path><path d="M0 18.398v298.146h1024V18.398H0z m1009.078 283.226H14.922V33.32H1009.08v268.304z" fill="#4B555F" p-id="29007"></path></svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

1
src/icons/svg/zip.svg Normal file
View File

@ -0,0 +1 @@
<svg t="1580291823744" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="31150" width="32" height="32"><path d="M944 944H80c-26.4 0-48-18.4-48-40.8V656h960v247.2c0 22.4-21.6 40.8-48 40.8z" fill="#5ACC9B" p-id="31151"></path><path d="M80 80h864c26.4 0 48 18.4 48 40.8V368H32V120.8c0-22.4 21.6-40.8 48-40.8z" fill="#6CCBFF" p-id="31152"></path><path d="M32 368h960v288H32z" fill="#FFD766" p-id="31153"></path><path d="M352 80h320v864H352z" fill="#FF5562" p-id="31154"></path><path d="M444 128h64v48h-64zM508 80h64v48h-64zM508 176h64v48h-64zM444 224h64v48h-64zM508 272h64v48h-64zM444 320h64v48h-64zM508 368h64v48h-64zM444 416h64v48h-64zM508 464h64v48h-64zM444 512h64v48h-64zM508 560h64v48h-64zM444 608h64v48h-64zM508 656h64v48h-64zM444 704h64v48h-64zM508 752h64v48h-64zM444 800h64v48h-64zM444 896h64v48h-64zM508 848h64v48h-64z" fill="#FFFFFF" p-id="31155"></path></svg>

After

Width:  |  Height:  |  Size: 909 B

1
src/icons/svg/ziyuan.svg Normal file
View File

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="200px" height="160.00px" viewBox="0 0 1280 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M0 992a32 32 0 0 0 32 32h1216a32 32 0 0 0 32-32V224a32 32 0 0 0-32-32H576l-192-192H32a32 32 0 0 0-32 32z" /></svg>

After

Width:  |  Height:  |  Size: 381 B

View File

@ -0,0 +1 @@
<svg t="1579936520620" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="8696" width="200" height="200"><path d="M785.546573 781.547354c-35.593048 35.093146-76.984964 62.787737-123.275923 82.183948-47.890646 20.196055-98.780707 30.694005-151.470416 31.193908h-4.099199c-53.289592 0-104.579574-10.297989-152.770162-30.594025-46.49092-19.596173-87.882835-47.690685-123.075962-83.383714-70.286272-71.386057-108.278852-166.667448-106.679164-267.947666 0.799844-52.089826 11.497754-102.280023 31.893771-149.570787 19.696153-45.791056 47.590705-86.78305 82.883811-121.976177 72.585823-72.285882 169.466901-112.17809 272.446788-112.17809 52.389768 0 103.179848 10.198008 150.970514 30.194103 46.190978 19.296231 87.482913 46.990822 123.075961 82.183948 35.593048 35.193126 63.4876 76.08514 82.883812 121.676235 20.096075 47.090803 30.394064 97.181019 30.394064 148.770943 0 101.780121-40.19215 197.461433-113.177895 269.447374M511.400117 69.286467c-246.951767 0-443.413396 198.261277-447.112673 442.813513C60.488186 759.351689 259.649287 954.813513 506.701035 954.813513h4.699082c246.951767-2.499512 447.212654-198.161297 447.212654-442.813513 0.09998-244.452255-200.260887-442.713533-447.212654-442.713533" p-id="8697"></path><path d="M736.656122 517.998828H511.200156V290.543253c0-16.596758-13.397383-29.994142-29.994142-29.994141s-29.994142 13.397383-29.994141 29.994141V547.89299c0 16.596758 13.397383 29.994142 29.994141 29.994141h255.350127c16.596758 0 29.994142-13.397383 29.994142-29.994141 0-16.496778-13.397383-29.894161-29.894161-29.894162" p-id="8698"></path></svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

22
src/icons/svgo.yml Normal file
View File

@ -0,0 +1,22 @@
# replace default config
# multipass: true
# full: true
plugins:
# - name
#
# or:
# - name: false
# - name: true
#
# or:
# - name:
# param1: 1
# param2: 2
- removeAttrs:
attrs:
- 'fill'
- 'fill-rule'

View File

@ -0,0 +1,40 @@
<template>
<section class="app-main">
<transition name="fade-transform" mode="out-in">
<router-view :key="key" />
</transition>
</section>
</template>
<script>
export default {
name: 'AppMain',
computed: {
key() {
return this.$route.path
}
}
}
</script>
<style scoped>
.app-main {
/*50 = navbar */
min-height: calc(100vh - 50px);
width: 100%;
position: relative;
overflow: hidden;
}
.fixed-header+.app-main {
padding-top: 50px;
}
</style>
<style lang="scss">
// fix css style bug in open el-dialog
.el-popup-parent--hidden {
.fixed-header {
padding-right: 15px;
}
}
</style>

View File

@ -0,0 +1,139 @@
<template>
<div class="navbar">
<hamburger :is-active="sidebar.opened" class="hamburger-container" @toggleClick="toggleSideBar" />
<breadcrumb class="breadcrumb-container" />
<div class="right-menu">
<el-dropdown class="avatar-container" trigger="click">
<div class="avatar-wrapper">
<img :src="avatar+'?imageView2/1/w/80/h/80'" class="user-avatar">
<i class="el-icon-caret-bottom" />
</div>
<el-dropdown-menu slot="dropdown" class="user-dropdown">
<router-link to="/">
<el-dropdown-item>
Home
</el-dropdown-item>
</router-link>
<a target="_blank" href="https://github.com/PanJiaChen/vue-admin-template/">
<el-dropdown-item>Github</el-dropdown-item>
</a>
<a target="_blank" href="https://panjiachen.github.io/vue-element-admin-site/#/">
<el-dropdown-item>Docs</el-dropdown-item>
</a>
<el-dropdown-item divided @click.native="logout">
<span style="display:block;">Log Out</span>
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
import Breadcrumb from '@/components/Breadcrumb'
import Hamburger from '@/components/Hamburger'
export default {
components: {
Breadcrumb,
Hamburger
},
computed: {
...mapGetters([
'sidebar',
'avatar'
])
},
methods: {
toggleSideBar() {
this.$store.dispatch('app/toggleSideBar')
},
async logout() {
await this.$store.dispatch('user/logout')
this.$router.push(`/login?redirect=${this.$route.fullPath}`)
}
}
}
</script>
<style lang="scss" scoped>
.navbar {
height: 50px;
overflow: hidden;
position: relative;
background: #fff;
box-shadow: 0 1px 4px rgba(0,21,41,.08);
.hamburger-container {
line-height: 46px;
height: 100%;
float: left;
cursor: pointer;
transition: background .3s;
-webkit-tap-highlight-color:transparent;
&:hover {
background: rgba(0, 0, 0, .025)
}
}
.breadcrumb-container {
float: left;
}
.right-menu {
float: right;
height: 100%;
line-height: 50px;
&:focus {
outline: none;
}
.right-menu-item {
display: inline-block;
padding: 0 8px;
height: 100%;
font-size: 18px;
color: #5a5e66;
vertical-align: text-bottom;
&.hover-effect {
cursor: pointer;
transition: background .3s;
&:hover {
background: rgba(0, 0, 0, .025)
}
}
}
.avatar-container {
margin-right: 30px;
.avatar-wrapper {
margin-top: 5px;
position: relative;
.user-avatar {
cursor: pointer;
width: 40px;
height: 40px;
border-radius: 10px;
}
.el-icon-caret-bottom {
cursor: pointer;
position: absolute;
right: -20px;
top: 25px;
font-size: 12px;
}
}
}
}
}
</style>

View File

@ -0,0 +1,26 @@
export default {
computed: {
device() {
return this.$store.state.app.device
}
},
mounted() {
// In order to fix the click on menu on the ios device will trigger the mouseleave bug
// https://github.com/PanJiaChen/vue-element-admin/issues/1135
this.fixBugIniOS()
},
methods: {
fixBugIniOS() {
const $subMenu = this.$refs.subMenu
if ($subMenu) {
const handleMouseleave = $subMenu.handleMouseleave
$subMenu.handleMouseleave = (e) => {
if (this.device === 'mobile') {
return
}
handleMouseleave(e)
}
}
}
}
}

View File

@ -0,0 +1,29 @@
<script>
export default {
name: 'MenuItem',
functional: true,
props: {
icon: {
type: String,
default: ''
},
title: {
type: String,
default: ''
}
},
render(h, context) {
const { icon, title } = context.props
const vnodes = []
if (icon) {
vnodes.push(<svg-icon icon-class={icon}/>)
}
if (title) {
vnodes.push(<span slot='title'>{(title)}</span>)
}
return vnodes
}
}
</script>

View File

@ -0,0 +1,36 @@
<template>
<!-- eslint-disable vue/require-component-is -->
<component v-bind="linkProps(to)">
<slot />
</component>
</template>
<script>
import { isExternal } from '@/utils/validate'
export default {
props: {
to: {
type: String,
required: true
}
},
methods: {
linkProps(url) {
if (isExternal(url)) {
return {
is: 'a',
href: url,
target: '_blank',
rel: 'noopener'
}
}
return {
is: 'router-link',
to: url
}
}
}
}
</script>

View File

@ -0,0 +1,82 @@
<template>
<div class="sidebar-logo-container" :class="{'collapse':collapse}">
<transition name="sidebarLogoFade">
<router-link v-if="collapse" key="collapse" class="sidebar-logo-link" to="/">
<img v-if="logo" :src="logo" class="sidebar-logo">
<h1 v-else class="sidebar-title">{{ title }} </h1>
</router-link>
<router-link v-else key="expand" class="sidebar-logo-link" to="/">
<img v-if="logo" :src="logo" class="sidebar-logo">
<h1 class="sidebar-title">{{ title }} </h1>
</router-link>
</transition>
</div>
</template>
<script>
export default {
name: 'SidebarLogo',
props: {
collapse: {
type: Boolean,
required: true
}
},
data() {
return {
title: 'Vue Admin Template',
logo: 'https://wpimg.wallstcn.com/69a1c46c-eb1c-4b46-8bd4-e9e686ef5251.png'
}
}
}
</script>
<style lang="scss" scoped>
.sidebarLogoFade-enter-active {
transition: opacity 1.5s;
}
.sidebarLogoFade-enter,
.sidebarLogoFade-leave-to {
opacity: 0;
}
.sidebar-logo-container {
position: relative;
width: 100%;
height: 50px;
line-height: 50px;
background: #2b2f3a;
text-align: center;
overflow: hidden;
& .sidebar-logo-link {
height: 100%;
width: 100%;
& .sidebar-logo {
width: 32px;
height: 32px;
vertical-align: middle;
margin-right: 12px;
}
& .sidebar-title {
display: inline-block;
margin: 0;
color: #fff;
font-weight: 600;
line-height: 50px;
font-size: 14px;
font-family: Avenir, Helvetica Neue, Arial, Helvetica, sans-serif;
vertical-align: middle;
}
}
&.collapse {
.sidebar-logo {
margin-right: 0px;
}
}
}
</style>

View File

@ -0,0 +1,95 @@
<template>
<div v-if="!item.hidden">
<template v-if="hasOneShowingChild(item.children,item) && (!onlyOneChild.children||onlyOneChild.noShowingChildren)&&!item.alwaysShow">
<app-link v-if="onlyOneChild.meta" :to="resolvePath(onlyOneChild.path)">
<el-menu-item :index="resolvePath(onlyOneChild.path)" :class="{'submenu-title-noDropdown':!isNest}">
<item :icon="onlyOneChild.meta.icon||(item.meta&&item.meta.icon)" :title="onlyOneChild.meta.title" />
</el-menu-item>
</app-link>
</template>
<el-submenu v-else ref="subMenu" :index="resolvePath(item.path)" popper-append-to-body>
<template slot="title">
<item v-if="item.meta" :icon="item.meta && item.meta.icon" :title="item.meta.title" />
</template>
<sidebar-item
v-for="child in item.children"
:key="child.path"
:is-nest="true"
:item="child"
:base-path="resolvePath(child.path)"
class="nest-menu"
/>
</el-submenu>
</div>
</template>
<script>
import path from 'path'
import { isExternal } from '@/utils/validate'
import Item from './Item'
import AppLink from './Link'
import FixiOSBug from './FixiOSBug'
export default {
name: 'SidebarItem',
components: { Item, AppLink },
mixins: [FixiOSBug],
props: {
// route object
item: {
type: Object,
required: true
},
isNest: {
type: Boolean,
default: false
},
basePath: {
type: String,
default: ''
}
},
data() {
// To fix https://github.com/PanJiaChen/vue-admin-template/issues/237
// TODO: refactor with render function
this.onlyOneChild = null
return {}
},
methods: {
hasOneShowingChild(children = [], parent) {
const showingChildren = children.filter(item => {
if (item.hidden) {
return false
} else {
// Temp set(will be used if only has one showing child)
this.onlyOneChild = item
return true
}
})
// When there is only one child router, the child router is displayed by default
if (showingChildren.length === 1) {
return true
}
// Show parent if there are no child router to display
if (showingChildren.length === 0) {
this.onlyOneChild = { ... parent, path: '', noShowingChildren: true }
return true
}
return false
},
resolvePath(routePath) {
if (isExternal(routePath)) {
return routePath
}
if (isExternal(this.basePath)) {
return this.basePath
}
return path.resolve(this.basePath, routePath)
}
}
}
</script>

View File

@ -0,0 +1,56 @@
<template>
<div :class="{'has-logo':showLogo}">
<logo v-if="showLogo" :collapse="isCollapse" />
<el-scrollbar wrap-class="scrollbar-wrapper">
<el-menu
:default-active="activeMenu"
:collapse="isCollapse"
:background-color="variables.menuBg"
:text-color="variables.menuText"
:unique-opened="false"
:active-text-color="variables.menuActiveText"
:collapse-transition="false"
mode="vertical"
>
<sidebar-item v-for="route in routes" :key="route.path" :item="route" :base-path="route.path" />
</el-menu>
</el-scrollbar>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
import Logo from './Logo'
import SidebarItem from './SidebarItem'
import variables from '@/styles/variables.scss'
export default {
components: { SidebarItem, Logo },
computed: {
...mapGetters([
'sidebar'
]),
routes() {
return this.$router.options.routes
},
activeMenu() {
const route = this.$route
const { meta, path } = route
// if set path, the sidebar will highlight the path you set
if (meta.activeMenu) {
return meta.activeMenu
}
return path
},
showLogo() {
return this.$store.state.settings.sidebarLogo
},
variables() {
return variables
},
isCollapse() {
return !this.sidebar.opened
}
}
}
</script>

View File

@ -0,0 +1,3 @@
export { default as Navbar } from './Navbar'
export { default as Sidebar } from './Sidebar'
export { default as AppMain } from './AppMain'

93
src/layout/index.vue Normal file
View File

@ -0,0 +1,93 @@
<template>
<div :class="classObj" class="app-wrapper">
<div v-if="device==='mobile'&&sidebar.opened" class="drawer-bg" @click="handleClickOutside" />
<sidebar class="sidebar-container" />
<div class="main-container">
<div :class="{'fixed-header':fixedHeader}">
<navbar />
</div>
<app-main />
</div>
</div>
</template>
<script>
import { Navbar, Sidebar, AppMain } from './components'
import ResizeMixin from './mixin/ResizeHandler'
export default {
name: 'Layout',
components: {
Navbar,
Sidebar,
AppMain
},
mixins: [ResizeMixin],
computed: {
sidebar() {
return this.$store.state.app.sidebar
},
device() {
return this.$store.state.app.device
},
fixedHeader() {
return this.$store.state.settings.fixedHeader
},
classObj() {
return {
hideSidebar: !this.sidebar.opened,
openSidebar: this.sidebar.opened,
withoutAnimation: this.sidebar.withoutAnimation,
mobile: this.device === 'mobile'
}
}
},
methods: {
handleClickOutside() {
this.$store.dispatch('app/closeSideBar', { withoutAnimation: false })
}
}
}
</script>
<style lang="scss" scoped>
@import "~@/styles/mixin.scss";
@import "~@/styles/variables.scss";
.app-wrapper {
@include clearfix;
position: relative;
height: 100%;
width: 100%;
&.mobile.openSidebar{
position: fixed;
top: 0;
}
}
.drawer-bg {
background: #000;
opacity: 0.3;
width: 100%;
top: 0;
height: 100%;
position: absolute;
z-index: 999;
}
.fixed-header {
position: fixed;
top: 0;
right: 0;
z-index: 9;
width: calc(100% - #{$sideBarWidth});
transition: width 0.28s;
}
.hideSidebar .fixed-header {
width: calc(100% - 54px)
}
.mobile .fixed-header {
width: 100%;
}
</style>

View File

@ -0,0 +1,45 @@
import store from '@/store'
const { body } = document
const WIDTH = 992 // refer to Bootstrap's responsive design
export default {
watch: {
$route(route) {
if (this.device === 'mobile' && this.sidebar.opened) {
store.dispatch('app/closeSideBar', { withoutAnimation: false })
}
}
},
beforeMount() {
window.addEventListener('resize', this.$_resizeHandler)
},
beforeDestroy() {
window.removeEventListener('resize', this.$_resizeHandler)
},
mounted() {
const isMobile = this.$_isMobile()
if (isMobile) {
store.dispatch('app/toggleDevice', 'mobile')
store.dispatch('app/closeSideBar', { withoutAnimation: true })
}
},
methods: {
// use $_ for mixins properties
// https://vuejs.org/v2/style-guide/index.html#Private-property-names-essential
$_isMobile() {
const rect = body.getBoundingClientRect()
return rect.width - 1 < WIDTH
},
$_resizeHandler() {
if (!document.hidden) {
const isMobile = this.$_isMobile()
store.dispatch('app/toggleDevice', isMobile ? 'mobile' : 'desktop')
if (isMobile) {
store.dispatch('app/closeSideBar', { withoutAnimation: true })
}
}
}
}
}

67
src/main.js Normal file
View File

@ -0,0 +1,67 @@
import Vue from 'vue'
import 'normalize.css/normalize.css' // A modern alternative to CSS resets
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
// import locale from 'element-ui/lib/locale/lang/en' // lang i18n
import '@/styles/index.scss' // global css
import uploader from 'vue-simple-uploader'
import EVueContextmenu from 'e-vue-contextmenu'
import App from './App'
import store from './store'
import router from './router'
import WeVue from 'we-vue'
import 'we-vue/lib/style.css'
import '@/icons' // icon
import '@/permission' // permission control
/**
* If you don't want to use mock-server
* you want to use MockJs for mock api
* you can execute: mockXHR()
*
* Currently MockJs will be used in the production environment,
* please remove it before going online ! ! !
*/
// if (process.env.NODE_ENV === 'production') {
// const { mockXHR } = require('../mock')
// mockXHR()
// }
// set ElementUI lang to EN
// Vue.use(ElementUI, { locale })
// 如果想要中文版 element-ui,按如下方式声明
Vue.use(ElementUI)
Vue.use(WeVue)
Vue.use(uploader)
Vue.use(EVueContextmenu)
Vue.config.productionTip = false
new Vue({
el: '#app',
router,
store,
render: h => h(App)
})
if (/Android|webOS|iPhone|iPod|BlackBerry/i.test(navigator.userAgent)) {
Vue.prototype.$pc = false
} else {
Vue.prototype.$pc = true
let winWidth = document.documentElement.offsetWidth ||
document.body.offsetWidth
winWidth = winWidth < 1366 ? 1366 : winWidth
const oHtml = document.getElementsByTagName('html')[0]
oHtml.style.fontSize = 100 * winWidth / 1920 + 'px'
window.addEventListener('resize', function() {
let winWidth = document.documentElement.offsetWidth || document.body.offsetWidth
winWidth = winWidth < 1366 ? 1366 : winWidth
const oHtml = document.getElementsByTagName('html')[0]
oHtml.style.fontSize = 100 * winWidth / 1920 + 'px'
})
}

64
src/permission.js Normal file
View File

@ -0,0 +1,64 @@
import router from './router'
import store from './store'
import { Message } from 'element-ui'
import NProgress from 'nprogress' // progress bar
import 'nprogress/nprogress.css' // progress bar style
import { getToken } from '@/utils/auth' // get token from cookie
import getPageTitle from '@/utils/get-page-title'
NProgress.configure({ showSpinner: false }) // NProgress Configuration
const whiteList = ['/login'] // no redirect whitelist
router.beforeEach(async(to, from, next) => {
// start progress bar
NProgress.start()
// set page title
document.title = getPageTitle(to.meta.title)
// determine whether the user has logged in
const hasToken = getToken()
if (hasToken) {
if (to.path === '/login') {
// if is logged in, redirect to the home page
next({ path: '/' })
NProgress.done()
} else {
const hasGetUserInfo = store.getters.name
if (hasGetUserInfo) {
next()
} else {
try {
// get user info
await store.dispatch('user/getInfo')
next()
} catch (error) {
// remove token and go to login page to re-login
await store.dispatch('user/resetToken')
Message.error(error || 'Has Error')
next(`/login?redirect=${to.path}`)
NProgress.done()
}
}
}
} else {
/* has no token*/
if (whiteList.indexOf(to.path) !== -1) {
// in the free login whitelist, go directly
next()
} else {
// other pages that do not have permission to access are redirected to the login page.
next(`/login?redirect=${to.path}`)
NProgress.done()
}
}
})
router.afterEach(() => {
// finish progress bar
NProgress.done()
})

264
src/router/index.js Normal file
View File

@ -0,0 +1,264 @@
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
/* Layout */
import Layout from '@/layout'
/**
* Note: sub-menu only appear when route children.length >= 1
* Detail see: https://panjiachen.github.io/vue-element-admin-site/guide/essentials/router-and-nav.html
*
* hidden: true if set true, item will not show in the sidebar(default is false)
* alwaysShow: true if set true, will always show the root menu
* if not set alwaysShow, when item has more than one children route,
* it will becomes nested mode, otherwise not show the root menu
* redirect: noRedirect if set noRedirect will no redirect in the breadcrumb
* name:'router-name' the name is used by <keep-alive> (must set!!!)
* meta : {
roles: ['admin','editor'] control the page roles (you can set multiple roles)
title: 'title' the name show in sidebar and breadcrumb (recommend set)
icon: 'svg-name' the icon show in the sidebar
breadcrumb: false if set false, the item will hidden in breadcrumb(default is true)
activeMenu: '/example/list' if set path, the sidebar will highlight the path you set
}
*/
/**
* constantRoutes
* a base page that does not have permission requirements
* all roles can be accessed
*/
export const constantRoutes = [
{
path: '/login',
component: () => import('@/views/login/index'),
hidden: true
},
{
path: '/login_m',
component: () => import('@/views/login/index'),
hidden: true
},
{
path: '/404',
component: () => import('@/views/404'),
hidden: true
},
{
path: '/',
component: Layout,
redirect: '/home',
children: [{
path: '',
name: 'Home',
component: () => import('@/views/home/index'),
meta: { title: '所有文件', icon: 'ziyuan' }
}]
},
{
path: '/recently',
component: Layout,
redirect: '/recently',
children: [
{
path: 'recently',
name: 'recently',
component: () => import('@/views/recently/index'),
meta: { title: '最近', icon: 'zuijinyuedu' }
}
]
},
{
path: '/favorite',
component: Layout,
children: [
{
path: 'index',
name: 'Form',
component: () => import('@/views/form/index'),
meta: { title: '收藏', icon: 'Favoritestarrate' }
}
]
},
{
path: '/share',
component: Layout,
children: [
{
path: 'index',
name: 'share',
component: () => import('@/views/form/index'),
meta: { title: '分享', icon: 'gongxiangzhongxin' }
}
]
},
{
path: '/demo',
component: Layout,
children: [
{
path: 'index',
name: 'demo',
component: () => import('@/views/demo/index'),
meta: { title: 'demo', icon: 'example' }
}
]
},
// {
// path: '/example',
// component: Layout,
// redirect: '/example/table',
// name: 'Example',
// meta: { title: 'Example', icon: 'example' },
// children: [
// {
// path: 'table',
// name: 'Table',
// component: () => import('@/views/table/index'),
// meta: { title: 'Table', icon: 'table' }
// },
// {
// path: 'tree',
// name: 'Tree',
// component: () => import('@/views/tree/index'),
// meta: { title: 'Tree', icon: 'tree' }
// }
// ]
// },
//
// {
// path: '/form',
// component: Layout,
// children: [
// {
// path: 'index',
// name: 'Form',
// component: () => import('@/views/form/index'),
// meta: { title: 'Form', icon: 'form' }
// }
// ]
// },
//
// {
// path: '/nested',
// component: Layout,
// redirect: '/nested/menu1',
// name: 'Nested',
// meta: {
// title: 'Nested',
// icon: 'nested'
// },
// children: [
// {
// path: 'menu1',
// component: () => import('@/views/nested/menu1/index'), // Parent router-view
// name: 'Menu1',
// meta: { title: 'Menu1' },
// children: [
// {
// path: 'menu1-1',
// component: () => import('@/views/nested/menu1/menu1-1'),
// name: 'Menu1-1',
// meta: { title: 'Menu1-1' }
// },
// {
// path: 'menu1-2',
// component: () => import('@/views/nested/menu1/menu1-2'),
// name: 'Menu1-2',
// meta: { title: 'Menu1-2' },
// children: [
// {
// path: 'menu1-2-1',
// component: () => import('@/views/nested/menu1/menu1-2/menu1-2-1'),
// name: 'Menu1-2-1',
// meta: { title: 'Menu1-2-1' }
// },
// {
// path: 'menu1-2-2',
// component: () => import('@/views/nested/menu1/menu1-2/menu1-2-2'),
// name: 'Menu1-2-2',
// meta: { title: 'Menu1-2-2' }
// }
// ]
// },
// {
// path: 'menu1-3',
// component: () => import('@/views/nested/menu1/menu1-3'),
// name: 'Menu1-3',
// meta: { title: 'Menu1-3' }
// }
// ]
// },
// {
// path: 'menu2',
// component: () => import('@/views/nested/menu2/index'),
// meta: { title: 'menu2' }
// }
// ]
// },
//
// {
// path: 'external-link',
// component: Layout,
// children: [
// {
// path: 'https://panjiachen.github.io/vue-element-admin-site/#/',
// meta: { title: 'External Link', icon: 'link' }
// }
// ]
// },
// 404 page must be placed at the end !!!
{ path: '*', redirect: '/404', hidden: true }
]
export const dynamicRouters = [
{
path: '/_m',
component: Layout,
redirect: '/home_m',
children: [{
path: '',
name: 'Home_m',
component: () => import('@/views/home/mobile/index'),
meta: { title: '所有文件', icon: 'ziyuan' }
}]
},
{
path: '/demo',
component: Layout,
children: [
{
path: 'index_m',
name: 'demo_m',
component: () => import('@/views/demo/index_m'),
meta: { title: 'demo', icon: 'example' }
}
]
}
]
const createRouter = () => new Router({
mode: 'history', // require service support
scrollBehavior: () => ({ y: 0 }),
routes: constantRoutes
})
const router = createRouter()
// Detail see: https://github.com/vuejs/vue-router/issues/1234#issuecomment-357941465
export function resetRouter() {
const newRouter = createRouter()
newRouter.addRoutes(dynamicRouters)
router.matcher = newRouter.matcher // reset router
}
router.addRoutes(dynamicRouters)
export default router

18
src/settings.js Normal file
View File

@ -0,0 +1,18 @@
module.exports = {
title: 'jmalCloud',
/**
* @type {boolean} true | false
* @description Whether fix the header
*/
fixedHeader: false,
/**
* @type {boolean} true | false
* @description Whether show the logo in sidebar
*/
sidebarLogo: false,
FILE_SERVER_URL: 'http://192.168.1.118:10010/' // nginx文件服务器地址
}

Some files were not shown because too many files have changed in this diff Show More