├── .babelrc ├── .editorconfig ├── .eslintrc.js ├── .gitignore ├── .npmignore ├── .postcssrc.js ├── LICENSE ├── README.md ├── READNE-EN.md ├── build ├── build.js ├── devServer.js ├── release.js ├── webpack.base.conf.js ├── webpack.dev.conf.js ├── webpack.prod.conf.js └── webpack.release.conf.js ├── config.js ├── dist ├── fonts │ ├── element-icons.535877f.woff │ └── element-icons.732389d.ttf ├── vue-willtable.min.css └── vue-willtable.min.js ├── example ├── App.vue ├── favicon.ico ├── github.jpg ├── index.html ├── main.js └── mock.js ├── package.json ├── src ├── assets │ ├── ascending.png │ ├── date.png │ ├── descending.png │ ├── dropdown.png │ ├── number.png │ ├── select.png │ └── text.png ├── components │ ├── Table.vue │ ├── TableBody.vue │ ├── TableDropdown.vue │ ├── TableEditor.vue │ ├── TableHeader.vue │ └── TableScroll.vue ├── directives │ └── clickoutside.js ├── index.js ├── mixins │ ├── events.js │ ├── methods.js │ └── verify.js ├── store │ └── index.js └── style │ ├── reset.scss │ └── transition.scss └── yarn.lock /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | [ 4 | "@babel/preset-env", 5 | { 6 | "targets": { 7 | "esmodules": false, 8 | "browsers": ["> 1%", "last 2 versions", "not ie <= 8"] 9 | } 10 | } 11 | ] 12 | ], 13 | "plugins": [ 14 | "@babel/plugin-syntax-dynamic-import", 15 | "@babel/plugin-proposal-class-properties", 16 | [ 17 | "component", 18 | { 19 | "libraryName": "element-ui", 20 | "styleLibraryName": "theme-chalk" 21 | } 22 | ] 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | 3 | module.exports = { 4 | root: true, 5 | env: { 6 | browser: true, 7 | node: true, 8 | }, 9 | extends: [ 10 | 'plugin:vue/essential', 11 | 'airbnb-base', 12 | ], 13 | settings: { 14 | 'import/resolver': { 15 | webpack: { 16 | config: path.resolve(__dirname, './build/webpack.base.conf.js') 17 | } 18 | } 19 | }, 20 | rules: { 21 | 'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off', 22 | 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off', 23 | 'linebreak-style': 'off', 24 | 'no-mixed-operators': 'off', 25 | 'max-len': [1, 300], 26 | 'default-case': 0, 27 | 'func-names': 0, 28 | 'no-param-reassign': 0, 29 | 'no-console': 'off', 30 | 'no-underscore-dangle': 'off', 31 | 'no-lonely-if': 0, 32 | 'import/no-extraneous-dependencies': 0, 33 | 'global-require': 0, 34 | 'prefer-promise-reject-errors': 'off', 35 | "consistent-return": 0, 36 | "no-prototype-builtins": 0, 37 | "no-restricted-globals": 0, 38 | "class-methods-use-this": 0, 39 | 'no-restricted-syntax': 'off', 40 | 'guard-for-in': 'off', 41 | }, 42 | parserOptions: { 43 | parser: 'babel-eslint', 44 | }, 45 | }; 46 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | demo 4 | dist 5 | npm-debug.log* 6 | yarn-debug.log* 7 | yarn-error.log* 8 | 9 | # Editor directories and files 10 | .idea 11 | .vscode 12 | *.suo 13 | *.ntvs* 14 | *.njsproj 15 | *.sln 16 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .* 2 | build/ 3 | node_modules/ 4 | demo/ -------------------------------------------------------------------------------- /.postcssrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "plugins": { 3 | "postcss-import": {}, 4 | "autoprefixer": {} 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 KevinMint 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # vue-willtable可编辑的表格组件 2 | 3 | [English document](https://github.com/KevinMint55/vue-willtable/blob/master/READNE-EN.md) 4 | 5 | 适用于Vue的可编辑的表格组件,支持多种快捷键操作,模拟Excel的操作体验 6 | 7 | Demo here: https://demo.willwuwei.com/willtable/ 8 | 9 | 基于该组件实现的多人实时共享编辑表格系统: 10 | 11 | [访问网址](https://castle.willwuwei.com) 12 | 13 | [前端项目地址](https://github.com/KevinMint55/vue-castle) 14 | 15 | [后端项目地址](https://github.com/KevinMint55/node-castle) 16 | 17 | ## 截图 18 | 19 | ![image](https://qiniu.willwuwei.com/willtable1.gif) 20 | 21 | ![image](https://qiniu.willwuwei.com/willtable2.gif) 22 | 23 | ## 特性 24 | 25 | - 表格宽度调整 26 | - 表格列固定 27 | - 数据筛选与排序 28 | - 行多选 29 | - 批量删除与复制粘贴 30 | - 可与Excel互相复制粘贴 31 | - 数据下拉复制 32 | - 下拉复制与多选单元格时候表格可自动滚动 33 | - 获取改变的数据行 34 | - 多种数据类型校验 35 | - 支持自定义规则数据校验 36 | - 获取校验非法的数据行 37 | - 支持撤销与重做 38 | - 可自定义每个单元格样式与类名 39 | - 使用局部渲染,支持更大量数据的展示 40 | 41 | ## 安装 42 | 43 | ``` 44 | npm install vue-willtable --save 45 | ``` 46 | 47 | ## 挂载 48 | 49 | ### 挂载在全局 50 | 51 | ``` javascript 52 | import Vue from 'vue' 53 | import VueWilltable from 'vue-willtable' 54 | 55 | // require styles 56 | import 'vue-willtable/dist/vue-willtable.min.css' 57 | 58 | Vue.component('VueWilltable', VueWilltable) 59 | ``` 60 | 61 | ### 挂载在组件 62 | 63 | ``` javascript 64 | import VueWilltable from 'vue-willtable' 65 | 66 | // require styles 67 | import 'vue-willtable/dist/vue-willtable.min.css' 68 | 69 | export default { 70 | components: { 71 | VueWilltable 72 | } 73 | } 74 | ``` 75 | 76 | ## 使用例子 77 | 78 | ```vue 79 | 86 | 87 | 205 | ``` 206 | 207 | ### 数据 208 | 209 | this.$refs.willtable调用setData方法来更新整表数据,并会重置历史数据记录. 210 | 211 | this.$refs.willtable调用getData方法来获取整表数据. 212 | 213 | `v-model`进行值的绑定 214 | 215 | ### 属性 216 | 217 | 参数 | 说明 | 类型 | 可选值 | 默认值 218 | ---|---|---|---|--- 219 | columns | 表格列的配置描述 | Array | —— | [] 220 | maxHeight | 表格最大高度 | string / number | —— | —— 221 | rowHeight | 每行高度 | string / number | —— | —— 222 | disabled | 禁止编辑 | Boolean | —— | true 223 | showIcon | 显示表头类型图标 | Boolean | —— | false 224 | cellStyle | 单元格的 style 的回调方法 | Function({row, column, rowIndex, columnIndex}) | —— | —— 225 | cellClassName | 单元格的 className 的回调方法 | Function({row, column, rowIndex, columnIndex}) | —— | —— 226 | disabledCell | 禁用单元格 | Function({row, column, rowIndex, columnIndex}) => Boolean | —— | () => false 227 | showAddRow | 显示添加行功能 | Boolean | —— | false 228 | addRowAndCopy | 添加行时复制上一行数据 | Boolean | —— | false 229 | 230 | ### 事件 231 | 232 | 事件名称 | 说明 | 回调参数 233 | ---|---|--- 234 | selection-change | 当选择项发生变化时会触发该事件 | selection 235 | 236 | ### 方法 237 | 238 | 方法名 | 说明 | 参数 239 | ---|---|--- 240 | getData | 用来获取数据,返回当前表格数据 | —— 241 | setData | 用来设置数据,并重置历史记录 | data 242 | getChangeData | 获取变化的数据行 | —— 243 | getErrorRows | 获取校验错误的数据和索引 | —— 244 | addItem | 底部添加一行数据 | item 245 | addRow | 添加行 | rowIndex, copyRow, customData 246 | removeItems | 批量删除,参数key为每行的唯一标识属性如id,values为该标识属性的数组 | key, values 247 | setCellData | 设置单元格数据 | rowIndex, columnIndex, value 248 | fullscreen | 全屏展示 | —— 249 | exitFullscreen | 退出全屏 | —— 250 | 251 | ### 列属性 252 | 253 | 参数 | 说明 | 类型 | 可选值 | 默认值 254 | ---|---|---|---|--- 255 | key | 对应列内容的字段名 | String | —— | —— 256 | title | 列头显示文字 | String | —— | —— 257 | width | 列宽度 | String / Number | —— | —— 258 | type | 列类型 | String | selection/number/date/select/month | —— 259 | format | 千分号格式(用于number类型) | Boolean | —— | true 260 | options | select下拉选项 | Array | { value: '值', label: '显示文字' } | —— 261 | fixed | 是否固定在左侧 | Boolean | —— | false 262 | action | 是否启用筛选和排序 | Boolean | —— | false 263 | disabled | 是否禁止编辑 | Boolean | —— | false 264 | noVerify | 是否禁用校验 | Boolean | —— | false 265 | validate | 自定义校验 | Function(value) | —— | —— 266 | customInput | 自定义输入 | Function({ row, column, rowIndex, columnIndex, value }) | —— | —— 267 | 268 | ### 快捷键 269 | 270 | 快捷键 | 说明 271 | ---|--- 272 | 方向键 | 移动编辑框 273 | Ctrl + C | 粘贴 274 | Ctrl + V | 复制 275 | Ctrl + A | 单元格全选 276 | Ctrl + Z | 撤销 277 | Ctrl + Y | 重做 278 | Enter | 单元格编辑/完成单元格编辑 279 | Delete、Backspace | 删除 280 | 281 | ## 作者 282 | 283 | [WillWu](https://www.willwuwei.com) -------------------------------------------------------------------------------- /READNE-EN.md: -------------------------------------------------------------------------------- 1 | # vue-willtable Editable table component 2 | 3 | [中文文档](https://github.com/KevinMint55/vue-willtable/blob/master/README.md) 4 | 5 | An editable table component for vue,support mutiple shortcut keys,mimic the similar operations in Excel 6 | 7 | Demo here: https://demo.willwuwei.com/willtable/ 8 | 9 | Multi-person real-time online editing table system based on this component: 10 | 11 | [website URL](https://castle.willwuwei.com) 12 | 13 | [Front-end project URL](https://github.com/KevinMint55/vue-castle) 14 | 15 | [Back-end project URL](https://github.com/KevinMint55/node-castle) 16 | 17 | ## ScreenShot 18 | 19 | ![image](https://qiniu.willwuwei.com/willtable1.gif) 20 | 21 | ![image](https://qiniu.willwuwei.com/willtable2.gif) 22 | 23 | ## Features 24 | 25 | - Table width adjustment 26 | - Fix table columns 27 | - Data filtering and sorting 28 | - select mutiple rows 29 | - Batch delete, copy and paste 30 | - Can copy and paste with Excel 31 | - Drop down to copy the data 32 | - The table scrolls automatically when multiple cells are selected 33 | - Get the changed data row 34 | - Multiple data type validation 35 | - Support custom rule data verification 36 | - Obtain illegal rows after data verification 37 | - Support undo and redo 38 | - Each cell style and class name can be customized 39 | - Use partial rendering, support the display of larger amounts of data 40 | 41 | ## Installation 42 | 43 | ``` 44 | npm install vue-willtable --save 45 | ``` 46 | 47 | ## Mount 48 | 49 | ### mount with global 50 | 51 | ``` javascript 52 | import Vue from 'vue' 53 | import VueWilltable from 'vue-willtable' 54 | 55 | // require styles 56 | import 'vue-willtable/dist/vue-willtable.min.css' 57 | 58 | Vue.component('VueWilltable', VueWilltable) 59 | ``` 60 | 61 | ### mount with component 62 | 63 | ``` javascript 64 | import VueWilltable from 'vue-willtable' 65 | 66 | // require styles 67 | import 'vue-willtable/dist/vue-willtable.min.css' 68 | 69 | export default { 70 | components: { 71 | VueWilltable 72 | } 73 | } 74 | ``` 75 | 76 | ## Usage 77 | 78 | ```vue 79 | 86 | 87 | 205 | ``` 206 | 207 | ### Data 208 | 209 | this.$refs.willtable call the setData method to update the entire table data, and will reset the historical data records. 210 | 211 | this.$refs.willtable call the getData method to get the entire table data. 212 | 213 | `v-model`Value-Binding 214 | 215 | ### Attributes 216 | 217 | parameter | Explanation | Type | Optional value | Default value 218 | ---|---|---|---|--- 219 | columns | Table column configuration description | Array | —— | [] 220 | maxHeight | Max height of column | string / number | —— | —— 221 | rowHeight | Height per row | string / number | —— | —— 222 | disabled | Whether to prohibit editing | Boolean | —— | true 223 | showIcon | Whether to display the header icon | Boolean | —— | false 224 | cellStyle | Callback method of cell's style | Function({row, column, rowIndex, columnIndex}) | —— | —— 225 | cellClassName | Callback method of cell's classname | Function({row, column, rowIndex, columnIndex}) | —— | —— 226 | disabledCell | Disable Cells | Function({row, column, rowIndex, columnIndex}) => Boolean | —— | () => false 227 | showAddRow | Display the Add row function | Boolean | —— | false 228 | addRowAndCopy | Copy the previous row when adding a row| Boolean | —— | false 229 | 230 | ### Events 231 | 232 | Event name | Explanation | callback parameter 233 | ---|---|--- 234 | selection-change | trigger event when the selection changes | selection 235 | 236 | ### Methods 237 | 238 | Name | Explanation | parameter 239 | ---|---|--- 240 | getData | Return the current table data | —— 241 | setData | set the data and reset the historical data records | data 242 | getChangeData | Get changed rows | —— 243 | getErrorRows | Get data and its index that doesn't pass the verification | —— 244 | addItem | Add a row of data to the bottom | item 245 | addRow | Add a row | rowIndex, copyRow, customData 246 | removeItems | delete, the key is the unique identification attribute of each row, such as id, and the values are the array of the identification attribute | key, values 247 | setCellData | Set the cell data | rowIndex, columnIndex, value 248 | fullscreen | fullscreen | —— 249 | exitFullscreen | Exit fullscreen | —— 250 | 251 | ### Columns-Attributes 252 | 253 | parameter | Explanation | Type | Optional value | Default value 254 | ---|---|---|---|--- 255 | key | fieldName | String | —— | —— 256 | title | display text | String | —— | —— 257 | width | width | String / Number | —— | —— 258 | type | type | String | selection/number/date/select/month | —— 259 | format | Thousand semicolon format(for number type) | Boolean | —— | true 260 | options | select drop-down options | Array | { value: 'value', label: 'text' } | —— 261 | fixed | Whether fixed on the left | Boolean | —— | false 262 | action | Whether to enable filtering and sorting | Boolean | —— | false 263 | disabled | Whether to disable editing | Boolean | —— | false 264 | noVerify | Whether to disable verification | Boolean | —— | false 265 | validate | self-defined verification | Function(value) | —— | —— 266 | customInput | Custom input | Function({ row, column, rowIndex, columnIndex, value }) | —— | —— 267 | 268 | ### Shortcut 269 | 270 | Shortcut keys | Explanation 271 | ---|--- 272 | Arrow key | Move the edit box 273 | Ctrl + C | Paste 274 | Ctrl + V | Copy 275 | Ctrl + A | Select all cells 276 | Ctrl + Z | Undo 277 | Ctrl + Y | Redo 278 | Enter | Cell editing / complete cell editing 279 | Delete、Backspace | Delete 280 | 281 | ## Author 282 | 283 | [WillWu](https://www.willwuwei.com) -------------------------------------------------------------------------------- /build/build.js: -------------------------------------------------------------------------------- 1 | process.env.NODE_ENV = 'production'; 2 | 3 | const webpack = require('webpack'); 4 | const chalk = require('chalk'); 5 | const ora = require('ora'); 6 | const buildWebpackConfig = require('./webpack.prod.conf'); 7 | 8 | (() => { 9 | const spinner = ora('构建中...'); 10 | spinner.start(); 11 | 12 | webpack(buildWebpackConfig, (err, status) => { 13 | spinner.stop(); 14 | if (err) throw err; 15 | process.stdout.write(`${status.toString({ 16 | colors: true, 17 | modules: false, 18 | children: false, 19 | chunks: false, 20 | chunkModules: false, 21 | })}\n\n`); 22 | 23 | if (status.hasErrors()) { 24 | console.log(chalk.red(' 构建出错!!!\n')); 25 | process.exit(1); 26 | } 27 | 28 | console.log(chalk.cyan(' 构建成功!!!\n')); 29 | console.log(chalk.yellow( 30 | ' Tip: 构建的文件需要通过HTTP服务启动.\n' 31 | + ' 直接打开 index.html 在 file:// 没有作用.\n', 32 | )); 33 | process.exit(); 34 | }); 35 | })(); 36 | -------------------------------------------------------------------------------- /build/devServer.js: -------------------------------------------------------------------------------- 1 | const webpack = require('webpack'); 2 | const WebpackDevServer = require('webpack-dev-server'); 3 | const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin'); 4 | const devWebpackConfig = require('./webpack.dev.conf'); 5 | const config = require('../config'); 6 | 7 | const options = { 8 | publicPath: config.dev.assetsPublicPath, 9 | clientLogLevel: 'warning', 10 | contentBase: false, 11 | historyApiFallback: true, 12 | hot: true, 13 | host: '0.0.0.0', 14 | inline: true, 15 | compress: true, 16 | overlay: { warnings: false, errors: true }, 17 | quiet: true, 18 | watchOptions: { 19 | ignored: [/node_modules/], 20 | poll: true, 21 | }, 22 | }; 23 | 24 | const getIPAddress = () => { 25 | const interfaces = require('os').networkInterfaces(); 26 | for (const devName in interfaces) { 27 | for (const alias of interfaces[devName]) { 28 | if (alias.family === 'IPv4' && alias.address !== '127.0.0.1' && !alias.internal) { 29 | return alias.address; 30 | } 31 | } 32 | } 33 | return ''; 34 | }; 35 | 36 | (() => { 37 | const pkgConfig = require('../package.json'); 38 | const IP = getIPAddress(); 39 | devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({ 40 | compilationSuccessInfo: { 41 | messages: [`${pkgConfig.name} 运行地址: http://${IP}:${config.dev.port}`], 42 | }, 43 | })); 44 | WebpackDevServer.addDevServerEntrypoints(devWebpackConfig, options); 45 | new WebpackDevServer(webpack(devWebpackConfig), options).listen(config.dev.port, '0.0.0.0', () => { }); 46 | })(); 47 | -------------------------------------------------------------------------------- /build/release.js: -------------------------------------------------------------------------------- 1 | process.env.NODE_ENV = 'production'; 2 | 3 | const webpack = require('webpack'); 4 | const chalk = require('chalk'); 5 | const ora = require('ora'); 6 | const buildWebpackConfig = require('./webpack.release.conf'); 7 | 8 | (() => { 9 | const spinner = ora('构建中...'); 10 | spinner.start(); 11 | 12 | webpack(buildWebpackConfig, (err, status) => { 13 | spinner.stop(); 14 | if (err) throw err; 15 | process.stdout.write(`${status.toString({ 16 | colors: true, 17 | modules: false, 18 | children: false, 19 | chunks: false, 20 | chunkModules: false, 21 | })}\n\n`); 22 | 23 | if (status.hasErrors()) { 24 | console.log(chalk.red(' 构建出错!!!\n')); 25 | process.exit(1); 26 | } 27 | 28 | console.log(chalk.cyan(' 构建成功!!!\n')); 29 | console.log(chalk.yellow( 30 | ' Tip: 构建的文件需要通过HTTP服务启动.\n' 31 | + ' 直接打开 index.html 在 file:// 没有作用.\n', 32 | )); 33 | process.exit(); 34 | }); 35 | })(); 36 | -------------------------------------------------------------------------------- /build/webpack.base.conf.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const VueLoaderPlugin = require('vue-loader/lib/plugin'); 3 | const MiniCssExtractPlugin = require('mini-css-extract-plugin'); 4 | 5 | const isProduction = process.env.NODE_ENV === 'production'; 6 | 7 | function resolve(dir) { 8 | return path.join(__dirname, '..', dir); 9 | } 10 | 11 | const webpackConfig = { 12 | output: { 13 | filename: 'js/[name].js', 14 | publicPath: '/', 15 | }, 16 | resolve: { 17 | modules: [ 18 | 'node_modules', 19 | ], 20 | extensions: ['.js', '.json', '.vue', '.scss'], 21 | alias: { 22 | vue$: 'vue/dist/vue.esm.js', 23 | }, 24 | }, 25 | module: { 26 | rules: [ 27 | { 28 | test: /\.(js|vue)$/, 29 | loader: 'eslint-loader', 30 | enforce: 'pre', 31 | include: [resolve('src'), resolve('example'), resolve('node_modules/webpack-dev-server/client')], 32 | options: { 33 | formatter: require('eslint-friendly-formatter'), 34 | emitWarning: true, 35 | }, 36 | }, 37 | { 38 | test: /\.vue$/, 39 | loader: 'vue-loader', 40 | }, 41 | { 42 | test: /\.js$/, 43 | loader: 'babel-loader', 44 | exclude: /node_modules/, 45 | }, 46 | { 47 | test: /\.(sa|sc|c)ss$/, 48 | oneOf: [ 49 | { 50 | resourceQuery: /module/, 51 | use: [ 52 | isProduction ? MiniCssExtractPlugin.loader : 'vue-style-loader', 53 | { 54 | loader: 'css-loader', 55 | options: { 56 | modules: { 57 | localIdentName: '[local]_[hash:base64:8]', 58 | }, 59 | }, 60 | }, 61 | 'postcss-loader', 62 | 'sass-loader', 63 | ], 64 | }, 65 | { 66 | use: [ 67 | isProduction ? MiniCssExtractPlugin.loader : 'vue-style-loader', 68 | 'css-loader', 69 | 'postcss-loader', 70 | 'sass-loader', 71 | ], 72 | }, 73 | ], 74 | }, 75 | { 76 | test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, 77 | use: [ 78 | { 79 | loader: 'url-loader', 80 | options: { 81 | limit: 1024, 82 | name: 'img/[name].[hash:7].[ext]', 83 | }, 84 | }, 85 | ], 86 | }, 87 | { 88 | test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/, 89 | loader: 'url-loader', 90 | options: { 91 | limit: 1024, 92 | name: 'media/[name].[hash:7].[ext]', 93 | }, 94 | }, 95 | { 96 | test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, 97 | loader: 'url-loader', 98 | options: { 99 | limit: 1024, 100 | name: 'fonts/[name].[hash:7].[ext]', 101 | }, 102 | }, 103 | ], 104 | }, 105 | node: { 106 | setImmediate: false, 107 | dgram: 'empty', 108 | fs: 'empty', 109 | net: 'empty', 110 | tls: 'empty', 111 | child_process: 'empty', 112 | }, 113 | plugins: [ 114 | new VueLoaderPlugin(), 115 | ], 116 | }; 117 | 118 | module.exports = webpackConfig; 119 | -------------------------------------------------------------------------------- /build/webpack.dev.conf.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const merge = require('webpack-merge'); 3 | const webpack = require('webpack'); 4 | const HtmlWebpackPlugin = require('html-webpack-plugin'); 5 | const betterProgress = require('better-webpack-progress'); 6 | const baseWebpackConfig = require('./webpack.base.conf'); 7 | const config = require('../config'); 8 | 9 | function resolve(dir) { 10 | return path.join(__dirname, '..', dir); 11 | } 12 | 13 | const webpackConfig = { 14 | mode: 'development', 15 | context: resolve('./'), 16 | entry: { 17 | app: ['babel-polyfill', './example/main.js'], 18 | }, 19 | devtool: config.dev.devtool, 20 | plugins: [ 21 | new webpack.NamedModulesPlugin(), 22 | new webpack.HotModuleReplacementPlugin(), 23 | new webpack.ProgressPlugin(betterProgress({ 24 | mode: 'compact', // or 'detailed' or 'bar' 25 | })), 26 | new HtmlWebpackPlugin({ 27 | filename: 'index.html', 28 | template: resolve('example/index.html'), 29 | favicon: resolve('example/favicon.ico'), 30 | inject: true, 31 | minify: { 32 | removeComments: true, 33 | collapseWhitespace: true, 34 | removeAttributeQuotes: true, 35 | }, 36 | chunksSortMode: 'auto', 37 | }), 38 | ], 39 | }; 40 | 41 | if (config.dev.styleLint) { 42 | const StyleLintPlugin = require('stylelint-webpack-plugin'); 43 | webpackConfig.plugins.push(new StyleLintPlugin({ 44 | files: ['**/src/**/*.{vue,htm,html,css,sss,less,scss,sass}'], 45 | configFile: path.resolve(__dirname, 'stylelintrc.js'), 46 | syntax: 'scss', 47 | })); 48 | } 49 | 50 | module.exports = merge(baseWebpackConfig, webpackConfig); 51 | -------------------------------------------------------------------------------- /build/webpack.prod.conf.js: -------------------------------------------------------------------------------- 1 | const webpack = require('webpack'); 2 | const merge = require('webpack-merge'); 3 | const path = require('path'); 4 | const { CleanWebpackPlugin } = require('clean-webpack-plugin'); 5 | const HtmlWebpackPlugin = require('html-webpack-plugin'); 6 | const UglifyJSPlugin = require('uglifyjs-webpack-plugin'); 7 | const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin'); 8 | const MiniCssExtractPlugin = require('mini-css-extract-plugin'); 9 | const baseWebpackConfig = require('./webpack.base.conf'); 10 | const config = require('../config'); 11 | 12 | function resolve(dir) { 13 | return path.join(__dirname, '..', dir); 14 | } 15 | 16 | const webpackConfig = { 17 | mode: 'production', 18 | context: resolve('./'), 19 | entry: { 20 | app: ['babel-polyfill', './example/main.js'], 21 | }, 22 | output: { 23 | path: config.build.assetsRoot, 24 | publicPath: config.build.assetsPublicPath, 25 | filename: 'js/[name].[chunkhash].js', 26 | chunkFilename: 'js/[name].[chunkhash].js', 27 | }, 28 | plugins: [ 29 | new CleanWebpackPlugin(), 30 | new UglifyJSPlugin({ 31 | uglifyOptions: { 32 | output: { 33 | comments: false, 34 | }, 35 | }, 36 | parallel: true, 37 | }), 38 | new OptimizeCSSAssetsPlugin({}), 39 | // keep module.id stable when vendor modules does not change 40 | new webpack.HashedModuleIdsPlugin(), 41 | new HtmlWebpackPlugin({ 42 | filename: 'index.html', 43 | template: resolve('example/index.html'), 44 | favicon: resolve('example/favicon.ico'), 45 | inject: true, 46 | minify: { 47 | removeComments: true, 48 | collapseWhitespace: true, 49 | removeAttributeQuotes: true, 50 | }, 51 | chunksSortMode: 'auto', 52 | }), 53 | new MiniCssExtractPlugin({ 54 | filename: 'css/[name].[hash].css', 55 | chunkFilename: 'css/[name].[hash].css', 56 | }), 57 | ], 58 | optimization: { 59 | runtimeChunk: 'single', 60 | splitChunks: { 61 | // chunks: 'all' 62 | cacheGroups: { 63 | vendor: { 64 | test: /[\\/]node_modules[\\/]/, 65 | name: 'vendors', 66 | chunks: 'all', 67 | }, 68 | }, 69 | }, 70 | }, 71 | }; 72 | 73 | if (config.build.bundleAnalyzerReport) { 74 | const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer'); 75 | webpackConfig.plugins.push(new BundleAnalyzerPlugin()); 76 | } 77 | 78 | module.exports = merge(baseWebpackConfig, webpackConfig); 79 | -------------------------------------------------------------------------------- /build/webpack.release.conf.js: -------------------------------------------------------------------------------- 1 | const merge = require('webpack-merge'); 2 | const { CleanWebpackPlugin } = require('clean-webpack-plugin'); 3 | const UglifyJSPlugin = require('uglifyjs-webpack-plugin'); 4 | const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin'); 5 | const MiniCssExtractPlugin = require('mini-css-extract-plugin'); 6 | const baseWebpackConfig = require('./webpack.base.conf'); 7 | const config = require('../config'); 8 | 9 | const webpackConfig = { 10 | mode: 'production', 11 | entry: { 12 | app: ['./src/index.js'], 13 | }, 14 | output: { 15 | path: config.release.assetsRoot, 16 | publicPath: config.release.assetsPublicPath, 17 | filename: `${config.release.filename}.min.js`, 18 | library: config.release.library, 19 | libraryTarget: 'umd', 20 | }, 21 | plugins: [ 22 | new CleanWebpackPlugin(), 23 | new UglifyJSPlugin({ 24 | uglifyOptions: { 25 | output: { 26 | comments: false, 27 | }, 28 | }, 29 | parallel: true, 30 | }), 31 | new OptimizeCSSAssetsPlugin({}), 32 | new MiniCssExtractPlugin({ 33 | filename: `${config.release.filename}.min.css`, 34 | }), 35 | ], 36 | }; 37 | 38 | module.exports = merge(baseWebpackConfig, webpackConfig); 39 | -------------------------------------------------------------------------------- /config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | 3 | module.exports = { 4 | dev: { 5 | assetsPublicPath: '/', 6 | port: 5001, 7 | styleLint: false, 8 | devtool: 'cheap-module-eval-source-map', 9 | }, 10 | build: { 11 | assetsRoot: path.resolve(__dirname, './demo'), 12 | assetsPublicPath: '/willtable/', 13 | bundleAnalyzerReport: false, 14 | }, 15 | release: { 16 | assetsRoot: path.resolve(__dirname, './dist'), 17 | assetsPublicPath: './', 18 | filename: 'vue-willtable', 19 | library: 'VueWilltable', 20 | }, 21 | }; 22 | -------------------------------------------------------------------------------- /dist/fonts/element-icons.535877f.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinMint55/vue-willtable/893cf0d363a8a37d5aacb51170b0060e23b2c525/dist/fonts/element-icons.535877f.woff -------------------------------------------------------------------------------- /dist/fonts/element-icons.732389d.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinMint55/vue-willtable/893cf0d363a8a37d5aacb51170b0060e23b2c525/dist/fonts/element-icons.732389d.ttf -------------------------------------------------------------------------------- /dist/vue-willtable.min.css: -------------------------------------------------------------------------------- 1 | .fade-enter-active,.fade-leave-active{-webkit-transition:all .3s linear;transition:all .3s linear}.fade-enter,.fade-leave-active{opacity:0}a,body,dd,div,dl,dt,fieldset,figcaption,figure,form,h1,h2,h3,h4,h5,h6,header,hgroup,i,img,input,li,ol,p,pre,section,table,td,ul{padding:0;margin:0;-webkit-box-sizing:border-box;box-sizing:border-box;word-break:break-all}ol,ul{list-style:none}a{color:inherit;-webkit-tap-highlight-color:transparent;text-decoration:none!important}button,input{border:none;outline:none}button{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}i{font-style:normal}.ellipsis{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.el-checkbox,.el-checkbox__input{display:inline-block;position:relative}.el-checkbox-button__inner,.el-checkbox__input{white-space:nowrap;vertical-align:middle;outline:0}.el-checkbox{color:#606266;font-weight:500;font-size:14px;cursor:pointer;white-space:nowrap;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;margin-right:30px}.el-checkbox.is-bordered{padding:9px 20px 9px 10px;border-radius:4px;border:1px solid #dcdfe6;-webkit-box-sizing:border-box;box-sizing:border-box;line-height:normal;height:40px}.el-checkbox.is-bordered.is-checked{border-color:#409eff}.el-checkbox.is-bordered.is-disabled{border-color:#ebeef5;cursor:not-allowed}.el-checkbox.is-bordered+.el-checkbox.is-bordered{margin-left:10px}.el-checkbox.is-bordered.el-checkbox--medium{padding:7px 20px 7px 10px;border-radius:4px;height:36px}.el-checkbox.is-bordered.el-checkbox--medium .el-checkbox__label{line-height:17px;font-size:14px}.el-checkbox.is-bordered.el-checkbox--medium .el-checkbox__inner{height:14px;width:14px}.el-checkbox.is-bordered.el-checkbox--small{padding:5px 15px 5px 10px;border-radius:3px;height:32px}.el-checkbox.is-bordered.el-checkbox--small .el-checkbox__label{line-height:15px;font-size:12px}.el-checkbox.is-bordered.el-checkbox--small .el-checkbox__inner{height:12px;width:12px}.el-checkbox.is-bordered.el-checkbox--small .el-checkbox__inner:after{height:6px;width:2px}.el-checkbox.is-bordered.el-checkbox--mini{padding:3px 15px 3px 10px;border-radius:3px;height:28px}.el-checkbox.is-bordered.el-checkbox--mini .el-checkbox__label{line-height:12px;font-size:12px}.el-checkbox.is-bordered.el-checkbox--mini .el-checkbox__inner{height:12px;width:12px}.el-checkbox.is-bordered.el-checkbox--mini .el-checkbox__inner:after{height:6px;width:2px}.el-checkbox__input{cursor:pointer;line-height:1}.el-checkbox__input.is-disabled .el-checkbox__inner{background-color:#edf2fc;border-color:#dcdfe6;cursor:not-allowed}.el-checkbox__input.is-disabled .el-checkbox__inner:after{cursor:not-allowed;border-color:#c0c4cc}.el-checkbox__input.is-disabled .el-checkbox__inner+.el-checkbox__label{cursor:not-allowed}.el-checkbox__input.is-disabled.is-checked .el-checkbox__inner{background-color:#f2f6fc;border-color:#dcdfe6}.el-checkbox__input.is-disabled.is-checked .el-checkbox__inner:after{border-color:#c0c4cc}.el-checkbox__input.is-disabled.is-indeterminate .el-checkbox__inner{background-color:#f2f6fc;border-color:#dcdfe6}.el-checkbox__input.is-disabled.is-indeterminate .el-checkbox__inner:before{background-color:#c0c4cc;border-color:#c0c4cc}.el-checkbox__input.is-checked .el-checkbox__inner,.el-checkbox__input.is-indeterminate .el-checkbox__inner{background-color:#409eff;border-color:#409eff}.el-checkbox__input.is-disabled+span.el-checkbox__label{color:#c0c4cc;cursor:not-allowed}.el-checkbox__input.is-checked .el-checkbox__inner:after{-webkit-transform:rotate(45deg) scaleY(1);transform:rotate(45deg) scaleY(1)}.el-checkbox__input.is-checked+.el-checkbox__label{color:#409eff}.el-checkbox__input.is-focus .el-checkbox__inner{border-color:#409eff}.el-checkbox__input.is-indeterminate .el-checkbox__inner:before{content:"";position:absolute;display:block;background-color:#fff;height:2px;-webkit-transform:scale(.5);transform:scale(.5);left:0;right:0;top:5px}.el-checkbox__input.is-indeterminate .el-checkbox__inner:after{display:none}.el-checkbox__inner{display:inline-block;position:relative;border:1px solid #dcdfe6;border-radius:2px;-webkit-box-sizing:border-box;box-sizing:border-box;width:14px;height:14px;background-color:#fff;z-index:1;-webkit-transition:border-color .25s cubic-bezier(.71,-.46,.29,1.46),background-color .25s cubic-bezier(.71,-.46,.29,1.46);transition:border-color .25s cubic-bezier(.71,-.46,.29,1.46),background-color .25s cubic-bezier(.71,-.46,.29,1.46)}.el-checkbox__inner:hover{border-color:#409eff}.el-checkbox__inner:after{-webkit-box-sizing:content-box;box-sizing:content-box;content:"";border:1px solid #fff;border-left:0;border-top:0;height:7px;left:4px;position:absolute;top:1px;-webkit-transform:rotate(45deg) scaleY(0);transform:rotate(45deg) scaleY(0);width:3px;-webkit-transition:-webkit-transform .15s ease-in .05s;transition:-webkit-transform .15s ease-in .05s;transition:transform .15s ease-in .05s;transition:transform .15s ease-in .05s,-webkit-transform .15s ease-in .05s;-webkit-transform-origin:center;transform-origin:center}.el-checkbox__original{opacity:0;outline:0;position:absolute;margin:0;width:0;height:0;z-index:-1}.el-checkbox-button,.el-checkbox-button__inner{display:inline-block;position:relative}.el-checkbox__label{display:inline-block;padding-left:10px;line-height:19px;font-size:14px}.el-checkbox:last-of-type{margin-right:0}.el-checkbox-button__inner{line-height:1;font-weight:500;cursor:pointer;background:#fff;border:1px solid #dcdfe6;border-left:0;color:#606266;-webkit-appearance:none;text-align:center;-webkit-box-sizing:border-box;box-sizing:border-box;margin:0;-webkit-transition:all .3s cubic-bezier(.645,.045,.355,1);transition:all .3s cubic-bezier(.645,.045,.355,1);-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none;padding:12px 20px;font-size:14px;border-radius:0}.el-checkbox-button__inner.is-round{padding:12px 20px}.el-checkbox-button__inner:hover{color:#409eff}.el-checkbox-button__inner [class*=el-icon-]{line-height:.9}.el-checkbox-button__inner [class*=el-icon-]+span{margin-left:5px}.el-checkbox-button__original{opacity:0;outline:0;position:absolute;margin:0;z-index:-1}.el-checkbox-button.is-checked .el-checkbox-button__inner{color:#fff;background-color:#409eff;border-color:#409eff;-webkit-box-shadow:-1px 0 0 0 #8cc5ff;box-shadow:-1px 0 0 0 #8cc5ff}.el-checkbox-button.is-checked:first-child .el-checkbox-button__inner{border-left-color:#409eff}.el-checkbox-button.is-disabled .el-checkbox-button__inner{color:#c0c4cc;cursor:not-allowed;background-image:none;background-color:#fff;border-color:#ebeef5;-webkit-box-shadow:none;box-shadow:none}.el-checkbox-button.is-disabled:first-child .el-checkbox-button__inner{border-left-color:#ebeef5}.el-checkbox-button:first-child .el-checkbox-button__inner{border-left:1px solid #dcdfe6;border-radius:4px 0 0 4px;-webkit-box-shadow:none!important;box-shadow:none!important}.el-checkbox-button.is-focus .el-checkbox-button__inner{border-color:#409eff}.el-checkbox-button:last-child .el-checkbox-button__inner{border-radius:0 4px 4px 0}.el-checkbox-button--medium .el-checkbox-button__inner{padding:10px 20px;font-size:14px;border-radius:0}.el-checkbox-button--medium .el-checkbox-button__inner.is-round{padding:10px 20px}.el-checkbox-button--small .el-checkbox-button__inner{padding:9px 15px;font-size:12px;border-radius:0}.el-checkbox-button--small .el-checkbox-button__inner.is-round{padding:9px 15px}.el-checkbox-button--mini .el-checkbox-button__inner{padding:7px 15px;font-size:12px;border-radius:0}.el-checkbox-button--mini .el-checkbox-button__inner.is-round{padding:7px 15px}.el-checkbox-group{font-size:0}@font-face{font-family:element-icons;src:url(fonts/element-icons.535877f.woff) format("woff"),url(fonts/element-icons.732389d.ttf) format("truetype");font-weight:400;font-display:"auto";font-style:normal}[class*=" el-icon-"],[class^=el-icon-]{font-family:element-icons!important;speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;line-height:1;vertical-align:baseline;display:inline-block;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.el-icon-ice-cream-round:before{content:"\e6a0"}.el-icon-ice-cream-square:before{content:"\e6a3"}.el-icon-lollipop:before{content:"\e6a4"}.el-icon-potato-strips:before{content:"\e6a5"}.el-icon-milk-tea:before{content:"\e6a6"}.el-icon-ice-drink:before{content:"\e6a7"}.el-icon-ice-tea:before{content:"\e6a9"}.el-icon-coffee:before{content:"\e6aa"}.el-icon-orange:before{content:"\e6ab"}.el-icon-pear:before{content:"\e6ac"}.el-icon-apple:before{content:"\e6ad"}.el-icon-cherry:before{content:"\e6ae"}.el-icon-watermelon:before{content:"\e6af"}.el-icon-grape:before{content:"\e6b0"}.el-icon-refrigerator:before{content:"\e6b1"}.el-icon-goblet-square-full:before{content:"\e6b2"}.el-icon-goblet-square:before{content:"\e6b3"}.el-icon-goblet-full:before{content:"\e6b4"}.el-icon-goblet:before{content:"\e6b5"}.el-icon-cold-drink:before{content:"\e6b6"}.el-icon-coffee-cup:before{content:"\e6b8"}.el-icon-water-cup:before{content:"\e6b9"}.el-icon-hot-water:before{content:"\e6ba"}.el-icon-ice-cream:before{content:"\e6bb"}.el-icon-dessert:before{content:"\e6bc"}.el-icon-sugar:before{content:"\e6bd"}.el-icon-tableware:before{content:"\e6be"}.el-icon-burger:before{content:"\e6bf"}.el-icon-knife-fork:before{content:"\e6c1"}.el-icon-fork-spoon:before{content:"\e6c2"}.el-icon-chicken:before{content:"\e6c3"}.el-icon-food:before{content:"\e6c4"}.el-icon-dish-1:before{content:"\e6c5"}.el-icon-dish:before{content:"\e6c6"}.el-icon-moon-night:before{content:"\e6ee"}.el-icon-moon:before{content:"\e6f0"}.el-icon-cloudy-and-sunny:before{content:"\e6f1"}.el-icon-partly-cloudy:before{content:"\e6f2"}.el-icon-cloudy:before{content:"\e6f3"}.el-icon-sunny:before{content:"\e6f6"}.el-icon-sunset:before{content:"\e6f7"}.el-icon-sunrise-1:before{content:"\e6f8"}.el-icon-sunrise:before{content:"\e6f9"}.el-icon-heavy-rain:before{content:"\e6fa"}.el-icon-lightning:before{content:"\e6fb"}.el-icon-light-rain:before{content:"\e6fc"}.el-icon-wind-power:before{content:"\e6fd"}.el-icon-baseball:before{content:"\e712"}.el-icon-soccer:before{content:"\e713"}.el-icon-football:before{content:"\e715"}.el-icon-basketball:before{content:"\e716"}.el-icon-ship:before{content:"\e73f"}.el-icon-truck:before{content:"\e740"}.el-icon-bicycle:before{content:"\e741"}.el-icon-mobile-phone:before{content:"\e6d3"}.el-icon-service:before{content:"\e6d4"}.el-icon-key:before{content:"\e6e2"}.el-icon-unlock:before{content:"\e6e4"}.el-icon-lock:before{content:"\e6e5"}.el-icon-watch:before{content:"\e6fe"}.el-icon-watch-1:before{content:"\e6ff"}.el-icon-timer:before{content:"\e702"}.el-icon-alarm-clock:before{content:"\e703"}.el-icon-map-location:before{content:"\e704"}.el-icon-delete-location:before{content:"\e705"}.el-icon-add-location:before{content:"\e706"}.el-icon-location-information:before{content:"\e707"}.el-icon-location-outline:before{content:"\e708"}.el-icon-location:before{content:"\e79e"}.el-icon-place:before{content:"\e709"}.el-icon-discover:before{content:"\e70a"}.el-icon-first-aid-kit:before{content:"\e70b"}.el-icon-trophy-1:before{content:"\e70c"}.el-icon-trophy:before{content:"\e70d"}.el-icon-medal:before{content:"\e70e"}.el-icon-medal-1:before{content:"\e70f"}.el-icon-stopwatch:before{content:"\e710"}.el-icon-mic:before{content:"\e711"}.el-icon-copy-document:before{content:"\e718"}.el-icon-full-screen:before{content:"\e719"}.el-icon-switch-button:before{content:"\e71b"}.el-icon-aim:before{content:"\e71c"}.el-icon-crop:before{content:"\e71d"}.el-icon-odometer:before{content:"\e71e"}.el-icon-time:before{content:"\e71f"}.el-icon-bangzhu:before{content:"\e724"}.el-icon-close-notification:before{content:"\e726"}.el-icon-microphone:before{content:"\e727"}.el-icon-turn-off-microphone:before{content:"\e728"}.el-icon-position:before{content:"\e729"}.el-icon-postcard:before{content:"\e72a"}.el-icon-message:before{content:"\e72b"}.el-icon-chat-line-square:before{content:"\e72d"}.el-icon-chat-dot-square:before{content:"\e72e"}.el-icon-chat-dot-round:before{content:"\e72f"}.el-icon-chat-square:before{content:"\e730"}.el-icon-chat-line-round:before{content:"\e731"}.el-icon-chat-round:before{content:"\e732"}.el-icon-set-up:before{content:"\e733"}.el-icon-turn-off:before{content:"\e734"}.el-icon-open:before{content:"\e735"}.el-icon-connection:before{content:"\e736"}.el-icon-link:before{content:"\e737"}.el-icon-cpu:before{content:"\e738"}.el-icon-thumb:before{content:"\e739"}.el-icon-female:before{content:"\e73a"}.el-icon-male:before{content:"\e73b"}.el-icon-guide:before{content:"\e73c"}.el-icon-news:before{content:"\e73e"}.el-icon-price-tag:before{content:"\e744"}.el-icon-discount:before{content:"\e745"}.el-icon-wallet:before{content:"\e747"}.el-icon-coin:before{content:"\e748"}.el-icon-money:before{content:"\e749"}.el-icon-bank-card:before{content:"\e74a"}.el-icon-box:before{content:"\e74b"}.el-icon-present:before{content:"\e74c"}.el-icon-sell:before{content:"\e6d5"}.el-icon-sold-out:before{content:"\e6d6"}.el-icon-shopping-bag-2:before{content:"\e74d"}.el-icon-shopping-bag-1:before{content:"\e74e"}.el-icon-shopping-cart-2:before{content:"\e74f"}.el-icon-shopping-cart-1:before{content:"\e750"}.el-icon-shopping-cart-full:before{content:"\e751"}.el-icon-smoking:before{content:"\e752"}.el-icon-no-smoking:before{content:"\e753"}.el-icon-house:before{content:"\e754"}.el-icon-table-lamp:before{content:"\e755"}.el-icon-school:before{content:"\e756"}.el-icon-office-building:before{content:"\e757"}.el-icon-toilet-paper:before{content:"\e758"}.el-icon-notebook-2:before{content:"\e759"}.el-icon-notebook-1:before{content:"\e75a"}.el-icon-files:before{content:"\e75b"}.el-icon-collection:before{content:"\e75c"}.el-icon-receiving:before{content:"\e75d"}.el-icon-suitcase-1:before{content:"\e760"}.el-icon-suitcase:before{content:"\e761"}.el-icon-film:before{content:"\e763"}.el-icon-collection-tag:before{content:"\e765"}.el-icon-data-analysis:before{content:"\e766"}.el-icon-pie-chart:before{content:"\e767"}.el-icon-data-board:before{content:"\e768"}.el-icon-data-line:before{content:"\e76d"}.el-icon-reading:before{content:"\e769"}.el-icon-magic-stick:before{content:"\e76a"}.el-icon-coordinate:before{content:"\e76b"}.el-icon-mouse:before{content:"\e76c"}.el-icon-brush:before{content:"\e76e"}.el-icon-headset:before{content:"\e76f"}.el-icon-umbrella:before{content:"\e770"}.el-icon-scissors:before{content:"\e771"}.el-icon-mobile:before{content:"\e773"}.el-icon-attract:before{content:"\e774"}.el-icon-monitor:before{content:"\e775"}.el-icon-search:before{content:"\e778"}.el-icon-takeaway-box:before{content:"\e77a"}.el-icon-paperclip:before{content:"\e77d"}.el-icon-printer:before{content:"\e77e"}.el-icon-document-add:before{content:"\e782"}.el-icon-document:before{content:"\e785"}.el-icon-document-checked:before{content:"\e786"}.el-icon-document-copy:before{content:"\e787"}.el-icon-document-delete:before{content:"\e788"}.el-icon-document-remove:before{content:"\e789"}.el-icon-tickets:before{content:"\e78b"}.el-icon-folder-checked:before{content:"\e77f"}.el-icon-folder-delete:before{content:"\e780"}.el-icon-folder-remove:before{content:"\e781"}.el-icon-folder-add:before{content:"\e783"}.el-icon-folder-opened:before{content:"\e784"}.el-icon-folder:before{content:"\e78a"}.el-icon-edit-outline:before{content:"\e764"}.el-icon-edit:before{content:"\e78c"}.el-icon-date:before{content:"\e78e"}.el-icon-c-scale-to-original:before{content:"\e7c6"}.el-icon-view:before{content:"\e6ce"}.el-icon-loading:before{content:"\e6cf"}.el-icon-rank:before{content:"\e6d1"}.el-icon-sort-down:before{content:"\e7c4"}.el-icon-sort-up:before{content:"\e7c5"}.el-icon-sort:before{content:"\e6d2"}.el-icon-finished:before{content:"\e6cd"}.el-icon-refresh-left:before{content:"\e6c7"}.el-icon-refresh-right:before{content:"\e6c8"}.el-icon-refresh:before{content:"\e6d0"}.el-icon-video-play:before{content:"\e7c0"}.el-icon-video-pause:before{content:"\e7c1"}.el-icon-d-arrow-right:before{content:"\e6dc"}.el-icon-d-arrow-left:before{content:"\e6dd"}.el-icon-arrow-up:before{content:"\e6e1"}.el-icon-arrow-down:before{content:"\e6df"}.el-icon-arrow-right:before{content:"\e6e0"}.el-icon-arrow-left:before{content:"\e6de"}.el-icon-top-right:before{content:"\e6e7"}.el-icon-top-left:before{content:"\e6e8"}.el-icon-top:before{content:"\e6e6"}.el-icon-bottom:before{content:"\e6eb"}.el-icon-right:before{content:"\e6e9"}.el-icon-back:before{content:"\e6ea"}.el-icon-bottom-right:before{content:"\e6ec"}.el-icon-bottom-left:before{content:"\e6ed"}.el-icon-caret-top:before{content:"\e78f"}.el-icon-caret-bottom:before{content:"\e790"}.el-icon-caret-right:before{content:"\e791"}.el-icon-caret-left:before{content:"\e792"}.el-icon-d-caret:before{content:"\e79a"}.el-icon-share:before{content:"\e793"}.el-icon-menu:before{content:"\e798"}.el-icon-s-grid:before{content:"\e7a6"}.el-icon-s-check:before{content:"\e7a7"}.el-icon-s-data:before{content:"\e7a8"}.el-icon-s-opportunity:before{content:"\e7aa"}.el-icon-s-custom:before{content:"\e7ab"}.el-icon-s-claim:before{content:"\e7ad"}.el-icon-s-finance:before{content:"\e7ae"}.el-icon-s-comment:before{content:"\e7af"}.el-icon-s-flag:before{content:"\e7b0"}.el-icon-s-marketing:before{content:"\e7b1"}.el-icon-s-shop:before{content:"\e7b4"}.el-icon-s-open:before{content:"\e7b5"}.el-icon-s-management:before{content:"\e7b6"}.el-icon-s-ticket:before{content:"\e7b7"}.el-icon-s-release:before{content:"\e7b8"}.el-icon-s-home:before{content:"\e7b9"}.el-icon-s-promotion:before{content:"\e7ba"}.el-icon-s-operation:before{content:"\e7bb"}.el-icon-s-unfold:before{content:"\e7bc"}.el-icon-s-fold:before{content:"\e7a9"}.el-icon-s-platform:before{content:"\e7bd"}.el-icon-s-order:before{content:"\e7be"}.el-icon-s-cooperation:before{content:"\e7bf"}.el-icon-bell:before{content:"\e725"}.el-icon-message-solid:before{content:"\e799"}.el-icon-video-camera:before{content:"\e772"}.el-icon-video-camera-solid:before{content:"\e796"}.el-icon-camera:before{content:"\e779"}.el-icon-camera-solid:before{content:"\e79b"}.el-icon-download:before{content:"\e77c"}.el-icon-upload2:before{content:"\e77b"}.el-icon-upload:before{content:"\e7c3"}.el-icon-picture-outline-round:before{content:"\e75f"}.el-icon-picture-outline:before{content:"\e75e"}.el-icon-picture:before{content:"\e79f"}.el-icon-close:before{content:"\e6db"}.el-icon-check:before{content:"\e6da"}.el-icon-plus:before{content:"\e6d9"}.el-icon-minus:before{content:"\e6d8"}.el-icon-help:before{content:"\e73d"}.el-icon-s-help:before{content:"\e7b3"}.el-icon-circle-close:before{content:"\e78d"}.el-icon-circle-check:before{content:"\e720"}.el-icon-circle-plus-outline:before{content:"\e723"}.el-icon-remove-outline:before{content:"\e722"}.el-icon-zoom-out:before{content:"\e776"}.el-icon-zoom-in:before{content:"\e777"}.el-icon-error:before{content:"\e79d"}.el-icon-success:before{content:"\e79c"}.el-icon-circle-plus:before{content:"\e7a0"}.el-icon-remove:before{content:"\e7a2"}.el-icon-info:before{content:"\e7a1"}.el-icon-question:before{content:"\e7a4"}.el-icon-warning-outline:before{content:"\e6c9"}.el-icon-warning:before{content:"\e7a3"}.el-icon-goods:before{content:"\e7c2"}.el-icon-s-goods:before{content:"\e7b2"}.el-icon-star-off:before{content:"\e717"}.el-icon-star-on:before{content:"\e797"}.el-icon-more-outline:before{content:"\e6cc"}.el-icon-more:before{content:"\e794"}.el-icon-phone-outline:before{content:"\e6cb"}.el-icon-phone:before{content:"\e795"}.el-icon-user:before{content:"\e6e3"}.el-icon-user-solid:before{content:"\e7a5"}.el-icon-setting:before{content:"\e6ca"}.el-icon-s-tools:before{content:"\e7ac"}.el-icon-delete:before{content:"\e6d7"}.el-icon-delete-solid:before{content:"\e7c9"}.el-icon-eleme:before{content:"\e7c7"}.el-icon-platform-eleme:before{content:"\e7ca"}.el-icon-loading{-webkit-animation:rotating 2s linear infinite;animation:rotating 2s linear infinite}.el-icon--right{margin-left:5px}.el-icon--left{margin-right:5px}@-webkit-keyframes rotating{0%{-webkit-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}@keyframes rotating{0%{-webkit-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}.ww-theader{position:relative;font-size:12px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;overflow:hidden;border-right:1px solid #d6dfe4;z-index:5}.ww-theader.fixed{position:absolute;top:0;left:0;-webkit-box-shadow:1px 0 8px #d3d4d6;box-shadow:1px 0 8px #d3d4d6;z-index:6}.ww-theader .ww-tr{background-color:#eef1f6;border-bottom:1px solid #d6dfe4}.ww-theader .ww-th,.ww-theader .ww-tr{display:-webkit-box;display:-ms-flexbox;display:flex}.ww-theader .ww-th{position:relative;-webkit-box-align:center;-ms-flex-align:center;align-items:center;border-top:1px solid #d6dfe4;border-left:1px solid #d6dfe4}.ww-theader .ww-th.selection{-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.ww-theader .dropdown{position:absolute;right:10px;z-index:1;display:-webkit-box;display:-ms-flexbox;display:flex}.ww-theader .dropdown i{display:inline-block;width:10px;height:10px;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABwAAAAcCAYAAAByDd+UAAABeklEQVRIS+2UPUvDUBSG35OmguDi4KajYBdB02IhSdNoQR1UUPBXiuAHfoDa5qNYSEPB1c3FSVwcxJIcuYWIiK25bekgufM597nvc+69hAkvmjAPGXDsxjOl/1hp3QtqKpRX09RCmZiuGy6zEs9bRunit76+l6bhBx0wlkjJbVr6qpsGWvfDMoFvATxVjWJBCuh57bWIcCeaGLRhG1prENTzQi0CNxjIg1CzjaIvBRTFdb9tEHANRpwDVfvpFRojhV0Cpolo29K13kGlgQkUjBsQ3nMxVSoV7eH7Rs59WOAo9gGaYaY929SuBplI9fCdZrjOzJcAv5Gqlq3yyqPY1Gl1FrkbNQGeZSg7f8FETypgL6kXbhHxCRgvNJXXe7P96ArYHBEOLKN0muZipQZ+QRGfAXgGUcTMCwphPy1MKmFyescPdmPGMREpTHxo66WjNMmSGqmESZPQC0C1Te1cBjZUQlnAz/qhEo4CzYCj2Bvuaxs3MZvhuI3iE2mqfx0B5BCgAAAAAElFTkSuQmCC) 50% no-repeat;cursor:pointer;-webkit-transition:all .3s;transition:all .3s}.ww-theader .dropdown.active i{-webkit-transform:rotate(180deg);transform:rotate(180deg)}.ww-theader .handler{position:absolute;z-index:1;top:0;right:-8px;width:16px;height:30px;cursor:col-resize;text-align:center}.ww-theader .active{color:#2d8cf0}.ww-theader .ww-title{height:30px;line-height:30px;text-indent:4px;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.ww-theader .icon{display:inline-block;width:14px;height:14px;background-position:50%;background-repeat:no-repeat;background-size:contain;vertical-align:text-bottom;margin-bottom:1px}.ww-theader .icon.text{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABwAAAAcCAYAAAByDd+UAAAA8UlEQVRIS+3UoUvDQRjG8c/A2VWWTaJ9bQaDxWBfnM1kNJg0+xcYVw2iVWyyOMOag6VhstgEi8jBL4yx/dzr5mBwV4737t773vvw3Fux5FFZMk8GLlzxMklruEMVa8F5G2+TXlsG3MUrbnA7ktzCSRE38Y517CPFKW8P/SiwjmscjiVe4qpYS5UMx/a7OMVLFHiATdwHgWfo4TkK3MAnvoLALXzjIwqc5tDfJC119l8+fgZmScPtMptm9U2TGvp5UcYOBhEXRDtNOt9Bo4Ac4fG/gBc4HoElTmruD2jjaRZwtMJZ7ly4aeaC5grnkm9S8g+c6DQdaI0JoQAAAABJRU5ErkJggg==)}.ww-theader .icon.select{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABwAAAAcCAYAAAByDd+UAAAC7UlEQVRIS73WXeifcxjH8dcMEdkkC2FJHpoUWxiJaEXCASGJJXlWZiUP7YADkRMOGMnDmCmPB0pDnpXybIWIg2GMHDCplRh9fl133e5+9+93/zf5Ht3dXd/r/f1e1/X9XNcs//OaNQPeIpyK+dgHf2MjvsGL+HCIr2nA2bgcN2D/cvgzvsV22Bd71v/8uxP3468++CRgbvQ4DsXneAhP4MeOs71xPi7BAnyBC/HBOGgf8Dw8ip9wc4ESwkkrNw74dszDUjzZ3TAOeBaexQu4AJuG5KZlMweP4cxKxwPt/V1gwvcRXsMZVRgz5I3M4/dlnIzTsbZx0gV+jLk4HL9vDalz03UFPwh/NCdpbC7Gw3Wq17cR1mw/B0/hGtzbBX6KDfXW/iPeyE1uuUNV8CjWWXnI31dp55bNuho74q6BJzgGV+HSJoS4Fndjv1yoAcYg1RRw1KNZz+Bs3IJbp0AX4s2yybPYXN8Rh+9wZUShAd6GZdil43Q3vIKjcF2ddBw3sFR2lOkUvNMxSgHegxsb4CM4tlSl63DXctYHTUW/XbA8g/fHnOhLvIuLGuAqLO4BZn8bmhzdV04DSxhzsyU9sJgG+F4krx3SlG5Uom8F+hKOq8LI00noAjsRn0zY+xtWtkMa4X2wOkIS3Ld2rpwG+mspUcI4CZbqTCf5V9HshR+wfEJhNIcINFKVznASPptSvSnGPKsDsL4tbW9Ubzts4JsbapaHvz1GftvA06pDnIunh3qbYtdIW5r4qGt0xTulm/AeXb1wW7h7VOdJro9oOk8XeGC9l6jNCfhlK4m749V6ZhGFTAGjNa4BH4m3SshTgW2pG8JPdJKSzECRxefam/pGjEMqnzvhJqzBlim0dIQVNZJkiIo+r+7umTRERQTuwGX4qg6Qm39dYpwZJ8J8MI6vkSLfGZ6u6Bsbp42JOWDK+fpymNyMW5l7ni/xyKF61xBgszkSFr1NbjIaZm8zCKe6/xyS4JkAh/ibavMPM7eSHfbP2HIAAAAASUVORK5CYII=)}.ww-theader .icon.date{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABwAAAAcCAYAAAByDd+UAAABnElEQVRIS+2WvUoDQRDHZ26TNp1dBEErleOyCxJIlWcQzDMYsJDUKvYhlR+voBY+g6AoFjvhomCjWEQ7G7HN7siGS0hCPuUSAmaru2XY385/5v5zCDNeOGMezBdQSplFxAdmLhDR1TA1pJQFRLwAgKzW+nFQbDND3/fTnuet9QYJIdYB4JSZj621N8OAiJj3PO8QAIrGmJfeWGvta61W+2gClVIlAChPs57W2lK1Wq10ARuNRjoMw88WOAiCnBDijpm3iej6L5IGQbAihHgfC+j7/mYikTgBgAMiuh0GVErlmfkIAHaJqC3pRMA4JP7nwDgkHHRG36YBgAoz/8QMTiHi/lhdGgfYmUoymayPBCqlnD1tOWjndyilrLgbR5epaK2daUCHtbn4eyLKtVxsAWxb26xrKI0xKQcVQjxrrb8io181xixH+3Wt9Zt7zmQyS8y8EdX8OwzD6qKG5c7xpJQ6Y2Y3gN1qTwulVJGZd9wmIl5qrc8jqVvTwr0+EdHeRJLG0TAjgTO3triy6ndOl7VNE9R79nz9l04j81/VJfoszhfN5AAAAABJRU5ErkJggg==)}.ww-theader .icon.number{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABwAAAAcCAYAAAByDd+UAAADF0lEQVRIS+WWXUgUURTHz5kZXAITJchehBLqodVm5l4KioryISoQiXrpJSmfQsgHw0DCIDGoSIIiCCqkh4LqQcIoCPqiD6juubuDEoUR9VSBiqHEsrPeGLkr2zizrSvUQ/O295zz/839n3vuLMJffrBUnuM4uw3D6NL5I0TUHlXLOe9QSu3RsXtEdLYwr2Qg5/wKALTp4n4hRGcMUAAAC2IzMzNtUspr5QI/AkB9UKyUaiaioTAwmUxWJhKJH4g4u5FsNlvved6nBQMbGhpqE4nEVw1TmUymamRkZCoMdBynxTTNQZ33mYhWhnNKspRz3goAA1roDRFtiLKTMXYeETt03gARHSwXGMACaGDnGSI6FgNMI+I63b9WKeX1coGBnbUauIuIHoSFGhsbayoqKsbz65lMZsXw8PC3WCBjrAkAtka8+RJEzI9DED6nlJrXP0RcBQAHdP3PwIkCrWdE9Cj4PddDxlgfInZHWbXYNaVUHxEd/7fAuF1wzuf6l8vldqRSqYcR41BtmuZEfj2bzdZ6nvc9SrPoWNi2vcayrPe60J+cnKwcHR3NhIVc191vGMYNfajeEdHauA0UBXLODwPAJS30lIi2xYzDVUQ8pGMXhBBHygIyxu4g4l5d3COE6I0S4px/AYA6PX8tUsq75QCRMTaGiDVBcS6X25xKpV5E9G+1aZoftAvK9/2lnudNLxho27ZrWRZpoWkiqgYAPywUsv0VEW0qNkb/0RwWXm1KKTQMoydvjVLqIgCMRVhVV3A6/eBGibFz/tVWmOg4znrTNF/r/k0RUVXwoQiLMcbaETF4meB5LoTYUqx/QSxyDhljXYh4WgOHiKg5ZhxuA8A+HesVQsy5sqBTyhi7j4g79Vx1Sin7YwZ+PD82ANAkhHhczg4txtgEIlYGxb7vs3Q6LcNCtm0nLcsa1uux1164bp6lrutuNAzjpbZzgoiWldC/J0KI7X/aXWQPGWPdiJg/bYNCiPx/zN/0OOeF/TshhDhZFtB13VOIOHtbKKUuSylvxhyYW0qp5TrvqJTybVnAUooWk/MLR2dzLEpBurgAAAAASUVORK5CYII=)}.ww-tbody{font-size:12px;overflow:hidden;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;border-bottom:1px solid #d6dfe4;border-right:1px solid #d6dfe4}.ww-tbody,.ww-tbody>div{position:relative}.ww-tbody.empty{border-left:1px solid #d6dfe4}.ww-tbody.fixed{position:absolute;left:0;-webkit-box-shadow:1px 0 8px #d3d4d6;box-shadow:1px 0 8px #d3d4d6;overflow-x:hidden;background:#fff;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;z-index:2}.ww-tbody.scrollY{padding-bottom:8px}.ww-tbody .ww-tr{position:absolute;top:0;left:0;display:-webkit-box;display:-ms-flexbox;display:flex}.ww-tbody .ww-tr:first-child .ww-td{border-top:none}.ww-tbody .ww-td{position:relative;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;border-top:1px solid #d6dfe4;border-left:1px solid #d6dfe4;min-width:0}.ww-tbody .ww-td.selection{-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.ww-tbody .ww-td.disabled{color:#c5c5c5}.ww-tbody .ww-td.error{background-color:#ff4c42!important}.ww-cell-content{width:100%;text-indent:4px;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.ww-empty-block{position:relative;z-index:9;font-size:14px;padding:30px;text-align:center;color:#909399}.ww-tr-add{position:absolute;left:-16px;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;width:32px;height:32px;cursor:pointer;z-index:10}.ww-tr-add.prev{top:-16px}.ww-tr-add.next{bottom:-16px}.ww-tr-add:before{content:"";display:inline-block;width:8px;height:8px;border-radius:50%;background-color:#d6dfe4;-webkit-transition:all .3s;transition:all .3s}.ww-tr-add:hover:before{width:16px;height:16px;background-color:#57a3f3}.el-select-dropdown__item{white-space:nowrap}.el-select-dropdown{position:absolute;z-index:1001;border:1px solid #e4e7ed;border-radius:4px;background-color:#fff;-webkit-box-shadow:0 2px 12px 0 rgba(0,0,0,.1);box-shadow:0 2px 12px 0 rgba(0,0,0,.1);-webkit-box-sizing:border-box;box-sizing:border-box;margin:5px 0}.el-select-dropdown.is-multiple .el-select-dropdown__item.selected{color:#409eff;background-color:#fff}.el-select-dropdown.is-multiple .el-select-dropdown__item.selected.hover{background-color:#f5f7fa}.el-select-dropdown.is-multiple .el-select-dropdown__item.selected:after{position:absolute;right:20px;font-family:element-icons;content:"\e6da";font-size:12px;font-weight:700;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.el-select-dropdown .el-scrollbar.is-empty .el-select-dropdown__list{padding:0}.el-select-dropdown__empty{padding:10px 0;margin:0;text-align:center;color:#999;font-size:14px}.el-select-dropdown__wrap{max-height:274px}.el-select-dropdown__list{list-style:none;padding:6px 0;margin:0;-webkit-box-sizing:border-box;box-sizing:border-box}.el-select-dropdown__item,.el-tag{white-space:nowrap;-webkit-box-sizing:border-box}.el-tag{background-color:#ecf5ff;display:inline-block;height:32px;padding:0 10px;line-height:30px;font-size:12px;color:#409eff;border:1px solid #d9ecff;border-radius:4px;-webkit-box-sizing:border-box;box-sizing:border-box}.el-tag.is-hit{border-color:#409eff}.el-tag .el-tag__close{color:#409eff}.el-tag .el-tag__close:hover{color:#fff;background-color:#409eff}.el-tag.el-tag--info{background-color:#f4f4f5;border-color:#e9e9eb;color:#909399}.el-tag.el-tag--info.is-hit{border-color:#909399}.el-tag.el-tag--info .el-tag__close{color:#909399}.el-tag.el-tag--info .el-tag__close:hover{color:#fff;background-color:#909399}.el-tag.el-tag--success{background-color:#f0f9eb;border-color:#e1f3d8;color:#67c23a}.el-tag.el-tag--success.is-hit{border-color:#67c23a}.el-tag.el-tag--success .el-tag__close{color:#67c23a}.el-tag.el-tag--success .el-tag__close:hover{color:#fff;background-color:#67c23a}.el-tag.el-tag--warning{background-color:#fdf6ec;border-color:#faecd8;color:#e6a23c}.el-tag.el-tag--warning.is-hit{border-color:#e6a23c}.el-tag.el-tag--warning .el-tag__close{color:#e6a23c}.el-tag.el-tag--warning .el-tag__close:hover{color:#fff;background-color:#e6a23c}.el-tag.el-tag--danger{background-color:#fef0f0;border-color:#fde2e2;color:#f56c6c}.el-tag.el-tag--danger.is-hit{border-color:#f56c6c}.el-tag.el-tag--danger .el-tag__close{color:#f56c6c}.el-tag.el-tag--danger .el-tag__close:hover{color:#fff;background-color:#f56c6c}.el-tag .el-icon-close{border-radius:50%;text-align:center;position:relative;cursor:pointer;font-size:12px;height:16px;width:16px;line-height:16px;vertical-align:middle;top:-1px;right:-5px}.el-tag .el-icon-close:before{display:block}.el-tag--dark{background-color:#409eff;color:#fff}.el-tag--dark,.el-tag--dark.is-hit{border-color:#409eff}.el-tag--dark .el-tag__close{color:#fff}.el-tag--dark .el-tag__close:hover{color:#fff;background-color:#66b1ff}.el-tag--dark.el-tag--info{background-color:#909399;border-color:#909399;color:#fff}.el-tag--dark.el-tag--info.is-hit{border-color:#909399}.el-tag--dark.el-tag--info .el-tag__close{color:#fff}.el-tag--dark.el-tag--info .el-tag__close:hover{color:#fff;background-color:#a6a9ad}.el-tag--dark.el-tag--success{background-color:#67c23a;border-color:#67c23a;color:#fff}.el-tag--dark.el-tag--success.is-hit{border-color:#67c23a}.el-tag--dark.el-tag--success .el-tag__close{color:#fff}.el-tag--dark.el-tag--success .el-tag__close:hover{color:#fff;background-color:#85ce61}.el-tag--dark.el-tag--warning{background-color:#e6a23c;border-color:#e6a23c;color:#fff}.el-tag--dark.el-tag--warning.is-hit{border-color:#e6a23c}.el-tag--dark.el-tag--warning .el-tag__close{color:#fff}.el-tag--dark.el-tag--warning .el-tag__close:hover{color:#fff;background-color:#ebb563}.el-tag--dark.el-tag--danger{background-color:#f56c6c;border-color:#f56c6c;color:#fff}.el-tag--dark.el-tag--danger.is-hit{border-color:#f56c6c}.el-tag--dark.el-tag--danger .el-tag__close{color:#fff}.el-tag--dark.el-tag--danger .el-tag__close:hover{color:#fff;background-color:#f78989}.el-tag--plain{background-color:#fff;border-color:#b3d8ff;color:#409eff}.el-tag--plain.is-hit{border-color:#409eff}.el-tag--plain .el-tag__close{color:#409eff}.el-tag--plain .el-tag__close:hover{color:#fff;background-color:#409eff}.el-tag--plain.el-tag--info{background-color:#fff;border-color:#d3d4d6;color:#909399}.el-tag--plain.el-tag--info.is-hit{border-color:#909399}.el-tag--plain.el-tag--info .el-tag__close{color:#909399}.el-tag--plain.el-tag--info .el-tag__close:hover{color:#fff;background-color:#909399}.el-tag--plain.el-tag--success{background-color:#fff;border-color:#c2e7b0;color:#67c23a}.el-tag--plain.el-tag--success.is-hit{border-color:#67c23a}.el-tag--plain.el-tag--success .el-tag__close{color:#67c23a}.el-tag--plain.el-tag--success .el-tag__close:hover{color:#fff;background-color:#67c23a}.el-tag--plain.el-tag--warning{background-color:#fff;border-color:#f5dab1;color:#e6a23c}.el-tag--plain.el-tag--warning.is-hit{border-color:#e6a23c}.el-tag--plain.el-tag--warning .el-tag__close{color:#e6a23c}.el-tag--plain.el-tag--warning .el-tag__close:hover{color:#fff;background-color:#e6a23c}.el-tag--plain.el-tag--danger{background-color:#fff;border-color:#fbc4c4;color:#f56c6c}.el-tag--plain.el-tag--danger.is-hit{border-color:#f56c6c}.el-tag--plain.el-tag--danger .el-tag__close{color:#f56c6c}.el-tag--plain.el-tag--danger .el-tag__close:hover{color:#fff;background-color:#f56c6c}.el-tag--medium{height:28px;line-height:26px}.el-tag--medium .el-icon-close{-webkit-transform:scale(.8);transform:scale(.8)}.el-tag--small{height:24px;padding:0 8px;line-height:22px}.el-tag--small .el-icon-close{-webkit-transform:scale(.8);transform:scale(.8)}.el-tag--mini{height:20px;padding:0 5px;line-height:19px}.el-tag--mini .el-icon-close{margin-left:-3px;-webkit-transform:scale(.7);transform:scale(.7)}.el-select-dropdown__item{font-size:14px;padding:0 20px;position:relative;overflow:hidden;text-overflow:ellipsis;color:#606266;height:34px;line-height:34px;-webkit-box-sizing:border-box;box-sizing:border-box;cursor:pointer}.el-select-dropdown__item.is-disabled{color:#c0c4cc;cursor:not-allowed}.el-select-dropdown__item.is-disabled:hover{background-color:#fff}.el-select-dropdown__item.hover,.el-select-dropdown__item:hover{background-color:#f5f7fa}.el-select-dropdown__item.selected{color:#409eff;font-weight:700}.el-select-group{margin:0;padding:0}.el-select-group__wrap{position:relative;list-style:none;margin:0;padding:0}.el-select-group__wrap:not(:last-of-type){padding-bottom:24px}.el-select-group__wrap:not(:last-of-type):after{content:"";position:absolute;display:block;left:20px;right:20px;bottom:12px;height:1px;background:#e4e7ed}.el-select-group__title{padding-left:20px;font-size:12px;color:#909399;line-height:30px}.el-select-group .el-select-dropdown__item{padding-left:20px}.el-select{display:inline-block;position:relative}.el-select .el-select__tags>span{display:contents}.el-select:hover .el-input__inner{border-color:#c0c4cc}.el-select .el-input__inner{cursor:pointer;padding-right:35px}.el-select .el-input__inner:focus{border-color:#409eff}.el-select .el-input .el-select__caret{color:#c0c4cc;font-size:14px;-webkit-transition:-webkit-transform .3s;transition:-webkit-transform .3s;transition:transform .3s;transition:transform .3s,-webkit-transform .3s;-webkit-transform:rotate(180deg);transform:rotate(180deg);cursor:pointer}.el-select .el-input .el-select__caret.is-reverse{-webkit-transform:rotate(0);transform:rotate(0)}.el-select .el-input .el-select__caret.is-show-close{font-size:14px;text-align:center;-webkit-transform:rotate(180deg);transform:rotate(180deg);border-radius:100%;color:#c0c4cc;-webkit-transition:color .2s cubic-bezier(.645,.045,.355,1);transition:color .2s cubic-bezier(.645,.045,.355,1)}.el-select .el-input .el-select__caret.is-show-close:hover{color:#909399}.el-select .el-input.is-disabled .el-input__inner{cursor:not-allowed}.el-select .el-input.is-disabled .el-input__inner:hover{border-color:#e4e7ed}.el-select .el-input.is-focus .el-input__inner{border-color:#409eff}.el-select>.el-input{display:block}.el-select__input{border:none;outline:0;padding:0;margin-left:15px;color:#666;font-size:14px;-webkit-appearance:none;-moz-appearance:none;appearance:none;height:28px;background-color:transparent}.el-select__input.is-mini{height:14px}.el-select__close{cursor:pointer;position:absolute;top:8px;z-index:1000;right:25px;color:#c0c4cc;line-height:18px;font-size:14px}.el-select__close:hover{color:#909399}.el-select__tags{position:absolute;line-height:normal;white-space:normal;z-index:1;top:50%;-webkit-transform:translateY(-50%);transform:translateY(-50%);display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-ms-flex-wrap:wrap;flex-wrap:wrap}.el-select .el-tag__close{margin-top:-2px}.el-select .el-tag{-webkit-box-sizing:border-box;box-sizing:border-box;border-color:transparent;margin:2px 0 2px 6px;background-color:#f0f2f5}.el-select .el-tag__close.el-icon-close{background-color:#c0c4cc;right:-7px;top:0;color:#fff}.el-select .el-tag__close.el-icon-close:hover{background-color:#909399}.el-select .el-tag__close.el-icon-close:before{display:block;-webkit-transform:translateY(.5px);transform:translateY(.5px)}.el-date-table.is-week-mode .el-date-table__row.current div,.el-date-table.is-week-mode .el-date-table__row:hover div,.el-date-table td.in-range div,.el-date-table td.in-range div:hover{background-color:#f2f6fc}.el-date-table{font-size:12px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.el-date-table.is-week-mode .el-date-table__row:hover td.available:hover{color:#606266}.el-date-table.is-week-mode .el-date-table__row:hover td:first-child div{margin-left:5px;border-top-left-radius:15px;border-bottom-left-radius:15px}.el-date-table.is-week-mode .el-date-table__row:hover td:last-child div{margin-right:5px;border-top-right-radius:15px;border-bottom-right-radius:15px}.el-date-table td{width:32px;padding:4px 0;text-align:center;cursor:pointer;position:relative}.el-date-table td,.el-date-table td div{height:30px;-webkit-box-sizing:border-box;box-sizing:border-box}.el-date-table td div{padding:3px 0}.el-date-table td span{width:24px;height:24px;display:block;margin:0 auto;line-height:24px;position:absolute;left:50%;-webkit-transform:translateX(-50%);transform:translateX(-50%);border-radius:50%}.el-date-table td.next-month,.el-date-table td.prev-month{color:#c0c4cc}.el-date-table td.today{position:relative}.el-date-table td.today span{color:#409eff;font-weight:700}.el-date-table td.today.end-date span,.el-date-table td.today.start-date span{color:#fff}.el-date-table td.available:hover{color:#409eff}.el-date-table td.current:not(.disabled) span{color:#fff;background-color:#409eff}.el-date-table td.end-date div,.el-date-table td.start-date div{color:#fff}.el-date-table td.end-date span,.el-date-table td.start-date span{background-color:#409eff}.el-date-table td.start-date div{margin-left:5px;border-top-left-radius:15px;border-bottom-left-radius:15px}.el-date-table td.end-date div{margin-right:5px;border-top-right-radius:15px;border-bottom-right-radius:15px}.el-date-table td.disabled div{background-color:#f5f7fa;opacity:1;cursor:not-allowed;color:#c0c4cc}.el-fade-in-enter,.el-fade-in-leave-active,.el-fade-in-linear-enter,.el-fade-in-linear-leave,.el-fade-in-linear-leave-active,.fade-in-linear-enter,.fade-in-linear-leave,.fade-in-linear-leave-active{opacity:0}.el-date-table td.selected div{margin-left:5px;margin-right:5px;background-color:#f2f6fc;border-radius:15px}.el-date-table td.selected div:hover{background-color:#f2f6fc}.el-date-table td.selected span{background-color:#409eff;color:#fff;border-radius:15px}.el-date-table td.week{font-size:80%;color:#606266}.el-date-table th{padding:5px;color:#606266;font-weight:400;border-bottom:1px solid #ebeef5}.el-month-table{font-size:12px;margin:-1px;border-collapse:collapse}.el-month-table td{text-align:center;padding:8px 0;cursor:pointer}.el-month-table td div{height:48px;padding:6px 0;-webkit-box-sizing:border-box;box-sizing:border-box}.el-month-table td.today .cell{color:#409eff;font-weight:700}.el-month-table td.today.end-date .cell,.el-month-table td.today.start-date .cell{color:#fff}.el-month-table td.disabled .cell{background-color:#f5f7fa;cursor:not-allowed;color:#c0c4cc}.el-month-table td.disabled .cell:hover{color:#c0c4cc}.el-month-table td .cell{width:60px;height:36px;display:block;line-height:36px;color:#606266;margin:0 auto;border-radius:18px}.el-month-table td .cell:hover{color:#409eff}.el-month-table td.in-range div,.el-month-table td.in-range div:hover{background-color:#f2f6fc}.el-month-table td.end-date div,.el-month-table td.start-date div{color:#fff}.el-month-table td.end-date .cell,.el-month-table td.start-date .cell{color:#fff;background-color:#409eff}.el-month-table td.start-date div{border-top-left-radius:24px;border-bottom-left-radius:24px}.el-month-table td.end-date div{border-top-right-radius:24px;border-bottom-right-radius:24px}.el-month-table td.current:not(.disabled) .cell{color:#409eff}.el-year-table{font-size:12px;margin:-1px;border-collapse:collapse}.el-year-table .el-icon{color:#303133}.el-year-table td{text-align:center;padding:20px 3px;cursor:pointer}.el-year-table td.today .cell{color:#409eff;font-weight:700}.el-year-table td.disabled .cell{background-color:#f5f7fa;cursor:not-allowed;color:#c0c4cc}.el-year-table td.disabled .cell:hover{color:#c0c4cc}.el-year-table td .cell{width:48px;height:32px;display:block;line-height:32px;color:#606266;margin:0 auto}.el-year-table td .cell:hover,.el-year-table td.current:not(.disabled) .cell{color:#409eff}.el-time-spinner.has-seconds .el-time-spinner__wrapper{width:33.3%}.el-time-spinner__wrapper{max-height:190px;overflow:auto;display:inline-block;width:50%;vertical-align:top;position:relative}.el-time-spinner__wrapper .el-scrollbar__wrap:not(.el-scrollbar__wrap--hidden-default){padding-bottom:15px}.el-time-spinner__wrapper.is-arrow{-webkit-box-sizing:border-box;box-sizing:border-box;text-align:center;overflow:hidden}.el-time-spinner__wrapper.is-arrow .el-time-spinner__list{-webkit-transform:translateY(-32px);transform:translateY(-32px)}.el-time-spinner__wrapper.is-arrow .el-time-spinner__item:hover:not(.disabled):not(.active){background:#fff;cursor:default}.el-time-spinner__arrow{font-size:12px;color:#909399;position:absolute;left:0;width:100%;z-index:1;text-align:center;height:30px;line-height:30px;cursor:pointer}.el-time-spinner__arrow:hover{color:#409eff}.el-time-spinner__arrow.el-icon-arrow-up{top:10px}.el-time-spinner__arrow.el-icon-arrow-down{bottom:10px}.el-time-spinner__input.el-input{width:70%}.el-time-spinner__input.el-input .el-input__inner,.el-time-spinner__list{padding:0;text-align:center}.el-time-spinner__list{margin:0;list-style:none}.el-time-spinner__list:after,.el-time-spinner__list:before{content:"";display:block;width:100%;height:80px}.el-time-spinner__item{height:32px;line-height:32px;font-size:12px;color:#606266}.el-time-spinner__item:hover:not(.disabled):not(.active){background:#f5f7fa;cursor:pointer}.el-time-spinner__item.active:not(.disabled){color:#303133;font-weight:700}.el-time-spinner__item.disabled{color:#c0c4cc;cursor:not-allowed}.el-fade-in-linear-enter-active,.el-fade-in-linear-leave-active,.fade-in-linear-enter-active,.fade-in-linear-leave-active{-webkit-transition:opacity .2s linear;transition:opacity .2s linear}.el-fade-in-enter-active,.el-fade-in-leave-active,.el-zoom-in-center-enter-active,.el-zoom-in-center-leave-active{-webkit-transition:all .3s cubic-bezier(.55,0,.1,1);transition:all .3s cubic-bezier(.55,0,.1,1)}.el-zoom-in-center-enter,.el-zoom-in-center-leave-active{opacity:0;-webkit-transform:scaleX(0);transform:scaleX(0)}.el-zoom-in-top-enter-active,.el-zoom-in-top-leave-active{opacity:1;-webkit-transform:scaleY(1);transform:scaleY(1);-webkit-transition:opacity .3s cubic-bezier(.23,1,.32,1),-webkit-transform .3s cubic-bezier(.23,1,.32,1);transition:opacity .3s cubic-bezier(.23,1,.32,1),-webkit-transform .3s cubic-bezier(.23,1,.32,1);transition:transform .3s cubic-bezier(.23,1,.32,1),opacity .3s cubic-bezier(.23,1,.32,1);transition:transform .3s cubic-bezier(.23,1,.32,1),opacity .3s cubic-bezier(.23,1,.32,1),-webkit-transform .3s cubic-bezier(.23,1,.32,1);-webkit-transform-origin:center top;transform-origin:center top}.el-zoom-in-top-enter,.el-zoom-in-top-leave-active{opacity:0;-webkit-transform:scaleY(0);transform:scaleY(0)}.el-zoom-in-bottom-enter-active,.el-zoom-in-bottom-leave-active{opacity:1;-webkit-transform:scaleY(1);transform:scaleY(1);-webkit-transition:opacity .3s cubic-bezier(.23,1,.32,1),-webkit-transform .3s cubic-bezier(.23,1,.32,1);transition:opacity .3s cubic-bezier(.23,1,.32,1),-webkit-transform .3s cubic-bezier(.23,1,.32,1);transition:transform .3s cubic-bezier(.23,1,.32,1),opacity .3s cubic-bezier(.23,1,.32,1);transition:transform .3s cubic-bezier(.23,1,.32,1),opacity .3s cubic-bezier(.23,1,.32,1),-webkit-transform .3s cubic-bezier(.23,1,.32,1);-webkit-transform-origin:center bottom;transform-origin:center bottom}.el-zoom-in-bottom-enter,.el-zoom-in-bottom-leave-active{opacity:0;-webkit-transform:scaleY(0);transform:scaleY(0)}.el-zoom-in-left-enter-active,.el-zoom-in-left-leave-active{opacity:1;-webkit-transform:scale(1);transform:scale(1);-webkit-transition:opacity .3s cubic-bezier(.23,1,.32,1),-webkit-transform .3s cubic-bezier(.23,1,.32,1);transition:opacity .3s cubic-bezier(.23,1,.32,1),-webkit-transform .3s cubic-bezier(.23,1,.32,1);transition:transform .3s cubic-bezier(.23,1,.32,1),opacity .3s cubic-bezier(.23,1,.32,1);transition:transform .3s cubic-bezier(.23,1,.32,1),opacity .3s cubic-bezier(.23,1,.32,1),-webkit-transform .3s cubic-bezier(.23,1,.32,1);-webkit-transform-origin:top left;transform-origin:top left}.el-zoom-in-left-enter,.el-zoom-in-left-leave-active{opacity:0;-webkit-transform:scale(.45);transform:scale(.45)}.collapse-transition{-webkit-transition:height .3s ease-in-out,padding-top .3s ease-in-out,padding-bottom .3s ease-in-out;transition:height .3s ease-in-out,padding-top .3s ease-in-out,padding-bottom .3s ease-in-out}.horizontal-collapse-transition{-webkit-transition:width .3s ease-in-out,padding-left .3s ease-in-out,padding-right .3s ease-in-out;transition:width .3s ease-in-out,padding-left .3s ease-in-out,padding-right .3s ease-in-out}.el-list-enter-active,.el-list-leave-active{-webkit-transition:all 1s;transition:all 1s}.el-list-enter,.el-list-leave-active{opacity:0;-webkit-transform:translateY(-30px);transform:translateY(-30px)}.el-opacity-transition{-webkit-transition:opacity .3s cubic-bezier(.55,0,.1,1);transition:opacity .3s cubic-bezier(.55,0,.1,1)}.el-date-editor{position:relative;display:inline-block;text-align:left}.el-date-editor.el-input,.el-date-editor.el-input__inner{width:220px}.el-date-editor--monthrange.el-input,.el-date-editor--monthrange.el-input__inner{width:300px}.el-date-editor--daterange.el-input,.el-date-editor--daterange.el-input__inner,.el-date-editor--timerange.el-input,.el-date-editor--timerange.el-input__inner{width:350px}.el-date-editor--datetimerange.el-input,.el-date-editor--datetimerange.el-input__inner{width:400px}.el-date-editor--dates .el-input__inner{text-overflow:ellipsis;white-space:nowrap}.el-date-editor .el-icon-circle-close{cursor:pointer}.el-date-editor .el-range__icon{font-size:14px;margin-left:-5px;color:#c0c4cc;float:left;line-height:32px}.el-date-editor .el-range-input,.el-date-editor .el-range-separator{height:100%;margin:0;text-align:center;display:inline-block;font-size:14px}.el-date-editor .el-range-input{-webkit-appearance:none;-moz-appearance:none;appearance:none;border:none;outline:0;padding:0;width:39%;color:#606266}.el-date-editor .el-range-input::-webkit-input-placeholder{color:#c0c4cc}.el-date-editor .el-range-input:-ms-input-placeholder{color:#c0c4cc}.el-date-editor .el-range-input::-ms-input-placeholder{color:#c0c4cc}.el-date-editor .el-range-input::-moz-placeholder{color:#c0c4cc}.el-date-editor .el-range-input::placeholder{color:#c0c4cc}.el-date-editor .el-range-separator{padding:0 5px;line-height:32px;width:5%;color:#303133}.el-date-editor .el-range__close-icon{font-size:14px;color:#c0c4cc;width:25px;display:inline-block;float:right;line-height:32px}.el-range-editor.el-input__inner{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;padding:3px 10px}.el-range-editor .el-range-input{line-height:1}.el-range-editor.is-active,.el-range-editor.is-active:hover{border-color:#409eff}.el-range-editor--medium.el-input__inner{height:36px}.el-range-editor--medium .el-range-separator{line-height:28px;font-size:14px}.el-range-editor--medium .el-range-input{font-size:14px}.el-range-editor--medium .el-range__close-icon,.el-range-editor--medium .el-range__icon{line-height:28px}.el-range-editor--small.el-input__inner{height:32px}.el-range-editor--small .el-range-separator{line-height:24px;font-size:13px}.el-range-editor--small .el-range-input{font-size:13px}.el-range-editor--small .el-range__close-icon,.el-range-editor--small .el-range__icon{line-height:24px}.el-range-editor--mini.el-input__inner{height:28px}.el-range-editor--mini .el-range-separator{line-height:20px;font-size:12px}.el-range-editor--mini .el-range-input{font-size:12px}.el-range-editor--mini .el-range__close-icon,.el-range-editor--mini .el-range__icon{line-height:20px}.el-range-editor.is-disabled{background-color:#f5f7fa;border-color:#e4e7ed;color:#c0c4cc;cursor:not-allowed}.el-range-editor.is-disabled:focus,.el-range-editor.is-disabled:hover{border-color:#e4e7ed}.el-range-editor.is-disabled input{background-color:#f5f7fa;color:#c0c4cc;cursor:not-allowed}.el-range-editor.is-disabled input::-webkit-input-placeholder{color:#c0c4cc}.el-range-editor.is-disabled input:-ms-input-placeholder{color:#c0c4cc}.el-range-editor.is-disabled input::-ms-input-placeholder{color:#c0c4cc}.el-range-editor.is-disabled input::-moz-placeholder{color:#c0c4cc}.el-range-editor.is-disabled input::placeholder{color:#c0c4cc}.el-range-editor.is-disabled .el-range-separator{color:#c0c4cc}.el-picker-panel{color:#606266;border:1px solid #e4e7ed;-webkit-box-shadow:0 2px 12px 0 rgba(0,0,0,.1);box-shadow:0 2px 12px 0 rgba(0,0,0,.1);background:#fff;border-radius:4px;line-height:30px;margin:5px 0}.el-picker-panel__body-wrapper:after,.el-picker-panel__body:after{content:"";display:table;clear:both}.el-picker-panel__content{position:relative;margin:15px}.el-picker-panel__footer{border-top:1px solid #e4e4e4;padding:4px;text-align:right;background-color:#fff;position:relative;font-size:0}.el-picker-panel__shortcut{display:block;width:100%;border:0;background-color:transparent;line-height:28px;font-size:14px;color:#606266;padding-left:12px;text-align:left;outline:0;cursor:pointer}.el-picker-panel__shortcut:hover{color:#409eff}.el-picker-panel__shortcut.active{background-color:#e6f1fe;color:#409eff}.el-picker-panel__btn{border:1px solid #dcdcdc;color:#333;line-height:24px;border-radius:2px;padding:0 20px;cursor:pointer;background-color:transparent;outline:0;font-size:12px}.el-picker-panel__btn[disabled]{color:#ccc;cursor:not-allowed}.el-picker-panel__icon-btn{font-size:12px;color:#303133;border:0;background:0 0;cursor:pointer;outline:0;margin-top:8px}.el-picker-panel__icon-btn:hover{color:#409eff}.el-picker-panel__icon-btn.is-disabled{color:#bbb}.el-picker-panel__icon-btn.is-disabled:hover{cursor:not-allowed}.el-picker-panel__link-btn{vertical-align:middle}.el-picker-panel [slot=sidebar],.el-picker-panel__sidebar{position:absolute;top:0;bottom:0;width:110px;border-right:1px solid #e4e4e4;-webkit-box-sizing:border-box;box-sizing:border-box;padding-top:6px;background-color:#fff;overflow:auto}.el-picker-panel [slot=sidebar]+.el-picker-panel__body,.el-picker-panel__sidebar+.el-picker-panel__body{margin-left:110px}.el-date-picker{width:322px}.el-date-picker.has-sidebar.has-time{width:434px}.el-date-picker.has-sidebar{width:438px}.el-date-picker.has-time .el-picker-panel__body-wrapper{position:relative}.el-date-picker .el-picker-panel__content{width:292px}.el-date-picker table{table-layout:fixed;width:100%}.el-date-picker__editor-wrap{position:relative;display:table-cell;padding:0 5px}.el-date-picker__time-header{position:relative;border-bottom:1px solid #e4e4e4;font-size:12px;padding:8px 5px 5px;display:table;width:100%;-webkit-box-sizing:border-box;box-sizing:border-box}.el-date-picker__header{margin:12px;text-align:center}.el-date-picker__header--bordered{margin-bottom:0;padding-bottom:12px;border-bottom:1px solid #ebeef5}.el-date-picker__header--bordered+.el-picker-panel__content{margin-top:0}.el-date-picker__header-label{font-size:16px;font-weight:500;padding:0 5px;line-height:22px;text-align:center;cursor:pointer;color:#606266}.el-date-picker__header-label.active,.el-date-picker__header-label:hover{color:#409eff}.el-date-picker__prev-btn{float:left}.el-date-picker__next-btn{float:right}.el-date-picker__time-wrap{padding:10px;text-align:center}.el-date-picker__time-label{float:left;cursor:pointer;line-height:30px;margin-left:10px}.el-date-range-picker{width:646px}.el-date-range-picker.has-sidebar{width:756px}.el-date-range-picker table{table-layout:fixed;width:100%}.el-date-range-picker .el-picker-panel__body{min-width:513px}.el-date-range-picker .el-picker-panel__content{margin:0}.el-date-range-picker__header{position:relative;text-align:center;height:28px}.el-date-range-picker__header [class*=arrow-left]{float:left}.el-date-range-picker__header [class*=arrow-right]{float:right}.el-date-range-picker__header div{font-size:16px;font-weight:500;margin-right:50px}.el-date-range-picker__content{float:left;width:50%;-webkit-box-sizing:border-box;box-sizing:border-box;margin:0;padding:16px}.el-date-range-picker__content.is-left{border-right:1px solid #e4e4e4}.el-date-range-picker__content .el-date-range-picker__header div{margin-left:50px;margin-right:50px}.el-date-range-picker__editors-wrap{-webkit-box-sizing:border-box;box-sizing:border-box;display:table-cell}.el-date-range-picker__editors-wrap.is-right{text-align:right}.el-date-range-picker__time-header{position:relative;border-bottom:1px solid #e4e4e4;font-size:12px;padding:8px 5px 5px;display:table;width:100%;-webkit-box-sizing:border-box;box-sizing:border-box}.el-date-range-picker__time-header>.el-icon-arrow-right{font-size:20px;vertical-align:middle;display:table-cell;color:#303133}.el-date-range-picker__time-picker-wrap{position:relative;display:table-cell;padding:0 5px}.el-date-range-picker__time-picker-wrap .el-picker-panel{position:absolute;top:13px;right:0;z-index:1;background:#fff}.el-time-range-picker{width:354px;overflow:visible}.el-time-range-picker__content{position:relative;text-align:center;padding:10px}.el-time-range-picker__cell{-webkit-box-sizing:border-box;box-sizing:border-box;margin:0;padding:4px 7px 7px;width:50%;display:inline-block}.el-time-range-picker__header{margin-bottom:5px;text-align:center;font-size:14px}.el-time-panel,.el-time-range-picker__body{border-radius:2px;border:1px solid #e4e7ed}.el-time-panel{margin:5px 0;background-color:#fff;-webkit-box-shadow:0 2px 12px 0 rgba(0,0,0,.1);box-shadow:0 2px 12px 0 rgba(0,0,0,.1);position:absolute;width:180px;left:0;z-index:1000;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-box-sizing:content-box;box-sizing:content-box}.el-time-panel__content{font-size:0;position:relative;overflow:hidden}.el-time-panel__content:after,.el-time-panel__content:before{content:"";top:50%;position:absolute;margin-top:-15px;height:32px;z-index:-1;left:0;right:0;-webkit-box-sizing:border-box;box-sizing:border-box;padding-top:6px;text-align:left;border-top:1px solid #e4e7ed;border-bottom:1px solid #e4e7ed}.el-time-panel__content:after{left:50%;margin-left:12%;margin-right:12%}.el-time-panel__content:before{padding-left:50%;margin-right:12%;margin-left:12%}.el-time-panel__content.has-seconds:after{left:66.66667%}.el-time-panel__content.has-seconds:before{padding-left:33.33333%}.el-time-panel__footer{border-top:1px solid #e4e4e4;padding:4px;height:36px;line-height:25px;text-align:right;-webkit-box-sizing:border-box;box-sizing:border-box}.el-time-panel__btn{border:none;line-height:28px;padding:0 5px;margin:0 5px;cursor:pointer;background-color:transparent;outline:0;font-size:12px;color:#303133}.el-time-panel__btn.confirm{font-weight:800;color:#409eff}.el-textarea{position:relative;display:inline-block;width:100%;vertical-align:bottom;font-size:14px}.el-textarea__inner{display:block;resize:vertical;padding:5px 15px;line-height:1.5;-webkit-box-sizing:border-box;box-sizing:border-box;width:100%;font-size:inherit;color:#606266;background-color:#fff;background-image:none;border:1px solid #dcdfe6;border-radius:4px;-webkit-transition:border-color .2s cubic-bezier(.645,.045,.355,1);transition:border-color .2s cubic-bezier(.645,.045,.355,1)}.el-textarea__inner::-webkit-input-placeholder{color:#c0c4cc}.el-textarea__inner:-ms-input-placeholder{color:#c0c4cc}.el-textarea__inner::-ms-input-placeholder{color:#c0c4cc}.el-textarea__inner::-moz-placeholder{color:#c0c4cc}.el-textarea__inner::placeholder{color:#c0c4cc}.el-textarea__inner:hover{border-color:#c0c4cc}.el-textarea__inner:focus{outline:0;border-color:#409eff}.el-textarea .el-input__count{color:#909399;background:#fff;position:absolute;font-size:12px;bottom:5px;right:10px}.el-textarea.is-disabled .el-textarea__inner{background-color:#f5f7fa;border-color:#e4e7ed;color:#c0c4cc;cursor:not-allowed}.el-textarea.is-disabled .el-textarea__inner::-webkit-input-placeholder{color:#c0c4cc}.el-textarea.is-disabled .el-textarea__inner:-ms-input-placeholder{color:#c0c4cc}.el-textarea.is-disabled .el-textarea__inner::-ms-input-placeholder{color:#c0c4cc}.el-textarea.is-disabled .el-textarea__inner::-moz-placeholder{color:#c0c4cc}.el-textarea.is-disabled .el-textarea__inner::placeholder{color:#c0c4cc}.el-textarea.is-exceed .el-textarea__inner{border-color:#f56c6c}.el-textarea.is-exceed .el-input__count{color:#f56c6c}.el-input{position:relative;font-size:14px;display:inline-block;width:100%}.el-input::-webkit-scrollbar{z-index:11;width:6px}.el-input::-webkit-scrollbar:horizontal{height:6px}.el-input::-webkit-scrollbar-thumb{border-radius:5px;width:6px;background:#b4bccc}.el-input::-webkit-scrollbar-corner,.el-input::-webkit-scrollbar-track{background:#fff}.el-input::-webkit-scrollbar-track-piece{background:#fff;width:6px}.el-input .el-input__clear{color:#c0c4cc;font-size:14px;cursor:pointer;-webkit-transition:color .2s cubic-bezier(.645,.045,.355,1);transition:color .2s cubic-bezier(.645,.045,.355,1)}.el-input .el-input__clear:hover{color:#909399}.el-input .el-input__count{height:100%;display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;color:#909399;font-size:12px}.el-input .el-input__count .el-input__count-inner{background:#fff;line-height:normal;display:inline-block;padding:0 5px}.el-input__inner{-webkit-appearance:none;background-color:#fff;background-image:none;border-radius:4px;border:1px solid #dcdfe6;-webkit-box-sizing:border-box;box-sizing:border-box;color:#606266;display:inline-block;font-size:inherit;height:40px;line-height:40px;outline:0;padding:0 15px;-webkit-transition:border-color .2s cubic-bezier(.645,.045,.355,1);transition:border-color .2s cubic-bezier(.645,.045,.355,1);width:100%}.el-input__prefix,.el-input__suffix{position:absolute;top:0;-webkit-transition:all .3s;text-align:center;height:100%;color:#c0c4cc}.el-input__inner::-webkit-input-placeholder{color:#c0c4cc}.el-input__inner:-ms-input-placeholder{color:#c0c4cc}.el-input__inner::-ms-input-placeholder{color:#c0c4cc}.el-input__inner::-moz-placeholder{color:#c0c4cc}.el-input__inner::placeholder{color:#c0c4cc}.el-input__inner:hover{border-color:#c0c4cc}.el-input.is-active .el-input__inner,.el-input__inner:focus{border-color:#409eff;outline:0}.el-input__suffix{right:5px;-webkit-transition:all .3s;transition:all .3s;pointer-events:none}.el-input__suffix-inner{pointer-events:all}.el-input__prefix{left:5px}.el-input__icon,.el-input__prefix{-webkit-transition:all .3s;transition:all .3s}.el-input__icon{height:100%;width:25px;text-align:center;line-height:40px}.el-input__icon:after{content:"";height:100%;width:0;display:inline-block;vertical-align:middle}.el-input__validateIcon{pointer-events:none}.el-input.is-disabled .el-input__inner{background-color:#f5f7fa;border-color:#e4e7ed;color:#c0c4cc;cursor:not-allowed}.el-input.is-disabled .el-input__inner::-webkit-input-placeholder{color:#c0c4cc}.el-input.is-disabled .el-input__inner:-ms-input-placeholder{color:#c0c4cc}.el-input.is-disabled .el-input__inner::-ms-input-placeholder{color:#c0c4cc}.el-input.is-disabled .el-input__inner::-moz-placeholder{color:#c0c4cc}.el-input.is-disabled .el-input__inner::placeholder{color:#c0c4cc}.el-input.is-disabled .el-input__icon{cursor:not-allowed}.el-input.is-exceed .el-input__inner{border-color:#f56c6c}.el-input.is-exceed .el-input__suffix .el-input__count{color:#f56c6c}.el-input--suffix .el-input__inner{padding-right:30px}.el-input--prefix .el-input__inner{padding-left:30px}.el-input--medium{font-size:14px}.el-input--medium .el-input__inner{height:36px;line-height:36px}.el-input--medium .el-input__icon{line-height:36px}.el-input--small{font-size:13px}.el-input--small .el-input__inner{height:32px;line-height:32px}.el-input--small .el-input__icon{line-height:32px}.el-input--mini{font-size:12px}.el-input--mini .el-input__inner{height:28px;line-height:28px}.el-input--mini .el-input__icon{line-height:28px}.el-input-group{line-height:normal;display:inline-table;width:100%;border-collapse:separate;border-spacing:0}.el-input-group>.el-input__inner{vertical-align:middle;display:table-cell}.el-input-group__append,.el-input-group__prepend{background-color:#f5f7fa;color:#909399;vertical-align:middle;display:table-cell;position:relative;border:1px solid #dcdfe6;border-radius:4px;padding:0 20px;width:1px;white-space:nowrap}.el-input-group--prepend .el-input__inner,.el-input-group__append{border-top-left-radius:0;border-bottom-left-radius:0}.el-input-group--append .el-input__inner,.el-input-group__prepend{border-top-right-radius:0;border-bottom-right-radius:0}.el-input-group__append:focus,.el-input-group__prepend:focus{outline:0}.el-input-group__append .el-button,.el-input-group__append .el-select,.el-input-group__prepend .el-button,.el-input-group__prepend .el-select{display:inline-block;margin:-10px -20px}.el-input-group__append button.el-button,.el-input-group__append div.el-select .el-input__inner,.el-input-group__append div.el-select:hover .el-input__inner,.el-input-group__prepend button.el-button,.el-input-group__prepend div.el-select .el-input__inner,.el-input-group__prepend div.el-select:hover .el-input__inner{border-color:transparent;background-color:transparent;color:inherit;border-top:0;border-bottom:0}.el-input-group__append .el-button,.el-input-group__append .el-input,.el-input-group__prepend .el-button,.el-input-group__prepend .el-input{font-size:inherit}.el-input-group__prepend{border-right:0}.el-input-group__append{border-left:0}.el-input-group--append .el-select .el-input.is-focus .el-input__inner,.el-input-group--prepend .el-select .el-input.is-focus .el-input__inner{border-color:transparent}.el-input__inner::-ms-clear{display:none;width:0;height:0}.el-scrollbar{overflow:hidden;position:relative}.el-scrollbar:active>.el-scrollbar__bar,.el-scrollbar:focus>.el-scrollbar__bar,.el-scrollbar:hover>.el-scrollbar__bar{opacity:1;-webkit-transition:opacity .34s ease-out;transition:opacity .34s ease-out}.el-scrollbar__wrap{overflow:scroll;height:100%}.el-scrollbar__wrap--hidden-default::-webkit-scrollbar{width:0;height:0}.el-scrollbar__thumb{position:relative;display:block;width:0;height:0;cursor:pointer;border-radius:inherit;background-color:rgba(144,147,153,.3);-webkit-transition:background-color .3s;transition:background-color .3s}.el-scrollbar__thumb:hover{background-color:rgba(144,147,153,.5)}.el-scrollbar__bar{position:absolute;right:2px;bottom:2px;z-index:1;border-radius:4px;opacity:0;-webkit-transition:opacity .12s ease-out;transition:opacity .12s ease-out}.el-scrollbar__bar.is-vertical{width:6px;top:2px}.el-scrollbar__bar.is-vertical>div{width:100%}.el-scrollbar__bar.is-horizontal{height:6px;left:2px}.el-scrollbar__bar.is-horizontal>div{height:100%}.el-popper .popper__arrow,.el-popper .popper__arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.el-popper .popper__arrow{border-width:6px;-webkit-filter:drop-shadow(0 2px 12px rgba(0,0,0,.03));filter:drop-shadow(0 2px 12px rgba(0,0,0,.03))}.el-popper .popper__arrow:after{content:" ";border-width:6px}.el-popper[x-placement^=top]{margin-bottom:12px}.el-popper[x-placement^=top] .popper__arrow{bottom:-6px;left:50%;margin-right:3px;border-top-color:#ebeef5;border-bottom-width:0}.el-popper[x-placement^=top] .popper__arrow:after{bottom:1px;margin-left:-6px;border-top-color:#fff;border-bottom-width:0}.el-popper[x-placement^=bottom]{margin-top:12px}.el-popper[x-placement^=bottom] .popper__arrow{top:-6px;left:50%;margin-right:3px;border-top-width:0;border-bottom-color:#ebeef5}.el-popper[x-placement^=bottom] .popper__arrow:after{top:1px;margin-left:-6px;border-top-width:0;border-bottom-color:#fff}.el-popper[x-placement^=right]{margin-left:12px}.el-popper[x-placement^=right] .popper__arrow{top:50%;left:-6px;margin-bottom:3px;border-right-color:#ebeef5;border-left-width:0}.el-popper[x-placement^=right] .popper__arrow:after{bottom:-6px;left:1px;border-right-color:#fff;border-left-width:0}.el-popper[x-placement^=left]{margin-right:12px}.el-popper[x-placement^=left] .popper__arrow{top:50%;right:-6px;margin-bottom:3px;border-right-width:0;border-left-color:#ebeef5}.el-popper[x-placement^=left] .popper__arrow:after{right:1px;bottom:-6px;margin-left:-6px;border-right-width:0;border-left-color:#fff}.ww-cell-editor{position:absolute;top:30px;left:0;display:-webkit-box;display:-ms-flexbox;display:flex;width:200px;border:1px solid #57a3f3;z-index:4;overflow:hidden}.ww-cell-editor.else{overflow:visible;border:none}.ww-cell-editor textarea{width:100%;height:50px;line-height:20px;outline:0;resize:none;padding:4px 6px;white-space:pre;border:none}.ww-autofill-handler{position:absolute;top:56px;left:196px;width:8px;height:8px;border:1px solid #57a3f3;background-color:#fff;cursor:crosshair;z-index:5}.ww-clipboard{width:0!important;height:0!important;-webkit-box-flex:0!important;-ms-flex:0 0!important;flex:0 0!important;padding:0!important}.ww-cover-area{position:absolute;top:0;left:0;pointer-events:none}.ww-cover-area.selected{background-color:rgba(74,149,235,.2)}.ww-cover-area.autofill{background-color:hsla(0,0%,49.8%,.2)}.ww-cover-area.fixed{z-index:3}.ww-dropdown-wrapper{position:absolute;top:0;left:0;z-index:30;min-width:100px;opacity:0;-webkit-transform:rotateX(90deg);transform:rotateX(90deg);-webkit-transform-origin:top center;transform-origin:top center;-webkit-transition:-webkit-transform .3s;transition:-webkit-transform .3s;transition:transform .3s;transition:transform .3s,-webkit-transform .3s;border:1px solid #ebeef5;border-radius:2px;background-color:#fff;-webkit-box-shadow:0 2px 12px 0 rgba(0,0,0,.1);box-shadow:0 2px 12px 0 rgba(0,0,0,.1);padding:8px;overflow-y:auto}.ww-dropdown-wrapper.active{opacity:1;-webkit-transform:rotateX(0);transform:rotateX(0)}.ww-sort{font-size:13px}.ww-sort,.ww-sort span{display:-webkit-box;display:-ms-flexbox;display:flex}.ww-sort span{-webkit-box-align:center;-ms-flex-align:center;align-items:center;cursor:pointer;padding:4px 8px;-webkit-transition:all .3s;transition:all .3s}.ww-sort span.active{background-color:#c5e1ba}.ww-sort span:hover{background-color:#cfc}.ww-sort span:before{content:"";display:inline-block;width:14px;height:14px;margin-right:2px}.ww-sort span:first-child:before{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABwAAAAcCAYAAAByDd+UAAAB5UlEQVRIS+3Wy8tNYRTH8c/rEgMDBpKUW0QkMkH8ATKi3jJACmXgMjIiEQOGDMQcoRQy0FsSuQ0pJbkOEFIGBi7l1qrn1O6xzz77nPY2sqbnec53rd+z1vrtIf84hip4ozAF7wbIaQbe4kd+twq4DgexeADgfdzFnn6AGxNwTp/AJXiAz5iKL8X7VRUOCjyDDQmyEyfaBMabv8GYBHmJUOh3B9p0hYewP3uC1RhpAxhVfcBzfE2AqPgV1rQB3IyjmIZfCTA9Aeci5NWkpNGZlxCyFuManmF3k8Dlae6iuvcZcC3OYnKMSFMVzsIqnC6Z2dFpARzHt6aAtXfDf2As7353aaW8TUo6FvtKaLEMTrYx+ONxHhML0KW409amyYtbgIcIu3qcVzgOYbiRYSfK7Gkmws1v1ZiDOPME28vsKZbsI1zArnQgB85LoPC3wz2AkXz4YiT4sZsfzsc9XExZhYl2unQhbuIqtvSAhVpPcQpH8rN5ly7CbVzBdRzAMG7gMrYWzbQLeC92YDa+9wLG79FZAfiESYivt6hsUw1YfMOEH27DubKEus1hQOPRJySJ1xc8rkrReLfozrhfGlWDvyw5wDH8rNGVMX+hSv6f0Rcr6wx+DcZfR1YgmqYYr/GiLWDPJP8AW8VkHQynzXwAAAAASUVORK5CYII=) 50% no-repeat;background-size:contain}.ww-sort span:last-child:before{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABwAAAAcCAYAAAByDd+UAAAB3klEQVRIS+3WS6hNcRTH8c+lFPIaeCuSPCJSZvJMRihlhIGBx8hAUTK5yoABUp5DM2QgipG8YsKEPIeIvMrEyMCjVf+j3b+9z9mXu/fImZzOPuv//6619lq/tfq0/OnrwhuCifgwAJ8WY0xm/xkvOs+6ATfiIBbVBI7CO4zO7J9iYR3g1gScVROYm43DG+zHmTaAp7EWc/GjaWBk5RU24EYx9G7v8F9Seh0jsTLPcxPAFbiNBcXqbCqlEcAzPMDOsmIb7Ah34ARm4EvTwBF4jfe4WoA9x+UmUjocezE0i+wTzjYBrKUPg/0Oe0L/A2Na/I14h2DfwsM2lCbGU8zQR21J2x7swyTMx8sy8R6GGLiXCn+WifdMTMO9inKMInyL41iTIt1eBhyPmMzXChqYA+fgfrrscAVwPS5iMpbiCqbga1njh/fhecyvXdhSmPiRmjs4n9JV1W83sQSPEdEuxwH8cTDvw+kJGpfH4X5sShV3Mv2ugs1L4+gIviejcHRZivJnPCtr/KkJGlvbWMT3IRztISPnEGlfVbCLxeojtnUEvEppYj28my7YjVM9YJ1W2JxNijgWZ2Pzi0hLI+zcHdDVuNBTIFmHY2lh+pXZz8YTTMC3blpagzNwk9aBvwH7i10d+/e2WwAAAABJRU5ErkJggg==) 50% no-repeat;background-size:contain}.ww-filter{border:1px solid #e0e0e0;padding:4px}.ww-filter .title{font-size:13px;padding:2px 6px;background-color:#f3f4f5}.ww-filter .title span{color:#909399}.ww-filter .content{border-bottom:1px solid #e0e0e0;padding:4px 0;margin-bottom:4px;overflow-y:auto;max-height:300px}.ww-filter .content li{-webkit-box-align:center;-ms-flex-align:center;align-items:center}.ww-filter .content li,.ww-filter .content p{display:-webkit-box;display:-ms-flexbox;display:flex}.ww-filter .content p{margin-left:4px;font-size:12px}.ww-filter .content p span{display:inline-block;max-width:200px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ww-filter .content p i{color:#909399}.ww-filter .btns{font-size:13px}.ww-filter .btns span{display:inline-block;cursor:pointer;-webkit-transition:all .5s;transition:all .5s;padding:0 4px}.ww-filter .btns span:hover{color:#20a0ff}.ww-scroll-wrap{position:absolute;z-index:20;background-color:#f8f8f9}.ww-scroll-wrap.x{bottom:0;left:0;width:100%;height:8px}.ww-scroll-wrap.x .ww-scroll-box{height:8px}.ww-scroll-wrap.y{top:0;right:0;width:8px;height:100%}.ww-scroll-wrap.y .ww-scroll-box{width:8px}.ww-scroll-box{border-radius:4px;background-color:#bbbec4;-webkit-transition:background-color .3s;transition:background-color .3s;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.ww-scroll-box:hover{background-color:#80848f}.ww-willtable{position:relative;background-color:#fff}.ww-willtable .el-checkbox{font-size:12px}.ww-table-wrapper{position:relative;overflow:hidden}.ww-table-wrapper.scrollX{padding-bottom:8px}.ww-table-wrapper.scrollY{padding-right:8px}.ww-empty-columns{text-align:center;border:1px solid #dcdfe6;padding:10px 20px;color:#909399}.ww-adjustLine{position:absolute;top:0;left:0;width:1px;height:100%;background-color:#d6dfe4;z-index:10} -------------------------------------------------------------------------------- /example/App.vue: -------------------------------------------------------------------------------- 1 | 56 | 57 | 381 | 382 | 480 | -------------------------------------------------------------------------------- /example/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinMint55/vue-willtable/893cf0d363a8a37d5aacb51170b0060e23b2c525/example/favicon.ico -------------------------------------------------------------------------------- /example/github.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinMint55/vue-willtable/893cf0d363a8a37d5aacb51170b0060e23b2c525/example/github.jpg -------------------------------------------------------------------------------- /example/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | vue-willtable 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /example/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | import App from './App.vue'; 3 | 4 | require('./mock.js'); 5 | 6 | new Vue({ 7 | render: (h) => h(App), 8 | }).$mount('#app'); 9 | -------------------------------------------------------------------------------- /example/mock.js: -------------------------------------------------------------------------------- 1 | import Mock from 'mockjs'; 2 | 3 | Mock.mock('https://demo.kevinmint.com/1.json', 'get', { 4 | // 属性 list 的值是一个数组,其中含有 1 到 3 个元素 5 | 'list|100': [{ 6 | // 属性 sid 是一个自增数,起始值为 1,每次增 1 7 | 'sid|+1': 1, 8 | // 属性 userId 是一个5位的随机码 9 | 'userId|5': '', 10 | // 属性 sex 是一个bool值 11 | 'sex|1-2': true, 12 | // 属性 guid 是唯一机器码 13 | guid: '@guid', 14 | // 属性 id 是随机id 15 | id: '@id', 16 | // 属性 title 是一个随机长度的标题 17 | title: '@title()', 18 | // 属性 paragraph 是一个随机长度的段落 19 | paragraph: '@cparagraph', 20 | // 属性 image 是一个随机图片 参数分别为size, background, text 21 | image: "@image('200x100', '#4A7BF7', 'Hello')", 22 | // 属性 address 是一个随机地址 23 | address: '@county(true)', 24 | // 属性 date 是一个yyyy-MM-dd 的随机日期 25 | date: '@date("yyyy-MM-dd")', 26 | // 属性 date 是一个yyyy-MM-dd 的随机日期 27 | month: '', 28 | // 属性 time 是一个 size, background, text 的随机时间 29 | time: '@time("HH:mm:ss")', 30 | // 属性 url 是一个随机的url 31 | url: '@url', 32 | // 属性 email 是一个随机email 33 | work: '@email', 34 | // 属性 ip 是一个随机ip 35 | ip: '@ip', 36 | sum: '@ip', 37 | // 属性 regexp 是一个正则表达式匹配到的值 如aA1 38 | regexp: /[a-z][A-Z][0-9]/, 39 | name: '@name()', 40 | color: '@rgba()', 41 | }], 42 | }); 43 | 44 | Mock.mock('http://2.json', 'get', { 45 | 'list|20': [ 46 | '@range(1, 100, 9)', 47 | ], 48 | }); 49 | 50 | Mock.mock('http://3.json', 'get', { 51 | 'list|120': [{ 52 | // 属性 sid 是一个自增数,起始值为 1,每次增 1 53 | 'sid|+1': 1, 54 | // 属性 userId 是一个5位的随机码 55 | 'userId|5': '', 56 | // 属性 sex 是一个bool值 57 | 'sex|1-2': true, 58 | // 属性 guid 是唯一机器码 59 | guid: '@guid', 60 | // 属性 id 是随机id 61 | id: '@id', 62 | // 属性 title 是一个随机长度的标题 63 | title: '@title()', 64 | // 属性 paragraph 是一个随机长度的段落 65 | paragraph: '@cparagraph', 66 | // 属性 image 是一个随机图片 参数分别为size, background, text 67 | image: "@image('200x100', '#4A7BF7', 'Hello')", 68 | // 属性 address 是一个随机地址 69 | address: '@county(true)', 70 | // 属性 date 是一个yyyy-MM-dd 的随机日期 71 | date: '@date("yyyy-MM-dd")', 72 | // 属性 date 是一个yyyy-MM-dd 的随机日期 73 | month: '', 74 | // 属性 time 是一个 size, background, text 的随机时间 75 | time: '@time("HH:mm:ss")', 76 | // 属性 url 是一个随机的url 77 | url: '@url', 78 | // 属性 email 是一个随机email 79 | email: '@email', 80 | // 属性 ip 是一个随机ip 81 | ip: '@ip', 82 | // 属性 regexp 是一个正则表达式匹配到的值 如aA1 83 | regexp: /[a-z][A-Z][0-9]/, 84 | }], 85 | }); 86 | 87 | Mock.mock('http://4.json', 'get', { 88 | 'list|200': [{ 89 | // 属性 sid 是一个自增数,起始值为 1,每次增 1 90 | 'sid|+1': 1, 91 | // 属性 userId 是一个5位的随机码 92 | 'userId|5': '', 93 | // 属性 sex 是一个bool值 94 | 'sex|1-2': true, 95 | // 属性 guid 是唯一机器码 96 | guid: '@guid', 97 | // 属性 id 是随机id 98 | id: '@id', 99 | // 属性 title 是一个随机长度的标题 100 | title: '@title()', 101 | // 属性 paragraph 是一个随机长度的段落 102 | paragraph: '@cparagraph', 103 | // 属性 image 是一个随机图片 参数分别为size, background, text 104 | image: "@image('200x100', '#4A7BF7', 'Hello')", 105 | // 属性 address 是一个随机地址 106 | address: '@county(true)', 107 | // 属性 date 是一个yyyy-MM-dd 的随机日期 108 | date: '@date("yyyy-MM-dd")', 109 | // 属性 date 是一个yyyy-MM-dd 的随机日期 110 | month: '', 111 | // 属性 time 是一个 size, background, text 的随机时间 112 | time: '@time("HH:mm:ss")', 113 | // 属性 url 是一个随机的url 114 | url: '@url', 115 | // 属性 email 是一个随机email 116 | email: '@email', 117 | // 属性 ip 是一个随机ip 118 | ip: '@ip', 119 | // 属性 regexp 是一个正则表达式匹配到的值 如aA1 120 | regexp: /[a-z][A-Z][0-9]/, 121 | }], 122 | }); 123 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-willtable", 3 | "version": "2.2.8", 4 | "description": "An editable table component for Vue", 5 | "author": { 6 | "name": "WillWu", 7 | "email": "innovation55@foxmail.com", 8 | "url": "https://www.willwuwei.com" 9 | }, 10 | "private": false, 11 | "main": "dist/vue-willtable.min.js", 12 | "license": "MIT", 13 | "repository": { 14 | "type": "git", 15 | "url": "https://github.com/KevinMint55/vue-willtable.git" 16 | }, 17 | "keywords": [ 18 | "vue-willtable", 19 | "vue editable table", 20 | "vue component", 21 | "vue" 22 | ], 23 | "scripts": { 24 | "start": "npm run dev", 25 | "dev": "node build/devServer.js", 26 | "build": "node build/build.js", 27 | "release": "node build/release.js", 28 | "lint": "eslint --ext .js,.vue src example --fix" 29 | }, 30 | "peerDependencies": { 31 | "element-ui": "^2.12.0", 32 | "vue": "^2.6.10" 33 | }, 34 | "devDependencies": { 35 | "@babel/core": "^7.6.4", 36 | "@babel/plugin-proposal-class-properties": "^7.5.5", 37 | "@babel/plugin-syntax-dynamic-import": "^7.2.0", 38 | "@babel/preset-env": "^7.6.3", 39 | "autoprefixer": "^9.6.5", 40 | "axios": "^0.19.0", 41 | "babel-eslint": "^10.0.3", 42 | "babel-loader": "^8.0.6", 43 | "babel-plugin-component": "^1.1.1", 44 | "babel-polyfill": "^6.26.0", 45 | "babel-preset-env": "^1.7.0", 46 | "better-webpack-progress": "^1.1.0", 47 | "chalk": "^2.4.2", 48 | "clean-webpack-plugin": "^3.0.0", 49 | "css-loader": "^3.2.0", 50 | "element-ui": "^2.12.0", 51 | "eslint": "^6.5.1", 52 | "eslint-config-airbnb-base": "^14.0.0", 53 | "eslint-friendly-formatter": "^4.0.1", 54 | "eslint-import-resolver-webpack": "^0.11.1", 55 | "eslint-loader": "^3.0.2", 56 | "eslint-plugin-import": "^2.18.2", 57 | "eslint-plugin-vue": "^5.2.3", 58 | "file-loader": "^4.2.0", 59 | "friendly-errors-webpack-plugin": "^1.7.0", 60 | "html-webpack-plugin": "^3.2.0", 61 | "mini-css-extract-plugin": "^0.8.0", 62 | "mockjs": "^1.0.1-beta3", 63 | "node-sass": "^4.12.0", 64 | "optimize-css-assets-webpack-plugin": "^5.0.3", 65 | "ora": "^4.0.2", 66 | "postcss-import": "^12.0.1", 67 | "postcss-loader": "^3.0.0", 68 | "sass-loader": "^8.0.0", 69 | "style-loader": "^1.0.0", 70 | "stylelint": "^11.1.1", 71 | "stylelint-config-standard": "^19.0.0", 72 | "stylelint-processor-html": "^1.0.0", 73 | "stylelint-webpack-plugin": "^1.0.2", 74 | "uglifyjs-webpack-plugin": "^2.2.0", 75 | "url-loader": "^2.2.0", 76 | "vue": "^2.6.10", 77 | "vue-loader": "^15.7.1", 78 | "vue-style-loader": "^4.1.2", 79 | "vue-template-compiler": "^2.6.10", 80 | "webpack": "^4.41.2", 81 | "webpack-bundle-analyzer": "^3.5.2", 82 | "webpack-cli": "^3.3.9", 83 | "webpack-dev-server": "^3.8.2", 84 | "webpack-merge": "^4.2.2" 85 | }, 86 | "engines": { 87 | "node": ">= 10.13.0", 88 | "npm": ">= 6.4.1" 89 | }, 90 | "browserslist": [ 91 | "> 1%", 92 | "last 2 versions", 93 | "not ie <= 9" 94 | ] 95 | } 96 | -------------------------------------------------------------------------------- /src/assets/ascending.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinMint55/vue-willtable/893cf0d363a8a37d5aacb51170b0060e23b2c525/src/assets/ascending.png -------------------------------------------------------------------------------- /src/assets/date.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinMint55/vue-willtable/893cf0d363a8a37d5aacb51170b0060e23b2c525/src/assets/date.png -------------------------------------------------------------------------------- /src/assets/descending.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinMint55/vue-willtable/893cf0d363a8a37d5aacb51170b0060e23b2c525/src/assets/descending.png -------------------------------------------------------------------------------- /src/assets/dropdown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinMint55/vue-willtable/893cf0d363a8a37d5aacb51170b0060e23b2c525/src/assets/dropdown.png -------------------------------------------------------------------------------- /src/assets/number.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinMint55/vue-willtable/893cf0d363a8a37d5aacb51170b0060e23b2c525/src/assets/number.png -------------------------------------------------------------------------------- /src/assets/select.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinMint55/vue-willtable/893cf0d363a8a37d5aacb51170b0060e23b2c525/src/assets/select.png -------------------------------------------------------------------------------- /src/assets/text.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinMint55/vue-willtable/893cf0d363a8a37d5aacb51170b0060e23b2c525/src/assets/text.png -------------------------------------------------------------------------------- /src/components/Table.vue: -------------------------------------------------------------------------------- 1 | 106 | 107 | 778 | 779 | 816 | -------------------------------------------------------------------------------- /src/components/TableBody.vue: -------------------------------------------------------------------------------- 1 | 69 | 70 | 201 | 202 | 313 | -------------------------------------------------------------------------------- /src/components/TableDropdown.vue: -------------------------------------------------------------------------------- 1 | 36 | 37 | 130 | 131 | 242 | -------------------------------------------------------------------------------- /src/components/TableEditor.vue: -------------------------------------------------------------------------------- 1 | 92 | 93 | 251 | 252 | 314 | -------------------------------------------------------------------------------- /src/components/TableHeader.vue: -------------------------------------------------------------------------------- 1 | 64 | 65 | 185 | 186 | 282 | -------------------------------------------------------------------------------- /src/components/TableScroll.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 105 | 106 | 141 | -------------------------------------------------------------------------------- /src/directives/clickoutside.js: -------------------------------------------------------------------------------- 1 | export default { 2 | bind(el, binding) { 3 | const documentHandler = (e) => { 4 | if (el.contains(e.target)) { 5 | return false; 6 | } 7 | if (binding.expression) { 8 | binding.value(e); 9 | } 10 | }; 11 | el.__vueClickOutside__ = documentHandler; 12 | document.addEventListener('click', documentHandler); 13 | }, 14 | update() { 15 | 16 | }, 17 | unbind(el) { 18 | document.removeEventListener('click', el.__vueClickOutside__); 19 | delete el.__vueClickOutside__; 20 | }, 21 | }; 22 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import VueWilltable from './components/Table.vue'; 2 | 3 | const install = (Vue) => { 4 | Vue.component(VueWilltable.name, VueWilltable); 5 | }; 6 | 7 | /* 支持使用标签的方式引入 */ 8 | if (typeof window !== 'undefined' && window.Vue) { 9 | install(window.Vue); 10 | } 11 | 12 | export { 13 | install, 14 | VueWilltable, 15 | }; 16 | 17 | export default VueWilltable; 18 | -------------------------------------------------------------------------------- /src/mixins/events.js: -------------------------------------------------------------------------------- 1 | export default { 2 | methods: { 3 | selectionChange() { 4 | const { states } = this.store; 5 | const selection = this.store.states.showData.filter((item, index) => states.dataStatusList[index].checked); 6 | this.$emit('selection-change', selection); 7 | if (states.dataStatusList.every((item) => item.checked)) { 8 | this.$refs.theader.checkedAll = true; 9 | this.$refs.fixedTheader.checkedAll = true; 10 | } else { 11 | this.$refs.theader.checkedAll = false; 12 | this.$refs.fixedTheader.checkedAll = false; 13 | } 14 | }, 15 | }, 16 | }; 17 | -------------------------------------------------------------------------------- /src/mixins/methods.js: -------------------------------------------------------------------------------- 1 | export default { 2 | methods: { 3 | getData() { 4 | return this.data; 5 | }, 6 | setData(data) { 7 | this.data = data; 8 | this.$nextTick(() => { 9 | this.initData(); 10 | this.store.handleFilters(); 11 | this.store.handleChangeData(); 12 | this.store.handleErrors(); 13 | }); 14 | }, 15 | setCellData(rowIndex, columnIndex, value) { 16 | const { states } = this.store; 17 | this.data[rowIndex][states.columns[columnIndex].key] = value; 18 | this.$nextTick(() => { 19 | this.store.handleFilters(); 20 | }); 21 | }, 22 | getChangeData() { 23 | return this.store.states.changeData; 24 | }, 25 | getErrorRows() { 26 | const { states } = this.store; 27 | const errorRowsIndex = states.dataStatusList.map((item, index) => { 28 | if (item.errors.length > 0) { 29 | return index; 30 | } 31 | return null; 32 | }); 33 | const errorRows = this.data.map((d, index) => { 34 | if (errorRowsIndex.includes(index)) { 35 | return { 36 | data: d, 37 | index, 38 | }; 39 | } 40 | return null; 41 | }).filter((i) => i); 42 | return errorRows; 43 | }, 44 | addItem(item) { 45 | const { states } = this.store; 46 | this.data.push(item); 47 | states.dataStatusList.push({ 48 | checked: false, 49 | errors: [], 50 | }); 51 | states.initialData.push(item); 52 | }, 53 | addRow(rowIndex, copyRow, customData) { 54 | this.store.addRow(rowIndex, copyRow, customData); 55 | }, 56 | removeItems(key, values) { 57 | const { states } = this.store; 58 | if (key && values instanceof Array) { 59 | values.forEach((value) => { 60 | const dIndex = this.data.findIndex((d) => d[key] === value); 61 | states.dataStatusList.splice(dIndex, 1); 62 | states.initialData.splice(dIndex, 1); 63 | this.data.splice(dIndex, 1); 64 | }); 65 | } 66 | }, 67 | fullscreen() { 68 | if (this.$refs.willtable.requestFullscreen) { 69 | this.$refs.willtable.requestFullscreen(); 70 | } else if (this.$refs.willtable.webkitRequestFullScreen) { 71 | this.$refs.willtable.webkitRequestFullScreen(); 72 | } else if (this.$refs.willtable.mozRequestFullScreen) { 73 | this.$refs.willtable.mozRequestFullScreen(); 74 | } else if (this.$refs.willtable.msRequestFullscreen) { 75 | this.$refs.willtable.msRequestFullscreen(); 76 | } 77 | }, 78 | exitFullscreen() { 79 | if (document.exitFullscreen) { 80 | document.exitFullscreen(); 81 | } else if (document.webkitCancelFullScreen) { 82 | document.webkitCancelFullScreen(); 83 | } else if (document.mozCancelFullScreen) { 84 | document.mozCancelFullScreen(); 85 | } else if (document.msExitFullscreen) { 86 | document.msExitFullscreen(); 87 | } 88 | }, 89 | }, 90 | }; 91 | -------------------------------------------------------------------------------- /src/mixins/verify.js: -------------------------------------------------------------------------------- 1 | const verifyDate = (value) => { 2 | const result = value.match(/^(\d{1,4})(-|\/)(\d{1,2})\2(\d{1,2})$/); 3 | if (result == null) { 4 | return false; 5 | } 6 | const d = new Date(result[1], result[3] - 1, result[4]); 7 | if (d.getFullYear() === Number(result[1]) && d.getMonth() + 1 === Number(result[3]) && d.getDate() === Number(result[4])) { 8 | return true; 9 | } 10 | return false; 11 | }; 12 | 13 | const verifyMonth = (value) => { 14 | const result = value.match(/^(\d{1,4})(-|\/)(\d{1,2})$/); 15 | if (result == null) { 16 | return false; 17 | } 18 | const d = new Date(result[1], result[3] - 1); 19 | if (d.getFullYear() === Number(result[1]) && d.getMonth() + 1 === Number(result[3])) { 20 | return true; 21 | } 22 | return false; 23 | }; 24 | 25 | const verifySelect = (value, options) => { 26 | const arr = options.map((item) => item.value); 27 | if (arr.includes(value)) { 28 | return true; 29 | } 30 | return false; 31 | }; 32 | 33 | const verifyNumber = (value) => { 34 | if (isNaN(value)) { 35 | return false; 36 | } 37 | return true; 38 | }; 39 | 40 | export { 41 | verifyDate, 42 | verifyMonth, 43 | verifySelect, 44 | verifyNumber, 45 | }; 46 | -------------------------------------------------------------------------------- /src/store/index.js: -------------------------------------------------------------------------------- 1 | import { 2 | verifyDate, 3 | verifyMonth, 4 | verifySelect, 5 | verifyNumber, 6 | } from '../mixins/verify'; 7 | 8 | class TableStore { 9 | constructor() { 10 | this.states = { 11 | tableWidth: null, 12 | tableHeight: null, 13 | mainWidth: null, 14 | mainHeight: null, 15 | rowHeight: 28, 16 | theaderHeight: 30, 17 | scrollBarWidth: 8, 18 | tableBodyLeft: 0, 19 | tableBodyTop: 0, 20 | columns: [], 21 | data: [], 22 | showData: [], 23 | domData: [], 24 | initialData: null, 25 | changeData: [], 26 | dataStatusList: [], 27 | columnsStatusList: [], 28 | 29 | // editor 30 | editor: { 31 | editorRange: {}, 32 | editorXIndex: 0, 33 | editorYIndex: 0, 34 | curEditorCoverValue: '', 35 | editorShow: false, 36 | editorIsFixed: false, 37 | editing: false, 38 | editType: 'text', 39 | options: [], 40 | curEditorWidth: 80, 41 | }, 42 | 43 | // autofill 44 | autofill: { 45 | autofillXIndex: 0, 46 | autofillYIndex: 0, 47 | isAutofill: false, 48 | autofillYArr: [], 49 | }, 50 | 51 | // selection area 52 | selector: { 53 | isSelected: false, 54 | selectedXIndex: 0, 55 | selectedYIndex: 0, 56 | selectedXArr: [], 57 | selectedYArr: [], 58 | }, 59 | 60 | filters: {}, 61 | 62 | dropdown: { 63 | index: null, 64 | list: {}, 65 | key: '', 66 | sort: '', 67 | }, 68 | 69 | isMac: false, 70 | 71 | adjustLineLeft: 0, 72 | adjustLineShow: false, 73 | 74 | // history data 75 | historyData: [], 76 | curHisory: 0, 77 | isOperation: false, 78 | 79 | // custom scrollbars 80 | scrollbar: { 81 | posX: 0, 82 | posY: 0, 83 | xWidth: 0, 84 | yHeight: 0, 85 | }, 86 | 87 | visibleRowStartIndex: 0, 88 | visibleRowEndIndex: 0, 89 | }; 90 | } 91 | 92 | calcDomData() { 93 | const { states } = this; 94 | states.visibleRowStartIndex = Math.floor(states.tableBodyTop / states.rowHeight); 95 | states.visibleRowEndIndex = states.visibleRowStartIndex + Math.ceil(states.mainHeight / states.rowHeight); 96 | states.domData = states.showData.slice(states.visibleRowStartIndex, states.visibleRowEndIndex + 1); 97 | } 98 | 99 | initScrollBarLength() { 100 | const { states } = this; 101 | const barWidth = states.mainWidth / states.tableWidth * states.mainWidth; 102 | if (barWidth > states.mainWidth) { 103 | states.scrollbar.xWidth = 0; 104 | } else if (barWidth <= 20) { 105 | states.scrollbar.xWidth = 20; 106 | } else { 107 | states.scrollbar.xWidth = barWidth; 108 | } 109 | const barHeight = states.mainHeight / states.tableHeight * states.mainHeight; 110 | if (barHeight > states.mainHeight) { 111 | states.scrollbar.yHeight = 0; 112 | } else if (barHeight <= 20) { 113 | states.scrollbar.yHeight = 20; 114 | } else { 115 | states.scrollbar.yHeight = barHeight; 116 | } 117 | } 118 | 119 | setScrollStatus(tableBodyTop, tableBodyLeft) { 120 | const { states } = this; 121 | if (tableBodyTop <= 0) { 122 | states.tableBodyTop = 0; 123 | } else if (tableBodyTop > states.tableHeight - states.mainHeight) { 124 | states.tableBodyTop = states.tableHeight - states.mainHeight; 125 | } else { 126 | states.tableBodyTop = tableBodyTop; 127 | } 128 | if (tableBodyLeft <= 0) { 129 | states.tableBodyLeft = 0; 130 | } else if (tableBodyLeft > states.tableWidth - states.mainWidth) { 131 | states.tableBodyLeft = states.tableWidth - states.mainWidth; 132 | } else { 133 | states.tableBodyLeft = tableBodyLeft; 134 | } 135 | states.scrollbar.posX = states.tableBodyLeft / (states.tableWidth - states.mainWidth) * (states.mainWidth - states.scrollbar.xWidth); 136 | states.scrollbar.posY = states.tableBodyTop / (states.tableHeight - states.mainHeight) * (states.mainHeight - states.scrollbar.yHeight); 137 | } 138 | 139 | handleIsMac() { 140 | if (/macintosh|mac os x/i.test(navigator.userAgent)) { 141 | this.states.isMac = true; 142 | } 143 | } 144 | 145 | // editor 146 | getEditorContent(editContent) { 147 | const { states } = this; 148 | states.showData[states.editor.editorYIndex][states.columns[states.editor.editorXIndex].key] = editContent; 149 | } 150 | 151 | resetEditor() { 152 | const { states } = this; 153 | states.editor.editing = false; 154 | states.editor.editType = 'text'; 155 | } 156 | 157 | // autofill 158 | handleAutofill() { 159 | const { states } = this; 160 | states.autofill.isAutofill = true; 161 | window.addEventListener('mouseup', this.autofillUp.bind(this)); 162 | } 163 | 164 | autofillUp() { 165 | const { states } = this; 166 | if (states.autofill.autofillYArr[1] > states.selector.selectedYArr[1]) { 167 | for (let i = 0; i <= states.autofill.autofillYArr[1] - states.autofill.autofillYArr[0]; i += 1) { 168 | for (let j = 0; j <= states.selector.selectedXArr[1] - states.selector.selectedXArr[0]; j += 1) { 169 | if (!states.columns[j + states.selector.selectedXArr[0]].disabled) { 170 | states.showData[i + states.autofill.autofillYArr[0]][states.columns[j + states.selector.selectedXArr[0]].key] = states.showData[states.selector.selectedYArr[1]][states.columns[j + states.selector.selectedXArr[0]].key]; 171 | } 172 | } 173 | } 174 | states.selector.selectedYArr.splice(1, 1, states.autofill.autofillYArr[1]); 175 | const autofillYIndex = states.autofill.autofillYArr[1]; 176 | states.autofill.autofillYIndex = autofillYIndex; 177 | } 178 | if (states.autofill.autofillYArr[0] < states.selector.selectedYArr[0]) { 179 | for (let i = 0; i <= states.autofill.autofillYArr[1] - states.autofill.autofillYArr[0]; i += 1) { 180 | for (let j = 0; j <= states.selector.selectedXArr[1] - states.selector.selectedXArr[0]; j += 1) { 181 | if (!states.columns[j + states.selector.selectedXArr[0]].disabled) { 182 | states.showData[i + states.autofill.autofillYArr[0]][states.columns[j + states.selector.selectedXArr[0]].key] = states.showData[states.selector.selectedYArr[0]][states.columns[j + states.selector.selectedXArr[0]].key]; 183 | } 184 | } 185 | } 186 | states.selector.selectedYArr.splice(0, 1, states.autofill.autofillYArr[0]); 187 | } 188 | setTimeout(() => { 189 | states.autofill.autofillYArr = []; 190 | states.autofill.isAutofill = false; 191 | }, 0); 192 | } 193 | 194 | // selector 195 | multiSelect(e, x, y, columnType) { 196 | const { states } = this; 197 | if (columnType === 'selection') return; 198 | if (states.selector.isSelected) { 199 | setTimeout(() => { 200 | states.autofill.autofillXIndex = x > states.editor.editorXIndex ? x : states.editor.editorXIndex; 201 | states.autofill.autofillYIndex = y > states.editor.editorYIndex ? y : states.editor.editorYIndex; 202 | states.selector.selectedXIndex = x; 203 | states.selector.selectedYIndex = y; 204 | if (states.selector.selectedXIndex > states.editor.editorXIndex) { 205 | states.selector.selectedXArr.splice(0, 1, states.editor.editorXIndex); 206 | states.selector.selectedXArr.splice(1, 1, states.selector.selectedXIndex); 207 | } else { 208 | states.selector.selectedXArr.splice(0, 1, states.selector.selectedXIndex); 209 | states.selector.selectedXArr.splice(1, 1, states.editor.editorXIndex); 210 | } 211 | if (states.selector.selectedYIndex > states.editor.editorYIndex) { 212 | states.selector.selectedYArr.splice(0, 1, states.editor.editorYIndex); 213 | states.selector.selectedYArr.splice(1, 1, states.selector.selectedYIndex); 214 | } else { 215 | states.selector.selectedYArr.splice(0, 1, states.selector.selectedYIndex); 216 | states.selector.selectedYArr.splice(1, 1, states.editor.editorYIndex); 217 | } 218 | }, 0); 219 | } 220 | if (states.autofill.isAutofill) { 221 | if (y > states.selector.selectedYArr[1]) { 222 | states.autofill.autofillYArr = [states.selector.selectedYArr[1] + 1, y]; 223 | } else if (y < states.selector.selectedYArr[0]) { 224 | states.autofill.autofillYArr = [y, states.selector.selectedYArr[0] - 1]; 225 | } else { 226 | states.autofill.autofillYArr = []; 227 | } 228 | } 229 | } 230 | 231 | openDropdown(i) { 232 | const { states } = this; 233 | if (typeof (i) === 'number') { 234 | if (states.dropdown.index === i) { 235 | states.dropdown.index = null; 236 | } else { 237 | states.dropdown.index = i; 238 | states.dropdown = JSON.parse(JSON.stringify({ 239 | ...states.columnsStatusList[states.dropdown.index], 240 | index: states.dropdown.index, 241 | })); 242 | } 243 | } else { 244 | states.dropdown.index = null; 245 | } 246 | } 247 | 248 | selectAllCells() { 249 | const { states } = this; 250 | states.selector.selectedXIndex = states.editor.editorRange.minX; 251 | states.selector.selectedYIndex = states.editor.editorRange.minY; 252 | states.selector.selectedXArr = [states.editor.editorRange.minX, states.editor.editorRange.maxX]; 253 | states.selector.selectedYArr = [states.editor.editorRange.minY, states.editor.editorRange.maxY]; 254 | } 255 | 256 | handleFilters() { 257 | const { states } = this; 258 | states.columnsStatusList.forEach((th) => { 259 | if (th.type === 'selection') return; 260 | if (th.list) { 261 | Object.keys(th.list).forEach((item) => { 262 | th.list[item].count = 0; 263 | }); 264 | } else { 265 | th.list = {}; 266 | } 267 | states.data.forEach((td) => { 268 | if (td[th.key]) { 269 | if (th.list[td[th.key]]) { 270 | th.list[td[th.key]].count += 1; 271 | } else { 272 | th.list[td[th.key]] = {}; 273 | th.list[td[th.key]].count = 1; 274 | } 275 | } 276 | }); 277 | Object.keys(th.list).forEach((item) => { 278 | if (th.list[item].count === 0) { 279 | delete th.list[item]; 280 | } 281 | }); 282 | }); 283 | } 284 | 285 | // handle error data 286 | handleErrors() { 287 | const { states } = this; 288 | setTimeout(() => { 289 | states.dataStatusList.forEach((item, yIndex) => { 290 | states.columns.forEach((column) => { 291 | if (this.verify(column, states.data[yIndex][column.key])) { 292 | if (item.errors.includes(column.key)) { 293 | item.errors.splice(item.errors.indexOf(column.key), 1); 294 | } 295 | } else { 296 | if (!item.errors.includes(column.key)) { 297 | item.errors.push(column.key); 298 | } 299 | } 300 | }); 301 | }); 302 | }, 0); 303 | } 304 | 305 | verify(column, value) { 306 | if (!value || column.noVerify) { 307 | return true; 308 | } 309 | let correct; 310 | if (column.validate) { 311 | correct = column.validate(value); 312 | } else { 313 | switch (column.type) { 314 | case 'date': 315 | correct = verifyDate(value); 316 | break; 317 | case 'month': 318 | correct = verifyMonth(value); 319 | break; 320 | case 'select': 321 | correct = verifySelect(value, column.options); 322 | break; 323 | case 'number': 324 | correct = verifyNumber(value); 325 | break; 326 | default: 327 | correct = true; 328 | } 329 | } 330 | return correct; 331 | } 332 | 333 | sort(type) { 334 | const { states } = this; 335 | states.columnsStatusList.forEach((item) => { 336 | item.sort = ''; 337 | }); 338 | states.columnsStatusList[states.dropdown.index].sort = type; 339 | if (type === 'ascending') { 340 | states.showData.sort((x, y) => (x[states.columnsStatusList[states.dropdown.index].key] > y[states.columnsStatusList[states.dropdown.index].key] ? 1 : -1)); 341 | } else { 342 | states.showData.sort((x, y) => (x[states.columnsStatusList[states.dropdown.index].key] > y[states.columnsStatusList[states.dropdown.index].key] ? -1 : 1)); 343 | } 344 | states.dropdown.index = null; 345 | } 346 | 347 | // filter 348 | handleFilter() { 349 | const { states } = this; 350 | states.columnsStatusList[states.dropdown.index] = { 351 | list: states.dropdown.list, 352 | key: states.dropdown.key, 353 | sort: states.dropdown.sort, 354 | }; 355 | const arr = []; 356 | Object.keys(states.dropdown.list).forEach((key) => { 357 | if (states.dropdown.list[key].checked) { 358 | arr.push(key); 359 | } 360 | }); 361 | states.filters[states.columnsStatusList[states.dropdown.index].key] = arr; 362 | this.filterData(); 363 | } 364 | 365 | resetFilter() { 366 | const { states } = this; 367 | delete states.filters[states.columnsStatusList[states.dropdown.index].key]; 368 | Object.keys(states.columnsStatusList[states.dropdown.index].list).forEach((key) => { 369 | states.columnsStatusList[states.dropdown.index].list[key].checked = false; 370 | }); 371 | this.filterData(); 372 | } 373 | 374 | filterData() { 375 | const { states } = this; 376 | states.showData = states.data; 377 | Object.keys(states.filters).forEach((key) => { 378 | states.showData = states.showData.filter((item) => states.filters[key].includes(item[key].toString())); 379 | }); 380 | states.dropdown.index = null; 381 | } 382 | 383 | handleChangeData() { 384 | const { states } = this; 385 | const data = JSON.parse(JSON.stringify(states.data)); 386 | const initialData = JSON.parse(JSON.stringify(states.initialData)); 387 | states.changeData = data.filter((item, index) => JSON.stringify(item) !== JSON.stringify(initialData[index])); 388 | } 389 | 390 | // undo and recovery 391 | operation(type) { 392 | const { states } = this; 393 | if (!states.editor.editing) { 394 | if (type === 'undo' && states.curHisory > 1) { 395 | states.curHisory -= 1; 396 | } 397 | if (type === 'recovery' && states.curHisory < states.historyData.length) { 398 | states.curHisory += 1; 399 | } 400 | states.isOperation = true; 401 | JSON.parse(states.historyData[states.curHisory - 1]).forEach((i, index) => { 402 | Object.keys(i).forEach((j) => { 403 | states.data[index][j] = i[j]; 404 | }); 405 | }); 406 | setTimeout(() => { 407 | states.isOperation = false; 408 | }, 0); 409 | } 410 | } 411 | 412 | // delete the selected data 413 | clearSelected(disabledCell) { 414 | const { states } = this; 415 | for (let i = 0; i <= states.selector.selectedYArr[1] - states.selector.selectedYArr[0]; i += 1) { 416 | for (let j = 0; j <= states.selector.selectedXArr[1] - states.selector.selectedXArr[0]; j += 1) { 417 | if (!states.columns[j + states.selector.selectedXArr[0]].disabled && !disabledCell({ 418 | row: states.showData[i + states.selector.selectedYArr[0]], column: states.columns[j + states.selector.selectedXArr[0]], rowIndex: i + states.selector.selectedYArr[0], columnIndex: j + states.selector.selectedXArr[0], 419 | })) { 420 | states.showData[i + states.selector.selectedYArr[0]][states.columns[j + states.selector.selectedXArr[0]].key] = ''; 421 | } 422 | } 423 | } 424 | } 425 | 426 | // add row 427 | addRow(rowIndex, copyRow, customData) { 428 | const { states } = this; 429 | let data = {}; 430 | states.columns.forEach((column) => { 431 | if (column.key) { 432 | if (copyRow && rowIndex > 0) { 433 | data[column.key] = states.data[rowIndex - 1][column.key]; 434 | } else { 435 | data[column.key] = ''; 436 | } 437 | } 438 | }); 439 | if (customData) { 440 | data = { 441 | ...data, 442 | ...customData, 443 | }; 444 | } 445 | states.initialData.splice(rowIndex, 0, {}); 446 | states.data.splice(rowIndex, 0, data); 447 | states.dataStatusList.splice(rowIndex, 0, { 448 | checked: false, 449 | errors: [], 450 | }); 451 | } 452 | } 453 | 454 | export default TableStore; 455 | -------------------------------------------------------------------------------- /src/style/reset.scss: -------------------------------------------------------------------------------- 1 | @import './transition'; 2 | body, 3 | ul, 4 | ol, 5 | li, 6 | h1, 7 | h2, 8 | h3, 9 | h4, 10 | h5, 11 | h6, 12 | form, 13 | fieldset, 14 | table, 15 | td, 16 | img, 17 | div, 18 | dl, 19 | dt, 20 | dd, 21 | input, 22 | p, 23 | a, 24 | section, 25 | figure, 26 | figcaption, 27 | hgroup, 28 | pre, 29 | i, 30 | header { 31 | padding: 0; 32 | margin: 0; 33 | box-sizing: border-box; 34 | word-break: break-all; 35 | } 36 | 37 | ul, 38 | ol { 39 | list-style: none; 40 | } 41 | 42 | a { 43 | color: inherit; 44 | -webkit-tap-highlight-color: transparent; 45 | text-decoration: none !important; 46 | } 47 | 48 | input, 49 | button { 50 | border: none; 51 | outline: none; 52 | } 53 | 54 | button { 55 | user-select: none; 56 | } 57 | 58 | i { 59 | font-style: normal; 60 | } 61 | 62 | .ellipsis { 63 | overflow: hidden; 64 | text-overflow: ellipsis; 65 | white-space: nowrap; 66 | } -------------------------------------------------------------------------------- /src/style/transition.scss: -------------------------------------------------------------------------------- 1 | //淡入淡出过渡 2 | .fade-enter-active { 3 | transition: all .3s linear; 4 | } 5 | 6 | .fade-leave-active { 7 | opacity: 0; 8 | transition: all .3s linear; 9 | } 10 | 11 | .fade-enter { 12 | opacity: 0; 13 | } 14 | --------------------------------------------------------------------------------