Commit d5549a5d authored by 燕南天's avatar 燕南天

init mgt_pro

parent c57dec59
{
"presets": [
["env", {
"modules": false,
"targets": {
"browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
}
}],
"stage-2"
],
"plugins": ["transform-vue-jsx", "transform-runtime"]
}
# 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
build/*.js
config/*.js
src/assets
src
module.exports = {
root: true,
parser: 'babel-eslint',
parserOptions: {
sourceType: 'module'
},
env: {
browser: true,
node: true,
es6: true,
},
extends: 'eslint:recommended',
// required to lint *.vue files
plugins: [
'html'
],
// check if imports actually resolve
'settings': {
'import/resolver': {
'webpack': {
'config': 'build/webpack.base.conf.js'
}
}
},
// add your custom rules here
//it is base on https://github.com/vuejs/eslint-config-vue
'rules': {
'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': [2, 'allow-null'],
'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']
}
}
.DS_Store
node_modules/
dist/
npm-debug.log*
yarn-debug.log*
yarn-error.log*
test/unit/coverage
test/e2e/reports
selenium-debug.log
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
package-lock.json
yarn.lock
// https://github.com/michael-ciniawsky/postcss-load-config
module.exports = {
"plugins": {
"postcss-import": {},
"postcss-url": {},
// to edit target browsers: use "browserslist" field in package.json
"autoprefixer": {}
}
}
language: node_js
node_js: stable
script: npm run test
notifications:
email: false
MIT License
Copyright (c) 2017-present PanJiaChen
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
项目模板声明:vue-element-admin
- [地址传送](https://github.com/PanJiaChen/vue-element-admin)
\ No newline at end of file
'use strict'
require('./check-versions')()
const ora = require('ora')
const rm = require('rimraf')
const path = require('path')
const chalk = require('chalk')
const webpack = require('webpack')
const config = require('../config')
const webpackConfig = require('./webpack.prod.conf')
const server = require('pushstate-server')
var spinner = ora('building for '+ process.env.env_config+ ' environment...' )
spinner.start()
rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => {
if (err) throw err
webpack(webpackConfig, (err, stats) => {
spinner.stop()
if (err) throw err
process.stdout.write(stats.toString({
colors: true,
modules: false,
children: false,
chunks: false,
chunkModules: false
}) + '\n\n')
if (stats.hasErrors()) {
console.log(chalk.red(' Build failed with errors.\n'))
process.exit(1)
}
console.log(chalk.cyan(' Build complete.\n'))
console.log(chalk.yellow(
' Tip: built files are meant to be served over an HTTP server.\n' +
' Opening index.html over file:// won\'t work.\n'
))
if(process.env.npm_config_preview){
server.start({
port: 9526,
directory: './dist',
file: '/index.html'
});
console.log('> Listening at ' + 'http://localhost:9526' + '\n')
}
})
})
'use strict'
const chalk = require('chalk')
const semver = require('semver')
const packageConfig = require('../package.json')
const shell = require('shelljs')
function exec (cmd) {
return require('child_process').execSync(cmd).toString().trim()
}
const versionRequirements = [
{
name: 'node',
currentVersion: semver.clean(process.version),
versionRequirement: packageConfig.engines.node
}
]
if (shell.which('npm')) {
versionRequirements.push({
name: 'npm',
currentVersion: exec('npm --version'),
versionRequirement: packageConfig.engines.npm
})
}
module.exports = function () {
const warnings = []
for (let i = 0; i < versionRequirements.length; i++) {
const mod = versionRequirements[i]
if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) {
warnings.push(mod.name + ': ' +
chalk.red(mod.currentVersion) + ' should be ' +
chalk.green(mod.versionRequirement)
)
}
}
if (warnings.length) {
console.log('')
console.log(chalk.yellow('To use this template, you must update following to modules:'))
console.log()
for (let i = 0; i < warnings.length; i++) {
const warning = warnings[i]
console.log(' ' + warning)
}
console.log()
process.exit(1)
}
}
'use strict'
const path = require('path')
const config = require('../config')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const packageConfig = require('../package.json')
exports.assetsPath = function (_path) {
const assetsSubDirectory = process.env.NODE_ENV === 'production'
? config.build.assetsSubDirectory
: config.dev.assetsSubDirectory
return path.posix.join(assetsSubDirectory, _path)
}
exports.cssLoaders = function (options) {
options = options || {}
const cssLoader = {
loader: 'css-loader',
options: {
sourceMap: options.sourceMap
}
}
const postcssLoader = {
loader: 'postcss-loader',
options: {
sourceMap: options.sourceMap
}
}
// generate loader string to be used with extract text plugin
function generateLoaders (loader, loaderOptions) {
const loaders = options.usePostCSS ? [cssLoader, postcssLoader] : [cssLoader]
if (loader) {
loaders.push({
loader: loader + '-loader',
options: Object.assign({}, loaderOptions, {
sourceMap: options.sourceMap
})
})
}
// Extract CSS when that option is specified
// (which is the case during production build)
if (options.extract) {
return ExtractTextPlugin.extract({
use: loaders,
fallback: 'vue-style-loader'
})
} else {
return ['vue-style-loader'].concat(loaders)
}
}
// https://vue-loader.vuejs.org/en/configurations/extract-css.html
return {
css: generateLoaders(),
postcss: generateLoaders(),
less: generateLoaders('less'),
sass: generateLoaders('sass', { indentedSyntax: true }),
scss: generateLoaders('sass'),
stylus: generateLoaders('stylus'),
styl: generateLoaders('stylus')
}
}
// Generate loaders for standalone style files (outside of .vue)
exports.styleLoaders = function (options) {
const output = []
const loaders = exports.cssLoaders(options)
for (const extension in loaders) {
const loader = loaders[extension]
output.push({
test: new RegExp('\\.' + extension + '$'),
use: loader
})
}
return output
}
exports.createNotifierCallback = () => {
const notifier = require('node-notifier')
return (severity, errors) => {
if (severity !== 'error') return
const error = errors[0]
const filename = error.file && error.file.split('!').pop()
notifier.notify({
title: packageConfig.name,
message: severity + ': ' + error.name,
subtitle: filename || '',
icon: path.join(__dirname, 'logo.png')
})
}
}
'use strict'
const utils = require('./utils')
const config = require('../config')
const isProduction = process.env.NODE_ENV === 'production'
const sourceMapEnabled = isProduction
? config.build.productionSourceMap
: config.dev.cssSourceMap
module.exports = {
loaders: utils.cssLoaders({
sourceMap: sourceMapEnabled,
extract: isProduction
}),
cssSourceMap: sourceMapEnabled,
cacheBusting: config.dev.cacheBusting,
transformToRequire: {
video: ['src', 'poster'],
source: 'src',
img: 'src',
image: 'xlink:href'
}
}
'use strict'
const path = require('path')
const utils = require('./utils')
const config = require('../config')
const vueLoaderConfig = require('./vue-loader.conf')
function resolve (dir) {
return path.join(__dirname, '..', dir)
}
const createLintingRule = () => ({
test: /\.(js|vue)$/,
loader: 'eslint-loader',
enforce: 'pre',
include: [resolve('src'), resolve('test')],
options: {
formatter: require('eslint-friendly-formatter'),
emitWarning: !config.dev.showEslintErrorsInOverlay
}
})
module.exports = {
context: path.resolve(__dirname, '../'),
entry: {
app: ["babel-polyfill","./src/main.js"]
},
output: {
path: config.build.assetsRoot,
filename: '[name].js',
publicPath: process.env.NODE_ENV === 'production'
? config.build.assetsPublicPath
: config.dev.assetsPublicPath
},
resolve: {
extensions: ['.js', '.vue', '.json'],
alias: {
'vue$': 'vue/dist/vue.esm.js',
'@': resolve('src'),
}
},
module: {
rules: [
...(config.dev.useEslint ? [createLintingRule()] : []),
{
test: /\.vue$/,
loader: 'vue-loader',
options: vueLoaderConfig
},
{
test: /\.js$/,
loader: 'babel-loader?cacheDirectory',
include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')]
},
{
test: /\.svg$/,
loader: 'svg-sprite-loader',
include: [resolve('src/icons')],
options: {
symbolId: 'icon-[name]'
}
},
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: 'url-loader',
exclude: [resolve('src/icons')],
options: {
limit: 10000,
name: utils.assetsPath('img/[name].[hash:7].[ext]')
}
},
{
test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('media/[name].[hash:7].[ext]')
}
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
}
}
]
},
node: {
// prevent webpack from injecting useless setImmediate polyfill because Vue
// source contains it (although only uses it if it's native).
setImmediate: false,
// prevent webpack from injecting mocks to Node native modules
// that does not make sense for the client
dgram: 'empty',
fs: 'empty',
net: 'empty',
tls: 'empty',
child_process: 'empty'
}
}
'use strict'
const path = require('path')
const utils = require('./utils')
const webpack = require('webpack')
const config = require('../config')
const merge = require('webpack-merge')
const baseWebpackConfig = require('./webpack.base.conf')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
const portfinder = require('portfinder')
function resolve (dir) {
return path.join(__dirname, '..', dir)
}
const HOST = process.env.HOST
const PORT = process.env.PORT && Number(process.env.PORT)
const devWebpackConfig = merge(baseWebpackConfig, {
module: {
rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true })
},
// cheap-module-eval-source-map is faster for development
devtool: config.dev.devtool,
// these devServer options should be customized in /config/index.js
devServer: {
clientLogLevel: 'warning',
historyApiFallback: true,
hot: true,
compress: true,
host: HOST || config.dev.host,
port: PORT || config.dev.port,
open: config.dev.autoOpenBrowser,
overlay: config.dev.errorOverlay
? { warnings: false, errors: true }
: false,
publicPath: config.dev.assetsPublicPath,
proxy: config.dev.proxyTable,
quiet: true, // necessary for FriendlyErrorsPlugin
watchOptions: {
poll: config.dev.poll,
}
},
plugins: [
new webpack.DefinePlugin({
'process.env': require('../config/dev.env')
}),
new webpack.HotModuleReplacementPlugin(),
new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update.
new webpack.NoEmitOnErrorsPlugin(),
// https://github.com/ampedandwired/html-webpack-plugin
new HtmlWebpackPlugin({
filename: 'index.html',
template: 'index.html',
inject: true,
favicon: resolve('favicon.ico'),
title: 'vue-element-admin',
path: config.dev.assetsPublicPath + config.dev.assetsSubDirectory
}),
]
})
module.exports = new Promise((resolve, reject) => {
portfinder.basePort = process.env.PORT || config.dev.port
portfinder.getPort((err, port) => {
if (err) {
reject(err)
} else {
// publish the new Port, necessary for e2e tests
process.env.PORT = port
// add port to devServer config
devWebpackConfig.devServer.port = port
// Add FriendlyErrorsPlugin
devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({
compilationSuccessInfo: {
messages: [`Your application is running here: http://${devWebpackConfig.devServer.host}:${port}`],
},
onErrors: config.dev.notifyOnErrors
? utils.createNotifierCallback()
: undefined
}))
resolve(devWebpackConfig)
}
})
})
'use strict'
const path = require('path')
const utils = require('./utils')
const webpack = require('webpack')
const config = require('../config')
const merge = require('webpack-merge')
const baseWebpackConfig = require('./webpack.base.conf')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
function resolve (dir) {
return path.join(__dirname, '..', dir)
}
const env = require('../config/'+process.env.env_config+'.env')
const webpackConfig = merge(baseWebpackConfig, {
module: {
rules: utils.styleLoaders({
sourceMap: config.build.productionSourceMap,
extract: true,
usePostCSS: true
})
},
devtool: config.build.productionSourceMap ? config.build.devtool : false,
output: {
path: config.build.assetsRoot,
filename: utils.assetsPath('js/[name].[chunkhash].js'),
chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
},
plugins: [
// http://vuejs.github.io/vue-loader/en/workflow/production.html
new webpack.DefinePlugin({
'process.env': env
}),
new UglifyJsPlugin({
uglifyOptions: {
compress: {
warnings: false
}
},
sourceMap: config.build.productionSourceMap,
parallel: true
}),
// extract css into its own file
new ExtractTextPlugin({
filename: utils.assetsPath('css/[name].[contenthash].css'),
// Setting the following option to `false` will not extract CSS from codesplit chunks.
// Their CSS will instead be inserted dynamically with style-loader when the codesplit chunk has been loaded by webpack.
// increasing file size: https://github.com/vuejs-templates/webpack/issues/1110
allChunks: false,
}),
// Compress extracted CSS. We are using this plugin so that possible
// duplicated CSS from different components can be deduped.
new OptimizeCSSPlugin({
cssProcessorOptions: config.build.productionSourceMap
? { safe: true, map: { inline: false } }
: { safe: true }
}),
// generate dist index.html with correct asset hash for caching.
// you can customize output by editing /index.html
// see https://github.com/ampedandwired/html-webpack-plugin
new HtmlWebpackPlugin({
filename: config.build.index,
template: 'index.html',
inject: true,
favicon: resolve('favicon.ico'),
title: 'vue-element-admin',
path: config.build.assetsPublicPath + config.build.assetsSubDirectory,
minify: {
removeComments: true,
collapseWhitespace: true,
removeAttributeQuotes: true
// more options:
// https://github.com/kangax/html-minifier#options-quick-reference
},
// necessary to consistently work with multiple chunks via CommonsChunkPlugin
chunksSortMode: 'dependency'
}),
// keep module.id stable when vender modules does not change
new webpack.HashedModuleIdsPlugin(),
// enable scope hoisting
new webpack.optimize.ModuleConcatenationPlugin(),
// split vendor js into its own file
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
minChunks (module) {
// any required modules inside node_modules are extracted to vendor
return (
module.resource &&
/\.js$/.test(module.resource) &&
module.resource.indexOf(
path.join(__dirname, '../node_modules')
) === 0
)
}
}),
// extract webpack runtime and module manifest to its own file in order to
// prevent vendor hash from being updated whenever app bundle is updated
new webpack.optimize.CommonsChunkPlugin({
name: 'manifest',
minChunks: Infinity
}),
// This instance extracts shared chunks from code splitted chunks and bundles them
// in a separate chunk, similar to the vendor chunk
// see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk
new webpack.optimize.CommonsChunkPlugin({
name: 'app',
async: 'vendor-async',
children: true,
minChunks: 3
}),
// split echarts into its own file
new webpack.optimize.CommonsChunkPlugin({
async: 'echarts',
minChunks(module) {
var context = module.context;
return context && (context.indexOf('echarts') >= 0 || context.indexOf('zrender') >= 0);
}
}),
// split xlsx into its own file
new webpack.optimize.CommonsChunkPlugin({
async: 'xlsx',
minChunks(module) {
var context = module.context;
return context && (context.indexOf('xlsx') >= 0);
}
}),
// split codemirror into its own file
new webpack.optimize.CommonsChunkPlugin({
async: 'codemirror',
minChunks(module) {
var context = module.context;
return context && (context.indexOf('codemirror') >= 0);
}
}),
// copy custom static assets
new CopyWebpackPlugin([
{
from: path.resolve(__dirname, '../static'),
to: config.build.assetsSubDirectory,
ignore: ['.*']
}
])
]
})
if (config.build.productionGzip) {
const CompressionWebpackPlugin = require('compression-webpack-plugin')
webpackConfig.plugins.push(
new CompressionWebpackPlugin({
asset: '[path].gz[query]',
algorithm: 'gzip',
test: new RegExp(
'\\.(' +
config.build.productionGzipExtensions.join('|') +
')$'
),
threshold: 10240,
minRatio: 0.8
})
)
}
if (config.build.bundleAnalyzerReport) {
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
webpackConfig.plugins.push(new BundleAnalyzerPlugin())
}
module.exports = webpackConfig
var host = require('./host.cfg')
module.exports = {
NODE_ENV: '"development"',
ENV_CONFIG: '"dev"',
BASE_API: `'${host.sit}'`
}
/**
* 配置请求地址,支持多环境
* @param sit==>>测试开发环境
* @param prod==>正式上线环境
* */
module.exports = {
// sit: "http://192.168.1.102:8080/logistics-mgt",//超哥本地
// sit: "http://192.168.200.173:8080",//杨飞本地
// sit:"http://flynet.imwork.net:35609/logistics-mgt",
sit:"https://chalk.fqyxa.com", //上线环境
// sit:"http://192.168.1.103:8781",//毅豪本地
// -----------------------------------------------------------------
prod: "http:正式环境"
}
'use strict'
// Template version: 1.2.6
// see http://vuejs-templates.github.io/webpack for documentation.
const path = require('path')
module.exports = {
dev: {
// Paths
assetsSubDirectory: 'static',
assetsPublicPath: '/',
proxyTable: {},
// Various Dev Server settings
host: 'localhost', // can be overwritten by process.env.HOST
// host: '192.168.1.100', // can be overwritten by process.env.HOST
port: 9527, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined
autoOpenBrowser: true,
errorOverlay: true,
notifyOnErrors: false,
poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions-
// Use Eslint Loader?
// If true, your code will be linted during bundling and
// linting errors and warnings will be shown in the console.
useEslint: true,
// If true, eslint errors and warnings will also be shown in the error overlay
// in the browser.
showEslintErrorsInOverlay: false,
/**
* Source Maps
*/
// https://webpack.js.org/configuration/devtool/#development
devtool: '#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,
// CSS Sourcemaps off by default because relative paths are "buggy"
// with this option, according to the CSS-Loader README
// (https://github.com/webpack/css-loader#sourcemaps)
// In our experience, they generally work as expected,
// just be aware of this issue when enabling this option.
cssSourceMap: true,
},
build: {
// Template for index.html
index: path.resolve(__dirname, '../dist/index.html'),
// Paths
assetsRoot: path.resolve(__dirname, '../dist'),
assetsSubDirectory: 'static',
// you can set by youself according to actual condition
assetsPublicPath: './',
/**
* Source Maps
*/
productionSourceMap: false,
// 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
}
}
var host = require('./host.cfg')
module.exports = {
NODE_ENV: '"production"',
ENV_CONFIG: '"prod"',
BASE_API: `'${host.prod}'`
}
var host = require('./host.cfg')
module.exports = {
NODE_ENV: '"production"',
ENV_CONFIG: '"sit"',
BASE_API: `'${host.sit}'`
}
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<!-- <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> -->
<meta name="renderer" content="webkit">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<!-- 激活chrome frame内核插件 -->
<meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1">
<title>智慧大院后台管理系统</title>
<!-- <link rel="stylesheet" type="text/css" href="http://at.alicdn.com/t/font_674196_89pa9pmfyd0cz0k9.css"> -->
</head>
<body>
<!-- 富文本 -->
<script src=<%= htmlWebpackPlugin.options.path %>/tinymce4.7.5/tinymce.min.js></script>
<!-- 兼容IE引用的包 -->
<script src=<%= htmlWebpackPlugin.options.path %>/iePhoto/jquery.js></script>
<!-- 兼容IE引用的包 -->
<script src=<%= htmlWebpackPlugin.options.path %>/iePhoto/jquery.webcam.min.js></script>
<div id="app"></div>
</body>
</html>
{
"name": "vue-element-admin",
"version": "3.6.6",
"description": "A magical vue admin. Typical templates for enterprise applications. Newest development stack of vue. Lots of awesome features",
"author": "Pan <panfree23@gmail.com>",
"license": "MIT",
"scripts": {
"dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
"start": "npm run dev",
"build:prod": "cross-env NODE_ENV=production env_config=prod node build/build.js",
"build:sit": "cross-env NODE_ENV=production env_config=sit node build/build.js",
"lint": "eslint --ext .js,.vue src",
"test": "npm run lint"
},
"keywords": [
"vue",
"element-ui",
"admin",
"management-system",
"admin-template"
],
"repository": {
"type": "git",
"url": "git+https://github.com/PanJiaChen/vue-element-admin.git"
},
"bugs": {
"url": "https://github.com/PanJiaChen/vue-element-admin/issues"
},
"dependencies": {
"axios": "0.17.1",
"clipboard": "1.7.1",
"codemirror": "5.32.0",
"dropzone": "5.2.0",
"echarts": "3.8.5",
"element-ui": "2.3.2",
"file-saver": "1.3.3",
"font-awesome": "4.7.0",
"js-cookie": "2.2.0",
"jsonlint": "1.6.2",
"jszip": "3.1.5",
"mockjs": "1.0.1-beta3",
"moment": "^2.22.2",
"normalize.css": "7.0.0",
"nprogress": "0.2.0",
"screenfull": "3.3.2",
"showdown": "1.8.5",
"simplemde": "1.11.2",
"sortablejs": "1.7.0",
"vue": "2.5.10",
"vue-count-to": "1.0.13",
"vue-i18n": "7.3.2",
"vue-multiselect": "2.0.8",
"vue-router": "3.0.1",
"vue-splitpane": "1.0.2",
"vuedraggable": "^2.16.0",
"vuex": "3.0.1",
"xlsx": "^0.11.16"
},
"devDependencies": {
"autoprefixer": "7.2.3",
"babel-core": "6.26.0",
"babel-eslint": "8.0.3",
"babel-helper-vue-jsx-merge-props": "2.0.3",
"babel-loader": "7.1.2",
"babel-plugin-syntax-jsx": "6.18.0",
"babel-plugin-transform-runtime": "6.23.0",
"babel-plugin-transform-vue-jsx": "3.5.0",
"babel-polyfill": "^6.26.0",
"babel-preset-env": "1.6.1",
"babel-preset-stage-2": "6.24.1",
"chalk": "2.3.0",
"copy-webpack-plugin": "4.3.0",
"cross-env": "5.1.1",
"css-loader": "0.28.7",
"eslint": "4.13.1",
"eslint-friendly-formatter": "3.0.0",
"eslint-loader": "1.9.0",
"eslint-plugin-html": "4.0.1",
"extract-text-webpack-plugin": "3.0.2",
"file-loader": "1.1.5",
"friendly-errors-webpack-plugin": "1.6.1",
"html-webpack-plugin": "2.30.1",
"node-notifier": "5.1.2",
"node-sass": "^4.7.2",
"optimize-css-assets-webpack-plugin": "3.2.0",
"ora": "1.3.0",
"portfinder": "1.0.13",
"postcss-import": "11.0.0",
"postcss-loader": "2.0.9",
"postcss-url": "7.3.0",
"pushstate-server": "3.0.1",
"rimraf": "2.6.2",
"sass-loader": "6.0.6",
"script-loader": "0.7.2",
"semver": "5.4.1",
"shelljs": "0.7.8",
"svg-sprite-loader": "3.5.2",
"uglifyjs-webpack-plugin": "1.1.3",
"url-loader": "0.6.2",
"vue-loader": "13.5.0",
"vue-style-loader": "3.0.3",
"vue-template-compiler": "2.5.10",
"webpack": "3.10.0",
"webpack-bundle-analyzer": "2.9.1",
"webpack-dev-server": "2.9.7",
"webpack-merge": "4.1.1"
},
"engines": {
"node": ">= 4.0.0",
"npm": ">= 3.0.0"
},
"browserslist": [
"> 1%",
"last 2 versions",
"not ie <= 8"
]
}
<template>
<div id="app">
<router-view></router-view>
</div>
</template>
<script>
import '@/styles/index.scss' // global css
import "./assets/iconfont/iconfont.css";
export default {
name: "App"
};
</script>
<style lang="scss">
</style>
import request from './request'
import qs from 'qs'
export function getAdvertList(data) {
return request({
url: '/advert/getAdvertList',
method: 'post',
data:qs.stringify(data)
})
}
export function addOrEditAdvert(data) {
return request({
url: '/advert/addOrEditAdvert',
method: 'post',
data:qs.stringify(data)
})
}
import request from './request'
import qs from 'qs'
//品牌列表
export function getCarBrandList(data) {
return request({
url: '/carBrand/getCarBrandList',
method: 'post',
data: qs.stringify(data)
})
}
export function addOrEditCarBrand(data) {
return request({
url: '/carBrand/addOrEditCarBrand',
method: 'post',
data: qs.stringify(data)
})
}
// 车系列表
export function getCarSeriesList(data) {
return request({
url: '/carSeries/getCarSeriesList',
method: 'post',
data: qs.stringify(data)
})
}
export function addOrEditCarSeries(data) {
return request({
url: '/carSeries/addOrEditCarSeries',
method: 'post',
data: qs.stringify(data)
})
}
// 车辆年代
export function getCarPreiodList(data) {
return request({
url: '/carPeriod/getCarPreiodList',
method: 'post',
data: qs.stringify(data)
})
}
export function addOrEditCarPreiod(data) {
return request({
url: '/carPeriod/addOrEditCarPreiod',
method: 'post',
data: qs.stringify(data)
})
}
// 车辆列表
export function getCarList(data) {
return request({
url: '/car/getCarList',
method: 'post',
data: qs.stringify(data)
})
}
export function addOrEditCar(data) {
return request({
url: '/car/addOrEditCar',
method: 'post',
data: qs.stringify(data)
})
}
// 车辆删除
export function delCarByCarId(data) {
return request({
url: '/car/delCarByCarId',
method: 'post',
data: qs.stringify(data)
})
}
// 用车订单
export function getUseCarOrderList(data) {
return request({
url: '/useCarOrder/getUseCarOrderList',
method: 'post',
data: qs.stringify(data)
})
}
export function addOrEditUseCarOrder(data) {
return request({
url: '/useCarOrder/addOrEditUseCarOrder',
method: 'post',
data: qs.stringify(data)
})
}
// 用车事由
export function getUseCarReasonList(data) {
return request({
url: '/useCarReason/getUseCarReasonList',
method: 'post',
data: qs.stringify(data)
})
}
export function addOrEditUseCarReason(data) {
return request({
url: '/useCarReason/addOrEditUseCarReason',
method: 'post',
data: qs.stringify(data)
})
}
// 三级联动获取车辆接口
// 获取品牌列表
export function getCarBrands() {
return request({
url: '/carBrand/getCarBrands',
method: 'post'
})
}
// 获取车系列表
export function getCarSeries(data) {
// param carBrandId
return request({
url: '/carSeries/getCarSeries',
method: 'post',
data: qs.stringify(data)
})
}
export function getCars() {
// 可用车辆列表
return request({
url: '/car/getCars',
method: 'post'
})
}
import request from './request'
import qs from 'qs'
// 获取单位组织架构数据
export function getDepsInfo() {
return request({
url: '/common/getDepsInfo',
method: 'post'
})
}
// 获取访问事由列表
export function getVisitReasons() {
return request({
url: '/common/getVisitReasons',
method: 'post'
})
}
// 根据科室id查询,人员信息
export function getMemberListBySection(data) {
return request({
url: '/member/getMemberListBySection',
method: 'post',
data: qs.stringify(data)
})
}
\ No newline at end of file
import request from './request'
import qs from 'qs'
//科室管理
//获取科室列表
export function getSectionList(data) {
return request({
url: '/section/getSectionList',
method: 'post',
data:qs.stringify(data)
})
}
//增加编辑科室
export function addOrEditSection(data) {
return request({
url: '/section/addOrEditSection',
method: 'post',
data:qs.stringify(data)
})
}
//删除
export function deleteSection(data) {
return request({
url: '/section/deleteSection',
method: 'post',
data:qs.stringify(data)
})
}
// 部门管理
//获取部门列表
export function getDeptList(data) {
return request({
url: '/dept/getDeptList',
method: 'post',
data:qs.stringify(data)
})
}
//增加编辑部门
export function addOrEditDept(data) {
return request({
url: '/dept/addOrEditDept',
method: 'post',
data:qs.stringify(data)
})
}
// 获取员工列表
export function getMemberList(data) {
return request({
url: '/member/getMemberList',
method: 'post',
data:qs.stringify(data)
})
}
//增加编辑员工
export function addOrEditMember(data) {
return request({
url: '/member/addOrEditMember',
method: 'post',
data:qs.stringify(data)
})
}
// 获取可选科室
export function getSections() {
return request({
url: '/section/getSections',
method: 'post',
})
}
//职务管理
//获取职务列表
export function getPositionList(data){
return request({
url:'position/getPositionList',
method:'post',
data:qs.stringify(data)
})
}
//增加编辑职务
export function addOrEditPosition(data){
return request({
url:'/position/addOrEditPosition',
method:'post',
data:qs.stringify(data)
})
}
//删除职务
export function delPosition(data) {
return request({
url: '/position/delPosition',
method: 'post',
data:qs.stringify(data)
})
}
import request from './request'
import qs from 'qs'
export function login(data) {
return request({
url: '/login',
method: 'post',
data:qs.stringify(data)
})
}
export function loginOut() {
return request({
url: '/loginOut',
method: 'post'
})
}
import request from './request'
import qs from 'qs'
// 会议室列表
export function getMeetingRoomList(data) {
return request({
url: '/meetingRoom/getMeetingRoomList',
method: 'post',
data:qs.stringify(data)
})
}
export function addOrEditMeetingRoom(data) {
return request({
url: '/meetingRoom/addOrEditMeetingRoom',
method: 'post',
data:qs.stringify(data)
})
}
// 会议室订单列表
export function getMeetingRoomOrderList(data) {
return request({
url: '/meetingRoomOrder/getMeetingRoomOrderList',
method: 'post',
data:qs.stringify(data)
})
}
export function addOrEditMeetingRoomOrder(data) {
return request({
url: '/meetingRoomOrder/addOrEditMeetingRoomOrder',
method: 'post',
data:qs.stringify(data)
})
}
//会议室申请事由
export function getMeetingRoomReasonList(data) {
return request({
url: '/meetingRoomReason/getMeetingRoomReasonList',
method: 'post',
data:qs.stringify(data)
})
}
export function addOrEditMeetingRoomReason(data) {
return request({
url: '/meetingRoomReason/addOrEditMeetingRoomReason',
method: 'post',
data:qs.stringify(data)
})
}
// 获取可用会议室
export function getMeetingRooms() {
return request({
url: '/meetingRoom/getMeetingRooms',
method: 'post'
})
}
// 会议室评价
export function getMeetingRoomCommentList(data) {
return request({
url: 'meetingRoomComment/getMeetingRoomCommentList',
method: 'post',
data:qs.stringify(data)
})
}
// 获取会服信息
export function getMeetingService(data) {
return request({
url: 'meetingRoomOrder/getMeetingService',
method: 'post',
data:qs.stringify(data)
})
}
import request from './request'
import qs from 'qs'
export function getMessagePushList(data) {
return request({
url: '/messagePush/getMessagePushList',
method: 'post',
data: qs.stringify(data)
})
}
export function addOrEditMessagePush(data) {
return request({
url: '/messagePush/addOrEditMessagePush',
method: 'post',
data: qs.stringify(data)
})
}
export function delMessagePush(data) {
return request({
url: '/messagePush/delMessagePush',
method: 'post',
data: qs.stringify(data)
})
}
export function getMessagePushRecordList(data) {
return request({
url: '/messagePushRecord/getMessagePushRecordList',
method: 'post',
data: qs.stringify(data)
})
}
\ No newline at end of file
import request from './request'
import qs from 'qs'
export function getStartupPageConfigList(data) {
return request({
url: '/startupPageConfig/getStartupPageConfigList',
method: 'post',
data: qs.stringify(data)
})
}
export function addOrEditStartupPageConfig(data) {
return request({
url: '/startupPageConfig/addOrEditStartupPageConfig',
method: 'post',
data: qs.stringify(data)
})
}
export function getCustomerFeedbackList(data) {
return request({
url: '/customerFeedback/getCustomerFeedbackList',
method: 'post',
data: qs.stringify(data)
})
}
//投诉建议
export function getComplaintList(data) {
return request({
url: '/complaint/getComplaintList',
method: 'post',
data: qs.stringify(data)
})
}
export function addOrEditComplaint(data) {
return request({
url: '/complaint/addOrEditComplaint',
method: 'post',
data: qs.stringify(data)
})
}
//规章制度
export function getRuleList(data) {
return request({
url: 'rule/getRuleList',
method: 'post',
data: qs.stringify(data)
})
}
export function addOrEditRule(data) {
return request({
url: 'rule/addOrEditRule',
method: 'post',
data: qs.stringify(data)
})
}
export function delRule(data) {
return request({
url: 'rule/delRule',
method: 'post',
data: qs.stringify(data)
})
}
// 读取身份证
import axios from 'axios'
import { Message } from 'element-ui'
import store from '@/store'
import { getToken } from '@/utils/auth'
// create an axios instance
const service = axios.create({
baseURL: "https://localhost:24011/ZKIDROnline/ScanReadIdCardInfo?OP-DEV=1&CMD-URL=4", //身份证信息获取地址
timeout: 5000, // request timeout
headers: {'Content-Type':'application/x-www-form-urlencoded'}
})
console.log('请求地址:'+process.env.BASE_API);
// request interceptor
service.interceptors.request.use(config => {
// Do something before request is sent
return config
}, error => {
// Do something with request error
console.log(error) // for debug
Promise.reject(error)
})
// respone interceptor
service.interceptors.response.use(
//暂时这先全部返回,等登录的接口完善以后,再去修改完 response.data
response => response,
/**
* 下面的注释为通过response自定义code来标示请求状态,当code返回如下情况为权限有问题,登出并返回到登录页
* 如通过xmlhttprequest 状态码标识 逻辑可写在下面error中
*/
// const res = response.data;
// if (res.code !== 20000) {
// Message({
// message: res.message,
// type: 'error',
// duration: 5 * 1000
// });
// // 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了;
// if (res.code === 50008 || res.code === 50012 || res.code === 50014) {
// MessageBox.confirm('你已被登出,可以取消继续留在该页面,或者重新登录', '确定登出', {
// confirmButtonText: '重新登录',
// cancelButtonText: '取消',
// type: 'warning'
// }).then(() => {
// store.dispatch('FedLogOut').then(() => {
// location.reload();// 为了重新实例化vue-router对象 避免bug
// });
// })
// }
// return Promise.reject('error');
// } else {
// return response.data;
// }
error => {
console.log('err' + error)// for debug
Message({
message: "请检查身份证读取设备是否安装成功!",
type: 'error',
duration: 2000
})
return Promise.reject(error)
})
export function readCardInfro() {
return service({
method: 'get'
})
}
import request from './request'
import qs from 'qs'
export function getRepairWorkerList(data) {
return request({
url: '/repairWorker/getRepairWorkerList',
method: 'post',
data:qs.stringify(data)
})
}
export function addOrEditRepairWorker(data) {
return request({
url: '/repairWorker/addOrEditRepairWorker',
method: 'post',
data:qs.stringify(data)
})
}
// 维修订单列表
export function getRepairOrderList(data) {
return request({
url: '/repairOrder/getRepairOrderList',
method: 'post',
data:qs.stringify(data)
})
}
export function addOrEditRepairOrder(data) {
return request({
url: '/repairOrder/addOrEditRepairOrder',
method: 'post',
data:qs.stringify(data)
})
}
// 获取维修工下拉数据
export function getRepairWorker() {
return request({
url: '/repairOrder/getRepairWorker',
method: 'post'
})
}
// 维修事由
export function getRepairItemList(data) {
return request({
url: '/repairItem/getRepairItemList',
method: 'post',
data:qs.stringify(data)
})
}
export function addOrEditRepairItem(data) {
return request({
url: '/repairItem/addOrEditRepairItem',
method: 'post',
data:qs.stringify(data)
})
}
// 评价列表
export function getRepairCommentList(data) {
return request({
url: '/repairComment/getRepairCommentList',
method: 'post',
data:qs.stringify(data)
})
}
\ No newline at end of file
import axios from 'axios'
import { Message } from 'element-ui'
import store from '@/store'
import { getUserInfro } from '@/utils/auth'
// create an axios instance
const service = axios.create({
baseURL: process.env.BASE_API, // api的base_url
timeout: 5000, // request timeout
headers: {'Content-Type':'application/x-www-form-urlencoded'}
})
console.log('请求地址:'+process.env.BASE_API);
// request interceptor
service.interceptors.request.use(config => {
// Do something before request is sent
const userInfro = getUserInfro()
let param = config.data;
if (userInfro) {
// 添加公共参数
const userId = JSON.parse(userInfro).userId
if(param){
if(param.indexOf('userId')<0){
config.data = param+"&userId="+userId;
}
}else{
config.data = "&userId="+userId;
}
// JSON.parse(getUserInfro()).data.userId
}
return config
}, error => {
// Do something with request error
console.log(error) // for debug
Promise.reject(error)
})
// respone interceptor
service.interceptors.response.use(
//暂时这先全部返回,等登录的接口完善以后,再去修改完 response.data
response => response,
/**
* 下面的注释为通过response自定义code来标示请求状态,当code返回如下情况为权限有问题,登出并返回到登录页
* 如通过xmlhttprequest 状态码标识 逻辑可写在下面error中
*/
// const res = response.data;
// if (res.code !== 20000) {
// Message({
// message: res.message,
// type: 'error',
// duration: 5 * 1000
// });
// // 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了;
// if (res.code === 50008 || res.code === 50012 || res.code === 50014) {
// MessageBox.confirm('你已被登出,可以取消继续留在该页面,或者重新登录', '确定登出', {
// confirmButtonText: '重新登录',
// cancelButtonText: '取消',
// type: 'warning'
// }).then(() => {
// store.dispatch('FedLogOut').then(() => {
// location.reload();// 为了重新实例化vue-router对象 避免bug
// });
// })
// }
// return Promise.reject('error');
// } else {
// return response.data;
// }
error => {
Message({
message: '网络异常,请联系管理员',
type: 'error',
duration: 2000
})
return Promise.reject(error)
})
export default service
import request from './request'
import qs from 'qs'
// 菜品列表
export function getRestaurantDishesList(data) {
return request({
url: '/restaurantDishes/getRestaurantDishesList',
method: 'post',
data: qs.stringify(data)
})
}
//添加菜品
export function addOrEditRestaurantDishes(data) {
return request({
url: '/restaurantDishes/addOrEditRestaurantDishes',
method: 'post',
data: qs.stringify(data)
})
}
export function delRestaurantDishes(data) {
return request({
url: '/restaurantDishes/delRestaurantDishes',
method: 'post',
data: qs.stringify(data)
})
}
// 菜单
export function getDailyMenuList(data) {
return request({
url: '/dailyMenu/getDailyMenuList',
method: 'post',
data: qs.stringify(data)
})
}
export function addOrEditDailyMenu(data) {
return request({
url: '/dailyMenu/addOrEditDailyMenu',
method: 'post',
data: qs.stringify(data)
})
}
// 或许可选菜品
export function getRestaurantDishes() {
return request({
url: '/restaurantDishes/getRestaurantDishes',
method: 'post'
})
}
\ No newline at end of file
import request from './request'
import qs from 'qs'
// --------user---start-----------
//获取用户列表
export function getSysUserList(data) {
return request({
url: '/sysUser/getSysUserList',
method: 'post',
data:qs.stringify(data)
})
}
//增加编辑用户
export function addOrEditSysUser(data) {
return request({
url: '/sysUser/addOrEditSysUser',
method: 'post',
data:qs.stringify(data)
})
}
//删除用户
export function deleteSysUser(data) {
return request({
url: '/sysUser/deleteSysUser',
method: 'post',
data:qs.stringify(data)
})
}
// 选择角色
export function queryAllSysRole() {
return request({
url: '/sysRole/queryAllSysRole',
method: 'post',
})
}
// --------user---end-----------
// -------premission---start--------------
// 获取权限列表
export function getSysPermissionList(data) {
return request({
url: '/sysPermission/getSysPermissionList',
method: 'post',
data:qs.stringify(data)
})
}
// 增加编辑权限
export function addOrEditSysPermission(data) {
return request({
url: '/sysPermission/addOrEditSysPermission',
method: 'post',
data:qs.stringify(data)
})
}
// 删除权限列表
export function deleteSysPermission(data) {
return request({
url: '/sysPermission/deleteSysPermission',
method: 'post',
data:qs.stringify(data)
})
}
// 权限树
export function getSysPermssionTree() {
return request({
url: '/sysPermission/getSysPermssionTree',
method: 'post'
})
}
// -------premission---end--------------
// -------role---start--------------
// 获取角色列表
export function getSysRoleList(data) {
return request({
url: '/sysRole/getSysRoleList',
method: 'post',
data:qs.stringify(data)
})
}
// 增加编辑角色
export function addOrEditSysRole(data) {
return request({
url: '/sysRole/addOrEditSysRole',
method: 'post',
data:qs.stringify(data)
})
}
// 编辑获取权限树回显数组
export function getSysPermissionByRoleId(data) {
return request({
url: '/sysPermission/getSysPermissionByRoleId',
method: 'post',
data:qs.stringify(data)
})
}
// 删除角色
export function deleteSysRole(data) {
return request({
url: '/sysRole/deleteSysRole',
method: 'post',
data:qs.stringify(data)
})
}
// -------role---end--------------
// 获取部门的下拉数据
export function getDepts() {
return request({
url: '/dept/getDepts',
method: 'post',
})
}
// 系统参数
export function getSysParamList(data) {
return request({
url: '/sysParam/getSysParamList',
method: 'post',
data:qs.stringify(data)
})
}
export function addOrEditSysParam(data) {
return request({
url: '/sysParam/addOrEditSysParam',
method: 'post',
data:qs.stringify(data)
})
}
// 单个删除
export function deleteSysParam(data) {
return request({
url: '/sysParam/deleteSysParam',
method: 'post',
data:qs.stringify(data)
})
}
// 全部删除
export function batchDelete(data) {
return request({
url: '/sysParam/batchDelete',
method: 'post',
data:qs.stringify(data)
})
}
// 系统字典分类
export function getDataDictList(data) {
return request({
url: '/dataDictCat/getDataDictList',
method: 'post',
data:qs.stringify(data)
})
}
export function addOrEditDataDictCat(data) {
return request({
url: '/dataDictCat/addOrEditDataDictCat',
method: 'post',
data:qs.stringify(data)
})
}
export function deleteDataDictCat(data) {
return request({
url: '/dataDictCat/deleteDataDictCat',
method: 'post',
data:qs.stringify(data)
})
}
export function getDataDicts() {
return request({
url: '/dataDictCat/getDataDicts',
method: 'post'
})
}
export function getDataDictItemList(data) {
return request({
url: '/dataDictItem/getDataDictItemList',
method: 'post',
data:qs.stringify(data)
})
}
export function addOrEditDataDictItem(data) {
return request({
url: '/dataDictItem/addOrEditDataDictItem',
method: 'post',
data:qs.stringify(data)
})
}
export function delDataDictItem(data) {
return request({
url: '/dataDictItem/delDataDictItem',
method: 'post',
data:qs.stringify(data)
})
}
export function getDataDictItems() {
return request({
url: '/dataDictItem/getDataDictItems',
method: 'post'
})
}
// 根据部门id查科室
export function getSectionsByDeptId(data) {
return request({
url: 'section/getSectionsByDeptId',
method: 'post',
data:qs.stringify(data)
})
}
import request from './request'
import qs from 'qs'
// 根据科室id查询,人员信息
export function getMemberListBySection(data) {
return request({
url: '/member/getMemberListBySection',
method: 'post',
data: qs.stringify(data)
})
}
// 添加访客信息
export function addOrEditVisitor(data) {
return request({
url: '/visitor/addOrEditVisitor',
method: 'post',
data: qs.stringify(data)
})
}
// 获取访客信息列表
export function getVisitorList(data) {
return request({
url: '/visitor/getVisitorList',
method: 'post',
data: qs.stringify(data)
})
}
// 获取访客详情
export function getVisitor(data) {
return request({
url: '/visitor/getVisitor',
method: 'post',
data: qs.stringify(data)
})
}
// 获取访客事由列表
// 获取访客事由
export function getVisitReasonList(data) {
return request({
url: '/visitReason/getVisitReasonList',
method: 'post',
data: qs.stringify(data)
})
}
// 编辑访客事由
export function addOrEditVisitReason(data) {
return request({
url: '/visitReason/addOrEditVisitReason',
method: 'post',
data: qs.stringify(data)
})
}
// 删除事由
export function deleteVisitReason(data) {
return request({
url: '/visitReason/deleteVisitReason',
method: 'post',
data: qs.stringify(data)
})
}
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
/* eslint-disable */
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
define(['exports', 'echarts'], factory);
} else if (typeof exports === 'object' && typeof exports.nodeName !== 'string') {
// CommonJS
factory(exports, require('echarts'));
} else {
// Browser globals
factory({}, root.echarts);
}
}(this, function (exports, echarts) {
var log = function (msg) {
if (typeof console !== 'undefined') {
console && console.error && console.error(msg);
}
};
if (!echarts) {
log('ECharts is not Loaded');
return;
}
var colorPalette = [
'#2ec7c9','#b6a2de','#5ab1ef','#ffb980','#d87a80',
'#8d98b3','#e5cf0d','#97b552','#95706d','#dc69aa',
'#07a2a4','#9a7fd1','#588dd5','#f5994e','#c05050',
'#59678c','#c9ab00','#7eb00a','#6f5553','#c14089'
];
var theme = {
color: colorPalette,
title: {
textStyle: {
fontWeight: 'normal',
color: '#008acd'
}
},
visualMap: {
itemWidth: 15,
color: ['#5ab1ef','#e0ffff']
},
toolbox: {
iconStyle: {
normal: {
borderColor: colorPalette[0]
}
}
},
tooltip: {
backgroundColor: 'rgba(50,50,50,0.5)',
axisPointer : {
type : 'line',
lineStyle : {
color: '#008acd'
},
crossStyle: {
color: '#008acd'
},
shadowStyle : {
color: 'rgba(200,200,200,0.2)'
}
}
},
dataZoom: {
dataBackgroundColor: '#efefff',
fillerColor: 'rgba(182,162,222,0.2)',
handleColor: '#008acd'
},
grid: {
borderColor: '#eee'
},
categoryAxis: {
axisLine: {
lineStyle: {
color: '#008acd'
}
},
splitLine: {
lineStyle: {
color: ['#eee']
}
}
},
valueAxis: {
axisLine: {
lineStyle: {
color: '#008acd'
}
},
splitArea : {
show : true,
areaStyle : {
color: ['rgba(250,250,250,0.1)','rgba(200,200,200,0.1)']
}
},
splitLine: {
lineStyle: {
color: ['#eee']
}
}
},
timeline : {
lineStyle : {
color : '#008acd'
},
controlStyle : {
normal : { color : '#008acd'},
emphasis : { color : '#008acd'}
},
symbol : 'emptyCircle',
symbolSize : 3
},
line: {
smooth : true,
symbol: 'emptyCircle',
symbolSize: 3
},
candlestick: {
itemStyle: {
normal: {
color: '#d87a80',
color0: '#2ec7c9',
lineStyle: {
color: '#d87a80',
color0: '#2ec7c9'
}
}
}
},
scatter: {
symbol: 'circle',
symbolSize: 4
},
map: {
label: {
normal: {
textStyle: {
color: '#d87a80'
}
}
},
itemStyle: {
normal: {
borderColor: '#eee',
areaColor: '#ddd'
},
emphasis: {
areaColor: '#fe994e'
}
}
},
graph: {
color: colorPalette
},
gauge : {
axisLine: {
lineStyle: {
color: [[0.2, '#2ec7c9'],[0.8, '#5ab1ef'],[1, '#d87a80']],
width: 10
}
},
axisTick: {
splitNumber: 10,
length :15,
lineStyle: {
color: 'auto'
}
},
splitLine: {
length :22,
lineStyle: {
color: 'auto'
}
},
pointer : {
width : 5
}
}
};
echarts.registerTheme('macarons', theme);
}));
This diff is collapsed.
This diff is collapsed.
<template>
<el-breadcrumb class="app-breadcrumb" separator="/">
<transition-group name="breadcrumb">
<el-breadcrumb-item v-for="(item,index) in levelList" :key="item.path" v-if='item.meta.title'>
<span v-if='item.redirect==="noredirect"||index==levelList.length-1' class="no-redirect">{{item.meta.title}}</span>
<router-link v-else :to="item.redirect||item.path">{{item.meta.title}}</router-link>
</el-breadcrumb-item>
</transition-group>
</el-breadcrumb>
</template>
<script>
export default {
created() {
this.getBreadcrumb()
},
data() {
return {
levelList: null
}
},
watch: {
$route() {
this.getBreadcrumb()
}
},
methods: {
getBreadcrumb() {
let matched = this.$route.matched.filter(item => item.name)
const first = matched[0]
if (first && first.name !== 'home') {
matched = [{ path: '/home', meta: { title: '首页' }}].concat(matched)
}
this.levelList = matched
}
}
}
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
.app-breadcrumb.el-breadcrumb {
display: inline-block;
font-size: 14px;
line-height: 50px;
margin-left: 10px;
.no-redirect {
color: #97a8be;
cursor: text;
}
}
</style>
<template>
<div>
<svg t="1492500959545" @click="toggleClick" class="hamburger" :class="{'is-active':isActive}" style="" viewBox="0 0 1024 1024"
version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1691" xmlns:xlink="http://www.w3.org/1999/xlink" width="64" height="64">
<path d="M966.8023 568.849776 57.196677 568.849776c-31.397081 0-56.850799-25.452695-56.850799-56.850799l0 0c0-31.397081 25.452695-56.849776 56.850799-56.849776l909.605623 0c31.397081 0 56.849776 25.452695 56.849776 56.849776l0 0C1023.653099 543.397081 998.200404 568.849776 966.8023 568.849776z"
p-id="1692"></path>
<path d="M966.8023 881.527125 57.196677 881.527125c-31.397081 0-56.850799-25.452695-56.850799-56.849776l0 0c0-31.397081 25.452695-56.849776 56.850799-56.849776l909.605623 0c31.397081 0 56.849776 25.452695 56.849776 56.849776l0 0C1023.653099 856.07443 998.200404 881.527125 966.8023 881.527125z"
p-id="1693"></path>
<path d="M966.8023 256.17345 57.196677 256.17345c-31.397081 0-56.850799-25.452695-56.850799-56.849776l0 0c0-31.397081 25.452695-56.850799 56.850799-56.850799l909.605623 0c31.397081 0 56.849776 25.452695 56.849776 56.850799l0 0C1023.653099 230.720755 998.200404 256.17345 966.8023 256.17345z"
p-id="1694"></path>
</svg>
</div>
</template>
<script>
export default {
name: 'hamburger',
props: {
isActive: {
type: Boolean,
default: false
},
toggleClick: {
type: Function,
default: null
}
}
}
</script>
<style scoped>
.hamburger {
display: inline-block;
cursor: pointer;
width: 20px;
height: 20px;
transform: rotate(90deg);
transition: .38s;
transform-origin: 50% 50%;
}
.hamburger.is-active {
transform: rotate(0deg);
}
</style>
<template>
<div class="screenfull-icon">
<i @click='click' :class="isFullscreen?'iconfont icon-quanping':'iconfont icon-cancel-full-screen'"></i>
</div>
</template>
<script>
import screenfull from 'screenfull'
export default {
name: 'screenfull',
data() {
return {
isFullscreen: true
}
},
mounted: function() {},
methods: {
click() {
this.isFullscreen = screenfull.isFullscreen
if (!screenfull.enabled) {
this.$message({
message: 'you browser can not work',
type: 'warning'
})
return false
}
screenfull.toggle()
},
screeChange() {}
}
}
</script>
<style lang="scss" scoped>
.screenfull-icon {
display: inline-block;
height: 30px;
i{
font-size: 20px;
cursor: pointer;
color: #999;
&:hover{
color: #333;
}
}
}
</style>
<template>
<div class="scroll-container" ref="scrollContainer" @wheel.prevent="handleScroll" >
<div class="scroll-wrapper" ref="scrollWrapper" :style="{top: top + 'px'}">
<slot></slot>
</div>
</div>
</template>
<script>
const delta = 15
export default {
name: 'scrollBar',
data() {
return {
top: 0
}
},
methods: {
handleScroll(e) {
const eventDelta = e.wheelDelta || -e.deltaY * 3
const $container = this.$refs.scrollContainer
const $containerHeight = $container.offsetHeight
const $wrapper = this.$refs.scrollWrapper
const $wrapperHeight = $wrapper.offsetHeight
if (eventDelta > 0) {
this.top = Math.min(0, this.top + eventDelta)
} else {
if ($containerHeight - delta < $wrapperHeight) {
if (this.top < -($wrapperHeight - $containerHeight + delta)) {
this.top = this.top
} else {
this.top = Math.max(this.top + eventDelta, $containerHeight - $wrapperHeight - delta)
}
} else {
this.top = 0
}
}
}
}
}
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
@import '../../styles/variables.scss';
.scroll-container {
position: relative;
width: 100%;
height: 100%;
background-color: $menuBg;
.scroll-wrapper {
position: absolute;
width: 100%!important;
}
}
</style>
<template>
<div class="scroll-container" ref="scrollContainer" @wheel.prevent="handleScroll">
<div class="scroll-wrapper" ref="scrollWrapper" :style="{left: left + 'px'}">
<slot></slot>
</div>
</div>
</template>
<script>
const padding = 15 // tag's padding
export default {
name: 'scrollPane',
data() {
return {
left: 0
}
},
methods: {
handleScroll(e) {
const eventDelta = e.wheelDelta || -e.deltaY * 3
const $container = this.$refs.scrollContainer
const $containerWidth = $container.offsetWidth
const $wrapper = this.$refs.scrollWrapper
const $wrapperWidth = $wrapper.offsetWidth
if (eventDelta > 0) {
this.left = Math.min(0, this.left + eventDelta)
} else {
if ($containerWidth - padding < $wrapperWidth) {
if (this.left < -($wrapperWidth - $containerWidth + padding)) {
this.left = this.left
} else {
this.left = Math.max(this.left + eventDelta, $containerWidth - $wrapperWidth - padding)
}
} else {
this.left = 0
}
}
},
moveToTarget($target) {
const $container = this.$refs.scrollContainer
const $containerWidth = $container.offsetWidth
const $targetLeft = $target.offsetLeft
const $targetWidth = $target.offsetWidth
if ($targetLeft < -this.left) {
// tag in the left
this.left = -$targetLeft + padding
} else if ($targetLeft + padding > -this.left && $targetLeft + $targetWidth < -this.left + $containerWidth - padding) {
// tag in the current view
// eslint-disable-line
} else {
// tag in the right
this.left = -($targetLeft - ($containerWidth - $targetWidth) + padding)
}
}
}
}
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
.scroll-container {
white-space: nowrap;
position: relative;
overflow: hidden;
width: 100%;
.scroll-wrapper {
position: absolute;
}
}
</style>
<template>
<div class="upload-container">
<el-upload
action=""
:show-file-list="false"
:before-upload="uploadFile">
<el-button icon='el-icon-upload' size="mini" :style="{background:color,borderColor:color}" type="primary">上传图片</el-button>
</el-upload>
</div>
</template>
<script>
import axios from "axios";
export default {
name: 'editorSlideUpload',
props: {
color: {
type: String,
default: '#1890ff'
},
resPath:{
type:String,
default:"proImg"
}
},
data() {
return {
dialogVisible: false,
}
},
methods: {
uploadFile(file) {
const upLoadUrl = process.env.BASE_API + "/upload/uploadFile";
let formData = new FormData();
formData.append("files", file);
formData.append("resPath", this.resPath);
console.log(this.resPath)
const fileSize = file.size/1024/1024;
if(fileSize>2){
this.$message({
message: "上传图片不能大于2M",
type: "warning"
});
}else{
axios.post(upLoadUrl, formData).then(res => {
this.$emit('successCBK', res.data.data)
this.$message({
message: "上传成功",
type: "success"
});
});
}
}
}
}
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
</style>
\ No newline at end of file
<template>
<div class="tinymce-container editor-container" :class="{fullscreen:fullscreen}">
<textarea class="tinymce-textarea" :id="tinymceId"></textarea>
<div class="editor-custom-btn-container" v-if="hasImageLoad">
<editorImage color="#1890ff" class="editor-upload-btn" @successCBK="imageSuccessCBK" :resPath="resPath"></editorImage>
</div>
</div>
</template>
<script>
import editorImage from './components/editorImage'
import plugins from './plugins'
import toolbar from './toolbar'
export default {
name: 'tinymce',
components: { editorImage },
props: {
id: {
type: String
},
value: {
type: String,
default: ''
},
toolbar: {
type: Array,
required: false,
default() {
return []
}
},
menubar: {
default: 'file edit insert view format table'
},
height: {
type: Number,
required: false,
default: 360
},
hasImageLoad:{
type: Number,
default: 1
},
resPath:{
type: String,
default: "proImg"
}
},
data() {
return {
hasChange: false,
hasInit: false,
tinymceId: this.id || 'vue-tinymce-' + +new Date(),
fullscreen: false
}
},
watch: {
value(val) {
if (!this.hasChange && this.hasInit) {
this.$nextTick(() =>
window.tinymce.get(this.tinymceId).setContent(val || ''))
}
}
},
mounted() {
this.initTinymce()
},
activated() {
this.initTinymce()
},
deactivated() {
this.destroyTinymce()
},
methods: {
initTinymce() {
const _this = this
window.tinymce.init({
language: "zh_CN",
selector: `#${this.tinymceId}`,
height: this.height,
body_class: 'panel-body ',
object_resizing: false,
toolbar: this.toolbar.length > 0 ? this.toolbar : toolbar,
menubar: this.menubar,
plugins: plugins,
end_container_on_empty_block: true,
powerpaste_word_import: 'clean',
code_dialog_height: 450,
code_dialog_width: 1000,
advlist_bullet_styles: 'square',
advlist_number_styles: 'default',
imagetools_cors_hosts: ['www.tinymce.com', 'codepen.io'],
default_link_target: '_blank',
link_title: false,
init_instance_callback: editor => {
if (_this.value) {
editor.setContent(_this.value)
}
_this.hasInit = true
editor.on('NodeChange Change KeyUp SetContent', () => {
this.hasChange = true
this.$emit('input', editor.getContent())
})
},
setup(editor) {
editor.on('FullscreenStateChanged', (e) => {
_this.fullscreen = e.state
})
}
// 整合七牛上传
// images_dataimg_filter(img) {
// setTimeout(() => {
// const $image = $(img);
// $image.removeAttr('width');
// $image.removeAttr('height');
// if ($image[0].height && $image[0].width) {
// $image.attr('data-wscntype', 'image');
// $image.attr('data-wscnh', $image[0].height);
// $image.attr('data-wscnw', $image[0].width);
// $image.addClass('wscnph');
// }
// }, 0);
// return img
// },
// images_upload_handler(blobInfo, success, failure, progress) {
// progress(0);
// const token = _this.$store.getters.token;
// getToken(token).then(response => {
// const url = response.data.qiniu_url;
// const formData = new FormData();
// formData.append('token', response.data.qiniu_token);
// formData.append('key', response.data.qiniu_key);
// formData.append('file', blobInfo.blob(), url);
// upload(formData).then(() => {
// success(url);
// progress(100);
// })
// }).catch(err => {
// failure('出现未知问题,刷新页面,或者联系程序员')
// console.log(err);
// });
// },
})
},
destroyTinymce() {
if (window.tinymce.get(this.tinymceId)) {
window.tinymce.get(this.tinymceId).destroy()
}
},
setContent(value) {
window.tinymce.get(this.tinymceId).setContent(value)
},
getContent() {
window.tinymce.get(this.tinymceId).getContent()
},
imageSuccessCBK(url) {
const _this = this
window.tinymce.get(_this.tinymceId).insertContent(`<img class="wscnph" src="${url}" width="100%">`)
}
},
destroyed() {
this.destroyTinymce()
}
}
</script>
<style scoped>
.tinymce-container {
position: relative;
}
.tinymce-container>>>.mce-fullscreen {
z-index: 10000;
}
.tinymce-textarea {
visibility: hidden;
z-index: -1;
}
.editor-custom-btn-container {
position: absolute;
right: 4px;
top: 2px;
/*z-index: 2005;*/
}
.fullscreen .editor-custom-btn-container {
z-index: 10000;
position: fixed;
}
.editor-upload-btn {
display: inline-block;
}
</style>
\ No newline at end of file
// Any plugins you want to use has to be imported
// Detail plugins list see https://www.tinymce.com/docs/plugins/
// Custom builds see https://www.tinymce.com/download/custom-builds/
const plugins = ['advlist anchor autolink autosave code codesample colorpicker colorpicker contextmenu directionality emoticons fullscreen hr importcss insertdatetime legacyoutput link lists media nonbreaking noneditable pagebreak paste preview print save searchreplace spellchecker tabfocus table template textcolor textpattern visualblocks visualchars wordcount']
export default plugins
\ No newline at end of file
// Here is a list of the toolbar
// Detail list see https://www.tinymce.com/docs/advanced/editor-control-identifiers/#toolbarcontrols
const toolbar = ['bold italic underline strikethrough alignleft aligncenter alignright outdent indent blockquote undo redo removeformat subscript superscript code codesample', 'hr bullist numlist link charmap preview anchor pagebreak insertdatetime media table emoticons forecolor backcolor fullscreen']
export default toolbar
\ No newline at end of file
<template>
<div class="uploadimg-container" :style="{width:width+'px'}">
<el-upload
class="uploader-component"
:style="styleObj"
action=""
:show-file-list="false"
:before-upload="uploadFile">
<img :style="styleObj" v-if="type||imageUrl" :src="viewUrl || imageUrl" class="avatar">
<i v-else :style="styleObj" class="el-icon-plus avatar-uploader-icon"></i>
</el-upload>
<div class="tip">宽/高:{{`${width}*${height}`}}</div>
</div>
</template>
<script>
import axios from "axios";
export default {
props: ["width", "height", "resPath", "type", "viewUrl","imageType"],
data() {
return {
imageUrl: "",
param: { resPath: this.resPath },
styleObj: {
width: this.width + "px",
height: this.height + "px",
lineHeight: this.height + "px"
}
};
},
mounted() {},
updated() {},
methods: {
uploadFile(file) {
const upLoadUrl = process.env.BASE_API + "/upload/uploadFile";
let formData = new FormData();
formData.append("files", file);
formData.append("resPath", this.resPath);
// 限制图片上传比例
if(this.imageType==="banner"){
console.log(this.imageType)
formData.append("imageType", this.imageType);
}
const fileSize = file.size / 1024 / 1024;
if (fileSize > 2) {
this.$message({
message: "上传图片不能大于2M",
type: "warning"
});
} else {
axios.post(upLoadUrl, formData).then(res => {
if (res.data.code == 1) {
this.imageUrl = res.data.data;
this.$emit("emitSuccess", res.data.data);
this.$message({
message: "上传成功",
type: "success"
});
} else {
this.$message({
message: res.data.msg,
type: "warning"
});
}
});
}
},
clearImg() {
this.imageUrl = "";
}
}
};
</script>
<style lang="scss" scoped>
.uploadimg-container{
position: relative;
overflow: hidden;
display: inline-block;
.uploader-component {
border: 1px dashed #d9d9d9;
border-radius: 6px;
cursor: pointer;
position: relative;
overflow: hidden;
width: 178px;
height: 178px;
transition: all 0.3s;
.avatar-uploader-icon {
font-size: 28px;
color: #8c939d;
width: 178px;
height: 178px;
line-height: 178px;
text-align: center;
transition: all 0.3s;
}
.avatar {
width: 178px;
height: 178px;
display: block;
}
&:hover {
border-color: #409eff;
.avatar-uploader-icon {
font-size: 28px;
color: #409eff;
width: 178px;
height: 178px;
line-height: 178px;
text-align: center;
}
&+.tip{
left: 10px;
opacity: 1;
}
}
}
.tip{
position: absolute;
left: -140px;
opacity: 0;
top: 0;
width: 131px;
color: #fff;
text-shadow: 2px 2px 2px rgba($color: #000000, $alpha: 1);
font-weight: 700;
cursor: pointer;
transition: all .3s;
&:hover{
left: 10px;
opacity: 1;
}
}
}
</style>
// Inspired by https://github.com/Inndy/vue-clipboard2
const Clipboard = require('clipboard')
if (!Clipboard) {
throw new Error('you shold npm install `clipboard` --save at first ')
}
export default {
bind(el, binding) {
if (binding.arg === 'success') {
el._v_clipboard_success = binding.value
} else if (binding.arg === 'error') {
el._v_clipboard_error = binding.value
} else {
const clipboard = new Clipboard(el, {
text() { return binding.value },
action() { return binding.arg === 'cut' ? 'cut' : 'copy' }
})
clipboard.on('success', e => {
const callback = el._v_clipboard_success
callback && callback(e) // eslint-disable-line
})
clipboard.on('error', e => {
const callback = el._v_clipboard_error
callback && callback(e) // eslint-disable-line
})
el._v_clipboard = clipboard
}
},
update(el, binding) {
if (binding.arg === 'success') {
el._v_clipboard_success = binding.value
} else if (binding.arg === 'error') {
el._v_clipboard_error = binding.value
} else {
el._v_clipboard.text = function() { return binding.value }
el._v_clipboard.action = function() { return binding.arg === 'cut' ? 'cut' : 'copy' }
}
},
unbind(el, binding) {
if (binding.arg === 'success') {
delete el._v_clipboard_success
} else if (binding.arg === 'error') {
delete el._v_clipboard_error
} else {
el._v_clipboard.destroy()
delete el._v_clipboard
}
}
}
import Clipboard from './clipboard'
const install = function(Vue) {
Vue.directive('Clipboard', Clipboard)
}
if (window.Vue) {
window.clipboard = Clipboard
Vue.use(install); // eslint-disable-line
}
Clipboard.install = install
export default Clipboard
export default{
bind(el, binding) {
const dialogHeaderEl = el.querySelector('.el-dialog__header')
const dragDom = el.querySelector('.el-dialog')
dialogHeaderEl.style.cssText += ';cursor:move;'
dragDom.style.cssText += ';top:0px;'
// 获取原有属性 ie dom元素.currentStyle 火狐谷歌 window.getComputedStyle(dom元素, null);
function getStyle(dom, attr) {
if (dom.currentStyle) {
return dom.currentStyle[attr]
} else {
return getComputedStyle(dom, false)[attr]
}
}
dialogHeaderEl.onmousedown = (e) => {
// 鼠标按下,计算当前元素距离可视区的距离
const disX = e.clientX - dialogHeaderEl.offsetLeft
const disY = e.clientY - dialogHeaderEl.offsetTop
const dragDomWidth = dragDom.offsetWidth
const dragDomheight = dragDom.offsetHeight
const screenWidth = document.body.clientWidth
const screenHeight = document.body.clientHeight
const minDragDomLeft = dragDom.offsetLeft
const maxDragDomLeft = screenWidth - dragDom.offsetLeft - dragDomWidth
const minDragDomTop = dragDom.offsetTop
const maxDragDomTop = screenHeight - dragDom.offsetTop - dragDomheight
// 获取到的值带px 正则匹配替换
let styL = getStyle(dragDom, 'left')
let styT = getStyle(dragDom, 'top')
if (styL.includes('%')) {
styL = +document.body.clientWidth * (+styL.replace(/\%/g, '') / 100)
styT = +document.body.clientHeight * (+styT.replace(/\%/g, '') / 100)
} else {
styL = +styL.replace(/\px/g, '')
styT = +styT.replace(/\px/g, '')
}
document.onmousemove = function(e) {
// 通过事件委托,计算移动的距离
let left = e.clientX - disX
let top = e.clientY - disY
// 边界处理
if (-(left) > minDragDomLeft) {
left = -minDragDomLeft
} else if (left > maxDragDomLeft) {
left = maxDragDomLeft
}
if (-(top) > minDragDomTop) {
top = -minDragDomTop
} else if (top > maxDragDomTop) {
top = maxDragDomTop
}
// 移动当前元素
dragDom.style.cssText += `;left:${left + styL}px;top:${top + styT}px;`
}
document.onmouseup = function(e) {
document.onmousemove = null
document.onmouseup = null
}
}
}
}
import drag from './drag'
const install = function(Vue) {
Vue.directive('el-drag-dialog', drag)
}
if (window.Vue) {
window['el-drag-dialog'] = drag
Vue.use(install); // eslint-disable-line
}
drag.install = install
export default drag
const vueSticky = {}
let listenAction
vueSticky.install = Vue => {
Vue.directive('sticky', {
inserted(el, binding) {
const params = binding.value || {}
const stickyTop = params.stickyTop || 0
const zIndex = params.zIndex || 1000
const elStyle = el.style
elStyle.position = '-webkit-sticky'
elStyle.position = 'sticky'
// if the browser support css sticky(Currently Safari, Firefox and Chrome Canary)
// if (~elStyle.position.indexOf('sticky')) {
// elStyle.top = `${stickyTop}px`;
// elStyle.zIndex = zIndex;
// return
// }
const elHeight = el.getBoundingClientRect().height
const elWidth = el.getBoundingClientRect().width
elStyle.cssText = `top: ${stickyTop}px; z-index: ${zIndex}`
const parentElm = el.parentNode || document.documentElement
const placeholder = document.createElement('div')
placeholder.style.display = 'none'
placeholder.style.width = `${elWidth}px`
placeholder.style.height = `${elHeight}px`
parentElm.insertBefore(placeholder, el)
let active = false
const getScroll = (target, top) => {
const prop = top ? 'pageYOffset' : 'pageXOffset'
const method = top ? 'scrollTop' : 'scrollLeft'
let ret = target[prop]
if (typeof ret !== 'number') {
ret = window.document.documentElement[method]
}
return ret
}
const sticky = () => {
if (active) {
return
}
if (!elStyle.height) {
elStyle.height = `${el.offsetHeight}px`
}
elStyle.position = 'fixed'
elStyle.width = `${elWidth}px`
placeholder.style.display = 'inline-block'
active = true
}
const reset = () => {
if (!active) {
return
}
elStyle.position = ''
placeholder.style.display = 'none'
active = false
}
const check = () => {
const scrollTop = getScroll(window, true)
const offsetTop = el.getBoundingClientRect().top
if (offsetTop < stickyTop) {
sticky()
} else {
if (scrollTop < elHeight + stickyTop) {
reset()
}
}
}
listenAction = () => {
check()
}
window.addEventListener('scroll', listenAction)
},
unbind() {
window.removeEventListener('scroll', listenAction)
}
})
}
export default vueSticky
import viewImg from './viewImg'
const install = function(Vue) {
Vue.directive('viewImg', viewImg)
}
if (window.Vue) {
window.viewImg = viewImg
Vue.use(install); // eslint-disable-line
}
viewImg.install = install
export default viewImg
export default{
bind(el, binding) {
el.addEventListener('click', e => {
}, false)
}
}
import waves from './waves'
const install = function(Vue) {
Vue.directive('waves', waves)
}
if (window.Vue) {
window.waves = waves
Vue.use(install); // eslint-disable-line
}
waves.install = install
export default waves
.waves-ripple {
position: absolute;
border-radius: 100%;
background-color: rgba(0, 0, 0, 0.15);
background-clip: padding-box;
pointer-events: none;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
-webkit-transform: scale(0);
-ms-transform: scale(0);
transform: scale(0);
opacity: 1;
}
.waves-ripple.z-active {
opacity: 0;
-webkit-transform: scale(2);
-ms-transform: scale(2);
transform: scale(2);
-webkit-transition: opacity 1.2s ease-out, -webkit-transform 0.6s ease-out;
transition: opacity 1.2s ease-out, -webkit-transform 0.6s ease-out;
transition: opacity 1.2s ease-out, transform 0.6s ease-out;
transition: opacity 1.2s ease-out, transform 0.6s ease-out, -webkit-transform 0.6s ease-out;
}
\ No newline at end of file
import './waves.css'
export default{
bind(el, binding) {
el.addEventListener('click', e => {
const customOpts = Object.assign({}, binding.value)
const opts = Object.assign({
ele: el, // 波纹作用元素
type: 'hit', // hit点击位置扩散center中心点扩展
color: 'rgba(0, 0, 0, 0.15)' // 波纹颜色
}, customOpts)
const target = opts.ele
if (target) {
target.style.position = 'relative'
target.style.overflow = 'hidden'
const rect = target.getBoundingClientRect()
let ripple = target.querySelector('.waves-ripple')
if (!ripple) {
ripple = document.createElement('span')
ripple.className = 'waves-ripple'
ripple.style.height = ripple.style.width = Math.max(rect.width, rect.height) + 'px'
target.appendChild(ripple)
} else {
ripple.className = 'waves-ripple'
}
switch (opts.type) {
case 'center':
ripple.style.top = (rect.height / 2 - ripple.offsetHeight / 2) + 'px'
ripple.style.left = (rect.width / 2 - ripple.offsetWidth / 2) + 'px'
break
default:
ripple.style.top = (e.pageY - rect.top - ripple.offsetHeight / 2 - document.body.scrollTop) + 'px'
ripple.style.left = (e.pageX - rect.left - ripple.offsetWidth / 2 - document.body.scrollLeft) + 'px'
}
ripple.style.backgroundColor = opts.color
ripple.className = 'waves-ripple z-active'
return false
}
}, false)
}
}
import Vue from 'vue'
import store from './store'
// you can set only in production env show the error-log
// if (process.env.NODE_ENV === 'production') {
Vue.config.errorHandler = function(err, vm, info, a) {
// Don't ask me why I use Vue.nextTick, it just a hack.
// detail see https://forum.vuejs.org/t/dispatch-in-vue-config-errorhandler-has-some-problem/23500
Vue.nextTick(() => {
store.dispatch('addErrorLog', {
err,
vm,
info,
url: window.location.href
})
console.error(err, info)
})
}
// }
import Vue from 'vue'
import 'babel-polyfill'//兼容ie
import 'normalize.css/normalize.css'// A modern alternative to CSS resets
import Element from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
import App from './App'
import router from './router'
import store from './store'
import './errorLog'// error log
import './permission' // permission control
import './mock' // simulation data
// 注册全局表头搜索函数、注册全局表格数据重置函数(添加删除标识)
import * as seach from './utils/modelFuntion/seach'
import {addDelState} from './utils/modelFuntion/addDelState'
Vue.prototype.$addDelState = addDelState
Vue.prototype.$seach = seach
Vue.use(Element)
Vue.config.productionTip = false
new Vue({
el: '#app',
router,
store,
template: '<App/>',
components: { App }
})
import Mock from 'mockjs'
import loginAPI from './login'
// Mock.setup({
// timeout: '350-600'
// })
// 登录相关
Mock.mock(/\/login\/login/, 'post', loginAPI.loginByUsername)
Mock.mock(/\/login\/logout/, 'post', loginAPI.logout)
Mock.mock(/\/user\/info\.*/, 'get', loginAPI.getUserInfo)
export default Mock
import { param2Obj } from '@/utils'
const userMap = {
admin: {
roles: ['admin'],
permissionTree: 'all',
token: 'admin',
introduction: '我是超级管理员',
avatar: 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif',
name: 'Super Admin'
},
editor: {
roles: ['editor'],
permissionTree: [
{
path: '/department',
children: [
{ path: 'index' },
{ path: 'personnel' }
]
},
{
path: '/car',
children: [
{ path: 'brandList' },
{ path: 'seriesList' },
{ path: 'yearList' }
]
}
],
token: 'editor',
introduction: '我是编辑',
avatar: 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif',
name: 'Normal Editor'
}
}
export default {
loginByUsername: config => {
const { username } = JSON.parse(config.body)
return userMap[username]
},
getUserInfo: config => {
const { token } = param2Obj(config.url)
if (userMap[token]) {
return userMap[token]
} else {
return false
}
},
logout: () => 'success'
}
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 { getUserInfro } from '@/utils/auth' // getToken from cookie
NProgress.configure({ showSpinner: false })// NProgress Configuration
router.beforeEach((to, from, next) => {
NProgress.start() // start progress bar
if (getUserInfro()) { // determine if there has token
/* 如果有用户信息*/
if (to.path === '/login') {
next({ path: '/' })
NProgress.done() // if current page is dashboard will not trigger afterEach hook, so manually handle it
} else {
// 判断是不是已经有了
if(store.getters.addRouters.length === 0){
const permissionTree = JSON.parse(getUserInfro()).permissionTree;
store.dispatch('GenerateRoutes', { permissionTree }).then(() => {
router.addRoutes(store.getters.addRouters) // 动态添加可访问路由表
next({ ...to, replace: true }) // hack方法 确保addRoutes已完成 ,set the replace: true so the navigation will not leave a history record
}).catch(() => {
store.dispatch('FedLogOut').then(() => {
Message.error('Verification failed, please login again')
next({ path: '/login' })
})
})
}else{
next()
}
}
} else {
if(to.path!=="/login"){
next({ path: '/login' }) // 否则全部重定向到登录页
NProgress.done() // if current page is login will not trigger afterEach hook, so manually handle it
}else{
next()
NProgress.done()
}
}
})
router.afterEach(() => {
NProgress.done() // finish progress bar
})
module.exports = file => require('@/views/' + file + '.vue').default // vue-loader at least v13.0.0+
module.exports = file => () => import('@/views/' + file + '.vue')
import Vue from 'vue'
import Router from 'vue-router'
const _import = require('./_import_' + process.env.NODE_ENV)
// in development-env not use lazy-loading, because lazy-loading too many pages will cause webpack hot update too slow. so only in production use lazy-loading;
// detail: https://panjiachen.github.io/vue-element-admin-site/#/lazy-loading
Vue.use(Router)
/* Layout */
import Layout from '../views/layout/Layout'
/** note: submenu only apppear when children.length>=1
* detail see https://panjiachen.github.io/vue-element-admin-site/#/router-and-nav?id=sidebar
**/
/**
* hidden: true if `hidden:true` will not show in the sidebar(default is false)
* alwaysShow: true if set true, will always show the root menu, whatever its child routes length
* if not set alwaysShow, only more than one route under the children
* it will becomes nested mode, otherwise not show the root menu
* redirect: noredirect if `redirect:noredirect` will no redirct in the breadcrumb
* name:'router-name' the name is used by <keep-alive> (must set!!!)
* meta : {
roles: ['admin','editor'] will control the page roles (you can set multiple roles)
title: 'title' the name show in submenu and breadcrumb (recommend set)
icon: 'svg-name' the icon show in the sidebar,
noCache: true if true ,the page will no be cached(default is false)
}
**/
export const constantRouterMap = [
{ path: '/login', component: _import('login/index'), hidden: true },
{ path: '/404', component: _import('errorPage/404'), hidden: true },
{ path: '/401', component: _import('errorPage/401'), hidden: true },
{
path: '', //首页不加
component: Layout,
redirect: 'home',
children: [{
path: 'home',
component: _import('home/index'),
name: 'home',
meta: { title: '首页', icon: 'shouye', noCache: true }
}]
}
]
export default new Router({
// mode: 'history', // require service support
scrollBehavior: () => ({ y: 0 }),
routes: constantRouterMap
})
export const asyncRouterMap = [
// 车辆管理
{
path: '/car',
alwaysShow:true,
component: Layout,
redirect: '/car/brandList',
meta: {
title: '车辆管理',
icon: 'cheliang'
},
children: [
{ path: 'brandList', component: _import('car/brandList'), name: 'car_brandList', meta: { title: '品牌列表' }},
{ path: 'seriesList', component: _import('car/seriesList'), name: 'car_seriesList', meta: { title: '车系列表' }},
{ path: 'yearList', component: _import('car/yearList'), name: 'car_yearList', meta: { title: '年代列表' }},
{ path: 'carList', component: _import('car/carList'), name: 'car_carList', meta: { title: '车辆列表' }}
]
},
// 系统管理
{
path: '/system',
alwaysShow:true,
component: Layout,
redirect: '/system/permission',
meta: {
title: '系统管理',
icon: 'navicon-xtgl'
},
children: [
{ path: 'permission', component: _import('system/permission'), name: 'system_permission', meta: { title: '系统权限' }},
{ path: 'roles', component: _import('system/roles'), name: 'system_roles', meta: { title: '系统角色' }},
{ path: 'user', component: _import('system/user'), name: 'system_user', meta: { title: '系统用户' }},
{ path: 'param', component: _import('system/param'), name: 'system_param', meta: { title: '系统参数' }},
{ path: 'dataDicFl', component: _import('system/dataDicFl'), name: 'system_dataDicFl', meta: { title: '数据字典分类' }},
{ path: 'dataDicX', component: _import('system/dataDicX'), name: 'system_dataDicX', meta: { title: '数据字典项' }}
]
},
{ path: '*', redirect: '/404', hidden: true }
]
const getters = {
sidebar: state => state.app.sidebar, //左部菜单
language: state => state.app.language, //语言
device: state => state.app.device, //设备类型
visitedViews: state => state.tagsView.visitedViews, //顶部tag页签
cachedViews: state => state.tagsView.cachedViews,
// token: state => state.user.token,
// avatar: state => state.user.avatar,
// name: state => state.user.name,
// introduction: state => state.user.introduction,
userInfro: state => state.user.userInfro,
status: state => state.user.status,
roles: state => state.user.roles,
setting: state => state.user.setting,
permission_routers: state => state.permission.routers,
addRouters: state => state.permission.addRouters,
errorLogs: state => state.errorLog.logs //每个页面的条目数
}
export default getters
import Vue from 'vue'
import Vuex from 'vuex'
import app from './modules/app'
import errorLog from './modules/errorLog'
import permission from './modules/permission'
import tagsView from './modules/tagsView'
import user from './modules/user'
import getters from './getters'
Vue.use(Vuex)
const store = new Vuex.Store({
modules: {
app,
errorLog,
permission,
tagsView,
user
},
getters
})
export default store
import Cookies from 'js-cookie'
const app = {
state: {
sidebar: {
opened: !+Cookies.get('sidebarStatus'),
withoutAnimation: false
},
device: 'desktop',
language: Cookies.get('language') || 'en'
},
mutations: {
TOGGLE_SIDEBAR: state => {
if (state.sidebar.opened) {
Cookies.set('sidebarStatus', 1)
} else {
Cookies.set('sidebarStatus', 0)
}
state.sidebar.opened = !state.sidebar.opened
state.sidebar.withoutAnimation = false
},
CLOSE_SIDEBAR: (state, withoutAnimation) => {
Cookies.set('sidebarStatus', 1)
state.sidebar.opened = false
state.sidebar.withoutAnimation = withoutAnimation
},
TOGGLE_DEVICE: (state, device) => {
state.device = device
},
SET_LANGUAGE: (state, language) => {
state.language = language
Cookies.set('language', language)
}
},
actions: {
toggleSideBar({ commit }) {
commit('TOGGLE_SIDEBAR')
},
closeSideBar({ commit }, { withoutAnimation }) {
commit('CLOSE_SIDEBAR', withoutAnimation)
},
toggleDevice({ commit }, device) {
commit('TOGGLE_DEVICE', device)
},
setLanguage({ commit }, language) {
commit('SET_LANGUAGE', language)
}
}
}
export default app
const errorLog = {
state: {
logs: []
},
mutations: {
ADD_ERROR_LOG: (state, log) => {
state.logs.push(log)
}
},
actions: {
addErrorLog({ commit }, log) {
commit('ADD_ERROR_LOG', log)
}
}
}
export default errorLog
import { asyncRouterMap, constantRouterMap } from '@/router'
/**
* 通过meta.role判断是否与当前用户权限匹配
* @param roles
* @param route
*/
// function hasPermission(roles, route) {
// if (route.meta && route.meta.roles) {
// return roles.some(role => route.meta.roles.indexOf(role) >= 0)
// } else {
// return true
// }
// }
/**
* 递归过滤异步路由表,返回符合用户角色权限的路由表
* @param asyncRouterMap
* @param roles
*/
// function filterAsyncRouter(asyncRouterMap, roles) {
// const accessedRouters = asyncRouterMap.filter(route => {
// if (hasPermission(roles, route)) {
// if (route.children && route.children.length) {
// route.children = filterAsyncRouter(route.children, roles)
// }
// return true
// }
// return false
// })
// return accessedRouters
// }
function filterAsyncRouter(asyncRouterMap, permissionTree) {
const newRouter = asyncRouterMap.filter(router => {
if (router.path !== '*') {
for (const item of permissionTree) {
if (router.path.indexOf(item.path) > -1) {
if (item.children.length!==0) {
router.children = filterAsyncRouter(router.children, item.children)
}
return true
}
}
} else {
return true
}
})
return newRouter
}
const permission = {
state: {
routers: constantRouterMap,
addRouters: []
},
mutations: {
SET_ROUTERS: (state, routers) => {
state.addRouters = routers
state.routers = constantRouterMap.concat(routers)
}
},
actions: {
GenerateRoutes({ commit }, data) {
return new Promise(resolve => {
const { permissionTree } = data
let accessedRouters = filterAsyncRouter(asyncRouterMap, permissionTree)
commit('SET_ROUTERS', accessedRouters)
resolve()
})
}
}
}
export default permission
const tagsView = {
state: {
visitedViews: [],
cachedViews: []
},
mutations: {
ADD_VISITED_VIEWS: (state, view) => {
if (state.visitedViews.some(v => v.path === view.path)) return
state.visitedViews.push({
name: view.name,
path: view.path,
title: view.meta.title || 'no-name'
})
if (!view.meta.noCache) {
state.cachedViews.push(view.name)
}
},
DEL_VISITED_VIEWS: (state, view) => {
for (const [i, v] of state.visitedViews.entries()) {
if (v.path === view.path) {
state.visitedViews.splice(i, 1)
break
}
}
for (const i of state.cachedViews) {
if (i === view.name) {
const index = state.cachedViews.indexOf(i)
state.cachedViews.splice(index, 1)
break
}
}
},
DEL_OTHERS_VIEWS: (state, view) => {
for (const [i, v] of state.visitedViews.entries()) {
if (v.path === view.path) {
state.visitedViews = state.visitedViews.slice(i, i + 1)
break
}
}
for (const i of state.cachedViews) {
if (i === view.name) {
const index = state.cachedViews.indexOf(i)
state.cachedViews = state.cachedViews.slice(index, i + 1)
break
}
}
},
DEL_ALL_VIEWS: (state) => {
state.visitedViews = []
state.cachedViews = []
}
},
actions: {
addVisitedViews({ commit }, view) {
commit('ADD_VISITED_VIEWS', view)
},
delVisitedViews({ commit, state }, view) {
return new Promise((resolve) => {
commit('DEL_VISITED_VIEWS', view)
resolve([...state.visitedViews])
})
},
delOthersViews({ commit, state }, view) {
return new Promise((resolve) => {
commit('DEL_OTHERS_VIEWS', view)
resolve([...state.visitedViews])
})
},
delAllViews({ commit, state }) {
return new Promise((resolve) => {
commit('DEL_ALL_VIEWS')
resolve([...state.visitedViews])
})
}
}
}
export default tagsView
import { loginOut, login } from '@/api/login'
import * as cookie from '@/utils/auth'
const user = {
state: {
userInfro: null,
hasUserInfro:false
},
mutations: {
SET_USER_INFRO: (state, userInfro) => {
state.userInfro = userInfro
}
},
actions: {
// 用户名登录
LoginByUsername({ commit }, userInfo) {
const loginName = userInfo.username.trim()
const loginPassword = userInfo.password
return new Promise((resolve, reject) => {
login({ loginName, loginPassword }).then(res => {
if (res.data.code === "1") {
commit('SET_USER_INFRO', res.data.data)
cookie.setUserInfro(res.data.data)
cookie.setHasInfro(true)
resolve()
} else {
reject(res.data)
}
}).catch(error => {
reject(error)
})
})
},
// 登出
LogOut({ commit, state }) {
return new Promise((resolve, reject) => {
loginOut().then(() => {
commit('SET_USER_INFRO', null)
cookie.removeUserInfro()
resolve()
}).catch(error => {
reject(error)
})
})
},
// 前端 登出
FedLogOut({ commit }) {
return new Promise(resolve => {
commit('SET_USER_INFRO', null)
cookie.removeUserInfro()
resolve()
})
}
}
}
export default user
@import './variables.scss';
@mixin colorBtn($color) {
background: $color;
&:hover {
color: $color;
&:before,
&:after {
background: $color;
}
}
}
.blue-btn {
@include colorBtn($blue)
}
.light-blue-btn {
@include colorBtn($light-blue)
}
.red-btn {
@include colorBtn($red)
}
.pink-btn {
@include colorBtn($pink)
}
.green-btn {
@include colorBtn($green)
}
.tiffany-btn {
@include colorBtn($tiffany)
}
.yellow-btn {
@include colorBtn($yellow)
}
.pan-btn {
font-size: 14px;
color: #fff;
padding: 14px 36px;
border-radius: 8px;
border: none;
outline: none;
margin-right: 25px;
transition: 600ms ease all;
position: relative;
display: inline-block;
&:hover {
background: #fff;
&:before,
&:after {
width: 100%;
transition: 600ms ease all;
}
}
&:before,
&:after {
content: '';
position: absolute;
top: 0;
right: 0;
height: 2px;
width: 0;
transition: 400ms ease all;
}
&::after {
right: inherit;
top: inherit;
left: 0;
bottom: 0;
}
}
.custom-button {
display: inline-block;
line-height: 1;
white-space: nowrap;
cursor: pointer;
background: #fff;
color: #fff;
-webkit-appearance: none;
text-align: center;
box-sizing: border-box;
outline: 0;
margin: 0;
padding: 10px 15px;
font-size: 14px;
border-radius: 4px;
}
//覆盖一些element-ui样式
.el-breadcrumb__inner, .el-breadcrumb__inner a{
font-weight: 400!important;
}
.el-upload {
input[type="file"] {
display: none !important;
}
}
.el-upload__input {
display: none;
}
.cell {
.el-tag {
margin-right: 0px;
}
}
.small-padding {
.cell {
padding-left: 5px;
padding-right: 5px;
}
}
.fixed-width{
.el-button--mini{
padding: 7px 10px;
width: 60px;
}
}
.status-col {
.cell {
padding: 0 10px;
text-align: center;
.el-tag {
margin-right: 0px;
}
}
}
//暂时性解决dialog 问题 https://github.com/ElemeFE/element/issues/2461
.el-dialog {
transform: none;
left: 0;
position: relative;
margin: 0 auto;
}
//文章页textarea修改样式
.article-textarea {
textarea {
padding-right: 40px;
resize: none;
border: none;
border-radius: 0px;
border-bottom: 1px solid #bfcbd9;
}
}
//element ui upload
.upload-container {
.el-upload {
width: 100%;
.el-upload-dragger {
width: 100%;
height: 200px;
}
}
}
//dropdown
.el-dropdown-menu{
a{
display: block
}
}
.el-dialog__body{
padding-top: 0px;
padding-bottom: 0px;
}
//重置分页样式
.el-pagination{
margin-top: 18px;
text-align: center
}
@import './variables.scss';
@import './mixin.scss';
@import './transition.scss';
@import './element-ui.scss';
@import './sidebar.scss';
@import './btn.scss';
body {
height: 100%;
-moz-osx-font-smoothing: grayscale;
-webkit-font-smoothing: antialiased;
text-rendering: optimizeLegibility;
font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, Arial, sans-serif;
}
label {
font-weight: 700;
}
html {
height: 100%;
box-sizing: border-box;
}
#app{
height: 100%;
}
*,
*:before,
*:after {
box-sizing: inherit;
}
.no-padding {
padding: 0px !important;
}
.padding-content {
padding: 4px 0;
}
a:focus,
a:active {
outline: none;
}
a,
a:focus,
a:hover {
cursor: pointer;
color: inherit;
text-decoration: none;
}
// 样式reset
h1,h2,h3,h4,h5,h6{
margin: 0;
font-weight: normal;
}
p{
margin: 0;
}
ul{
padding: 0;
margin: 0;
}
li{
list-style: none;
}
div:focus{
outline: none;
}
.fr {
float: right;
}
.fl {
float: left;
}
.pr-5 {
padding-right: 5px;
}
.pl-5 {
padding-left: 5px;
}
.ml-15{
margin-left: 15px;
}
.mr-15{
margin-right: 15px;
}
.block {
display: block;
}
.pointer {
cursor: pointer;
}
.inlineBlock {
display: block;
}
.clearfix {
&:after {
visibility: hidden;
display: block;
font-size: 0;
content: " ";
clear: both;
height: 0;
}
}
code {
background: #eef1f6;
padding: 15px 16px;
margin-bottom: 20px;
display: block;
line-height: 36px;
font-size: 15px;
font-family: "Source Sans Pro", "Helvetica Neue", Arial, sans-serif;
a {
color: #337ab7;
cursor: pointer;
&:hover {
color: rgb(32, 160, 255);
}
}
}
.warn-content{
background: rgba(66,185,131,.1);
border-radius: 2px;
padding: 16px;
padding: 1rem;
line-height: 1.6rem;
word-spacing: .05rem;
a{
color: #42b983;
font-weight: 600;
}
}
//main-container全局样式
.app-container {
padding: 20px;
}
.components-container {
margin: 30px 50px;
position: relative;
}
.pagination-container {
margin-top: 30px;
}
.text-center {
text-align: center
}
.sub-navbar {
height: 50px;
line-height: 50px;
position: relative;
width: 100%;
text-align: right;
padding-right: 20px;
transition: 600ms ease position;
background: linear-gradient(90deg, rgba(32, 182, 249, 1) 0%, rgba(32, 182, 249, 1) 0%, rgba(33, 120, 241, 1) 100%, rgba(33, 120, 241, 1) 100%);
.subtitle {
font-size: 20px;
color: #fff;
}
&.draft {
background: #d0d0d0;
}
&.deleted {
background: #d0d0d0;
}
}
.link-type,
.link-type:focus {
color: #337ab7;
cursor: pointer;
&:hover {
color: rgb(32, 160, 255);
}
}
.filter-container {
padding-bottom: 10px;
.filter-item {
display: inline-block;
vertical-align: middle;
margin-bottom: 10px;
}
}
//refine vue-multiselect plugin
.multiselect {
line-height: 16px;
}
.multiselect--active {
z-index: 1000 !important;
}
// 公共模块央视
.model-container{
box-sizing: border-box;
padding: 14px;
.el-card{
box-shadow: none;
&:first-child{
margin-bottom: 10px;
}
.el-card__header{
padding: 12px 20px;
font-size: 14px;
color: #666;
font-weight: bold;
&>.clearfix>span{
line-height: 32px;
}
.iconfont{
font-size: 18px;
vertical-align: -2px;
color: #666;
margin-right: 4px;
}
.btns-wrapper-right,
.btns-wrapper-left{
.el-button{
padding: 8px 12px;
}
}
.btns-wrapper-right{
float: right;
}
.btns-wrapper-left{
float: left;
}
}
}
.input-name{
line-height: 40px;
padding: 0!important;
font-size: 14px;
color: #999;
text-align: right;
}
.table-icon{
padding: 6px;
i{
font-size: 16px;
}
}
.popver-btn{
margin-left: 10px;
}
.btns-wrapper {
text-align: right;
font-size: 16px;
padding: 15px;
margin-top: 15px;
border-top: solid 1px #eee;
i {
font-size: 18px;
vertical-align: -2px;
margin-right: 3px;
}
}
}
@mixin clearfix {
&:after {
content: "";
display: table;
clear: both;
}
}
@mixin scrollBar {
&::-webkit-scrollbar-track-piece {
background: #d3dce6;
}
&::-webkit-scrollbar {
width: 6px;
}
&::-webkit-scrollbar-thumb {
background: #99a9bf;
border-radius: 20px;
}
}
@mixin relative {
position: relative;
width: 100%;
height: 100%;
}
@mixin pct($pct) {
width: #{$pct};
position: relative;
margin: 0 auto;
}
@mixin triangle($width, $height, $color, $direction) {
$width: $width/2;
$color-border-style: $height solid $color;
$transparent-border-style: $width solid transparent;
height: 0;
width: 0;
@if $direction==up {
border-bottom: $color-border-style;
border-left: $transparent-border-style;
border-right: $transparent-border-style;
}
@else if $direction==right {
border-left: $color-border-style;
border-top: $transparent-border-style;
border-bottom: $transparent-border-style;
}
@else if $direction==down {
border-top: $color-border-style;
border-left: $transparent-border-style;
border-right: $transparent-border-style;
}
@else if $direction==left {
border-right: $color-border-style;
border-top: $transparent-border-style;
border-bottom: $transparent-border-style;
}
}
#app {
// 主体区域
.main-container {
min-height: 100%;
transition: margin-left .28s;
margin-left: 180px;
}
// 侧边栏
.sidebar-container {
.horizontal-collapse-transition {
transition: 0s width ease-in-out, 0s padding-left ease-in-out, 0s padding-right ease-in-out;
}
transition: width .28s;
width: 180px !important;
height: 100%;
position: fixed;
font-size: 0px;
top: 0;
bottom: 0;
left: 0;
z-index: 1001;
overflow: hidden;
a {
display: inline-block;
width: 100%;
}
.svg-icon {
margin-right: 16px;
}
.el-menu {
border: none;
width: 100% !important;
}
}
.hideSidebar {
.sidebar-container {
width: 36px !important;
}
.main-container {
margin-left: 36px;
}
.submenu-title-noDropdown {
padding-left: 10px !important;
position: relative;
.el-tooltip {
padding: 0 10px !important;
}
}
.el-submenu {
&>.el-submenu__title {
padding-left: 10px !important;
&>span {
height: 0;
width: 0;
overflow: hidden;
visibility: hidden;
display: inline-block;
}
.el-submenu__icon-arrow {
display: none;
}
}
}
}
.sidebar-container .nest-menu .el-submenu>.el-submenu__title,
.sidebar-container .el-submenu .el-menu-item {
min-width: 180px !important;
background-color: $subMenuBg !important;
&:hover {
background-color: $menuHover !important;
}
}
.el-menu--collapse .el-menu .el-submenu {
min-width: 180px !important;
}
//适配移动端
.mobile {
.main-container {
margin-left: 0px;
}
.sidebar-container {
top: 50px;
transition: transform .28s;
width: 180px !important;
}
&.hideSidebar {
.sidebar-container {
transition-duration: 0.3s;
transform: translate3d(-180px, 0, 0);
}
}
}
.withoutAnimation {
.main-container,
.sidebar-container {
transition: none;
}
}
}
//globl transition css
/*fade*/
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.28s;
}
.fade-enter,
.fade-leave-active {
opacity: 0;
}
/*fade*/
.breadcrumb-enter-active,
.breadcrumb-leave-active {
transition: all .5s;
}
.breadcrumb-enter,
.breadcrumb-leave-active {
opacity: 0;
transform: translateX(20px);
}
.breadcrumb-move {
transition: all .5s;
}
.breadcrumb-leave-active {
position: absolute;
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment