@ -0,0 +1,14 @@ |
|||||
|
# https://editorconfig.org |
||||
|
root = true |
||||
|
|
||||
|
[*] |
||||
|
charset = utf-8 |
||||
|
indent_style = space |
||||
|
indent_size = 2 |
||||
|
end_of_line = lf |
||||
|
insert_final_newline = true |
||||
|
trim_trailing_whitespace = true |
||||
|
|
||||
|
[*.md] |
||||
|
insert_final_newline = false |
||||
|
trim_trailing_whitespace = false |
@ -0,0 +1,8 @@ |
|||||
|
# just a flag |
||||
|
ENV = 'development' |
||||
|
|
||||
|
# base api |
||||
|
#VUE_APP_BASE_API = '/dev-api' |
||||
|
VUE_APP_BASE_API = '/base' |
||||
|
VUE_APP_USER_API = '/user' |
||||
|
VUE_APP_PRINT_API='http://dev.cd-top.com:9097' |
@ -0,0 +1,14 @@ |
|||||
|
# just a flag |
||||
|
ENV = 'production' |
||||
|
|
||||
|
# base api |
||||
|
#VUE_APP_BASE_API = '/prod-api' |
||||
|
VUE_APP_BASE_API = '/base' |
||||
|
VUE_APP_USER_API = '/user' |
||||
|
VUE_APP_PRINT_API='http://dev.cd-top.com:9097' |
||||
|
# 杭州 |
||||
|
#VUE_APP_PRINT_API='http://10.74.150.81:9082' |
||||
|
# 天津 |
||||
|
#VUE_APP_PRINT_API='http://10.74.160.70:9082' |
||||
|
|
||||
|
|
@ -0,0 +1,8 @@ |
|||||
|
NODE_ENV = production |
||||
|
|
||||
|
# just a flag |
||||
|
ENV = 'staging' |
||||
|
|
||||
|
# base api |
||||
|
VUE_APP_BASE_API = '/stage-api' |
||||
|
|
@ -0,0 +1,5 @@ |
|||||
|
# build/*.js |
||||
|
# src/assets |
||||
|
# public |
||||
|
# dist |
||||
|
* |
@ -0,0 +1,198 @@ |
|||||
|
module.exports = { |
||||
|
root: true, |
||||
|
parserOptions: { |
||||
|
parser: 'babel-eslint', |
||||
|
sourceType: 'module' |
||||
|
}, |
||||
|
env: { |
||||
|
browser: true, |
||||
|
node: true, |
||||
|
es6: true, |
||||
|
}, |
||||
|
extends: ['plugin:vue/recommended', 'eslint:recommended'], |
||||
|
|
||||
|
// add your custom rules here
|
||||
|
//it is base on https://github.com/vuejs/eslint-config-vue
|
||||
|
rules: { |
||||
|
"vue/max-attributes-per-line": [2, { |
||||
|
"singleline": 10, |
||||
|
"multiline": { |
||||
|
"max": 1, |
||||
|
"allowFirstLine": false |
||||
|
} |
||||
|
}], |
||||
|
"vue/singleline-html-element-content-newline": "off", |
||||
|
"vue/multiline-html-element-content-newline":"off", |
||||
|
"vue/name-property-casing": ["error", "PascalCase"], |
||||
|
"vue/no-v-html": "off", |
||||
|
'accessor-pairs': 2, |
||||
|
'arrow-spacing': [2, { |
||||
|
'before': true, |
||||
|
'after': true |
||||
|
}], |
||||
|
'block-spacing': [2, 'always'], |
||||
|
'brace-style': [2, '1tbs', { |
||||
|
'allowSingleLine': true |
||||
|
}], |
||||
|
'camelcase': [0, { |
||||
|
'properties': 'always' |
||||
|
}], |
||||
|
'comma-dangle': [2, 'never'], |
||||
|
'comma-spacing': [2, { |
||||
|
'before': false, |
||||
|
'after': true |
||||
|
}], |
||||
|
'comma-style': [2, 'last'], |
||||
|
'constructor-super': 2, |
||||
|
'curly': [2, 'multi-line'], |
||||
|
'dot-location': [2, 'property'], |
||||
|
'eol-last': 2, |
||||
|
'eqeqeq': ["error", "always", {"null": "ignore"}], |
||||
|
'generator-star-spacing': [2, { |
||||
|
'before': true, |
||||
|
'after': true |
||||
|
}], |
||||
|
'handle-callback-err': [2, '^(err|error)$'], |
||||
|
'indent': [2, 2, { |
||||
|
'SwitchCase': 1 |
||||
|
}], |
||||
|
'jsx-quotes': [2, 'prefer-single'], |
||||
|
'key-spacing': [2, { |
||||
|
'beforeColon': false, |
||||
|
'afterColon': true |
||||
|
}], |
||||
|
'keyword-spacing': [2, { |
||||
|
'before': true, |
||||
|
'after': true |
||||
|
}], |
||||
|
'new-cap': [2, { |
||||
|
'newIsCap': true, |
||||
|
'capIsNew': false |
||||
|
}], |
||||
|
'new-parens': 2, |
||||
|
'no-array-constructor': 2, |
||||
|
'no-caller': 2, |
||||
|
'no-console': 'off', |
||||
|
'no-class-assign': 2, |
||||
|
'no-cond-assign': 2, |
||||
|
'no-const-assign': 2, |
||||
|
'no-control-regex': 0, |
||||
|
'no-delete-var': 2, |
||||
|
'no-dupe-args': 2, |
||||
|
'no-dupe-class-members': 2, |
||||
|
'no-dupe-keys': 2, |
||||
|
'no-duplicate-case': 2, |
||||
|
'no-empty-character-class': 2, |
||||
|
'no-empty-pattern': 2, |
||||
|
'no-eval': 2, |
||||
|
'no-ex-assign': 2, |
||||
|
'no-extend-native': 2, |
||||
|
'no-extra-bind': 2, |
||||
|
'no-extra-boolean-cast': 2, |
||||
|
'no-extra-parens': [2, 'functions'], |
||||
|
'no-fallthrough': 2, |
||||
|
'no-floating-decimal': 2, |
||||
|
'no-func-assign': 2, |
||||
|
'no-implied-eval': 2, |
||||
|
'no-inner-declarations': [2, 'functions'], |
||||
|
'no-invalid-regexp': 2, |
||||
|
'no-irregular-whitespace': 2, |
||||
|
'no-iterator': 2, |
||||
|
'no-label-var': 2, |
||||
|
'no-labels': [2, { |
||||
|
'allowLoop': false, |
||||
|
'allowSwitch': false |
||||
|
}], |
||||
|
'no-lone-blocks': 2, |
||||
|
'no-mixed-spaces-and-tabs': 2, |
||||
|
'no-multi-spaces': 2, |
||||
|
'no-multi-str': 2, |
||||
|
'no-multiple-empty-lines': [2, { |
||||
|
'max': 1 |
||||
|
}], |
||||
|
'no-native-reassign': 2, |
||||
|
'no-negated-in-lhs': 2, |
||||
|
'no-new-object': 2, |
||||
|
'no-new-require': 2, |
||||
|
'no-new-symbol': 2, |
||||
|
'no-new-wrappers': 2, |
||||
|
'no-obj-calls': 2, |
||||
|
'no-octal': 2, |
||||
|
'no-octal-escape': 2, |
||||
|
'no-path-concat': 2, |
||||
|
'no-proto': 2, |
||||
|
'no-redeclare': 2, |
||||
|
'no-regex-spaces': 2, |
||||
|
'no-return-assign': [2, 'except-parens'], |
||||
|
'no-self-assign': 2, |
||||
|
'no-self-compare': 2, |
||||
|
'no-sequences': 2, |
||||
|
'no-shadow-restricted-names': 2, |
||||
|
'no-spaced-func': 2, |
||||
|
'no-sparse-arrays': 2, |
||||
|
'no-this-before-super': 2, |
||||
|
'no-throw-literal': 2, |
||||
|
'no-trailing-spaces': 2, |
||||
|
'no-undef': 2, |
||||
|
'no-undef-init': 2, |
||||
|
'no-unexpected-multiline': 2, |
||||
|
'no-unmodified-loop-condition': 2, |
||||
|
'no-unneeded-ternary': [2, { |
||||
|
'defaultAssignment': false |
||||
|
}], |
||||
|
'no-unreachable': 2, |
||||
|
'no-unsafe-finally': 2, |
||||
|
'no-unused-vars': [2, { |
||||
|
'vars': 'all', |
||||
|
'args': 'none' |
||||
|
}], |
||||
|
'no-useless-call': 2, |
||||
|
'no-useless-computed-key': 2, |
||||
|
'no-useless-constructor': 2, |
||||
|
'no-useless-escape': 0, |
||||
|
'no-whitespace-before-property': 2, |
||||
|
'no-with': 2, |
||||
|
'one-var': [2, { |
||||
|
'initialized': 'never' |
||||
|
}], |
||||
|
'operator-linebreak': [2, 'after', { |
||||
|
'overrides': { |
||||
|
'?': 'before', |
||||
|
':': 'before' |
||||
|
} |
||||
|
}], |
||||
|
'padded-blocks': [2, 'never'], |
||||
|
'quotes': [2, 'single', { |
||||
|
'avoidEscape': true, |
||||
|
'allowTemplateLiterals': true |
||||
|
}], |
||||
|
'semi': [2, 'never'], |
||||
|
'semi-spacing': [2, { |
||||
|
'before': false, |
||||
|
'after': true |
||||
|
}], |
||||
|
'space-before-blocks': [2, 'always'], |
||||
|
'space-before-function-paren': [2, 'never'], |
||||
|
'space-in-parens': [2, 'never'], |
||||
|
'space-infix-ops': 2, |
||||
|
'space-unary-ops': [2, { |
||||
|
'words': true, |
||||
|
'nonwords': false |
||||
|
}], |
||||
|
'spaced-comment': [2, 'always', { |
||||
|
'markers': ['global', 'globals', 'eslint', 'eslint-disable', '*package', '!', ','] |
||||
|
}], |
||||
|
'template-curly-spacing': [2, 'never'], |
||||
|
'use-isnan': 2, |
||||
|
'valid-typeof': 2, |
||||
|
'wrap-iife': [2, 'any'], |
||||
|
'yield-star-spacing': [2, 'both'], |
||||
|
'yoda': [2, 'never'], |
||||
|
'prefer-const': 2, |
||||
|
'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0, |
||||
|
'object-curly-spacing': [2, 'always', { |
||||
|
objectsInObjects: false |
||||
|
}], |
||||
|
'array-bracket-spacing': [2, 'never'] |
||||
|
} |
||||
|
} |
@ -0,0 +1,116 @@ |
|||||
|
# Logs |
||||
|
logs |
||||
|
*.log |
||||
|
npm-debug.log* |
||||
|
yarn-debug.log* |
||||
|
yarn-error.log* |
||||
|
lerna-debug.log* |
||||
|
|
||||
|
# Diagnostic reports (https://nodejs.org/api/report.html) |
||||
|
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json |
||||
|
|
||||
|
# Runtime data |
||||
|
pids |
||||
|
*.pid |
||||
|
*.seed |
||||
|
*.pid.lock |
||||
|
|
||||
|
# Directory for instrumented libs generated by jscoverage/JSCover |
||||
|
lib-cov |
||||
|
|
||||
|
# Coverage directory used by tools like istanbul |
||||
|
coverage |
||||
|
*.lcov |
||||
|
|
||||
|
# nyc test coverage |
||||
|
.nyc_output |
||||
|
|
||||
|
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) |
||||
|
.grunt |
||||
|
|
||||
|
# Bower dependency directory (https://bower.io/) |
||||
|
bower_components |
||||
|
|
||||
|
# node-waf configuration |
||||
|
.lock-wscript |
||||
|
|
||||
|
# Compiled binary addons (https://nodejs.org/api/addons.html) |
||||
|
build/Release |
||||
|
|
||||
|
# Dependency directories |
||||
|
node_modules/ |
||||
|
jspm_packages/ |
||||
|
|
||||
|
# Snowpack dependency directory (https://snowpack.dev/) |
||||
|
web_modules/ |
||||
|
|
||||
|
# TypeScript cache |
||||
|
*.tsbuildinfo |
||||
|
|
||||
|
# Optional npm cache directory |
||||
|
.npm |
||||
|
|
||||
|
# Optional eslint cache |
||||
|
.eslintcache |
||||
|
|
||||
|
# Microbundle cache |
||||
|
.rpt2_cache/ |
||||
|
.rts2_cache_cjs/ |
||||
|
.rts2_cache_es/ |
||||
|
.rts2_cache_umd/ |
||||
|
|
||||
|
# Optional REPL history |
||||
|
.node_repl_history |
||||
|
|
||||
|
# Output of 'npm pack' |
||||
|
*.tgz |
||||
|
|
||||
|
# Yarn Integrity file |
||||
|
.yarn-integrity |
||||
|
|
||||
|
# dotenv environment variables file |
||||
|
.env |
||||
|
.env.test |
||||
|
|
||||
|
# parcel-bundler cache (https://parceljs.org/) |
||||
|
.cache |
||||
|
.parcel-cache |
||||
|
|
||||
|
# Next.js build output |
||||
|
.next |
||||
|
out |
||||
|
|
||||
|
# Nuxt.js build / generate output |
||||
|
.nuxt |
||||
|
dist |
||||
|
|
||||
|
# Gatsby files |
||||
|
.cache/ |
||||
|
# Comment in the public line in if your project uses Gatsby and not Next.js |
||||
|
# https://nextjs.org/blog/next-9-1#public-directory-support |
||||
|
# public |
||||
|
|
||||
|
# vuepress build output |
||||
|
.vuepress/dist |
||||
|
|
||||
|
# Serverless directories |
||||
|
.serverless/ |
||||
|
|
||||
|
# FuseBox cache |
||||
|
.fusebox/ |
||||
|
|
||||
|
# DynamoDB Local files |
||||
|
.dynamodb/ |
||||
|
|
||||
|
# TernJS port file |
||||
|
.tern-port |
||||
|
|
||||
|
# Stores VSCode versions used for testing VSCode extensions |
||||
|
.vscode-test |
||||
|
|
||||
|
# yarn v2 |
||||
|
|
||||
|
.yarn/cache |
||||
|
.yarn/unplugged |
||||
|
.yarn/build-state.yml |
||||
|
.pnp.* |
@ -0,0 +1 @@ |
|||||
|
registry=https://registry.npm.taobao.org/ |
@ -0,0 +1,5 @@ |
|||||
|
language: node_js |
||||
|
node_js: 10 |
||||
|
script: npm run test |
||||
|
notifications: |
||||
|
email: false |
@ -0,0 +1,21 @@ |
|||||
|
MIT License |
||||
|
|
||||
|
Copyright (c) 2017-present PanJiaChen |
||||
|
|
||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy |
||||
|
of this software and associated documentation files (the "Software"), to deal |
||||
|
in the Software without restriction, including without limitation the rights |
||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||
|
copies of the Software, and to permit persons to whom the Software is |
||||
|
furnished to do so, subject to the following conditions: |
||||
|
|
||||
|
The above copyright notice and this permission notice shall be included in all |
||||
|
copies or substantial portions of the Software. |
||||
|
|
||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
||||
|
SOFTWARE. |
@ -0,0 +1,126 @@ |
|||||
|
|
||||
|
## websocket: |
||||
|
|
||||
|
import { sendWebsocket, closeWebsocket } from '@/utils/websocket' |
||||
|
|
||||
|
beforeDestroy () { |
||||
|
// 页面销毁时关闭ws。因为有可能ws连接接收数据尚未完成,用户就跳转了页面 |
||||
|
// 在需要主动关闭ws的地方都可以调用该方法 |
||||
|
closeWebsocket() |
||||
|
}, |
||||
|
// ws连接成功,后台返回的ws数据,组件要拿数据渲染页面等操作 |
||||
|
wsMessage (data) { |
||||
|
const dataJson = data |
||||
|
console.log(dataJson) |
||||
|
// 这里写拿到数据后的业务代码 |
||||
|
}, |
||||
|
// ws连接失败,组件要执行的代码 |
||||
|
wsError () { |
||||
|
// 比如取消页面的loading |
||||
|
}, |
||||
|
requstWs () { |
||||
|
// 防止用户多次连续点击发起请求,所以要先关闭上次的ws请求。 |
||||
|
closeWebsocket() |
||||
|
// 跟后端协商,需要什么参数数据给后台 |
||||
|
const obj = { |
||||
|
monitorUrl: 'xxxxxxxxxxxxx', |
||||
|
userName: 'xxxxxxxxxx' |
||||
|
} |
||||
|
// 发起ws请求 |
||||
|
sendWebsocket('ws://test.ws.com', obj, this.wsMessage, this.wsError) |
||||
|
} |
||||
|
|
||||
|
## 组件: |
||||
|
[主列表:tablePagination] |
||||
|
currenButtonData 主列表按钮 |
||||
|
tableData 主列表数据 |
||||
|
tableLoading 主列表loading |
||||
|
tableColumns 主列表表头 |
||||
|
totalCount 主列表数据总条数 |
||||
|
multipleSelection 主列表选择行数据 |
||||
|
MaxResultCount 主列表当前页最大条数 |
||||
|
topbutton 主列表按钮方法 tablePagination ==> TableHeaderMixins.js |
||||
|
inlineDialog 主列表抽屉展现 tablePagination ==> currenTable |
||||
|
sortChange 主列表排序 tablePagination ==> currenTable |
||||
|
alertoldSkipCount 主列表-分页-当前页条数 |
||||
|
alterResultCount 主列表-分页-每页最大页数 |
||||
|
handleSelectionChange 主列表-选择-行数据方法 tablePagination ==> currenTable |
||||
|
<----20230207添加 begin----> |
||||
|
buttonOperationClick_left 主列表-操作列按钮点击事件 |
||||
|
currentPageProps 主列表-当前页码值 |
||||
|
使用的是@/mixins/TableMixins的oldSkipCount值 |
||||
|
quicklySearchOption 主表查询-快速搜索数据配置 ==> 通用配置在@/utils/quicklySearchOption/index |
||||
|
quicklySearchClick 主表查询-快速搜索按钮点击事件(回车事件通用) |
||||
|
quicklySearchClear 主表查询-快速搜索清除点击事件 |
||||
|
<----20230207添加 end----> |
||||
|
<----20230215添加 [全面搜索相关配置] begin----> |
||||
|
:primarySearchOption 普通查询表单配置项 |
||||
|
(@utils/primarySearchOption/index.js) |
||||
|
:primarySearchButton 普通查询表单自定义按钮 |
||||
|
:showMoreSearch 是否显示高级筛选(默认true) |
||||
|
:tableColumns 高级筛选数据配置(tableColumns.js) |
||||
|
@overallSearchFormClick 全面搜索中所有按钮的点击事件汇总,包括普通和高级 |
||||
|
:httpOverallSearchData 全面筛选组件中当前数据的筛选项 |
||||
|
(参数目的:使回显与当前接口筛选项同步) |
||||
|
<----20230215添加 end----> |
||||
|
<----20230321添加 [字段设置] begin----> |
||||
|
rowDrop 主表字段设置事件(排序及显隐) |
||||
|
<----20230321添加 end----> |
||||
|
|
||||
|
[普通搜索:searchPrimaryComponent] |
||||
|
:primarySearchOption 查询表单配置项 |
||||
|
(@utils/primarySearchOption/index.js) |
||||
|
具体配置方法见上述文件的示例配置:primarySearchOptionExample |
||||
|
:primarySearchButton 查询表单自定义按钮(业务线页面内定义) |
||||
|
@primarySearchButtonClick 普通搜索自定义按钮事件(与primarySearchButton共同设置) |
||||
|
@primarySearchBaseHandle 普通查询基础按钮点击事件 |
||||
|
|
||||
|
|
||||
|
|
||||
|
[全面筛选:searchOverall] |
||||
|
:showSearchOverall 显示全面筛选组件 |
||||
|
@getShowSearchOverall 全面筛选组件内部显示/隐藏更改触发, |
||||
|
同步当前业务showSearchOverall与筛选内部是否显示 |
||||
|
:primarySearchOption 查询表单配置项 |
||||
|
(@utils/primarySearchOption/index.js) |
||||
|
:primarySearchButton 其他普通搜索按钮位置配置 |
||||
|
@overallSearchFormClick 所有按钮操作 |
||||
|
(包含primarySearchButton设置的按钮) |
||||
|
:showMoreSearch 是否显示高级筛选(默认true) |
||||
|
:httpOverallSearchData 全面筛选组件中当前数据的筛选项 |
||||
|
(参数目的:使回显与当前接口筛选项同步),格式: |
||||
|
{ |
||||
|
<!-- 普通数据 --> |
||||
|
"params": {"code": "12","status": 1}, |
||||
|
<!-- 高级数据 --> |
||||
|
"moreList": { |
||||
|
"filters": [ |
||||
|
{"logic": "And","column": "abcClass","action": "==","value": "A"}, |
||||
|
{"logic": "And","column": "Name","action": "Like","value": "A45415"}, |
||||
|
] |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
新增编辑:《newAndEdiDialog》 |
||||
|
loading 抽屉loading |
||||
|
active 步骤控制 |
||||
|
pageStatus 结合active控制返回结果 |
||||
|
|
||||
|
[字段设置:rowDrop] |
||||
|
@radio="rowDrop" 数据更新方法 |
||||
|
:tableColumns="tableColumns" 表头数据 |
||||
|
:visible="visible" 是否显示 |
||||
|
@closeRowDrop="closeRowDrop" 关闭方法 |
||||
|
|
||||
|
[表单组件补充:currenForm] |
||||
|
validType type仅等于input时:实时keyUp校验,类型如下: |
||||
|
1、 number:正整数, |
||||
|
2、 pointNumber:数字+带小数点(只能输入一个小数点, 小数点后方保留位数见<pointNumberFixed>), |
||||
|
3、 numberLetter: 数字+字母, |
||||
|
4、 letter:纯字母, |
||||
|
5、 letterCn:字母+中文 |
||||
|
6、 numberLetterBar:字母+中文+横杠(-) |
||||
|
pointNumberFixed 组合上方validType值仅等于pointNumber时: |
||||
|
小数点后方保留位数,如不填写默认为100位 |
||||
|
<validType>+<pointNumberFixed>示例: |
||||
|
{ type:"input", label:"金额", prop:"money", validType:'pointNumber',pointNumberFixed:2}, |
@ -0,0 +1,14 @@ |
|||||
|
module.exports = { |
||||
|
presets: [ |
||||
|
// https://github.com/vuejs/vue-cli/tree/master/packages/@vue/babel-preset-app
|
||||
|
'@vue/cli-plugin-babel/preset' |
||||
|
], |
||||
|
'env': { |
||||
|
'development': { |
||||
|
// babel-plugin-dynamic-import-node plugin only does one thing by converting all import() to require().
|
||||
|
// This plugin can significantly increase the speed of hot updates, when you have a large number of pages.
|
||||
|
// https://panjiachen.github.io/vue-element-admin-site/guide/advanced/lazy-loading.html
|
||||
|
'plugins': ['dynamic-import-node'] |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,35 @@ |
|||||
|
const { run } = require('runjs') |
||||
|
const chalk = require('chalk') |
||||
|
const config = require('../vue.config.js') |
||||
|
const rawArgv = process.argv.slice(2) |
||||
|
const args = rawArgv.join(' ') |
||||
|
|
||||
|
if (process.env.npm_config_preview || rawArgv.includes('--preview')) { |
||||
|
const report = rawArgv.includes('--report') |
||||
|
|
||||
|
run(`vue-cli-service build ${args}`) |
||||
|
|
||||
|
const port = 9526 |
||||
|
const publicPath = config.publicPath |
||||
|
|
||||
|
var connect = require('connect') |
||||
|
var serveStatic = require('serve-static') |
||||
|
const app = connect() |
||||
|
|
||||
|
app.use( |
||||
|
publicPath, |
||||
|
serveStatic('./dist', { |
||||
|
index: ['index.html', '/'] |
||||
|
}) |
||||
|
) |
||||
|
|
||||
|
app.listen(port, function () { |
||||
|
console.log(chalk.green(`> Preview at http://localhost:${port}${publicPath}`)) |
||||
|
if (report) { |
||||
|
console.log(chalk.green(`> Report at http://localhost:${port}${publicPath}report.html`)) |
||||
|
} |
||||
|
|
||||
|
}) |
||||
|
} else { |
||||
|
run(`vue-cli-service build ${args}`) |
||||
|
} |
@ -0,0 +1,24 @@ |
|||||
|
module.exports = { |
||||
|
moduleFileExtensions: ['js', 'jsx', 'json', 'vue'], |
||||
|
transform: { |
||||
|
'^.+\\.vue$': 'vue-jest', |
||||
|
'.+\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2)$': |
||||
|
'jest-transform-stub', |
||||
|
'^.+\\.jsx?$': 'babel-jest' |
||||
|
}, |
||||
|
moduleNameMapper: { |
||||
|
'^@/(.*)$': '<rootDir>/src/$1' |
||||
|
}, |
||||
|
snapshotSerializers: ['jest-serializer-vue'], |
||||
|
testMatch: [ |
||||
|
'**/tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)' |
||||
|
], |
||||
|
collectCoverageFrom: ['src/utils/**/*.{js,vue}', '!src/utils/auth.js', '!src/utils/request.js', 'src/components/**/*.{js,vue}'], |
||||
|
coverageDirectory: '<rootDir>/tests/unit/coverage', |
||||
|
// 'collectCoverage': true,
|
||||
|
'coverageReporters': [ |
||||
|
'lcov', |
||||
|
'text-summary' |
||||
|
], |
||||
|
testURL: 'http://localhost/' |
||||
|
} |
@ -0,0 +1,9 @@ |
|||||
|
{ |
||||
|
"compilerOptions": { |
||||
|
"baseUrl": "./", |
||||
|
"paths": { |
||||
|
"@/*": ["src/*"] |
||||
|
} |
||||
|
}, |
||||
|
"exclude": ["node_modules", "dist"] |
||||
|
} |
@ -0,0 +1,123 @@ |
|||||
|
{ |
||||
|
"name": "vue-element-admin", |
||||
|
"version": "4.4.1", |
||||
|
"description": "A magical vue admin. An out-of-box UI solution for enterprise applications. Newest development stack of vue. Lots of awesome features", |
||||
|
"author": "Pan <panfree23@gmail.com>", |
||||
|
"scripts": { |
||||
|
"dev": "vue-cli-service serve", |
||||
|
"lint": "eslint --ext .js,.vue src", |
||||
|
"build": "vue-cli-service build", |
||||
|
"build:stage": "vue-cli-service build --mode staging", |
||||
|
"preview": "node build/index.js --preview", |
||||
|
"new": "plop", |
||||
|
"svgo": "svgo -f src/icons/svg --config=src/icons/svgo.yml", |
||||
|
"test:unit": "jest --clearCache && vue-cli-service test:unit", |
||||
|
"test:ci": "npm run lint && npm run test:unit" |
||||
|
}, |
||||
|
"dependencies": { |
||||
|
"af-table-column": "^1.0.3", |
||||
|
"axios": "0.18.1", |
||||
|
"clipboard": "2.0.4", |
||||
|
"codemirror": "5.45.0", |
||||
|
"core-js": "3.6.5", |
||||
|
"driver.js": "0.9.5", |
||||
|
"dropzone": "5.5.1", |
||||
|
"echarts": "4.2.1", |
||||
|
"element-ui": "^2.15.13", |
||||
|
"file-saver": "2.0.1", |
||||
|
"fuse.js": "3.4.4", |
||||
|
"js-cookie": "2.2.0", |
||||
|
"jsonlint": "1.6.3", |
||||
|
"jszip": "3.2.1", |
||||
|
"lodash": "^4.17.21", |
||||
|
"moment": "^2.29.1", |
||||
|
"normalize.css": "7.0.0", |
||||
|
"nprogress": "0.2.0", |
||||
|
"oidc-client": "^1.11.5", |
||||
|
"path-to-regexp": "2.4.0", |
||||
|
"qs": "^6.10.3", |
||||
|
"screenfull": "4.2.0", |
||||
|
"script-loader": "0.7.2", |
||||
|
"sortable.js": "^0.3.0", |
||||
|
"sortablejs": "^1.8.4", |
||||
|
"tui-editor": "1.3.3", |
||||
|
"umy-ui": "^1.1.6", |
||||
|
"v-fit-columns": "^0.2.0", |
||||
|
"vue": "2.6.10", |
||||
|
"vue-count-to": "1.0.13", |
||||
|
"vue-grid-layout": "^2.4.0", |
||||
|
"vue-i18n": "^8.28.2", |
||||
|
"vue-pdf": "^4.3.0", |
||||
|
"vue-router": "3.0.2", |
||||
|
"vue-splitpane": "1.0.4", |
||||
|
"vuedraggable": "2.20.0", |
||||
|
"vuex": "3.1.0", |
||||
|
"xlsx": "0.14.1" |
||||
|
}, |
||||
|
"devDependencies": { |
||||
|
"@vue/cli-plugin-babel": "4.4.4", |
||||
|
"@vue/cli-plugin-eslint": "4.4.4", |
||||
|
"@vue/cli-plugin-unit-jest": "4.4.4", |
||||
|
"@vue/cli-service": "4.4.4", |
||||
|
"@vue/test-utils": "1.0.0-beta.29", |
||||
|
"autoprefixer": "9.5.1", |
||||
|
"babel-eslint": "10.1.0", |
||||
|
"babel-jest": "23.6.0", |
||||
|
"babel-plugin-component": "^1.1.1", |
||||
|
"babel-plugin-dynamic-import-node": "2.3.3", |
||||
|
"chalk": "2.4.2", |
||||
|
"chokidar": "2.1.5", |
||||
|
"connect": "3.6.6", |
||||
|
"eslint": "6.7.2", |
||||
|
"eslint-plugin-vue": "6.2.2", |
||||
|
"html-webpack-plugin": "3.2.0", |
||||
|
"husky": "1.3.1", |
||||
|
"lint-staged": "8.1.5", |
||||
|
"mockjs": "1.0.1-beta3", |
||||
|
"plop": "2.3.0", |
||||
|
"runjs": "4.3.2", |
||||
|
"sass": "~1.26.5", |
||||
|
"sass-loader": "10.1.0", |
||||
|
"script-ext-html-webpack-plugin": "2.1.3", |
||||
|
"serve-static": "1.13.2", |
||||
|
"svg-sprite-loader": "4.1.3", |
||||
|
"svgo": "1.2.0", |
||||
|
"vue-template-compiler": "2.6.10" |
||||
|
}, |
||||
|
"browserslist": [ |
||||
|
"> 1%", |
||||
|
"last 2 versions" |
||||
|
], |
||||
|
"bugs": { |
||||
|
"url": "https://github.com/PanJiaChen/vue-element-admin/issues" |
||||
|
}, |
||||
|
"engines": { |
||||
|
"node": ">=8.9", |
||||
|
"npm": ">= 3.0.0" |
||||
|
}, |
||||
|
"keywords": [ |
||||
|
"vue", |
||||
|
"admin", |
||||
|
"dashboard", |
||||
|
"element-ui", |
||||
|
"boilerplate", |
||||
|
"admin-template", |
||||
|
"management-system" |
||||
|
], |
||||
|
"license": "MIT", |
||||
|
"lint-staged": { |
||||
|
"src/**/*.{js,vue}": [ |
||||
|
"eslint --fix", |
||||
|
"git add" |
||||
|
] |
||||
|
}, |
||||
|
"husky": { |
||||
|
"hooks": { |
||||
|
"pre-commit": "lint-staged" |
||||
|
} |
||||
|
}, |
||||
|
"repository": { |
||||
|
"type": "git", |
||||
|
"url": "git+https://github.com/PanJiaChen/vue-element-admin.git" |
||||
|
} |
||||
|
} |
@ -0,0 +1,26 @@ |
|||||
|
{{#if template}} |
||||
|
<template> |
||||
|
<div /> |
||||
|
</template> |
||||
|
{{/if}} |
||||
|
|
||||
|
{{#if script}} |
||||
|
<script> |
||||
|
export default { |
||||
|
name: '{{ properCase name }}', |
||||
|
props: {}, |
||||
|
data() { |
||||
|
return {} |
||||
|
}, |
||||
|
created() {}, |
||||
|
mounted() {}, |
||||
|
methods: {} |
||||
|
} |
||||
|
</script> |
||||
|
{{/if}} |
||||
|
|
||||
|
{{#if style}} |
||||
|
<style lang="scss" scoped> |
||||
|
|
||||
|
</style> |
||||
|
{{/if}} |
@ -0,0 +1,55 @@ |
|||||
|
const { notEmpty } = require('../utils.js') |
||||
|
|
||||
|
module.exports = { |
||||
|
description: 'generate vue component', |
||||
|
prompts: [{ |
||||
|
type: 'input', |
||||
|
name: 'name', |
||||
|
message: 'component name please', |
||||
|
validate: notEmpty('name') |
||||
|
}, |
||||
|
{ |
||||
|
type: 'checkbox', |
||||
|
name: 'blocks', |
||||
|
message: 'Blocks:', |
||||
|
choices: [{ |
||||
|
name: '<template>', |
||||
|
value: 'template', |
||||
|
checked: true |
||||
|
}, |
||||
|
{ |
||||
|
name: '<script>', |
||||
|
value: 'script', |
||||
|
checked: true |
||||
|
}, |
||||
|
{ |
||||
|
name: 'style', |
||||
|
value: 'style', |
||||
|
checked: true |
||||
|
} |
||||
|
], |
||||
|
validate(value) { |
||||
|
if (value.indexOf('script') === -1 && value.indexOf('template') === -1) { |
||||
|
return 'Components require at least a <script> or <template> tag.' |
||||
|
} |
||||
|
return true |
||||
|
} |
||||
|
} |
||||
|
], |
||||
|
actions: data => { |
||||
|
const name = '{{properCase name}}' |
||||
|
const actions = [{ |
||||
|
type: 'add', |
||||
|
path: `src/components/${name}/index.vue`, |
||||
|
templateFile: 'plop-templates/component/index.hbs', |
||||
|
data: { |
||||
|
name: name, |
||||
|
template: data.blocks.includes('template'), |
||||
|
script: data.blocks.includes('script'), |
||||
|
style: data.blocks.includes('style') |
||||
|
} |
||||
|
}] |
||||
|
|
||||
|
return actions |
||||
|
} |
||||
|
} |
@ -0,0 +1,16 @@ |
|||||
|
{{#if state}} |
||||
|
const state = {} |
||||
|
{{/if}} |
||||
|
|
||||
|
{{#if mutations}} |
||||
|
const mutations = {} |
||||
|
{{/if}} |
||||
|
|
||||
|
{{#if actions}} |
||||
|
const actions = {} |
||||
|
{{/if}} |
||||
|
|
||||
|
export default { |
||||
|
namespaced: true, |
||||
|
{{options}} |
||||
|
} |
@ -0,0 +1,62 @@ |
|||||
|
const { notEmpty } = require('../utils.js') |
||||
|
|
||||
|
module.exports = { |
||||
|
description: 'generate store', |
||||
|
prompts: [{ |
||||
|
type: 'input', |
||||
|
name: 'name', |
||||
|
message: 'store name please', |
||||
|
validate: notEmpty('name') |
||||
|
}, |
||||
|
{ |
||||
|
type: 'checkbox', |
||||
|
name: 'blocks', |
||||
|
message: 'Blocks:', |
||||
|
choices: [{ |
||||
|
name: 'state', |
||||
|
value: 'state', |
||||
|
checked: true |
||||
|
}, |
||||
|
{ |
||||
|
name: 'mutations', |
||||
|
value: 'mutations', |
||||
|
checked: true |
||||
|
}, |
||||
|
{ |
||||
|
name: 'actions', |
||||
|
value: 'actions', |
||||
|
checked: true |
||||
|
} |
||||
|
], |
||||
|
validate(value) { |
||||
|
if (!value.includes('state') || !value.includes('mutations')) { |
||||
|
return 'store require at least state and mutations' |
||||
|
} |
||||
|
return true |
||||
|
} |
||||
|
} |
||||
|
], |
||||
|
actions(data) { |
||||
|
const name = '{{name}}' |
||||
|
const { blocks } = data |
||||
|
const options = ['state', 'mutations'] |
||||
|
const joinFlag = `,
|
||||
|
` |
||||
|
if (blocks.length === 3) { |
||||
|
options.push('actions') |
||||
|
} |
||||
|
|
||||
|
const actions = [{ |
||||
|
type: 'add', |
||||
|
path: `src/store/modules/${name}.js`, |
||||
|
templateFile: 'plop-templates/store/index.hbs', |
||||
|
data: { |
||||
|
options: options.join(joinFlag), |
||||
|
state: blocks.includes('state'), |
||||
|
mutations: blocks.includes('mutations'), |
||||
|
actions: blocks.includes('actions') |
||||
|
} |
||||
|
}] |
||||
|
return actions |
||||
|
} |
||||
|
} |
@ -0,0 +1,2 @@ |
|||||
|
exports.notEmpty = name => v => |
||||
|
!v || v.trim() === '' ? `${name} is required` : true |
@ -0,0 +1,26 @@ |
|||||
|
{{#if template}} |
||||
|
<template> |
||||
|
<div /> |
||||
|
</template> |
||||
|
{{/if}} |
||||
|
|
||||
|
{{#if script}} |
||||
|
<script> |
||||
|
export default { |
||||
|
name: '{{ properCase name }}', |
||||
|
props: {}, |
||||
|
data() { |
||||
|
return {} |
||||
|
}, |
||||
|
created() {}, |
||||
|
mounted() {}, |
||||
|
methods: {} |
||||
|
} |
||||
|
</script> |
||||
|
{{/if}} |
||||
|
|
||||
|
{{#if style}} |
||||
|
<style lang="scss" scoped> |
||||
|
|
||||
|
</style> |
||||
|
{{/if}} |
@ -0,0 +1,55 @@ |
|||||
|
const { notEmpty } = require('../utils.js') |
||||
|
|
||||
|
module.exports = { |
||||
|
description: 'generate a view', |
||||
|
prompts: [{ |
||||
|
type: 'input', |
||||
|
name: 'name', |
||||
|
message: 'view name please', |
||||
|
validate: notEmpty('name') |
||||
|
}, |
||||
|
{ |
||||
|
type: 'checkbox', |
||||
|
name: 'blocks', |
||||
|
message: 'Blocks:', |
||||
|
choices: [{ |
||||
|
name: '<template>', |
||||
|
value: 'template', |
||||
|
checked: true |
||||
|
}, |
||||
|
{ |
||||
|
name: '<script>', |
||||
|
value: 'script', |
||||
|
checked: true |
||||
|
}, |
||||
|
{ |
||||
|
name: 'style', |
||||
|
value: 'style', |
||||
|
checked: true |
||||
|
} |
||||
|
], |
||||
|
validate(value) { |
||||
|
if (value.indexOf('script') === -1 && value.indexOf('template') === -1) { |
||||
|
return 'View require at least a <script> or <template> tag.' |
||||
|
} |
||||
|
return true |
||||
|
} |
||||
|
} |
||||
|
], |
||||
|
actions: data => { |
||||
|
const name = '{{name}}' |
||||
|
const actions = [{ |
||||
|
type: 'add', |
||||
|
path: `src/views/${name}/index.vue`, |
||||
|
templateFile: 'plop-templates/view/index.hbs', |
||||
|
data: { |
||||
|
name: name, |
||||
|
template: data.blocks.includes('template'), |
||||
|
script: data.blocks.includes('script'), |
||||
|
style: data.blocks.includes('style') |
||||
|
} |
||||
|
}] |
||||
|
|
||||
|
return actions |
||||
|
} |
||||
|
} |
@ -0,0 +1,9 @@ |
|||||
|
const viewGenerator = require('./plop-templates/view/prompt') |
||||
|
const componentGenerator = require('./plop-templates/component/prompt') |
||||
|
const storeGenerator = require('./plop-templates/store/prompt.js') |
||||
|
|
||||
|
module.exports = function(plop) { |
||||
|
plop.setGenerator('view', viewGenerator) |
||||
|
plop.setGenerator('component', componentGenerator) |
||||
|
plop.setGenerator('store', storeGenerator) |
||||
|
} |
@ -0,0 +1,5 @@ |
|||||
|
module.exports = { |
||||
|
plugins: { |
||||
|
autoprefixer: {} |
||||
|
} |
||||
|
} |
After Width: | Height: | Size: 1.6 KiB |
@ -0,0 +1,26 @@ |
|||||
|
// dev_win
|
||||
|
window.SITE_CONFIG['baseApi'] = 'http://dev.ccwin-in.com:60024' |
||||
|
window.SITE_CONFIG['authApi'] = 'http://dev.ccwin-in.com:60020' |
||||
|
// window.SITE_CONFIG['baseApi'] = 'http://192.168.0.190:60078'//http://dev.ccwin-in.com:60022
|
||||
|
// window.SITE_CONFIG['authApi'] = 'http://192.168.0.190:60065'//http://dev.ccwin-in.com:60020
|
||||
|
window.SITE_CONFIG['businessApi'] = 'http://dev.ccwin-in.com:10097' |
||||
|
//是否登录配置信息【loginName】
|
||||
|
window.SITE_CONFIG['isConfigLogin'] = false |
||||
|
//如果【isConfigLogin】为true则使用【loginName】登录
|
||||
|
window.SITE_CONFIG['configLoginName'] = 'admin' |
||||
|
// 默认登录密码(isConfigLogin为true或者链接参数存在loginName使用)
|
||||
|
window.SITE_CONFIG['configLoginPass'] = '1q2w3E*' |
||||
|
// 是否单页面(不显示菜单头部等部分)
|
||||
|
window.SITE_CONFIG['isSinglePage'] = false |
||||
|
// 项目配置
|
||||
|
window.SITE_CONFIG['appClientId'] = 'Z_App' |
||||
|
// 项目配置内部名称
|
||||
|
window.SITE_CONFIG['appClientScope'] = 'Inventory' |
||||
|
// 浏览器名称
|
||||
|
window.SITE_CONFIG['browserTitle'] = 'Inventory-QAD&WMS' |
||||
|
// 单点登录使用数据
|
||||
|
window.SITE_CONFIG['oidcLogin_url'] = 'http://dev.ccwin-in.com:60065', |
||||
|
window.SITE_CONFIG['oidcLogin_clientId'] = 'InterfaceDash_App' |
||||
|
window.SITE_CONFIG['oidcLogin_scopes'] = 'offline_access Z profile' |
||||
|
// 隐藏的页面
|
||||
|
window.SITE_CONFIG['menuHiddenConfig'] = [] |
After Width: | Height: | Size: 66 KiB |
After Width: | Height: | Size: 303 KiB |
@ -0,0 +1,30 @@ |
|||||
|
<!DOCTYPE html> |
||||
|
<html> |
||||
|
|
||||
|
<head> |
||||
|
<meta charset="utf-8"> |
||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> |
||||
|
<meta name="renderer" content="webkit"> |
||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> |
||||
|
<!-- <meta http-equiv="pragram" content="no-cache"> |
||||
|
<meta http-equiv="cache-control" content="no-cache, no-store, must-revalidate"> --> |
||||
|
<link rel="icon" href="<%= BASE_URL %>WMS.svg"> |
||||
|
<script> |
||||
|
// 初始化 |
||||
|
window.SITE_CONFIG = {}; |
||||
|
window.SITE_CONFIG['base'] = '' |
||||
|
window.SITE_CONFIG['user'] = '' |
||||
|
window.SITE_CONFIG['print'] = '' |
||||
|
window.SITE_CONFIG['warehouseCode'] = '' |
||||
|
window.SITE_CONFIG['company'] = '' |
||||
|
</script> |
||||
|
<title><%= webpackConfig.name %></title> |
||||
|
<script src="./config.js"></script> |
||||
|
</head> |
||||
|
|
||||
|
<body> |
||||
|
<div id="app"></div> |
||||
|
<!-- built files will be auto injected --> |
||||
|
</body> |
||||
|
|
||||
|
</html> |
@ -0,0 +1,3 @@ |
|||||
|
{ |
||||
|
"version": "1.0.45" |
||||
|
} |
@ -0,0 +1,98 @@ |
|||||
|
<template> |
||||
|
<div id="app"> |
||||
|
<router-view /> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
export default { |
||||
|
name: 'App' |
||||
|
} |
||||
|
localStorage.setItem('baseApi',window.SITE_CONFIG['baseApi']) |
||||
|
localStorage.setItem('authApi',window.SITE_CONFIG['authApi']) |
||||
|
// localStorage.setItem('userApi',window.SITE_CONFIG['userApi']) |
||||
|
localStorage.setItem('businessApi',window.SITE_CONFIG['businessApi']) |
||||
|
localStorage.setItem('isConfigLogin',window.SITE_CONFIG['isConfigLogin']) |
||||
|
localStorage.setItem('configLoginName',window.SITE_CONFIG['configLoginName']) |
||||
|
localStorage.setItem('configLoginPass',window.SITE_CONFIG['configLoginPass']) |
||||
|
localStorage.setItem('isSinglePage',window.SITE_CONFIG['isSinglePage']) |
||||
|
localStorage.setItem('appClientId',window.SITE_CONFIG['appClientId']) |
||||
|
localStorage.setItem('appClientScope',window.SITE_CONFIG['appClientScope']) |
||||
|
localStorage.setItem('browserTitle',window.SITE_CONFIG['browserTitle']) |
||||
|
// 单点登录使用数据 |
||||
|
localStorage.setItem('oidcLogin_url',window.SITE_CONFIG['oidcLogin_url']) |
||||
|
localStorage.setItem('oidcLogin_clientId',window.SITE_CONFIG['oidcLogin_clientId']) |
||||
|
localStorage.setItem('oidcLogin_scopes',window.SITE_CONFIG['oidcLogin_scopes']) |
||||
|
// 隐藏菜单 |
||||
|
localStorage.setItem('menuHiddenConfig',window.SITE_CONFIG['menuHiddenConfig']) |
||||
|
|
||||
|
// localStorage.setItem('isAutoLogin',window.SITE_CONFIG['isAutoLogin']) |
||||
|
// localStorage.setItem('userNameOrEmailAddress',window.SITE_CONFIG['userNameOrEmailAddress']) |
||||
|
// localStorage.setItem('client_secret',window.SITE_CONFIG['client_secret']) |
||||
|
|
||||
|
// 获取浏览器语言 |
||||
|
const language_brow = (navigator.language || navigator.browserLanguage) |
||||
|
console.log(21,language_brow) |
||||
|
if(language_brow.indexOf('zh') >= 0){ |
||||
|
localStorage.setItem('browserLanguage','zh-Hans') |
||||
|
}else{ |
||||
|
localStorage.setItem('browserLanguage','en') |
||||
|
} |
||||
|
|
||||
|
</script> |
||||
|
<style lang="scss"> |
||||
|
/* 滚动条 */ |
||||
|
::-webkit-scrollbar { |
||||
|
width: 7px; |
||||
|
height: 7px; |
||||
|
background: transparent; |
||||
|
border-radius: 5px; |
||||
|
} |
||||
|
|
||||
|
/* 滚动条两端按钮 */ |
||||
|
::-webkit-scrollbar-button { |
||||
|
width: 0; |
||||
|
height: 0; |
||||
|
} |
||||
|
|
||||
|
/* 外层轨道 */ |
||||
|
::-webkit-scrollbar-track { |
||||
|
border-radius: 5px; |
||||
|
} |
||||
|
|
||||
|
/* 内层轨道,它会覆盖外层轨道的样式 */ |
||||
|
::-webkit-scrollbar-track-piece { |
||||
|
// background-color: #f3f3f3; |
||||
|
height: 7px; |
||||
|
width: 7px; |
||||
|
margin: 0 -2px 0; |
||||
|
} |
||||
|
|
||||
|
/* 滑块 */ |
||||
|
::-webkit-scrollbar-thumb { |
||||
|
background-color: #ccc; |
||||
|
min-height: 60px; |
||||
|
min-width: 60px; |
||||
|
border-radius: 5px; |
||||
|
} |
||||
|
|
||||
|
/* 纵向滑块悬浮 */ |
||||
|
::-webkit-scrollbar-thumb:vertical:hover { |
||||
|
background-color: #ccc; |
||||
|
} |
||||
|
|
||||
|
/* 横向滑块悬浮 */ |
||||
|
::-webkit-scrollbar-thumb:horizontal:hover { |
||||
|
background-color: #ccc; |
||||
|
} |
||||
|
/*横竖滚动条交角图案*/ |
||||
|
// ::-webkit-resizer { |
||||
|
// /*background-image: url(/public/img/resizer-inactive.png);*/ |
||||
|
// background-repeat: no-repeat; |
||||
|
// background-position: bottom right; |
||||
|
// } |
||||
|
/*横竖滚动条交角*/ |
||||
|
// ::-webkit-scrollbar-corner { |
||||
|
// background-color: #f3f3f3; |
||||
|
// } |
||||
|
</style> |
@ -0,0 +1,177 @@ |
|||||
|
import request from '@/utils/request' |
||||
|
import store from '@/store' |
||||
|
// let baseURL = process.env.VUE_APP_BASE_API + '/'
|
||||
|
let baseAPI = localStorage.getItem('baseApi') + '/' |
||||
|
let baseURL = localStorage.getItem('baseApi') + '/api/' |
||||
|
|
||||
|
//新建
|
||||
|
export function postCreate(data, url) { |
||||
|
if (Object.keys(data).includes('company')) { |
||||
|
data.company = localStorage.getItem('company') |
||||
|
} |
||||
|
if (Object.keys(data).includes('warehouseCode')) { |
||||
|
data.warehouseCode = localStorage.getItem('warehouseCode') |
||||
|
} |
||||
|
if(Object.keys(data).includes('worker')) { |
||||
|
data.worker = store.getters.currentUserInfo.userName |
||||
|
} |
||||
|
return request({ |
||||
|
url: baseURL + url, |
||||
|
method: 'post', |
||||
|
data |
||||
|
}) |
||||
|
} |
||||
|
//编辑
|
||||
|
export function postUpdate(data, id, url) { |
||||
|
return request({ |
||||
|
// url: baseURL + url + '/' + id,
|
||||
|
url: baseURL + url, |
||||
|
method: 'put', |
||||
|
data, |
||||
|
params:{id:id} |
||||
|
}) |
||||
|
} |
||||
|
//删除
|
||||
|
export function postDelete(id, url) { |
||||
|
return request({ |
||||
|
// url: baseURL + url + '/' + id,
|
||||
|
url: baseURL + url, |
||||
|
method: 'delete', |
||||
|
params:{id:id} |
||||
|
}) |
||||
|
} |
||||
|
//分页+筛选【列表】
|
||||
|
export function getPageList(data, url, includeDetails) { |
||||
|
let _url = includeDetails ? baseURL + url + '/get-list-page-by-filter?includeDetails='+ includeDetails : baseURL + url + '/get-list-page-by-filter' |
||||
|
return request({ |
||||
|
url: _url, |
||||
|
method: 'post', |
||||
|
data |
||||
|
}) |
||||
|
} |
||||
|
//分页+筛选【明细列表】
|
||||
|
export function getPageListForDetail(data, url, includeDetails) { |
||||
|
return request({ |
||||
|
method:'post', |
||||
|
url: baseURL + url + '/get-list-page-by-filter?includeDetails='+Boolean(includeDetails), |
||||
|
data |
||||
|
}) |
||||
|
} |
||||
|
// 根据id获取主表信息
|
||||
|
export function getListDesById(url,id) { |
||||
|
return request({ |
||||
|
method:'get', |
||||
|
url: baseURL + url + '/' + id |
||||
|
}) |
||||
|
} |
||||
|
//导出-获取文件 blobName
|
||||
|
/** |
||||
|
* @param {*} data |
||||
|
* @param {*} url 地址 |
||||
|
* @param {*} special 是否为特殊,如果是特殊,则直接用url |
||||
|
* @returns |
||||
|
*/ |
||||
|
export function postExport(params,data, url, special) { |
||||
|
let _url = special ? baseURL + url : baseURL + url + '/export-to-excel' |
||||
|
return request({ |
||||
|
url: _url, |
||||
|
method: 'post', |
||||
|
data, |
||||
|
params:params, |
||||
|
responseType: 'blob' |
||||
|
}) |
||||
|
} |
||||
|
//导出(详情内)-获取文件 blobName
|
||||
|
/** |
||||
|
* @param {*} data |
||||
|
* @param {*} url 地址 |
||||
|
* @param {*} params |
||||
|
* @returns |
||||
|
*/ |
||||
|
export function postExportForDetail(data, url,params) { |
||||
|
return request({ |
||||
|
url: baseURL + url, |
||||
|
method: 'post', |
||||
|
data, |
||||
|
params: params, |
||||
|
responseType: 'blob' |
||||
|
}) |
||||
|
} |
||||
|
//导出-文件
|
||||
|
export function fileStorage(data) { |
||||
|
return request({ |
||||
|
url: baseURL + 'filestore/file', |
||||
|
method: 'get', |
||||
|
params: data, |
||||
|
}) |
||||
|
} |
||||
|
//导入 isSpecial 是否为特殊接口
|
||||
|
export function postImport(data, url,isSpecial) { |
||||
|
let _url = isSpecial ? url : url + '/import' |
||||
|
return request({ |
||||
|
url: baseURL + _url, |
||||
|
method: 'post', |
||||
|
headers: { |
||||
|
'Content-Type': 'multipart/form-data;' |
||||
|
}, |
||||
|
responseType: 'blob', |
||||
|
data |
||||
|
}) |
||||
|
} |
||||
|
//导入模板下载
|
||||
|
export function postImportDown(url) { |
||||
|
return request({ |
||||
|
url: baseURL + url + '/import-template', |
||||
|
method: 'post', |
||||
|
responseType: 'blob' |
||||
|
}) |
||||
|
} |
||||
|
//获取详情
|
||||
|
export function getDetailed(id, url) { |
||||
|
return request({ |
||||
|
url: baseURL + url + '/' + id, |
||||
|
method: 'get', |
||||
|
}) |
||||
|
} |
||||
|
//获取分页+筛选(只查询)
|
||||
|
export function getPage(data, url) { |
||||
|
return request({ |
||||
|
url: baseURL + url, |
||||
|
method: 'get', |
||||
|
params: data |
||||
|
}) |
||||
|
} |
||||
|
// 获取版本编号
|
||||
|
export function getVsersion() { |
||||
|
return request({ |
||||
|
url: window.SITE_CONFIG['versionUrl'] + `/version.json?t=${new Date().getTime()}`, |
||||
|
method: 'get' |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
// fast-new
|
||||
|
//API-POST
|
||||
|
export function ApiTypePost(data, url) { |
||||
|
return request({ |
||||
|
url: baseAPI + url, |
||||
|
method: 'post', |
||||
|
data |
||||
|
}) |
||||
|
} |
||||
|
//API-PUT
|
||||
|
export function ApiTypePut(data, id, url) { |
||||
|
return request({ |
||||
|
url: baseAPI + url, |
||||
|
method: 'put', |
||||
|
data, |
||||
|
params:{id:id} |
||||
|
}) |
||||
|
} |
||||
|
//API-DELETE
|
||||
|
export function ApiTypeDelete(id, url) { |
||||
|
return request({ |
||||
|
url: baseAPI + url, |
||||
|
method: 'delete', |
||||
|
params:{id:id} |
||||
|
}) |
||||
|
} |
@ -0,0 +1,207 @@ |
|||||
|
import request from '@/utils/request' |
||||
|
let baseApi = localStorage.getItem('baseApi') + '/api' |
||||
|
let authUrl = localStorage.getItem('authApi') |
||||
|
let authApi = authUrl + '/api' |
||||
|
|
||||
|
export function logout() { |
||||
|
return request({ |
||||
|
url: authApi + '/account/logout', |
||||
|
method: 'get' |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
|
||||
|
// faster-new
|
||||
|
// 登录
|
||||
|
export function login(data) { |
||||
|
return request({ |
||||
|
url: authUrl + '/CustAccount/login', |
||||
|
method: 'post', |
||||
|
data |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
// 获取token
|
||||
|
export function token(data) { |
||||
|
return request({ |
||||
|
url: authApi + '/connect/token', |
||||
|
method: 'post', |
||||
|
headers: { |
||||
|
'Content-Type': 'application/x-www-form-urlencoded' |
||||
|
}, |
||||
|
data |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
// 通过token获取用户信息(单点登录)
|
||||
|
export function getUsersByToken(token) { |
||||
|
return request({ |
||||
|
url: authUrl + '/connect/userinfo', |
||||
|
method: 'get', |
||||
|
Token:token |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
// 通过用户名获取用户信息
|
||||
|
export function getUsersByUserName(name) { |
||||
|
return request({ |
||||
|
url: authApi + '/identity/users/by-username/'+name, |
||||
|
method: 'get', |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
// 获取表头zh转义数据
|
||||
|
export function getInterfaceBoard() { |
||||
|
return request({ |
||||
|
method:'get', |
||||
|
url: baseApi + '/abp/application-localization', |
||||
|
params:{ |
||||
|
CultureName:localStorage.getItem('browserLanguage'), |
||||
|
OnlyDynamics:false |
||||
|
} |
||||
|
// params:{IncludeLocalizationResources:true}
|
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
// 获取菜单数据
|
||||
|
export function getDefinitionMenu(IncludeTypes) { |
||||
|
return request({ |
||||
|
method:'get', |
||||
|
url: baseApi + '/abp/application-configuration', |
||||
|
params:{IncludeLocalizationResources:true} |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
// 获取枚举数据/dto列类型等所有配置
|
||||
|
export async function getApiDefinition() { |
||||
|
return request({ |
||||
|
method:'get', |
||||
|
url: baseApi + '/abp/api-definition', |
||||
|
params:{IncludeTypes:true} |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
// *************权限Roles页面维护*************
|
||||
|
//获取列表
|
||||
|
export function getPageListRoles(data) { |
||||
|
return request({ |
||||
|
url: authApi + '/identity/roles', |
||||
|
// url: 'http://192.168.0.190:44330/Identity/Roles',
|
||||
|
method: 'get', |
||||
|
params: data |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
//获取权限模板
|
||||
|
export function getPermissionsRoles(data) { |
||||
|
return request({ |
||||
|
url: authApi +'/permission-management/permissions', |
||||
|
method: 'get', |
||||
|
params: data |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
// 创建角色
|
||||
|
export function postCreateRoles(data) { |
||||
|
return request({ |
||||
|
url: authApi + '/identity/roles', |
||||
|
method: 'post', |
||||
|
data |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
//编辑角色
|
||||
|
export function postUpdateRoles(data, id) { |
||||
|
return request({ |
||||
|
url: authApi+'/identity/roles/' + id, |
||||
|
method: 'put', |
||||
|
data |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
//删除角色
|
||||
|
export function postDeleteRoles(id) { |
||||
|
return request({ |
||||
|
url: authApi + '/identity/roles/' + id, |
||||
|
method: 'delete', |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
//保存权限模板
|
||||
|
export function savePermissionsRoles(URL, data) { |
||||
|
return request({ |
||||
|
url: authApi + URL, |
||||
|
method: 'put', |
||||
|
data |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
// 更新权限
|
||||
|
export function updatePermissionsGranted(pname,pkey) { |
||||
|
return request({ |
||||
|
url: authApi + `/permissions/get-isGranted?name=demox&providerName=${pname}&providerKey=${pkey}`, |
||||
|
method: 'post', |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
// *************用户Users页面维护*************
|
||||
|
|
||||
|
//获取全部用户信息
|
||||
|
export function getPageListUsers(data) { |
||||
|
return request({ |
||||
|
url: authApi + '/identity/users', |
||||
|
method: 'get', |
||||
|
params: data |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
//新建用户
|
||||
|
export function postCreateUser(data) { |
||||
|
return request({ |
||||
|
url: authApi + '/identity/users', |
||||
|
method: 'post', |
||||
|
data |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
//编辑用户
|
||||
|
export function postUpdateUser(data, id) { |
||||
|
return request({ |
||||
|
url: authApi + '/identity/users/' + id, |
||||
|
method: 'put', |
||||
|
data |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
//删除用户
|
||||
|
export function postDeleteUser(id) { |
||||
|
return request({ |
||||
|
url: authApi + '/identity/users/' + id, |
||||
|
method: 'delete', |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
// 获取当前用户的角色
|
||||
|
export function usersroles() { |
||||
|
return request({ |
||||
|
url: authApi + '/identity/users/assignable-roles', |
||||
|
method: 'get' |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
//获取当前角色
|
||||
|
export function getusersID(data) { |
||||
|
return request({ |
||||
|
url: authApi + '/identity/users/' + data + '/roles', |
||||
|
method: 'get' |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
//修改登录用户的密码-强密码规则
|
||||
|
export function postLoginUserInfo(data, id) { |
||||
|
return request({ |
||||
|
url: authApi + '/identity/users/change-password/' + id, |
||||
|
method: 'post', |
||||
|
data |
||||
|
}) |
||||
|
} |
@ -0,0 +1,49 @@ |
|||||
|
import request from '@/utils/request' |
||||
|
// let baseURL = process.env.VUE_APP_BASE_API + '/'
|
||||
|
let baseURL = localStorage.getItem('base') + '/api/' |
||||
|
|
||||
|
//---------------------------通用---------------------------
|
||||
|
//任务流程——承接
|
||||
|
export function accept(url, data) { |
||||
|
return request({ |
||||
|
url: baseURL + url + '/accept/'+data.id, |
||||
|
method: 'post', |
||||
|
// params: data
|
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
//任务流程——关闭
|
||||
|
export function close(url, data) { |
||||
|
return request({ |
||||
|
url: baseURL + url + '/close/'+data.id, |
||||
|
method: 'post', |
||||
|
// params: data
|
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
//任务流程——取消
|
||||
|
export function cancel(url, data) { |
||||
|
return request({ |
||||
|
url: baseURL + url + '/cancel/'+data.id, |
||||
|
method: 'post', |
||||
|
// params: data
|
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
//任务流程——取消承接 | 采购收货任务
|
||||
|
export function cancelAccept(url, data) { |
||||
|
return request({ |
||||
|
url: baseURL + url + '/cancel-accept/'+data.id, |
||||
|
method: 'post', |
||||
|
// params: data
|
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
//任务流程——打开
|
||||
|
export function open(url, data) { |
||||
|
return request({ |
||||
|
url: baseURL + url + '/open/'+data.id, |
||||
|
method: 'post', |
||||
|
// params: data
|
||||
|
}) |
||||
|
} |
After Width: | Height: | Size: 160 KiB |
After Width: | Height: | Size: 96 KiB |
After Width: | Height: | Size: 4.7 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 1.5 KiB |
@ -0,0 +1,84 @@ |
|||||
|
<template> |
||||
|
<el-breadcrumb class="app-breadcrumb" separator="/"> |
||||
|
<transition-group name="breadcrumb"> |
||||
|
<el-breadcrumb-item v-for="(item,index) in levelList" :key="item.path"> |
||||
|
<span v-if="item.redirect==='noRedirect'||index==levelList.length-1" class="no-redirect">{{ item.meta.title }}</span> |
||||
|
<a v-else @click.prevent="handleLink(item)">{{ item.meta.title }}</a> |
||||
|
</el-breadcrumb-item> |
||||
|
</transition-group> |
||||
|
</el-breadcrumb> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import pathToRegexp from 'path-to-regexp' |
||||
|
|
||||
|
export default { |
||||
|
data() { |
||||
|
return { |
||||
|
levelList: null |
||||
|
} |
||||
|
}, |
||||
|
watch: { |
||||
|
$route(route) { |
||||
|
// if you go to the redirect page, do not update the breadcrumbs |
||||
|
if (route.path.startsWith('/redirect/')) { |
||||
|
return |
||||
|
} |
||||
|
this.getBreadcrumb() |
||||
|
} |
||||
|
}, |
||||
|
created() { |
||||
|
this.getBreadcrumb() |
||||
|
}, |
||||
|
methods: { |
||||
|
getBreadcrumb() { |
||||
|
// only show routes with meta.title |
||||
|
let matched = this.$route.matched.filter(item => item.meta && item.meta.title) |
||||
|
const first = matched[0] |
||||
|
|
||||
|
if (!this.isDashboard(first)) { |
||||
|
matched = [].concat(matched) |
||||
|
// matched = [{ path: '/dashboard', meta: { title: '系统首页' }}].concat(matched) |
||||
|
} |
||||
|
|
||||
|
this.levelList = matched.filter(item => item.meta && item.meta.title && item.meta.breadcrumb !== false) |
||||
|
}, |
||||
|
isDashboard(route) { |
||||
|
const name = route && route.name |
||||
|
if (!name) { |
||||
|
return false |
||||
|
} |
||||
|
return name.trim().toLocaleLowerCase() === 'Dashboard'.toLocaleLowerCase() |
||||
|
}, |
||||
|
pathCompile(path) { |
||||
|
// To solve this problem https://github.com/PanJiaChen/vue-element-admin/issues/561 |
||||
|
const { params } = this.$route |
||||
|
var toPath = pathToRegexp.compile(path) |
||||
|
return toPath(params) |
||||
|
}, |
||||
|
handleLink(item) { |
||||
|
const { redirect, path } = item |
||||
|
if (redirect) { |
||||
|
this.$router.push(redirect) |
||||
|
return |
||||
|
} |
||||
|
this.$router.push(this.pathCompile(path)) |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss" scoped> |
||||
|
@import '../../styles/variables.scss'; |
||||
|
.app-breadcrumb.el-breadcrumb { |
||||
|
display: inline-block; |
||||
|
font-size: 14px; |
||||
|
line-height: $navHeight; |
||||
|
margin-left: 8px; |
||||
|
|
||||
|
.no-redirect { |
||||
|
color: #97a8be; |
||||
|
cursor: text; |
||||
|
} |
||||
|
} |
||||
|
</style> |
@ -0,0 +1,94 @@ |
|||||
|
<template> |
||||
|
<div v-if="errorLogs.length>0"> |
||||
|
<el-badge |
||||
|
:is-dot="true" |
||||
|
style="line-height: 10px;" |
||||
|
@click.native="dialogTableVisible=true" |
||||
|
> |
||||
|
<el-button style="padding: 4px" size="small" type="danger"> |
||||
|
<svg-icon icon-class="svg_bug" style="font-size: 16px;"/> |
||||
|
</el-button> |
||||
|
</el-badge> |
||||
|
|
||||
|
<el-dialog |
||||
|
:visible.sync="dialogTableVisible" |
||||
|
width="80%" |
||||
|
append-to-body |
||||
|
:close-on-click-modal="true" |
||||
|
:show-close="true" |
||||
|
> |
||||
|
<div slot="title"> |
||||
|
<span style="padding-right: 10px;">Error Log</span> |
||||
|
<el-button |
||||
|
size="mini" |
||||
|
type="primary" |
||||
|
icon="el-icon-delete" |
||||
|
@click="clearAll" |
||||
|
style="float: right;margin-right: 30px;" |
||||
|
>清除全部</el-button> |
||||
|
</div> |
||||
|
<el-table :data="errorLogs" border> |
||||
|
<el-table-column label="Message"> |
||||
|
<template slot-scope="{row}"> |
||||
|
<div> |
||||
|
<span class="message-title">Msg:</span> |
||||
|
<el-tag type="danger"> |
||||
|
{{ row.err.message }} |
||||
|
</el-tag> |
||||
|
</div> |
||||
|
<br> |
||||
|
<div> |
||||
|
<span class="message-title" style="padding-right: 10px;">Info: </span> |
||||
|
<el-tag type="warning"> |
||||
|
{{ row.vm.$vnode.tag }} error in {{ row.info }} |
||||
|
</el-tag> |
||||
|
</div> |
||||
|
<br> |
||||
|
<div> |
||||
|
<span class="message-title" style="padding-right: 16px;">Url: </span> |
||||
|
<el-tag type="success"> |
||||
|
{{ row.url }} |
||||
|
</el-tag> |
||||
|
</div> |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
<el-table-column label="Stack"> |
||||
|
<template slot-scope="scope"> |
||||
|
{{ scope.row.err.stack }} |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
</el-table> |
||||
|
</el-dialog> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
export default { |
||||
|
name: 'ErrorLog', |
||||
|
data() { |
||||
|
return { |
||||
|
dialogTableVisible: false |
||||
|
} |
||||
|
}, |
||||
|
computed: { |
||||
|
errorLogs() { |
||||
|
return this.$store.getters.errorLogs |
||||
|
} |
||||
|
}, |
||||
|
methods: { |
||||
|
clearAll() { |
||||
|
this.dialogTableVisible = false |
||||
|
this.$store.dispatch('errorLog/clearErrorLog') |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style scoped> |
||||
|
.message-title { |
||||
|
font-size: 16px; |
||||
|
color: #333; |
||||
|
font-weight: bold; |
||||
|
padding-right: 8px; |
||||
|
} |
||||
|
</style> |
@ -0,0 +1,44 @@ |
|||||
|
<template> |
||||
|
<div style="padding: 0 15px;" @click="toggleClick"> |
||||
|
<svg |
||||
|
:class="{'is-active':isActive}" |
||||
|
class="hamburger" |
||||
|
viewBox="0 0 1024 1024" |
||||
|
xmlns="http://www.w3.org/2000/svg" |
||||
|
width="64" |
||||
|
height="64" |
||||
|
> |
||||
|
<path d="M408 442h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8zm-8 204c0 4.4 3.6 8 8 8h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56zm504-486H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 632H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM142.4 642.1L298.7 519a8.84 8.84 0 0 0 0-13.9L142.4 381.9c-5.8-4.6-14.4-.5-14.4 6.9v246.3a8.9 8.9 0 0 0 14.4 7z" /> |
||||
|
</svg> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
export default { |
||||
|
name: 'Hamburger', |
||||
|
props: { |
||||
|
isActive: { |
||||
|
type: Boolean, |
||||
|
default: false |
||||
|
} |
||||
|
}, |
||||
|
methods: { |
||||
|
toggleClick() { |
||||
|
this.$emit('toggleClick') |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style scoped> |
||||
|
.hamburger { |
||||
|
display: inline-block; |
||||
|
vertical-align: middle; |
||||
|
width: 20px; |
||||
|
height: 20px; |
||||
|
} |
||||
|
|
||||
|
.hamburger.is-active { |
||||
|
transform: rotate(180deg); |
||||
|
} |
||||
|
</style> |
@ -0,0 +1,190 @@ |
|||||
|
<template> |
||||
|
<div :class="{ show: show }" class="header-search"> |
||||
|
<svg-icon |
||||
|
class-name="search-icon" |
||||
|
icon-class="svg_search" |
||||
|
@click.stop="click" |
||||
|
/> |
||||
|
<el-select |
||||
|
ref="headerSearchSelect" |
||||
|
v-model="search" |
||||
|
:remote-method="querySearch" |
||||
|
filterable |
||||
|
default-first-option |
||||
|
remote |
||||
|
placeholder="搜索导航栏" |
||||
|
class="header-search-select" |
||||
|
@change="change" |
||||
|
> |
||||
|
<el-option |
||||
|
v-for="item in options" |
||||
|
:key="item.path" |
||||
|
:value="item" |
||||
|
:label="item.title.join(' > ')" |
||||
|
/> |
||||
|
</el-select> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
// fuse is a lightweight fuzzy-search module |
||||
|
// make search results more in line with expectations |
||||
|
import Fuse from 'fuse.js' |
||||
|
import path from 'path' |
||||
|
|
||||
|
export default { |
||||
|
name: 'HeaderSearch', |
||||
|
data () { |
||||
|
return { |
||||
|
search: '', |
||||
|
options: [], |
||||
|
searchPool: [], |
||||
|
show: false, |
||||
|
fuse: undefined |
||||
|
} |
||||
|
}, |
||||
|
computed: { |
||||
|
routes () { |
||||
|
return this.$store.getters.permission_routes |
||||
|
} |
||||
|
}, |
||||
|
watch: { |
||||
|
routes () { |
||||
|
this.searchPool = this.generateRoutes(this.routes) |
||||
|
}, |
||||
|
searchPool (list) { |
||||
|
this.initFuse(list) |
||||
|
}, |
||||
|
show (value) { |
||||
|
if (value) { |
||||
|
document.body.addEventListener('click', this.close) |
||||
|
} else { |
||||
|
document.body.removeEventListener('click', this.close) |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
mounted () { |
||||
|
this.searchPool = this.generateRoutes(this.routes) |
||||
|
}, |
||||
|
methods: { |
||||
|
click () { |
||||
|
this.show = !this.show |
||||
|
if (this.show) { |
||||
|
this.$refs.headerSearchSelect && this.$refs.headerSearchSelect.focus() |
||||
|
} |
||||
|
}, |
||||
|
close () { |
||||
|
this.$refs.headerSearchSelect && this.$refs.headerSearchSelect.blur() |
||||
|
this.options = [] |
||||
|
this.show = false |
||||
|
}, |
||||
|
change (val) { |
||||
|
this.$router.push(val.path) |
||||
|
this.search = '' |
||||
|
this.options = [] |
||||
|
this.$nextTick(() => { |
||||
|
this.show = false |
||||
|
}) |
||||
|
}, |
||||
|
initFuse (list) { |
||||
|
this.fuse = new Fuse(list, { |
||||
|
shouldSort: true, |
||||
|
threshold: 0.4, |
||||
|
location: 0, |
||||
|
distance: 100, |
||||
|
maxPatternLength: 32, |
||||
|
minMatchCharLength: 1, |
||||
|
keys: [{ |
||||
|
name: 'title', |
||||
|
weight: 0.7 |
||||
|
}, { |
||||
|
name: 'path', |
||||
|
weight: 0.3 |
||||
|
}] |
||||
|
}) |
||||
|
}, |
||||
|
// Filter out the routes that can be displayed in the sidebar |
||||
|
// And generate the internationalized title |
||||
|
generateRoutes (routes, basePath = '/', prefixTitle = []) { |
||||
|
let res = [] |
||||
|
|
||||
|
for (const router of routes) { |
||||
|
// skip hidden router |
||||
|
if (router.hidden) { continue } |
||||
|
|
||||
|
const data = { |
||||
|
path: path.resolve(basePath, router.path), |
||||
|
title: [...prefixTitle] |
||||
|
} |
||||
|
|
||||
|
if (router.meta && router.meta.title) { |
||||
|
data.title = [...data.title, router.meta.title] |
||||
|
|
||||
|
if (router.redirect !== 'noRedirect') { |
||||
|
// only push the routes with title |
||||
|
// special case: need to exclude parent router without redirect |
||||
|
res.push(data) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// recursive child routes |
||||
|
if (router.children) { |
||||
|
const tempRoutes = this.generateRoutes(router.children, data.path, data.title) |
||||
|
if (tempRoutes.length >= 1) { |
||||
|
res = [...res, ...tempRoutes] |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
return res |
||||
|
}, |
||||
|
querySearch (query) { |
||||
|
if (query !== '') { |
||||
|
this.options = this.fuse.search(query) |
||||
|
} else { |
||||
|
this.options = [] |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss" scoped> |
||||
|
.header-search { |
||||
|
font-size: 0 !important; |
||||
|
|
||||
|
.search-icon { |
||||
|
cursor: pointer; |
||||
|
font-size: 18px; |
||||
|
vertical-align: middle; |
||||
|
} |
||||
|
|
||||
|
.header-search-select { |
||||
|
font-size: 18px; |
||||
|
transition: width 0.2s; |
||||
|
width: 0; |
||||
|
overflow: hidden; |
||||
|
background: transparent; |
||||
|
border-radius: 0; |
||||
|
display: inline-block; |
||||
|
vertical-align: middle; |
||||
|
|
||||
|
::v-deep .el-input__inner { |
||||
|
border-radius: 0; |
||||
|
border: 0; |
||||
|
padding-left: 0; |
||||
|
padding-right: 0; |
||||
|
box-shadow: none !important; |
||||
|
border-bottom: 1px solid #d9d9d9; |
||||
|
vertical-align: middle; |
||||
|
background: transparent; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
&.show { |
||||
|
.header-search-select { |
||||
|
width: 210px; |
||||
|
margin-left: 10px; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</style> |
@ -0,0 +1,82 @@ |
|||||
|
<template> |
||||
|
<div class="pagination elPaginationOuter"> |
||||
|
<el-pagination |
||||
|
background |
||||
|
@size-change="handleSizeChange" |
||||
|
@current-change="handleCurrentChange" |
||||
|
:current-page="currentPage" |
||||
|
:page-sizes="trendTotalCount" |
||||
|
:page-size="pagesize" |
||||
|
layout="total, sizes, prev, pager, next, jumper" |
||||
|
:total="totalCount" |
||||
|
> |
||||
|
</el-pagination> |
||||
|
<el-button |
||||
|
class="goPageBtn" |
||||
|
type="primary" |
||||
|
size="mini" |
||||
|
>跳转</el-button> |
||||
|
</div> |
||||
|
</template> |
||||
|
<script> |
||||
|
// import { setResultCount } from "@/utils/auth" |
||||
|
export default { |
||||
|
name: 'pagination', |
||||
|
props: { |
||||
|
totalCount: { |
||||
|
type: Number, |
||||
|
default: 0 |
||||
|
}, |
||||
|
pagesizeProps: { |
||||
|
type: Number, |
||||
|
default: 0 |
||||
|
}, |
||||
|
currentPageProps: { |
||||
|
type: Number, |
||||
|
default: 1 |
||||
|
} |
||||
|
}, |
||||
|
computed:{ |
||||
|
trendTotalCount(){ |
||||
|
return [20,50,100] |
||||
|
} |
||||
|
}, |
||||
|
watch:{ |
||||
|
currentPageProps(n,o){ |
||||
|
this.currentPage = n |
||||
|
} |
||||
|
}, |
||||
|
data () { |
||||
|
return { |
||||
|
currentPage: 1, |
||||
|
pagesize: 0 |
||||
|
} |
||||
|
}, |
||||
|
mounted () { |
||||
|
this.pagesize = this.pagesizeProps |
||||
|
this.currentPage = this.currentPageProps |
||||
|
}, |
||||
|
methods: { |
||||
|
//每页最大条数改变提交emit |
||||
|
handleSizeChange (val) { |
||||
|
// setResultCount(val) |
||||
|
this.pagesize = val |
||||
|
this.$emit('SizeChange', val) |
||||
|
}, |
||||
|
//当前页改变提交emit |
||||
|
handleCurrentChange (val) { |
||||
|
this.currentPage = val |
||||
|
this.$emit('CurrentChange', val) |
||||
|
}, |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
</script> |
||||
|
<style scoped> |
||||
|
.goPageBtn{ |
||||
|
margin-left: 20px; |
||||
|
background: #e8f4ff; |
||||
|
color:#409EFF; |
||||
|
border:none |
||||
|
} |
||||
|
</style> |
@ -0,0 +1,149 @@ |
|||||
|
<template> |
||||
|
<div ref="rightPanel" :class="{ show: show }" class="rightPanel-container"> |
||||
|
<div class="rightPanel-background" /> |
||||
|
<div class="rightPanel"> |
||||
|
<div |
||||
|
class="handle-button" |
||||
|
:style="{ top: buttonTop + 'px', 'background-color': theme }" |
||||
|
@click="show = !show" |
||||
|
> |
||||
|
<i :class="show?'el-icon-close':'el-icon-setting'" /> |
||||
|
</div> |
||||
|
<div class="rightPanel-items"> |
||||
|
<slot /> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import { addClass, removeClass } from '@/utils' |
||||
|
|
||||
|
export default { |
||||
|
name: 'RightPanel', |
||||
|
props: { |
||||
|
clickNotClose: { |
||||
|
default: false, |
||||
|
type: Boolean |
||||
|
}, |
||||
|
buttonTop: { |
||||
|
default: 250, |
||||
|
type: Number |
||||
|
} |
||||
|
}, |
||||
|
data () { |
||||
|
return { |
||||
|
show: false |
||||
|
} |
||||
|
}, |
||||
|
computed: { |
||||
|
theme () { |
||||
|
return this.$store.state.settings.theme |
||||
|
} |
||||
|
}, |
||||
|
watch: { |
||||
|
show (value) { |
||||
|
if (value && !this.clickNotClose) { |
||||
|
this.addEventClick() |
||||
|
} |
||||
|
if (value) { |
||||
|
addClass(document.body, 'showRightPanel') |
||||
|
} else { |
||||
|
removeClass(document.body, 'showRightPanel') |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
mounted () { |
||||
|
this.insertToBody() |
||||
|
}, |
||||
|
beforeDestroy () { |
||||
|
const elx = this.$refs.rightPanel |
||||
|
elx.remove() |
||||
|
}, |
||||
|
methods: { |
||||
|
addEventClick () { |
||||
|
window.addEventListener('click', this.closeSidebar) |
||||
|
}, |
||||
|
closeSidebar (evt) { |
||||
|
const parent = evt.target.closest('.rightPanel') |
||||
|
if (!parent) { |
||||
|
this.show = false |
||||
|
window.removeEventListener('click', this.closeSidebar) |
||||
|
} |
||||
|
}, |
||||
|
insertToBody () { |
||||
|
const elx = this.$refs.rightPanel |
||||
|
const body = document.querySelector('body') |
||||
|
body.insertBefore(elx, body.firstChild) |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style> |
||||
|
.showRightPanel { |
||||
|
overflow: hidden; |
||||
|
position: relative; |
||||
|
width: calc(100% - 15px); |
||||
|
} |
||||
|
</style> |
||||
|
|
||||
|
<style lang="scss" scoped> |
||||
|
.rightPanel-background { |
||||
|
position: fixed; |
||||
|
top: 0; |
||||
|
left: 0; |
||||
|
opacity: 0; |
||||
|
transition: opacity 0.3s cubic-bezier(0.7, 0.3, 0.1, 1); |
||||
|
background: rgba(0, 0, 0, 0.2); |
||||
|
z-index: -1; |
||||
|
} |
||||
|
|
||||
|
.rightPanel { |
||||
|
width: 100%; |
||||
|
max-width: 260px; |
||||
|
height: 100vh; |
||||
|
position: fixed; |
||||
|
top: 0; |
||||
|
right: 0; |
||||
|
box-shadow: 0px 0px 15px 0px rgba(0, 0, 0, 0.05); |
||||
|
transition: all 0.25s cubic-bezier(0.7, 0.3, 0.1, 1); |
||||
|
transform: translate(100%); |
||||
|
background: #fff; |
||||
|
z-index: 40000; |
||||
|
} |
||||
|
|
||||
|
.show { |
||||
|
transition: all 0.3s cubic-bezier(0.7, 0.3, 0.1, 1); |
||||
|
|
||||
|
.rightPanel-background { |
||||
|
z-index: 20000; |
||||
|
opacity: 1; |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
} |
||||
|
|
||||
|
.rightPanel { |
||||
|
transform: translate(0); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.handle-button { |
||||
|
width: 48px; |
||||
|
height: 48px; |
||||
|
position: absolute; |
||||
|
left: -48px; |
||||
|
text-align: center; |
||||
|
font-size: 24px; |
||||
|
border-radius: 6px 0 0 6px !important; |
||||
|
z-index: 0; |
||||
|
pointer-events: auto; |
||||
|
cursor: pointer; |
||||
|
color: #fff; |
||||
|
line-height: 48px; |
||||
|
i { |
||||
|
font-size: 24px; |
||||
|
line-height: 48px; |
||||
|
} |
||||
|
} |
||||
|
</style> |
@ -0,0 +1,60 @@ |
|||||
|
<template> |
||||
|
<div> |
||||
|
<svg-icon |
||||
|
:icon-class="isFullscreen?'svg_exitFullscreen':'svg_fullscreen'" |
||||
|
@click="click" |
||||
|
/> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import screenfull from 'screenfull' |
||||
|
|
||||
|
export default { |
||||
|
name: 'Screenfull', |
||||
|
data () { |
||||
|
return { |
||||
|
isFullscreen: false |
||||
|
} |
||||
|
}, |
||||
|
mounted () { |
||||
|
this.init() |
||||
|
}, |
||||
|
beforeDestroy () { |
||||
|
this.destroy() |
||||
|
}, |
||||
|
methods: { |
||||
|
click () { |
||||
|
if (!screenfull.enabled) { |
||||
|
this.$warningMsg('you browser can not work') |
||||
|
return false |
||||
|
} |
||||
|
screenfull.toggle() |
||||
|
}, |
||||
|
change () { |
||||
|
this.isFullscreen = screenfull.isFullscreen |
||||
|
}, |
||||
|
init () { |
||||
|
if (screenfull.enabled) { |
||||
|
screenfull.on('change', this.change) |
||||
|
} |
||||
|
}, |
||||
|
destroy () { |
||||
|
if (screenfull.enabled) { |
||||
|
screenfull.off('change', this.change) |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style scoped> |
||||
|
.screenfull-svg { |
||||
|
display: inline-block; |
||||
|
cursor: pointer; |
||||
|
fill: #5a5e66; |
||||
|
width: 20px; |
||||
|
height: 20px; |
||||
|
vertical-align: 10px; |
||||
|
} |
||||
|
</style> |
@ -0,0 +1,58 @@ |
|||||
|
<template> |
||||
|
<el-dropdown trigger="click" @command="handleSetSize"> |
||||
|
<div> |
||||
|
<svg-icon class-name="size-icon" icon-class="size" /> |
||||
|
</div> |
||||
|
<el-dropdown-menu slot="dropdown"> |
||||
|
<el-dropdown-item |
||||
|
v-for="item of sizeOptions" |
||||
|
:key="item.value" |
||||
|
:disabled="size === item.value" |
||||
|
:command="item.value" |
||||
|
> |
||||
|
{{ item.label }} |
||||
|
</el-dropdown-item> |
||||
|
</el-dropdown-menu> |
||||
|
</el-dropdown> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
export default { |
||||
|
data () { |
||||
|
return { |
||||
|
sizeOptions: [ |
||||
|
{ label: 'Default', value: 'default' }, |
||||
|
{ label: 'Medium', value: 'medium' }, |
||||
|
{ label: 'Small', value: 'small' }, |
||||
|
{ label: 'Mini', value: 'mini' } |
||||
|
] |
||||
|
} |
||||
|
}, |
||||
|
computed: { |
||||
|
size () { |
||||
|
return this.$store.getters.size |
||||
|
} |
||||
|
}, |
||||
|
methods: { |
||||
|
handleSetSize (size) { |
||||
|
this.$ELEMENT.size = size |
||||
|
this.$store.dispatch('app/setSize', size) |
||||
|
this.refreshView() |
||||
|
this.$successMsg('Switch Size Success') |
||||
|
}, |
||||
|
refreshView () { |
||||
|
// In order to make the cached page re-rendered |
||||
|
this.$store.dispatch('tagsView/delAllCachedViews', this.$route) |
||||
|
|
||||
|
const { fullPath } = this.$route |
||||
|
|
||||
|
this.$nextTick(() => { |
||||
|
this.$router.replace({ |
||||
|
path: '/redirect' + fullPath |
||||
|
}) |
||||
|
}) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
</script> |
@ -0,0 +1,213 @@ |
|||||
|
<template> |
||||
|
<div class="StepsFormAloneComponents"> |
||||
|
<div |
||||
|
class="pageMainContain" |
||||
|
:class="stepsDirection && stepsDirection == 'vertical' ? 'pageMainContainVertical' : ''" |
||||
|
> |
||||
|
<!-- 步骤流程图 --> |
||||
|
<div class="stepsContain"> |
||||
|
<el-steps |
||||
|
:active="active" |
||||
|
:process-status="processStatus" |
||||
|
:finish-status="finishStatus" |
||||
|
:direction="stepsDirection" |
||||
|
:space="stepsSpace" |
||||
|
:align-center="stepsAlignCenter" |
||||
|
:simple="stepsSimple" |
||||
|
:style="stepsStyle" |
||||
|
> |
||||
|
<el-step |
||||
|
v-for="(item, index) in steps" |
||||
|
:key="index" |
||||
|
:title="item.title" |
||||
|
:description="item.description" |
||||
|
:icon="item.icon" |
||||
|
></el-step> |
||||
|
</el-steps> |
||||
|
</div> |
||||
|
|
||||
|
<!-- 步骤对应页面内容 --> |
||||
|
<div class="allStepPages"> |
||||
|
<div |
||||
|
v-for="(item,index) in steps" |
||||
|
:key="index" |
||||
|
v-show="active == index" |
||||
|
class="stepBottomPage" |
||||
|
:class="'stepBottomPage'+(index+1)" |
||||
|
> |
||||
|
<slot :name="'stepSlot'+(index+1)"></slot> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<!-- 操作按钮 --> |
||||
|
<div class="stepsHandleBtns" v-if="(!((active == stepArray.length - 1) && hideLastBtsn))"> |
||||
|
<!-- 组件内已有按钮【前面】其他按钮位置插槽 --> |
||||
|
<slot name="stepOtherBeforeButton"></slot> |
||||
|
<!-- 组件内按钮 --> |
||||
|
<el-button |
||||
|
v-for="(item,index) in handleBtns" |
||||
|
:key="index" |
||||
|
v-show="!(active == 0 && item.name == 'cancle')" |
||||
|
:type="item.type" |
||||
|
@click="stepsHandleClick(item,index)" |
||||
|
:class="'stepsAloneBtn-'+item.name" |
||||
|
>{{item.label}}</el-button> |
||||
|
<!-- 组件内已有按钮【后面】其他按钮位置插槽 --> |
||||
|
<slot name="stepOtherAfterButton"></slot> |
||||
|
</div> |
||||
|
</div> |
||||
|
</template> |
||||
|
<script> |
||||
|
export default { |
||||
|
name: 'StepsFormAlone', |
||||
|
props: { |
||||
|
stepsStyle:{ |
||||
|
type: Object, |
||||
|
default: () => { |
||||
|
return {} |
||||
|
} |
||||
|
}, |
||||
|
// 结束状态 |
||||
|
finishStatus:{ |
||||
|
type: String, |
||||
|
default: 'success' |
||||
|
}, |
||||
|
// 当前步骤的状态 |
||||
|
processStatus:{ |
||||
|
type: String, |
||||
|
default: 'success' |
||||
|
}, |
||||
|
// 单独设置步骤名称 |
||||
|
stepNames: { |
||||
|
type: Array, |
||||
|
default: () => { |
||||
|
return null |
||||
|
} |
||||
|
}, |
||||
|
//步骤options |
||||
|
stepArray: { |
||||
|
type: Array, |
||||
|
default: () => { |
||||
|
return [ |
||||
|
{title:"步骤一",description:"",icon:"",status:null}, |
||||
|
{title:"步骤二",description:"",icon:"",status:null}, |
||||
|
{title:"步骤三",description:"",icon:"",status:null}, |
||||
|
] |
||||
|
} |
||||
|
}, |
||||
|
// 显示方向 如果更改为vertical:最好与stepsAlignCenter=false同步赋值 |
||||
|
stepsDirection:{ |
||||
|
type: String, |
||||
|
default: 'horizontal' |
||||
|
}, |
||||
|
//居中对齐 |
||||
|
stepsAlignCenter: { |
||||
|
type: Boolean, |
||||
|
default: () => { |
||||
|
return true |
||||
|
} |
||||
|
}, |
||||
|
// 每个 step 的间距 |
||||
|
stepsSpace:{ |
||||
|
type: Number, |
||||
|
default: null |
||||
|
}, |
||||
|
//简洁风格 |
||||
|
stepsSimple: { |
||||
|
type: Boolean, |
||||
|
default: () => { |
||||
|
return false |
||||
|
} |
||||
|
}, |
||||
|
// 步骤操作 |
||||
|
stepHandleFuncs:{ |
||||
|
type: Object, |
||||
|
default: () => {} |
||||
|
}, |
||||
|
// 最后一步是否隐藏按钮 |
||||
|
hideLastBtsn:{ |
||||
|
type: Boolean, |
||||
|
default: () => { |
||||
|
return false |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
data () { |
||||
|
return { |
||||
|
active: 0, |
||||
|
steps: null,//步骤标头 |
||||
|
// 操作按钮 |
||||
|
handleBtns:[ |
||||
|
{name:"cancle",label:"上一步"}, |
||||
|
{name:"next",label:"下一步",type:"primary"}, |
||||
|
] |
||||
|
} |
||||
|
}, |
||||
|
created(){ |
||||
|
this.initStepsOption() |
||||
|
}, |
||||
|
mounted () { |
||||
|
}, |
||||
|
methods: { |
||||
|
// 设置步骤标头 |
||||
|
initStepsOption(){ |
||||
|
this.steps = Object.assign([], this.stepArray); |
||||
|
if(!this.stepNames)return; |
||||
|
this.stepNames.forEach((item,key)=>{ |
||||
|
if(key < this.steps.length) |
||||
|
this.steps[key].title = item |
||||
|
}) |
||||
|
}, |
||||
|
// 操作按钮 |
||||
|
stepsHandleClick(item,index){ |
||||
|
// 上一步 |
||||
|
if(item.name == 'cancle'){ |
||||
|
if(this.steps[this.active].cancle){ |
||||
|
this.steps[this.active].cancle().then((data) => { |
||||
|
this.active -- |
||||
|
}).catch((err) => { |
||||
|
console.log('cancle-err',err) |
||||
|
}) |
||||
|
}else{ |
||||
|
this.active -- |
||||
|
} |
||||
|
} |
||||
|
// 下一步 |
||||
|
if(item.name == 'next'){ |
||||
|
// 非最后一步 |
||||
|
if(this.active < this.steps.length - 1){ |
||||
|
if(this.steps[this.active].next){ |
||||
|
this.steps[this.active].next().then(res => { |
||||
|
this.active ++ |
||||
|
}).catch((err) => { |
||||
|
console.log('next-err',err) |
||||
|
}) |
||||
|
}else{ |
||||
|
this.active ++ |
||||
|
} |
||||
|
} |
||||
|
// 最后一步 |
||||
|
else{ |
||||
|
if(this.steps[this.active].next){ |
||||
|
this.steps[this.active].next() |
||||
|
// .then(res => { |
||||
|
// // 回到第一步 |
||||
|
// this.returnFirstActive() |
||||
|
// console.log('res',res) |
||||
|
// }).catch((err) => { |
||||
|
// console.log('next-err',err) |
||||
|
// }) |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
returnFirstActive(){ |
||||
|
this.active = 0 |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
<style lang="scss" scoped> |
||||
|
@import "./style/index.scss"; |
||||
|
</style> |
@ -0,0 +1,44 @@ |
|||||
|
.StepsFormAloneComponents{ |
||||
|
padding: 30px 30px 20px; |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
box-sizing: border-box; |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
|
||||
|
.allStepPages{ |
||||
|
height: calc(100% - 110px); |
||||
|
margin-top: 30px; |
||||
|
|
||||
|
.stepBottomPage{ |
||||
|
height: 100%; |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.stepsHandleBtns{ |
||||
|
display: flex; |
||||
|
justify-content: flex-end; |
||||
|
} |
||||
|
|
||||
|
.pageMainContain{ |
||||
|
height: 100%; |
||||
|
|
||||
|
// 竖排列 |
||||
|
&.pageMainContainVertical{ |
||||
|
display: flex; |
||||
|
|
||||
|
.stepsContain{ |
||||
|
min-width: 260px; |
||||
|
flex-shrink: 0; |
||||
|
padding: 30px 0; |
||||
|
} |
||||
|
|
||||
|
.allStepPages{ |
||||
|
width: 100%; |
||||
|
height: calc(100% - 50px); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,62 @@ |
|||||
|
<template> |
||||
|
<div v-if="isExternal" :style="styleExternalIcon" class="svg-external-icon svg-icon" v-on="$listeners" /> |
||||
|
<svg v-else :class="svgClass" aria-hidden="true" v-on="$listeners"> |
||||
|
<use :xlink:href="iconName" /> |
||||
|
</svg> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
// doc: https://panjiachen.github.io/vue-element-admin-site/feature/component/svg-icon.html#usage |
||||
|
import { isExternal } from '@/utils/validate' |
||||
|
|
||||
|
export default { |
||||
|
name: 'SvgIcon', |
||||
|
props: { |
||||
|
iconClass: { |
||||
|
type: String, |
||||
|
required: true |
||||
|
}, |
||||
|
className: { |
||||
|
type: String, |
||||
|
default: '' |
||||
|
} |
||||
|
}, |
||||
|
computed: { |
||||
|
isExternal() { |
||||
|
return isExternal(this.iconClass) |
||||
|
}, |
||||
|
iconName() { |
||||
|
return `#icon-${this.iconClass}` |
||||
|
}, |
||||
|
svgClass() { |
||||
|
if (this.className) { |
||||
|
return 'svg-icon ' + this.className |
||||
|
} else { |
||||
|
return 'svg-icon' |
||||
|
} |
||||
|
}, |
||||
|
styleExternalIcon() { |
||||
|
return { |
||||
|
mask: `url(${this.iconClass}) no-repeat 50% 50%`, |
||||
|
'-webkit-mask': `url(${this.iconClass}) no-repeat 50% 50%` |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style scoped> |
||||
|
.svg-icon { |
||||
|
width: 1em; |
||||
|
height: 1em; |
||||
|
vertical-align: -0.15em; |
||||
|
fill: currentColor; |
||||
|
overflow: hidden; |
||||
|
} |
||||
|
|
||||
|
.svg-external-icon { |
||||
|
background-color: currentColor; |
||||
|
mask-size: cover!important; |
||||
|
display: inline-block; |
||||
|
} |
||||
|
</style> |
@ -0,0 +1,173 @@ |
|||||
|
<template> |
||||
|
<el-color-picker |
||||
|
v-model="theme" |
||||
|
:predefine="['#409EFF', '#1890ff', '#304156','#212121','#11a983', '#13c2c2', '#6959CD', '#f5222d', ]" |
||||
|
class="theme-picker" |
||||
|
popper-class="theme-picker-dropdown" |
||||
|
/> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
const version = require('element-ui/package.json').version // element-ui version from node_modules |
||||
|
const ORIGINAL_THEME = '#409EFF' // default color |
||||
|
|
||||
|
export default { |
||||
|
data() { |
||||
|
return { |
||||
|
chalk: '', // content of theme-chalk css |
||||
|
theme: '' |
||||
|
} |
||||
|
}, |
||||
|
computed: { |
||||
|
defaultTheme() { |
||||
|
return this.$store.state.settings.theme |
||||
|
} |
||||
|
}, |
||||
|
watch: { |
||||
|
defaultTheme: { |
||||
|
handler: function(val, oldVal) { |
||||
|
this.theme = val |
||||
|
}, |
||||
|
immediate: true |
||||
|
}, |
||||
|
async theme(val) { |
||||
|
const oldVal = this.chalk ? this.theme : ORIGINAL_THEME |
||||
|
if (typeof val !== 'string') return |
||||
|
const themeCluster = this.getThemeCluster(val.replace('#', '')) |
||||
|
const originalCluster = this.getThemeCluster(oldVal.replace('#', '')) |
||||
|
const $message = this.$message({ |
||||
|
message: ' Compiling the theme', |
||||
|
customClass: 'theme-message', |
||||
|
type: 'success', |
||||
|
duration: 0, |
||||
|
iconClass: 'el-icon-loading' |
||||
|
}) |
||||
|
|
||||
|
const getHandler = (variable, id) => { |
||||
|
return () => { |
||||
|
const originalCluster = this.getThemeCluster(ORIGINAL_THEME.replace('#', '')) |
||||
|
const newStyle = this.updateStyle(this[variable], originalCluster, themeCluster) |
||||
|
|
||||
|
let styleTag = document.getElementById(id) |
||||
|
if (!styleTag) { |
||||
|
styleTag = document.createElement('style') |
||||
|
styleTag.setAttribute('id', id) |
||||
|
document.head.appendChild(styleTag) |
||||
|
} |
||||
|
styleTag.innerText = newStyle |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if (!this.chalk) { |
||||
|
const url = `https://unpkg.com/element-ui@${version}/lib/theme-chalk/index.css` |
||||
|
await this.getCSSString(url, 'chalk') |
||||
|
} |
||||
|
|
||||
|
const chalkHandler = getHandler('chalk', 'chalk-style') |
||||
|
|
||||
|
chalkHandler() |
||||
|
|
||||
|
const styles = [].slice.call(document.querySelectorAll('style')) |
||||
|
.filter(style => { |
||||
|
const text = style.innerText |
||||
|
return new RegExp(oldVal, 'i').test(text) && !/Chalk Variables/.test(text) |
||||
|
}) |
||||
|
styles.forEach(style => { |
||||
|
const { innerText } = style |
||||
|
if (typeof innerText !== 'string') return |
||||
|
style.innerText = this.updateStyle(innerText, originalCluster, themeCluster) |
||||
|
}) |
||||
|
|
||||
|
this.$emit('change', val) |
||||
|
|
||||
|
$message.close() |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
methods: { |
||||
|
updateStyle(style, oldCluster, newCluster) { |
||||
|
let newStyle = style |
||||
|
oldCluster.forEach((color, index) => { |
||||
|
newStyle = newStyle.replace(new RegExp(color, 'ig'), newCluster[index]) |
||||
|
}) |
||||
|
return newStyle |
||||
|
}, |
||||
|
|
||||
|
getCSSString(url, variable) { |
||||
|
return new Promise(resolve => { |
||||
|
const xhr = new XMLHttpRequest() |
||||
|
xhr.onreadystatechange = () => { |
||||
|
if (xhr.readyState === 4 && xhr.status === 200) { |
||||
|
this[variable] = xhr.responseText.replace(/@font-face{[^}]+}/, '') |
||||
|
resolve() |
||||
|
} |
||||
|
} |
||||
|
xhr.open('GET', url) |
||||
|
xhr.send() |
||||
|
}) |
||||
|
}, |
||||
|
|
||||
|
getThemeCluster(theme) { |
||||
|
const tintColor = (color, tint) => { |
||||
|
let red = parseInt(color.slice(0, 2), 16) |
||||
|
let green = parseInt(color.slice(2, 4), 16) |
||||
|
let blue = parseInt(color.slice(4, 6), 16) |
||||
|
|
||||
|
if (tint === 0) { // when primary color is in its rgb space |
||||
|
return [red, green, blue].join(',') |
||||
|
} else { |
||||
|
red += Math.round(tint * (255 - red)) |
||||
|
green += Math.round(tint * (255 - green)) |
||||
|
blue += Math.round(tint * (255 - blue)) |
||||
|
|
||||
|
red = red.toString(16) |
||||
|
green = green.toString(16) |
||||
|
blue = blue.toString(16) |
||||
|
|
||||
|
return `#${red}${green}${blue}` |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
const shadeColor = (color, shade) => { |
||||
|
let red = parseInt(color.slice(0, 2), 16) |
||||
|
let green = parseInt(color.slice(2, 4), 16) |
||||
|
let blue = parseInt(color.slice(4, 6), 16) |
||||
|
|
||||
|
red = Math.round((1 - shade) * red) |
||||
|
green = Math.round((1 - shade) * green) |
||||
|
blue = Math.round((1 - shade) * blue) |
||||
|
|
||||
|
red = red.toString(16) |
||||
|
green = green.toString(16) |
||||
|
blue = blue.toString(16) |
||||
|
|
||||
|
return `#${red}${green}${blue}` |
||||
|
} |
||||
|
|
||||
|
const clusters = [theme] |
||||
|
for (let i = 0; i <= 9; i++) { |
||||
|
clusters.push(tintColor(theme, Number((i / 10).toFixed(2)))) |
||||
|
} |
||||
|
clusters.push(shadeColor(theme, 0.1)) |
||||
|
return clusters |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style> |
||||
|
.theme-message, |
||||
|
.theme-picker-dropdown { |
||||
|
z-index: 99999 !important; |
||||
|
} |
||||
|
|
||||
|
.theme-picker .el-color-picker__trigger { |
||||
|
height: 26px !important; |
||||
|
width: 26px !important; |
||||
|
padding: 2px; |
||||
|
} |
||||
|
|
||||
|
.theme-picker-dropdown .el-color-dropdown__link-btn { |
||||
|
display: none; |
||||
|
} |
||||
|
</style> |
@ -0,0 +1,324 @@ |
|||||
|
<template> |
||||
|
<el-dialog |
||||
|
title="导入" |
||||
|
element-loading-text="正在导入..." |
||||
|
:visible.sync="show" |
||||
|
:append-to-body="false" |
||||
|
:modal-append-to-body="false" |
||||
|
:fullscreen="true" |
||||
|
v-loading="loading" |
||||
|
:modal="false" |
||||
|
> |
||||
|
<!-- v-loading.fullscreen.lock="loading" --> |
||||
|
<el-button |
||||
|
type="success" |
||||
|
size="mini" |
||||
|
icon="el-icon-download" |
||||
|
@click="postImportDown" |
||||
|
>获取模板</el-button |
||||
|
> |
||||
|
<!-- <el-button |
||||
|
type="warning" |
||||
|
size="mini" |
||||
|
icon="el-icon-upload" |
||||
|
@click="postImportDown" |
||||
|
>导入数据</el-button |
||||
|
> --> |
||||
|
<input ref="excel-upload-input" class="excel-upload-input" type="file" accept=".xlsx, .xls" @change="handleClick"> |
||||
|
<el-button |
||||
|
:loading="loading" |
||||
|
style="margin-left:16px;" |
||||
|
size="mini" |
||||
|
type="primary" |
||||
|
@click="handleUpload" |
||||
|
icon="el-icon-download" |
||||
|
> |
||||
|
导入数据 |
||||
|
</el-button> |
||||
|
<!-- <el-button |
||||
|
:loading="loading" |
||||
|
style="margin-left:16px;" |
||||
|
size="mini" |
||||
|
type="warning" |
||||
|
@click="handlePrint()" |
||||
|
icon="el-icon-printer" |
||||
|
> |
||||
|
全部打印 |
||||
|
</el-button> --> |
||||
|
<!-- <div class="drop" @drop="handleDrop" @dragover="handleDragover" @dragenter="handleDragover"> |
||||
|
Drop excel file here or |
||||
|
<el-button :loading="loading" style="margin-left:16px;" size="mini" type="primary" @click="handleUpload"> |
||||
|
Browse |
||||
|
</el-button> |
||||
|
</div> --> |
||||
|
<div style="height:calc(100% - 60px)" id="tableOuter"> |
||||
|
<el-table |
||||
|
:data="excelData.results" |
||||
|
border |
||||
|
highlight-current-row |
||||
|
style="width: 100%;margin-top:20px;" |
||||
|
:max-height="tableMaxHeight" |
||||
|
> |
||||
|
<!-- @selection-change="handleSelectionPrint" --> |
||||
|
<!-- <el-table-column type="selection" width="55"></el-table-column> --> |
||||
|
<el-table-column |
||||
|
v-if="excelData.header.length > 0" |
||||
|
type="index" |
||||
|
fixed="left" |
||||
|
label="序号" |
||||
|
width="50" |
||||
|
/> |
||||
|
<el-table-column |
||||
|
v-for="(item,index) of excelData.header" |
||||
|
:key="index" |
||||
|
:prop="item" |
||||
|
:label="item" |
||||
|
:fixed="headerFixed(item)" |
||||
|
/> |
||||
|
<!-- <el-table-column v-if="excelData.header.length > 0" label="明细-箱标签" fixed="right" width="100"> |
||||
|
<template slot-scope="scope"> |
||||
|
{{scope.row['明细-箱标签']}} |
||||
|
</template> |
||||
|
</el-table-column> --> |
||||
|
<!-- <el-table-column label="操作" fixed="right"> |
||||
|
<template slot-scope="scope"> |
||||
|
<el-button type="text" @click="handlePrint([scope.row])">打印</el-button> |
||||
|
</template> |
||||
|
</el-table-column> --> |
||||
|
</el-table> |
||||
|
</div> |
||||
|
<span slot="footer" class="dialog-footer"> |
||||
|
<el-button @click="submitForm(0)">取 消</el-button> |
||||
|
<el-button type="primary" @click="submitForm(1)">确 定</el-button> |
||||
|
</span> |
||||
|
</el-dialog> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import XLSX from 'xlsx' |
||||
|
import { mixins } from "@/mixins/mixins" |
||||
|
|
||||
|
export default { |
||||
|
name:"UploadExcel", |
||||
|
mixins:[mixins], |
||||
|
watch: { |
||||
|
show () { |
||||
|
this.reset() |
||||
|
} |
||||
|
}, |
||||
|
props: { |
||||
|
//表头浮动项 |
||||
|
fixedArr:{ |
||||
|
type:Array, |
||||
|
default: () => { |
||||
|
return [] |
||||
|
} |
||||
|
}, |
||||
|
fixedLeftArr:{ |
||||
|
type:Array, |
||||
|
default:null |
||||
|
}, |
||||
|
show: { |
||||
|
type: Boolean, |
||||
|
default: false |
||||
|
}, |
||||
|
beforeUpload: Function, // eslint-disable-line |
||||
|
onSuccess: Function// eslint-disable-line |
||||
|
}, |
||||
|
data() { |
||||
|
return { |
||||
|
loading: false, |
||||
|
excelData: { |
||||
|
header: [], |
||||
|
results: [] |
||||
|
}, |
||||
|
// printSelection:[],//已选打印 |
||||
|
tableMaxHeight:null,//表格流体最大高度 |
||||
|
} |
||||
|
}, |
||||
|
methods: { |
||||
|
// 数据重置 |
||||
|
reset(){ |
||||
|
this.excelData = { |
||||
|
header:[], |
||||
|
results:[] |
||||
|
} |
||||
|
this.loading = false |
||||
|
// this.printSelection = []; |
||||
|
}, |
||||
|
headerFixed(item){ |
||||
|
let _fix = false |
||||
|
this.fixedArr.forEach(fix=>{ |
||||
|
if(fix.name == item){ |
||||
|
_fix = fix.value |
||||
|
} |
||||
|
}) |
||||
|
return _fix |
||||
|
}, |
||||
|
/** |
||||
|
* 按钮操作 |
||||
|
* index 0:取消,1:确定 |
||||
|
*/ |
||||
|
submitForm(index) { |
||||
|
this.$emit("submitForm", index,this.excelData); |
||||
|
}, |
||||
|
// 多选 |
||||
|
// handleSelectionPrint(val) { |
||||
|
// this.printSelection = val; |
||||
|
// }, |
||||
|
/** |
||||
|
* 打印 |
||||
|
* arr 有参数为单独打印,无参数为批量打印 |
||||
|
*/ |
||||
|
// handlePrint(arr){ |
||||
|
// let rdlx = "xiangbq.rdlx"; |
||||
|
// let params = { |
||||
|
// "boxlabel":[] |
||||
|
// } |
||||
|
// // let printArr = arr ? arr : this.printSelection; |
||||
|
// let printArr = arr ? arr : this.excelData.results; |
||||
|
// if(!printArr || printArr.length <= 0){ |
||||
|
// this.$message({ |
||||
|
// message: '请选择要打印的数据', |
||||
|
// type: 'error' |
||||
|
// }); |
||||
|
// return |
||||
|
// } |
||||
|
// }, |
||||
|
postImportDown () { |
||||
|
this.$emit('postImportDown') |
||||
|
}, |
||||
|
// 成功后回显及渲染 |
||||
|
successShowExcel(header, results){ |
||||
|
this.excelData.header = header |
||||
|
this.excelData.results = results |
||||
|
this.tableMaxHeight = document.getElementById("tableOuter").clientHeight |
||||
|
this.loading = false |
||||
|
}, |
||||
|
generateData({ header, results }) { |
||||
|
// this.excelData.header = header |
||||
|
// this.excelData.results = results |
||||
|
// this.tableMaxHeight = document.getElementById("tableOuter").clientHeight |
||||
|
if(this.onSuccess){ |
||||
|
this.onSuccess(header, results).then((res_header, res_results)=>{ |
||||
|
let _header = res_header ? res_header : header; |
||||
|
let _results = res_results ? res_results : results; |
||||
|
this.successShowExcel(_header, _results) |
||||
|
}).catch(err=>{ |
||||
|
this.loading = false |
||||
|
}) |
||||
|
}else{ |
||||
|
this.successShowExcel(header, results) |
||||
|
} |
||||
|
}, |
||||
|
handleDrop(e) { |
||||
|
e.stopPropagation() |
||||
|
e.preventDefault() |
||||
|
if (this.loading) return |
||||
|
const files = e.dataTransfer.files |
||||
|
if (files.length !== 1) { |
||||
|
this.$message.error('Only support uploading one file!') |
||||
|
return |
||||
|
} |
||||
|
const rawFile = files[0] // only use files[0] |
||||
|
|
||||
|
if (!this.isExcel(rawFile)) { |
||||
|
this.$message.error('Only supports upload .xlsx, .xls, .csv suffix files') |
||||
|
return false |
||||
|
} |
||||
|
this.upload(rawFile) |
||||
|
e.stopPropagation() |
||||
|
e.preventDefault() |
||||
|
}, |
||||
|
handleDragover(e) { |
||||
|
e.stopPropagation() |
||||
|
e.preventDefault() |
||||
|
e.dataTransfer.dropEffect = 'copy' |
||||
|
}, |
||||
|
handleUpload() { |
||||
|
this.$refs['excel-upload-input'].click() |
||||
|
}, |
||||
|
handleClick(e) { |
||||
|
const files = e.target.files |
||||
|
const rawFile = files[0] // only use files[0] |
||||
|
if (!rawFile) return |
||||
|
this.upload(rawFile) |
||||
|
}, |
||||
|
upload(rawFile) { |
||||
|
this.loading = true |
||||
|
this.$refs['excel-upload-input'].value = null // fix can't select the same excel |
||||
|
|
||||
|
if (!this.beforeUpload) { |
||||
|
this.readerData(rawFile) |
||||
|
this.loading = false |
||||
|
return |
||||
|
} |
||||
|
const before = this.beforeUpload(rawFile) |
||||
|
if (before) { |
||||
|
this.readerData(rawFile) |
||||
|
} |
||||
|
}, |
||||
|
readerData(rawFile) { |
||||
|
return new Promise((resolve, reject) => { |
||||
|
const reader = new FileReader() |
||||
|
reader.onload = e => { |
||||
|
const data = e.target.result |
||||
|
// const workbook = XLSX.read(data, { type: 'array',cellText:false,cellDates:true }) |
||||
|
const workbook = XLSX.read(data, { type: 'array'}) |
||||
|
const firstSheetName = workbook.SheetNames[0] |
||||
|
const worksheet = workbook.Sheets[firstSheetName] |
||||
|
const header = this.getHeaderRow(worksheet) |
||||
|
const results = XLSX.utils.sheet_to_json(worksheet,{raw:false}) |
||||
|
// const results = XLSX.utils.sheet_to_json(worksheet) |
||||
|
if(results.length <= 0){ |
||||
|
this.$message.error('导入表格内无数据,请确认后重新导入'); |
||||
|
this.loading = false |
||||
|
return |
||||
|
} |
||||
|
this.generateData({ header, results }) |
||||
|
resolve() |
||||
|
this.tab |
||||
|
} |
||||
|
reader.readAsArrayBuffer(rawFile) |
||||
|
}) |
||||
|
}, |
||||
|
getHeaderRow(sheet) { |
||||
|
const headers = [] |
||||
|
const range = XLSX.utils.decode_range(sheet['!ref']) |
||||
|
let C |
||||
|
const R = range.s.r |
||||
|
/* start in the first row */ |
||||
|
for (C = range.s.c; C <= range.e.c; ++C) { /* walk every column in the range */ |
||||
|
const cell = sheet[XLSX.utils.encode_cell({ c: C, r: R })] |
||||
|
/* find the cell in the first row */ |
||||
|
let hdr = 'UNKNOWN ' + C // <-- replace with your desired default |
||||
|
if (cell && cell.t) hdr = XLSX.utils.format_cell(cell) |
||||
|
headers.push(hdr) |
||||
|
} |
||||
|
return headers |
||||
|
}, |
||||
|
isExcel(file) { |
||||
|
return /\.(xlsx|xls|csv)$/.test(file.name) |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style scoped> |
||||
|
.excel-upload-input{ |
||||
|
display: none; |
||||
|
z-index: -9999; |
||||
|
} |
||||
|
.drop{ |
||||
|
border: 2px dashed #bbb; |
||||
|
width: 600px; |
||||
|
height: 160px; |
||||
|
line-height: 160px; |
||||
|
margin: 0 auto; |
||||
|
font-size: 24px; |
||||
|
border-radius: 5px; |
||||
|
text-align: center; |
||||
|
color: #bbb; |
||||
|
position: relative; |
||||
|
} |
||||
|
</style> |
@ -0,0 +1,367 @@ |
|||||
|
<template> |
||||
|
<!-- 组件功能:普通新增编辑(目前只有主表)参数配置从api获取 --> |
||||
|
<el-dialog |
||||
|
:visible.sync="show" |
||||
|
:modal="false" |
||||
|
:modal-append-to-body="false" |
||||
|
:show-close="true" |
||||
|
@close="close" |
||||
|
class="searchPageComponents" |
||||
|
:fullscreen="true" |
||||
|
style="width:calc(100% - 28px);left:14px;top:14px;height:calc(100% - 28px)" |
||||
|
v-loading="Loading.addEditApiLoading" |
||||
|
> |
||||
|
<!-- 数据填写 --> |
||||
|
<div v-if="active === 0" style="height: 100%;"> |
||||
|
<div class="centerInnerContent" :class="{'hasDetails' : flexTableData}"> |
||||
|
<!-- 左侧主表 --> |
||||
|
<div class="leftMainForm"> |
||||
|
<div class="dialogOuterTitle">{{formTitle}} 【主表信息】</div> |
||||
|
<!-- 表单 --> |
||||
|
<el-form |
||||
|
class="addEditFrom" |
||||
|
ref="addEditFrom_Ref" |
||||
|
v-if="formData" |
||||
|
:model="formData" |
||||
|
:rules="formRules" |
||||
|
> |
||||
|
<el-row :gutter="40"> |
||||
|
<el-col |
||||
|
:span="item.colSpan || 12" |
||||
|
v-for="(item, index) in formItemData" |
||||
|
:key="index" |
||||
|
> |
||||
|
<el-form-item |
||||
|
:label="item.label" |
||||
|
:prop="item.prop" |
||||
|
v-if="item.label.toUpperCase() != 'DETAILS'" |
||||
|
> |
||||
|
<!-- 数值 --> |
||||
|
<el-input-number |
||||
|
v-if="item.apiBaseType === 'number'" |
||||
|
v-model="formData[item.prop]" |
||||
|
:min="item.minimum || undefined" |
||||
|
:max="item.maximum || undefined" |
||||
|
:maxlength="item.maxLength || undefined" |
||||
|
:minlength="item.minLength || undefined" |
||||
|
:disabled="Boolean(item.disabled)" |
||||
|
:placeholder="item.placeholder || '请输入' + item.label" |
||||
|
@change="changeValue(item.prop,item,$event)" |
||||
|
@clear="clearValue(item.prop,$event)" |
||||
|
></el-input-number> |
||||
|
|
||||
|
<!-- 时间转换 --> |
||||
|
<el-date-picker |
||||
|
v-else-if="item.apiBaseType === 'datetime'" |
||||
|
v-model="formData[item.prop]" |
||||
|
type="datetime" |
||||
|
placeholder="选择日期时间" |
||||
|
format="yyyy-MM-dd HH:mm:ss" |
||||
|
value-format="yyyy-MM-ddTHH:mm:ss" |
||||
|
:disabled="Boolean(item.disabled)" |
||||
|
></el-date-picker> |
||||
|
|
||||
|
<!-- 布尔、枚举 --> |
||||
|
<el-select |
||||
|
v-else-if="item.isEnums || item.apiBaseType === 'boolean'" |
||||
|
v-model="formData[item.prop]" |
||||
|
:placeholder="item.placeholder || '请选择' + item.label" |
||||
|
:disabled="Boolean(item.disabled)" |
||||
|
> |
||||
|
<el-option |
||||
|
v-for="item in item.enums_list" |
||||
|
:key="item.value" |
||||
|
:label="item.label" |
||||
|
:value="item.value" |
||||
|
></el-option> |
||||
|
</el-select> |
||||
|
|
||||
|
<!-- 文本框 --> |
||||
|
<!-- <el-input |
||||
|
v-else |
||||
|
type="textarea" |
||||
|
autosize |
||||
|
resize="none" |
||||
|
v-model="formData[item.prop]" |
||||
|
:placeholder="item.placeholder || '请输入' + item.label" |
||||
|
:disabled="Boolean(item.disabled)" |
||||
|
></el-input> --> |
||||
|
<el-input |
||||
|
v-else |
||||
|
v-model="formData[item.prop]" |
||||
|
:placeholder="item.placeholder || '请输入' + item.label" |
||||
|
:disabled="Boolean(item.disabled)" |
||||
|
></el-input> |
||||
|
</el-form-item> |
||||
|
</el-col> |
||||
|
</el-row> |
||||
|
</el-form> |
||||
|
</div> |
||||
|
<!-- 右侧子表 --> |
||||
|
<div class="rightDetailTable" v-if="flexTableData"> |
||||
|
<div class="dialogOuterTitle">{{formTitle}} 【子表信息】</div> |
||||
|
<currenTableFlex |
||||
|
ref="currenTableFlex_Ref" |
||||
|
:isShowIndex="true" |
||||
|
:isEditable="true" |
||||
|
:setUTableHeight="230" |
||||
|
class="currenTableFlex" |
||||
|
:flexTableData="flexTableData" |
||||
|
:flexTableColumns="flexTableColumns" |
||||
|
></currenTableFlex> |
||||
|
</div> |
||||
|
</div> |
||||
|
<!-- 操作按钮 --> |
||||
|
<div slot="footer" class="dialog-footer"> |
||||
|
<el-button @click="show = false">取 消</el-button> |
||||
|
<el-button type="primary" @click="submitHandle()">确 定</el-button> |
||||
|
</div> |
||||
|
</div> |
||||
|
<!-- 成功提示 --> |
||||
|
<div v-if="active === 1"> |
||||
|
<el-result icon="success" title="成功提示" :subTitle="formTitle + '成功'"> |
||||
|
<template slot="extra"> |
||||
|
<el-button type="primary" size="medium" @click="exitHandle" |
||||
|
>退出</el-button |
||||
|
> |
||||
|
</template> |
||||
|
</el-result> |
||||
|
</div> |
||||
|
<!-- 错误提示 --> |
||||
|
<div v-if="active === 2"> |
||||
|
<el-result icon="error" title="错误提示" :subTitle="formTitle + '失败'"> |
||||
|
<template slot="extra"> |
||||
|
<el-button type="primary" size="medium" @click="changeActive(0)" |
||||
|
>返回</el-button |
||||
|
> |
||||
|
<el-button type="primary" size="medium" @click="exitHandle" |
||||
|
>退出</el-button |
||||
|
> |
||||
|
</template> |
||||
|
</el-result> |
||||
|
</div> |
||||
|
</el-dialog> |
||||
|
</template> |
||||
|
<script> |
||||
|
import { ApiTypePost, ApiTypePut } from "@/api/wms-api" |
||||
|
import { LoadingMixins } from "@/mixins/LoadingMixins"; |
||||
|
import currenTableFlex from "@/components/currenTableFlex" |
||||
|
import * as allUrlOption from '@/utils/baseData/urlOption' |
||||
|
export default { |
||||
|
name:"addEditFromApiPop", |
||||
|
mixins:[ LoadingMixins ], |
||||
|
components: { currenTableFlex }, |
||||
|
props: { |
||||
|
// 编辑行数据 |
||||
|
editRowData:{ |
||||
|
type: Object, |
||||
|
default: null |
||||
|
}, |
||||
|
// 操作类型:add/edit |
||||
|
handleType:{ |
||||
|
type: String, |
||||
|
default: null |
||||
|
}, |
||||
|
// 提交事件 |
||||
|
submitForm:{ |
||||
|
type:Function, |
||||
|
default:null |
||||
|
}, |
||||
|
// 特殊的【新增】接口,如果没有就走路由下的配置文件 |
||||
|
addSubmitUrl:{ |
||||
|
type: String, |
||||
|
default: null |
||||
|
}, |
||||
|
// 特殊的【编辑】接口,如果没有就走路由下的配置文件 |
||||
|
editSubmitUrl:{ |
||||
|
type: String, |
||||
|
default: null |
||||
|
}, |
||||
|
}, |
||||
|
data () { |
||||
|
return { |
||||
|
//明细-列表 |
||||
|
URLOption_detailList:allUrlOption[this.$route.name].detailListURL, |
||||
|
// 当前的dto |
||||
|
currentDtos:this.$store.getters.dtoColumnTypes[this.$route.name], |
||||
|
active:0,//显示内容:0表单 1成功 2失败 |
||||
|
show:true, |
||||
|
formTitle:null,//form名称 |
||||
|
formData:{},//表单数据 |
||||
|
formItemData:null,//表单item配置 |
||||
|
formRules: {},//表单验证 |
||||
|
flexTableData:null,//子表table |
||||
|
// flexTableColumns:null,//子表table列 |
||||
|
flexTableColumns: null, |
||||
|
} |
||||
|
}, |
||||
|
mounted(){ |
||||
|
this.initTitle() |
||||
|
this.initFormItems() |
||||
|
}, |
||||
|
methods: { |
||||
|
// 初始化form名称 |
||||
|
initTitle(){ |
||||
|
if(this.handleType){ |
||||
|
this.formTitle = this.handleType == 'add' ? '新增'+this.$route.name : '编辑'+this.$route.name |
||||
|
} |
||||
|
}, |
||||
|
// 初始化表单配置、rules |
||||
|
initFormItems(){ |
||||
|
let _dtoList_type = this.handleType == 'add' ? 'C' : 'U' |
||||
|
let _dtoList = this.currentDtos[_dtoList_type].dtoList |
||||
|
// 除去子表信息 |
||||
|
let _formItems = _dtoList.filter(item=>{ |
||||
|
return item.prop.toUpperCase() != 'DETAILS' |
||||
|
}) |
||||
|
if(_formItems)this.formItemData = _formItems |
||||
|
// 编辑格式:特殊处理默认值 |
||||
|
if(this.handleType == 'edit' && this.editRowData){ |
||||
|
this.formData = JSON.parse(JSON.stringify(this.editRowData)) |
||||
|
}else{ |
||||
|
this.formData = {} |
||||
|
} |
||||
|
// 子表数据 |
||||
|
let _list = _dtoList.filter(item=>{ |
||||
|
return item.prop.toUpperCase() == 'DETAILS' |
||||
|
}) |
||||
|
if(_list && _list.length > 0){ |
||||
|
if(this.handleType == 'edit'){ |
||||
|
this.flexTableData = this.formData[_list[0].prop] |
||||
|
}else{ |
||||
|
this.flexTableData = [] |
||||
|
} |
||||
|
} |
||||
|
// 子表数据列 |
||||
|
if(this.URLOption_detailList){ |
||||
|
let _detailApi = this.URLOption_detailList.slice(0,this.URLOption_detailList.lastIndexOf('/')) |
||||
|
let _detailDtos = this.$store.getters.dtoColumnTypes[_detailApi].S.dtoList |
||||
|
this.flexTableColumns = _detailDtos |
||||
|
} |
||||
|
|
||||
|
// 表单验证格式化 |
||||
|
this.formRules={} |
||||
|
_dtoList.forEach(item=>{ |
||||
|
if(item.isRequired){ |
||||
|
this.formRules[item.prop] = [{ required: true, trigger: "blur", message: "不可为空" }] |
||||
|
} |
||||
|
}) |
||||
|
}, |
||||
|
// 关闭弹窗 |
||||
|
close() { |
||||
|
this.show = false |
||||
|
this.$emit("closePop") |
||||
|
}, |
||||
|
// 提交表单 |
||||
|
submitHandle(){ |
||||
|
this.$refs.addEditFrom_Ref.validate((valid) => { |
||||
|
if(this.submitForm){ |
||||
|
this.submitForm(valid,this.formData,this.handleType,this.formItemData,this.formRules) |
||||
|
return |
||||
|
} |
||||
|
this.formData.details = this.flexTableData |
||||
|
this.Loading.addEditApiLoading = true |
||||
|
if (valid) { |
||||
|
// 新增 |
||||
|
if(this.handleType == 'add'){ |
||||
|
ApiTypePost( |
||||
|
this.formData, |
||||
|
this.currentDtos.C.actionsUrl |
||||
|
).then(res => { |
||||
|
this.changeActive(1) |
||||
|
}).catch(err => { |
||||
|
this.changeActive(2) |
||||
|
}) |
||||
|
} |
||||
|
// 编辑 |
||||
|
else{ |
||||
|
ApiTypePut( |
||||
|
this.formData, |
||||
|
this.formData.id, |
||||
|
this.currentDtos.U.actionsUrl |
||||
|
).then(res => { |
||||
|
this.changeActive(1) |
||||
|
}).catch(err => { |
||||
|
this.changeActive(2) |
||||
|
}) |
||||
|
} |
||||
|
} else { |
||||
|
return false; |
||||
|
} |
||||
|
}); |
||||
|
}, |
||||
|
// 结果页退出 |
||||
|
exitHandle(){ |
||||
|
this.close() |
||||
|
if(this.active == '1')this.oldSkipCount = 1; |
||||
|
this.show = false |
||||
|
this.$emit("exitAfterHandle") |
||||
|
this.$nextTick(()=>{ |
||||
|
this.active = 0 |
||||
|
}) |
||||
|
}, |
||||
|
// 更改页面步骤 |
||||
|
changeActive(sta){ |
||||
|
this.active = sta |
||||
|
this.Loading.addEditApiLoading = false |
||||
|
}, |
||||
|
// 值更改函数 |
||||
|
changeValue(prop,item,val) { |
||||
|
this.$emit("changeValue", prop, item, val) |
||||
|
}, |
||||
|
// 值清除函数 |
||||
|
clearValue(prop,item,val) { |
||||
|
this.$emit("clearValue", prop, item, val) |
||||
|
}, |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss" scoped> |
||||
|
::v-deep .el-dialog__header{ |
||||
|
padding: 0 !important; |
||||
|
} |
||||
|
::v-deep .el-row{ |
||||
|
width: 100%; |
||||
|
} |
||||
|
::v-deep .addEditFrom{ |
||||
|
height: calc(100%); |
||||
|
overflow: auto; |
||||
|
} |
||||
|
::v-deep .el-form-item__label{ |
||||
|
float: unset; |
||||
|
} |
||||
|
|
||||
|
::v-deep .el-input,.el-select,.el-input-number{ |
||||
|
width: 100% !important; |
||||
|
} |
||||
|
|
||||
|
.dialog-footer{ |
||||
|
padding-top: 15px; |
||||
|
text-align: right; |
||||
|
} |
||||
|
.centerInnerContent{ |
||||
|
height: calc(100% - 60px); |
||||
|
overflow: auto; |
||||
|
|
||||
|
.leftMainForm{ |
||||
|
height: calc(100% - 60px); |
||||
|
} |
||||
|
|
||||
|
&.hasDetails{ |
||||
|
display: flex; |
||||
|
|
||||
|
.leftMainForm{ |
||||
|
width: 50%; |
||||
|
flex-shrink: 0; |
||||
|
} |
||||
|
|
||||
|
.rightDetailTable{ |
||||
|
height: calc(100% - 60px); |
||||
|
width: calc(50%); |
||||
|
padding-left:40px; |
||||
|
border-left: #ddd solid 1px; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</style> |
@ -0,0 +1,312 @@ |
|||||
|
<template> |
||||
|
<!-- 组件功能:普通新增编辑(目前只有主表)参数配置从api获取 --> |
||||
|
<el-dialog |
||||
|
:visible.sync="show" |
||||
|
:modal="false" |
||||
|
:modal-append-to-body="false" |
||||
|
:show-close="true" |
||||
|
@close="close" |
||||
|
class="searchPageComponents" |
||||
|
:fullscreen="true" |
||||
|
style="width:calc(100% - 28px);left:14px;top:14px;height:calc(100% - 28px)" |
||||
|
v-loading="Loading.addEditApiLoading" |
||||
|
> |
||||
|
<!-- 表单 --> |
||||
|
<div v-if="active === 0" style="height: 100%;"> |
||||
|
<!-- 标题 --> |
||||
|
<div class="dialogOuterTitle">{{formTitle}}</div> |
||||
|
<!-- 表单 --> |
||||
|
<el-form |
||||
|
class="addEditFrom" |
||||
|
ref="addEditFrom_Ref" |
||||
|
v-if="formData" |
||||
|
:model="formData" |
||||
|
:rules="formRules" |
||||
|
> |
||||
|
<el-row :gutter="40"> |
||||
|
<el-col |
||||
|
:span="item.colSpan || 12" |
||||
|
v-for="(item, index) in formItemData" |
||||
|
:key="index" |
||||
|
> |
||||
|
<el-form-item |
||||
|
:label="item.label" |
||||
|
:prop="item.prop" |
||||
|
> |
||||
|
<!-- 数值 --> |
||||
|
<el-input-number |
||||
|
v-if="item.apiBaseType === 'number'" |
||||
|
v-model="formData[item.prop]" |
||||
|
:min="item.minimum || undefined" |
||||
|
:max="item.maximum || undefined" |
||||
|
:maxlength="item.maxLength || undefined" |
||||
|
:minlength="item.minLength || undefined" |
||||
|
:disabled="Boolean(item.disabled)" |
||||
|
:placeholder="item.placeholder || '请输入' + item.label" |
||||
|
@change="changeValue(item.prop,item,$event)" |
||||
|
@clear="clearValue(item.prop,$event)" |
||||
|
></el-input-number> |
||||
|
|
||||
|
<!-- 时间转换 --> |
||||
|
<el-date-picker |
||||
|
v-else-if="item.apiBaseType === 'datetime'" |
||||
|
v-model="formData[item.prop]" |
||||
|
type="datetime" |
||||
|
placeholder="选择日期时间" |
||||
|
format="yyyy-MM-dd HH:mm:ss" |
||||
|
value-format="yyyy-MM-ddTHH:mm:ss" |
||||
|
:disabled="Boolean(item.disabled)" |
||||
|
></el-date-picker> |
||||
|
|
||||
|
<!-- 布尔、枚举 --> |
||||
|
<el-select |
||||
|
v-else-if="item.isEnums || item.apiBaseType === 'boolean'" |
||||
|
v-model="formData[item.prop]" |
||||
|
:placeholder="item.placeholder || '请选择' + item.label" |
||||
|
:disabled="Boolean(item.disabled)" |
||||
|
> |
||||
|
<el-option |
||||
|
v-for="item in getItemEnums(item)" |
||||
|
:key="item.value" |
||||
|
:label="item.label" |
||||
|
:value="item.value" |
||||
|
></el-option> |
||||
|
</el-select> |
||||
|
|
||||
|
<!-- 文本框 --> |
||||
|
<!-- <el-input |
||||
|
v-else |
||||
|
type="textarea" |
||||
|
autosize |
||||
|
resize="none" |
||||
|
v-model="formData[item.prop]" |
||||
|
:placeholder="item.placeholder || '请输入' + item.label" |
||||
|
:disabled="Boolean(item.disabled)" |
||||
|
></el-input> --> |
||||
|
<el-input |
||||
|
v-else |
||||
|
v-model="formData[item.prop]" |
||||
|
:placeholder="item.placeholder || '请输入' + item.label" |
||||
|
:disabled="Boolean(item.disabled)" |
||||
|
></el-input> |
||||
|
</el-form-item> |
||||
|
</el-col> |
||||
|
</el-row> |
||||
|
</el-form> |
||||
|
<!-- 操作按钮 --> |
||||
|
<div slot="footer" class="dialog-footer"> |
||||
|
<el-button @click="show = false">取 消</el-button> |
||||
|
<el-button type="primary" @click="submitHandle()">确 定</el-button> |
||||
|
</div> |
||||
|
</div> |
||||
|
<!-- 成功提示 --> |
||||
|
<div v-if="active === 1"> |
||||
|
<el-result icon="success" title="成功提示" :subTitle="formTitle + '成功'"> |
||||
|
<template slot="extra"> |
||||
|
<el-button type="primary" size="medium" @click="exitHandle" |
||||
|
>退出</el-button |
||||
|
> |
||||
|
</template> |
||||
|
</el-result> |
||||
|
</div> |
||||
|
<!-- 错误提示 --> |
||||
|
<div v-if="active === 2"> |
||||
|
<el-result icon="error" title="错误提示" :subTitle="formTitle + '失败'"> |
||||
|
<template slot="extra"> |
||||
|
<el-button type="primary" size="medium" @click="changeActive(0)" |
||||
|
>返回</el-button |
||||
|
> |
||||
|
<el-button type="primary" size="medium" @click="exitHandle" |
||||
|
>退出</el-button |
||||
|
> |
||||
|
</template> |
||||
|
</el-result> |
||||
|
</div> |
||||
|
</el-dialog> |
||||
|
</template> |
||||
|
<script> |
||||
|
import { ApiTypePost, ApiTypePut } from "@/api/wms-api" |
||||
|
import { LoadingMixins } from "@/mixins/LoadingMixins"; |
||||
|
import { tableMixins } from "@/mixins/TableMixins" |
||||
|
export default { |
||||
|
name:"addEditFromApiPop", |
||||
|
mixins:[ LoadingMixins,tableMixins ], |
||||
|
props: { |
||||
|
// 编辑行数据 |
||||
|
editRowData:{ |
||||
|
type: Object, |
||||
|
default: null |
||||
|
}, |
||||
|
// 操作类型:add/edit |
||||
|
handleType:{ |
||||
|
type: String, |
||||
|
default: null |
||||
|
}, |
||||
|
// 提交事件 |
||||
|
submitForm:{ |
||||
|
type:Function, |
||||
|
default:null |
||||
|
}, |
||||
|
// 特殊的【新增】接口,如果没有就走路由下的配置文件 |
||||
|
addSubmitUrl:{ |
||||
|
type: String, |
||||
|
default: null |
||||
|
}, |
||||
|
// 特殊的【编辑】接口,如果没有就走路由下的配置文件 |
||||
|
editSubmitUrl:{ |
||||
|
type: String, |
||||
|
default: null |
||||
|
} |
||||
|
}, |
||||
|
data () { |
||||
|
return { |
||||
|
currentDtos:this.$store.getters.dtoColumnTypes[this.$route.name], |
||||
|
active:0,//显示内容:0表单 1成功 2失败 |
||||
|
show:true, |
||||
|
formTitle:null,//form名称 |
||||
|
formData:{},//表单数据 |
||||
|
formItemData:null,//表单item配置 |
||||
|
formRules: {},//表单验证 |
||||
|
} |
||||
|
}, |
||||
|
mounted(){ |
||||
|
this.initTitle() |
||||
|
this.initFormItems() |
||||
|
}, |
||||
|
methods: { |
||||
|
// 初始化form名称 |
||||
|
initTitle(){ |
||||
|
if(this.handleType){ |
||||
|
this.formTitle = this.handleType == 'add' ? '新增'+this.$route.name : '编辑'+this.$route.name |
||||
|
} |
||||
|
}, |
||||
|
// 初始化表单配置、rules |
||||
|
initFormItems(){ |
||||
|
let _dtoList_type = this.handleType == 'add' ? 'C' : 'U' |
||||
|
let _dtoList = this.currentDtos[_dtoList_type].dtoList |
||||
|
this.formItemData = JSON.parse(JSON.stringify(_dtoList)) |
||||
|
// 编辑格式:特殊处理默认值 |
||||
|
if(this.handleType == 'edit' && this.editRowData){ |
||||
|
this.formData = JSON.parse(JSON.stringify(this.editRowData)) |
||||
|
}else{ |
||||
|
this.formData = {} |
||||
|
} |
||||
|
// 表单验证格式化 |
||||
|
this.formRules={} |
||||
|
_dtoList.forEach(item=>{ |
||||
|
if(item.isRequired){ |
||||
|
this.formRules[item.prop] = [{ required: true, trigger: "blur", message: "不可为空" }] |
||||
|
} |
||||
|
}) |
||||
|
}, |
||||
|
// 获取枚举、布尔 |
||||
|
getItemEnums(item){ |
||||
|
let _option = [] |
||||
|
// 布尔 |
||||
|
if(item.apiBaseType == 'boolean'){ |
||||
|
_option = [{ |
||||
|
value: true, |
||||
|
label: '是' |
||||
|
},{ |
||||
|
value: false, |
||||
|
label: '否' |
||||
|
},] |
||||
|
} |
||||
|
if(item.isEnums){ |
||||
|
_option = item.enums_list |
||||
|
} |
||||
|
return _option |
||||
|
}, |
||||
|
// 关闭弹窗 |
||||
|
close() { |
||||
|
this.show = false |
||||
|
this.$emit("closePop") |
||||
|
}, |
||||
|
// 提交表单 |
||||
|
submitHandle(){ |
||||
|
this.$refs.addEditFrom_Ref.validate((valid) => { |
||||
|
if(this.submitForm){ |
||||
|
this.submitForm(valid,this.formData,this.handleType,this.formItemData,this.formRules) |
||||
|
return |
||||
|
} |
||||
|
this.Loading.addEditApiLoading = true |
||||
|
if (valid) { |
||||
|
// 新增 |
||||
|
if(this.handleType == 'add'){ |
||||
|
ApiTypePost( |
||||
|
this.formData, |
||||
|
this.currentDtos.C.actionsUrl |
||||
|
).then(res => { |
||||
|
this.changeActive(1) |
||||
|
}).catch(err => { |
||||
|
this.changeActive(2) |
||||
|
}) |
||||
|
} |
||||
|
// 编辑 |
||||
|
else{ |
||||
|
ApiTypePut( |
||||
|
this.formData, |
||||
|
this.formData.id, |
||||
|
this.currentDtos.U.actionsUrl |
||||
|
).then(res => { |
||||
|
this.changeActive(1) |
||||
|
}).catch(err => { |
||||
|
this.changeActive(2) |
||||
|
}) |
||||
|
} |
||||
|
} else { |
||||
|
return false; |
||||
|
} |
||||
|
}); |
||||
|
}, |
||||
|
// 结果页退出 |
||||
|
exitHandle(){ |
||||
|
this.close() |
||||
|
if(this.active == '1')this.oldSkipCount = 1; |
||||
|
this.show = false |
||||
|
this.paging() |
||||
|
this.$nextTick(()=>{ |
||||
|
this.active = 0 |
||||
|
}) |
||||
|
}, |
||||
|
// 更改页面步骤 |
||||
|
changeActive(sta){ |
||||
|
this.active = sta |
||||
|
this.Loading.addEditApiLoading = false |
||||
|
}, |
||||
|
// 值更改函数 |
||||
|
changeValue(prop,item,val) { |
||||
|
this.$emit("changeValue", prop, item, val) |
||||
|
}, |
||||
|
// 值清除函数 |
||||
|
clearValue(prop,item,val) { |
||||
|
this.$emit("clearValue", prop, item, val) |
||||
|
}, |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss" scoped> |
||||
|
::v-deep .el-dialog__header{ |
||||
|
padding: 0 !important; |
||||
|
} |
||||
|
::v-deep .el-row{ |
||||
|
width: 100%; |
||||
|
} |
||||
|
::v-deep .addEditFrom{ |
||||
|
height: calc(100% - 120px); |
||||
|
overflow: auto; |
||||
|
} |
||||
|
::v-deep .el-form-item__label{ |
||||
|
float: unset; |
||||
|
} |
||||
|
|
||||
|
::v-deep .el-input,.el-select,.el-input-number{ |
||||
|
width: 100% !important; |
||||
|
} |
||||
|
|
||||
|
.dialog-footer{ |
||||
|
padding-top: 15px; |
||||
|
text-align: right; |
||||
|
} |
||||
|
</style> |
@ -0,0 +1,77 @@ |
|||||
|
<template> |
||||
|
<div class="batchButton"> |
||||
|
<div class="query-box" v-if="!checkButton.length"> |
||||
|
<el-input |
||||
|
v-model="input" |
||||
|
:placeholder="placeholder" |
||||
|
@keyup.enter.native="filtrate" |
||||
|
/> |
||||
|
<el-button type="primary" @click.native.prevent="filtrate" |
||||
|
>搜索</el-button |
||||
|
> |
||||
|
</div> |
||||
|
<div class="button-box" v-else> |
||||
|
<curren-Button |
||||
|
:Butttondata="Butttondata" |
||||
|
@tableButtonClick="tableButtonClick" |
||||
|
></curren-Button> |
||||
|
</div> |
||||
|
</div> |
||||
|
</template> |
||||
|
<script> |
||||
|
import currenButton from "@/components/currenButton" |
||||
|
export default { |
||||
|
name: 'batchButton', |
||||
|
components: { |
||||
|
currenButton, |
||||
|
}, |
||||
|
props: { |
||||
|
Butttondata: { |
||||
|
type: Array, |
||||
|
default: () => { |
||||
|
return [] |
||||
|
} |
||||
|
}, |
||||
|
placeholder: { |
||||
|
type: String, |
||||
|
default: '搜索...' |
||||
|
}, |
||||
|
checkButton: { |
||||
|
type: Array, |
||||
|
default: () => { |
||||
|
return [] |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
computed: { |
||||
|
|
||||
|
}, |
||||
|
data () { |
||||
|
return { |
||||
|
input: '' |
||||
|
} |
||||
|
}, |
||||
|
methods: { |
||||
|
//搜索字段变化时 |
||||
|
filtrate () { |
||||
|
this.$emit('filtrate', this.input) |
||||
|
}, |
||||
|
tableButtonClick (val) { |
||||
|
this.$emit('tableButtonClick', val) |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
<style lang="scss" scoped> |
||||
|
.batchButton { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
height: 50px; |
||||
|
.query-box { |
||||
|
display: flex; |
||||
|
.el-button { |
||||
|
margin: 0 0 0 10px; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</style> |
@ -0,0 +1,634 @@ |
|||||
|
<template> |
||||
|
<el-drawer |
||||
|
v-loading="DrawerLoading" |
||||
|
v-if="drawer" |
||||
|
:visible="true" |
||||
|
:close-on-press-escape="false" |
||||
|
:wrapperClosable="false" |
||||
|
:with-header="false" |
||||
|
:modal="false" |
||||
|
size="100%" |
||||
|
> |
||||
|
<!-- <div class="drawer-heder"> |
||||
|
<div class="heder-left"> |
||||
|
<div class="header-text"> |
||||
|
<span>{{ propsData[title[0].prop] }}</span> |
||||
|
<span>{{ title[0].label }}</span> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="heder-right"> |
||||
|
<curren-Button |
||||
|
:Butttondata="Butttondata" |
||||
|
@tableButtonClick="tableButtonClick" |
||||
|
> |
||||
|
<template> |
||||
|
<el-dropdown |
||||
|
trigger="click" |
||||
|
@command="handleCommand" |
||||
|
v-if="JSON.stringify(dropdownData) != '{}'" |
||||
|
> |
||||
|
<el-button size="mini" icon="el-icon-more"></el-button> |
||||
|
<el-dropdown-menu slot="dropdown"> |
||||
|
<el-dropdown-item |
||||
|
v-for="(item, index) in dropdownData" |
||||
|
:key="index" |
||||
|
:command="item.command" |
||||
|
>{{ item.label }}</el-dropdown-item |
||||
|
> |
||||
|
</el-dropdown-menu> |
||||
|
</el-dropdown> |
||||
|
</template> |
||||
|
</curren-Button> |
||||
|
</div> |
||||
|
</div> --> |
||||
|
<div class="drawer-main"> |
||||
|
<curren-tabs |
||||
|
:tabsData="dropdownTabs" |
||||
|
:activeName="firstTabs" |
||||
|
type="border-card" |
||||
|
@handleClick="handleClick" |
||||
|
> |
||||
|
<template slot-scope="scope"> |
||||
|
<curren-descriptions |
||||
|
border |
||||
|
v-if="scope.value == 'xq'" |
||||
|
:column="column" |
||||
|
:direction="direction" |
||||
|
:colon="false" |
||||
|
:tabsDesTions="tabsDesTions" |
||||
|
:propsData="propsData" |
||||
|
> |
||||
|
</curren-descriptions> |
||||
|
<!-- 明细 包含分页 头部按钮等 --> |
||||
|
<tablePagination |
||||
|
ref="tablePaginationForMX_Ref" |
||||
|
v-if="scope.value == 'mx'" |
||||
|
:currenButtonData="detailHeaderButton" |
||||
|
:tableData="propsData.details" |
||||
|
:tableColumns="tableColumns" |
||||
|
:setUTableHeight="showDetailColumnsSet || showDetailFilters ? 220 : 180" |
||||
|
@rowDrop="rowDrop" |
||||
|
:searchOverallCoverHeight="'calc(100vh - 345px)'" |
||||
|
:rowSource="'detail_api'" |
||||
|
:selectMaxHeight="'116px'" |
||||
|
:rowMaxHeight="rowMaxHeight" |
||||
|
:totalCount="totalCountForDetail" |
||||
|
:MaxResultCount="MaxResultCount" |
||||
|
@sortChange="sortChangeForDetail" |
||||
|
@alertoldSkipCount="alertoldSkipCountForDetail" |
||||
|
@alterResultCount="alterResultCountForDetail" |
||||
|
@handleSelectionChange="handleSelectionChange" |
||||
|
:currentPageProps="oldSkipCount" |
||||
|
@overallSearchFormClick="overallSearchClickForDetail" |
||||
|
:httpOverallSearchData="httpOverallSearchData" |
||||
|
@buttonOperationClick_left="buttonOperationClick_left" |
||||
|
:buttonOperationList_left="buttonOperationList_left" |
||||
|
:tableLoading="Loading.tableLoading" |
||||
|
></tablePagination> |
||||
|
<!-- 新增汇总 表头 区分明细表头使用 summaryTableColumns --> |
||||
|
<umyTable |
||||
|
v-if="scope.value == 'hz'" |
||||
|
:tableBorder="true" |
||||
|
:tableData="propsData.summaryDetails" |
||||
|
:tableColumns="summaryTableColumns.length == 0 ? tableColumns : summaryTableColumns" |
||||
|
:selectionTable="selectionTable" |
||||
|
:requiredRules="false" |
||||
|
@sortChange="sortChange" |
||||
|
@handleSelectionChange="handleSelectionChange" |
||||
|
@inlineDialog="inlineDialog" |
||||
|
@buttonClick="buttonClick" |
||||
|
:setUTableHeight="210" |
||||
|
> |
||||
|
<template> |
||||
|
<slot></slot> |
||||
|
</template> |
||||
|
</umyTable> |
||||
|
<!-- 自定义扩展 --> |
||||
|
<umyTable |
||||
|
v-if=" |
||||
|
scope.value == zdyValue && |
||||
|
scope.value != 'xq' && |
||||
|
scope.value != 'mx' && |
||||
|
scope.value != 'hz' && |
||||
|
scope.value != 'zwlcj' |
||||
|
" |
||||
|
:tableBorder="true" |
||||
|
:tableLoading="tableLoading" |
||||
|
:tableData="otherData" |
||||
|
:tableColumns="zdyTableColumns" |
||||
|
:selectionTable="selectionTable" |
||||
|
:requiredRules="false" |
||||
|
@sortChange="sortChange" |
||||
|
@handleSelectionChange="handleSelectionChange" |
||||
|
@inlineDialog="inlineDialog" |
||||
|
@buttonClick="buttonClick" |
||||
|
:setUTableHeight="210" |
||||
|
> |
||||
|
<template> |
||||
|
<slot></slot> |
||||
|
</template> |
||||
|
</umyTable> |
||||
|
</template> |
||||
|
</curren-tabs> |
||||
|
</div> |
||||
|
<div class="drawer-Shut" @click="drawerShut"> |
||||
|
<el-button type="danger" size="mini">关闭</el-button> |
||||
|
</div> |
||||
|
<!-- 明细-查看详情 --> |
||||
|
<el-dialog |
||||
|
width="90%" |
||||
|
:modal-append-to-body="false" |
||||
|
:append-to-body="false" |
||||
|
:title="detailInfoTitle" |
||||
|
:visible.sync="displayDialog.detailInfoDialog" |
||||
|
:show-close="true" |
||||
|
:close-on-click-modal="true" |
||||
|
:close-on-press-escape="true" |
||||
|
> |
||||
|
<div> |
||||
|
<curren-descriptions |
||||
|
v-if="detailInfoTableData" |
||||
|
border |
||||
|
:column="column" |
||||
|
:direction="direction" |
||||
|
:colon="false" |
||||
|
:tabsDesTions="tableColumns" |
||||
|
:propsData="detailInfoTableData" |
||||
|
style="padding-bottom: 20px;" |
||||
|
></curren-descriptions> |
||||
|
</div> |
||||
|
</el-dialog> |
||||
|
</el-drawer> |
||||
|
</template> |
||||
|
<script> |
||||
|
import { getPageListForDetail } from "@/api/wms-api" |
||||
|
import searchOverall from "@/components/searchOverall" |
||||
|
import currenButton from "@/components/currenButton" |
||||
|
import currenDescriptions from "@/components/currenDescriptions" |
||||
|
import currenTabs from "@/components/currenTabs" |
||||
|
import currenTable from "@/components/currenTable" |
||||
|
import pagination from "@/components/Pagination" |
||||
|
import rowDrop from "@/components/rowDrop/index.vue" |
||||
|
import * as allUrlOption from '@/utils/baseData/urlOption' |
||||
|
import { LoadingMixins } from "@/mixins/LoadingMixins"; |
||||
|
export default { |
||||
|
name: 'currenTabel-drawer', |
||||
|
components: { |
||||
|
pagination, |
||||
|
currenButton, |
||||
|
currenDescriptions, |
||||
|
currenTabs, |
||||
|
currenTable, |
||||
|
searchOverall, |
||||
|
rowDrop |
||||
|
}, |
||||
|
mixins: [ |
||||
|
LoadingMixins, |
||||
|
], |
||||
|
props: { |
||||
|
rowMaxHeight:{ |
||||
|
type:String, |
||||
|
default:'calc(90vh - 450px)' |
||||
|
}, |
||||
|
// 操作列按钮 |
||||
|
buttonOperationList_left:{ |
||||
|
type: Array, |
||||
|
default: null, |
||||
|
}, |
||||
|
// 是否显示明细-字段设置 |
||||
|
showDetailColumnsSet:{ |
||||
|
type: Boolean, |
||||
|
default: true |
||||
|
}, |
||||
|
// 是否显示明细-筛选 |
||||
|
showDetailFilters:{ |
||||
|
type: Boolean, |
||||
|
default: true |
||||
|
}, |
||||
|
title: { |
||||
|
type: Array, |
||||
|
default: () => { |
||||
|
return [] |
||||
|
} |
||||
|
}, |
||||
|
DrawerLoading: { |
||||
|
type: Boolean, |
||||
|
default: true |
||||
|
}, |
||||
|
drawer: { |
||||
|
type: Boolean, |
||||
|
default: false |
||||
|
}, |
||||
|
dropdownData: { |
||||
|
type: Object, |
||||
|
default: () => { |
||||
|
return {} |
||||
|
} |
||||
|
}, |
||||
|
propsData: { |
||||
|
type: Object, |
||||
|
default: () => { |
||||
|
return {} |
||||
|
} |
||||
|
}, |
||||
|
tabsDesTions: { |
||||
|
type: Array, |
||||
|
default: () => { |
||||
|
return [] |
||||
|
} |
||||
|
}, |
||||
|
dropdownTabsData: { |
||||
|
type: Array, |
||||
|
default: () => { |
||||
|
return [] |
||||
|
} |
||||
|
}, |
||||
|
tableLoading: { |
||||
|
type: Boolean, |
||||
|
default: false |
||||
|
}, |
||||
|
tableColumns: { |
||||
|
type: Array, |
||||
|
default: () => { |
||||
|
return [] |
||||
|
} |
||||
|
}, |
||||
|
summaryTableColumns: { |
||||
|
type: Array, |
||||
|
default: () => { |
||||
|
return [] |
||||
|
} |
||||
|
}, |
||||
|
Butttondata: { |
||||
|
type: Array, |
||||
|
default: () => { |
||||
|
return [{ |
||||
|
type: 'warning', |
||||
|
icon: 'el-icon-edit', |
||||
|
label: '编辑', |
||||
|
name: 'edit', |
||||
|
size: 'mini' |
||||
|
}] |
||||
|
} |
||||
|
}, |
||||
|
selectionTable: { |
||||
|
type: Boolean, |
||||
|
default: false |
||||
|
}, |
||||
|
MaxResultCount: { |
||||
|
type: Number, |
||||
|
default: 0 |
||||
|
}, |
||||
|
totalCount: { |
||||
|
type: Number, |
||||
|
default: 0 |
||||
|
}, |
||||
|
currentPage: { |
||||
|
type: Number, |
||||
|
default: 0 |
||||
|
}, |
||||
|
// 详情展现列数,默认为2列展现 |
||||
|
column: { |
||||
|
type: Number, |
||||
|
default: 2 |
||||
|
}, |
||||
|
// 详情展示方式,默认水平分布 |
||||
|
direction: { |
||||
|
type: String, |
||||
|
default: 'horizontal' |
||||
|
}, |
||||
|
// 详情tabs排序默认 |
||||
|
firstTabs: { |
||||
|
type: String, |
||||
|
default: 'xq' |
||||
|
} |
||||
|
|
||||
|
}, |
||||
|
computed: { |
||||
|
dropdownTabs () { |
||||
|
// 带有特殊扩展tabs页的 |
||||
|
if (this.dropdownTabsData.length !== 0) { |
||||
|
return this.dropdownTabsData |
||||
|
} else { |
||||
|
// 正常普通 详情,明细,汇总 |
||||
|
// if (Object.keys(this.propsData).length != 0) { |
||||
|
if (Object.keys(this.propsData)) { |
||||
|
this.initDropdownTabsData = [{ |
||||
|
label: "详情", |
||||
|
name: 'xq' |
||||
|
}] |
||||
|
// 明细可以为空数组,前端分页使用 |
||||
|
if(this.propsData.details){ |
||||
|
this.initDropdownTabsData.push({ |
||||
|
label: "明细", |
||||
|
name: 'mx' |
||||
|
}) |
||||
|
} |
||||
|
if(this.propsData.summaryDetails && this.propsData.summaryDetails.length > 0){ |
||||
|
this.initDropdownTabsData.push({ |
||||
|
label: "汇总", |
||||
|
name: 'hz' |
||||
|
}) |
||||
|
} |
||||
|
} |
||||
|
return this.initDropdownTabsData |
||||
|
} |
||||
|
}, |
||||
|
}, |
||||
|
mounted () { |
||||
|
this.initDetailHeaderButton() |
||||
|
}, |
||||
|
data () { |
||||
|
return { |
||||
|
detailHeaderButton:null,//明细-上方按钮 |
||||
|
detailInfoTableData:null,//明细-查看详情弹窗数据 |
||||
|
detailInfoTitle:null,//明细-查看详情弹窗title |
||||
|
otherData:[], // 切换tabs页赋值 |
||||
|
zdyTableColumns:[], // 自定义表头 |
||||
|
zdyValue:'', // 自定义展现值 |
||||
|
// firstTabs:'xq', |
||||
|
initDropdownTabsData:[ |
||||
|
{ |
||||
|
label: "详情", |
||||
|
name: 'xq' |
||||
|
}, |
||||
|
{ |
||||
|
label: "明细", |
||||
|
name: 'mx' |
||||
|
}, |
||||
|
{ |
||||
|
label: "汇总", |
||||
|
name: 'hz' |
||||
|
} |
||||
|
], |
||||
|
//明细列表- 改变当前页 |
||||
|
oldSkipCount: 1, |
||||
|
// 明细列表- 全面搜索:当前列表数据请求接口的筛选条件 |
||||
|
httpOverallSearchData:null, |
||||
|
//明细列表- 分页参数 |
||||
|
PageListParams: { |
||||
|
condition: { |
||||
|
filters: [] |
||||
|
}, |
||||
|
Sorting: "", |
||||
|
SkipCount: 0, |
||||
|
MaxResultCount: 20, |
||||
|
}, |
||||
|
totalCountForDetail:0, |
||||
|
//明细-查看主表的连接id |
||||
|
URLOption_masterId:allUrlOption[this.$route.name].masterId || 'masterId', |
||||
|
//明细-列表 |
||||
|
URLOption_detailList:allUrlOption[this.$route.name].detailListURL, |
||||
|
} |
||||
|
}, |
||||
|
methods: { |
||||
|
// 明细列表 - 获取明细列表(后端分页) |
||||
|
getDetailList(data,successFn,errorFn){ |
||||
|
if(data)this.PageListParams.condition.filters = [] |
||||
|
// 获取明细分页信息 |
||||
|
let _hasId = false |
||||
|
this.PageListParams.condition.filters.forEach(item=>{ |
||||
|
if(item.column == this.URLOption_masterId){ |
||||
|
_hasId = true |
||||
|
} |
||||
|
}) |
||||
|
if(!_hasId || data){ |
||||
|
this.PageListParams.condition.filters.push({ |
||||
|
logic: "And", |
||||
|
column: this.URLOption_masterId, |
||||
|
action: "==", |
||||
|
value: data ? data.id : this.propsData.id |
||||
|
}) |
||||
|
} |
||||
|
this.PageListParams.SkipCount = (this.oldSkipCount - 1) * this.PageListParams.MaxResultCount |
||||
|
this.Loading.tableLoading = true |
||||
|
getPageListForDetail(this.PageListParams,this.URLOption_detailList) |
||||
|
.then(result => { |
||||
|
this.propsData.details = result.items |
||||
|
this.totalCountForDetail = result.totalCount |
||||
|
this.Loading.tableLoading = false |
||||
|
if(successFn)successFn() |
||||
|
}) |
||||
|
.catch(err => { |
||||
|
this.Loading.tableLoading = false |
||||
|
if(errorFn)errorFn() |
||||
|
this.$message.error("数据获取失败") |
||||
|
}) |
||||
|
}, |
||||
|
// 明细列表 - 全面筛选组件查询 |
||||
|
overallSearchForDetailHandle(options){ |
||||
|
let _data_primary = options.data_primary, |
||||
|
_data_moreList = options.data_moreList, |
||||
|
_option_primary = options.option_primary, |
||||
|
_vm_quickly = options.vm_quickly, |
||||
|
_vm_moreList = options.vm_moreList |
||||
|
|
||||
|
//普通筛选数据集合 |
||||
|
let _primary_filters = [] |
||||
|
_option_primary.forEach(item=>{ |
||||
|
if(_data_primary[item.prop] && String(_data_primary[item.prop]).length > 0){ |
||||
|
let _item = { |
||||
|
action:item.action || '==', |
||||
|
column:item.prop, |
||||
|
logic:'And', |
||||
|
value:String(_data_primary[item.prop]) |
||||
|
} |
||||
|
_primary_filters.push(_item) |
||||
|
} |
||||
|
}) |
||||
|
//高级筛选数据集合 |
||||
|
let _moreList_filters = [] |
||||
|
_data_moreList.filters.forEach(item=>{ |
||||
|
if(String(item.column).length > 0 && String(item.value).length > 0){ |
||||
|
_moreList_filters.push(item) |
||||
|
} |
||||
|
}) |
||||
|
// 全部筛选数据集合 |
||||
|
let _all_filters = [] |
||||
|
_all_filters = _primary_filters.concat(_moreList_filters) |
||||
|
// 调用接口数据配置 |
||||
|
this.oldSkipCount = 1 |
||||
|
this.Loading.tableLoading = true; |
||||
|
this.PageListParams.SkipCount = (this.oldSkipCount - 1) * this.PageListParams.MaxResultCount; |
||||
|
this.PageListParams.condition = {filters:_all_filters} |
||||
|
this.getDetailList(null,()=>{ |
||||
|
//快速搜索清空 |
||||
|
if(_vm_quickly){_vm_quickly.searchNormalClear(true)} |
||||
|
//关闭高级筛选 |
||||
|
if(_vm_moreList){_vm_moreList.changeMoreListShow(false)} |
||||
|
// 同步当前列表数据请求接口的筛选条件 |
||||
|
this.httpOverallSearchData = {} |
||||
|
this.httpOverallSearchData.params = JSON.parse(JSON.stringify(_data_primary)) |
||||
|
this.httpOverallSearchData.moreList = JSON.parse(JSON.stringify(_data_moreList)) |
||||
|
},()=>{ |
||||
|
//快速搜索清空 |
||||
|
if(_vm_quickly){_vm_quickly.searchNormalClear(true)} |
||||
|
//关闭高级筛选 |
||||
|
if(_vm_moreList){_vm_moreList.changeMoreListShow(false)} |
||||
|
}) |
||||
|
}, |
||||
|
// 明细列表 - 全面筛选所有按钮操作集 |
||||
|
overallSearchClickForDetail(options){ |
||||
|
let _item = options.item; |
||||
|
// 普通搜索 + 高级搜索 + 普通重置 + 高级重置 |
||||
|
if( |
||||
|
_item.name == 'search' || _item.name == 'moreList-search' || |
||||
|
_item.name == 'reset' || _item.name == 'moreList-reset' |
||||
|
){ |
||||
|
this.overallSearchForDetailHandle(options) |
||||
|
} |
||||
|
}, |
||||
|
// 明细列表 -接收分页组件emit改变当前页 |
||||
|
alertoldSkipCountForDetail(val) { |
||||
|
this.oldSkipCount = val; |
||||
|
this.getDetailList(); |
||||
|
}, |
||||
|
// 明细列表 -接收分页组件emit改变每页最大页数 |
||||
|
alterResultCountForDetail(val) { |
||||
|
this.PageListParams.MaxResultCount = val; |
||||
|
this.getDetailList(); |
||||
|
}, |
||||
|
// 明细列表 - 排序查询 |
||||
|
sortChangeForDetail(val) { |
||||
|
const { |
||||
|
prop, |
||||
|
order |
||||
|
} = val; |
||||
|
if (!prop || !order) { |
||||
|
this.PageListParams.Sorting = ""; |
||||
|
this.oldSkipCount = 1; |
||||
|
this.getDetailList(); |
||||
|
return; |
||||
|
} |
||||
|
let orderdata = order.substr(0, order.indexOf("c") + 1); |
||||
|
const props = prop.charAt(0).toUpperCase() + prop.slice(1) |
||||
|
this.PageListParams.Sorting = props + " " + orderdata.toUpperCase(); |
||||
|
this.oldSkipCount = 1; |
||||
|
this.getDetailList(); |
||||
|
}, |
||||
|
// 初始化明细-上方按钮 |
||||
|
initDetailHeaderButton(){ |
||||
|
this.detailHeaderButton = [] |
||||
|
if(this.showDetailColumnsSet){this.detailHeaderButton.push(this.defaultFieldSettingBtn())} |
||||
|
if(this.showDetailFilters){this.detailHeaderButton.push(this.defaultFilterBtn())} |
||||
|
}, |
||||
|
// 关闭明细-详情弹窗 |
||||
|
closeDetailInfo(val){ |
||||
|
this.displayDialog.detailInfoDialog = val || false |
||||
|
}, |
||||
|
// 明细-操作列事件 |
||||
|
buttonOperationClick_left(row, item, index){ |
||||
|
// 查看详情 |
||||
|
if(item.name == "info"){ |
||||
|
this.displayDialog.detailInfoDialog = true |
||||
|
this.detailInfoTableData = row |
||||
|
let _name = allUrlOption[this.$route.name].detailInfoName |
||||
|
this.detailInfoTitle = _name ? row[_name] + ' 详情' : '详情' |
||||
|
} |
||||
|
this.$emit('buttonOperationClick_left',row, item, index) |
||||
|
}, |
||||
|
rowDrop(data,type) { |
||||
|
this.$emit('rowDrop',data,type) |
||||
|
}, |
||||
|
handleCommand (command) { |
||||
|
this.$emit('handleCommand', command) |
||||
|
}, |
||||
|
drawerShut () { |
||||
|
this.closeDetailInfo(false) |
||||
|
this.$emit('drawerShut', false) |
||||
|
}, |
||||
|
tableButtonClick (val) { |
||||
|
this.$emit('drawerbutton', val) |
||||
|
}, |
||||
|
//排序 |
||||
|
sortChange (data) { |
||||
|
this.$emit('sortChange', data) |
||||
|
}, |
||||
|
//点击selection框 |
||||
|
handleSelectionChange (val) { |
||||
|
this.$emit("handleSelectionChange", val) |
||||
|
}, |
||||
|
//点击name提交emit打开编辑页面 |
||||
|
inlineDialog (row) { |
||||
|
this.$emit("inlineDialog", row) |
||||
|
}, |
||||
|
//接收分页组件emit改变每页最大页数 |
||||
|
alterResultCountDetails (val) { |
||||
|
this.$emit('alterResultCountDetails', val) |
||||
|
}, |
||||
|
//接收分页组件emit改变当前页 |
||||
|
alertoldSkipCountDetails (val) { |
||||
|
this.$emit('alertoldSkipCountDetails', val) |
||||
|
}, |
||||
|
buttonClick(row) { |
||||
|
this.$emit("buttonClick", row); |
||||
|
}, |
||||
|
// 重新渲染表格 |
||||
|
doFreshTableLayout(){ |
||||
|
this.$nextTick(() => { |
||||
|
if(this.$refs.tablePaginationForMX_Ref && this.$refs.tablePaginationForMX_Ref.doFreshTableLayout){ |
||||
|
this.$refs.tablePaginationForMX_Ref.doFreshTableLayout() |
||||
|
} |
||||
|
}) |
||||
|
}, |
||||
|
// tabs 切换页 |
||||
|
handleClick (val) { |
||||
|
this.$emit("currenTabsChange", val);//父级获取当前的tab内容 |
||||
|
this.zdyValue = val.name |
||||
|
this.dropdownTabsData.forEach( item => { |
||||
|
if (item.name == val.name) { |
||||
|
let parent = this.$parent |
||||
|
parent.tableLoading = true |
||||
|
// 详情 明细 汇总 |
||||
|
parent.firstTabs = val.name |
||||
|
if (val.name == 'xq' || val.name == 'mx' || val.name == 'hz') { |
||||
|
this.zdyTableColumns = [] |
||||
|
this.otherData = [] |
||||
|
parent.tableLoading = false |
||||
|
} else { |
||||
|
this.zdyTableColumns = [] |
||||
|
this.otherData = [] |
||||
|
// this.firstTabs = val.name |
||||
|
// 其他自定义tab页 |
||||
|
// if (item.functionName == 'getListByItemcode') { |
||||
|
// let params = { |
||||
|
// itemCode: this.propsData.code |
||||
|
// } |
||||
|
// getListByItemcode(params, item.url).then(res => { |
||||
|
// let zdyTableColumnsJSON = JSON.parse(JSON.stringify(this.$isTableColumns[item.tableColumns])); |
||||
|
// delete zdyTableColumnsJSON[0].type |
||||
|
// this.zdyTableColumns = zdyTableColumnsJSON |
||||
|
// this.otherData = res |
||||
|
// parent.tableLoading = false |
||||
|
// }).catch(err => { |
||||
|
// console.log(err) |
||||
|
// parent.tableLoading = false |
||||
|
// }) |
||||
|
// } |
||||
|
// else if(item.functionName == "customerDismantleBackFlushNote"){ |
||||
|
// let zdyTableColumnsJSON = JSON.parse(JSON.stringify(this.$isTableColumns[item.tableColumns])); |
||||
|
// delete zdyTableColumnsJSON[0].type |
||||
|
// this.zdyTableColumns = zdyTableColumnsJSON |
||||
|
// this.otherData = this.propsData.noteAndBackFlushDetails |
||||
|
// } |
||||
|
} |
||||
|
} |
||||
|
}) |
||||
|
this.doFreshTableLayout() |
||||
|
}, |
||||
|
// 递归 子级层级 |
||||
|
recursion(val){ |
||||
|
val.forEach(item => { |
||||
|
if(item.componentDTOs) { |
||||
|
item.children = item.componentDTOs |
||||
|
this.recursion(item.componentDTOs) |
||||
|
} |
||||
|
}) |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
<style lang="scss" scoped> |
||||
|
// el-drawer |
||||
|
@import "./style/index.scss"; |
||||
|
</style> |
@ -0,0 +1,122 @@ |
|||||
|
.el-drawer__wrapper { |
||||
|
z-index: 10 !important; |
||||
|
position: absolute; |
||||
|
left: 32%; |
||||
|
overflow: visible; |
||||
|
// height:calc(100% - 28px); |
||||
|
// top: 14px; |
||||
|
// right:14px |
||||
|
|
||||
|
::v-deep .el-drawer { |
||||
|
height: 100%; |
||||
|
overflow: visible; |
||||
|
box-shadow: 0 8px 10px -5px rgb(0 0 0 / 15%), 0 16px 24px 2px rgb(0 0 0 / 9%), 0 6px 30px 5px rgb(0 0 0 / 7%); |
||||
|
|
||||
|
.el-drawer__body { |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
|
||||
|
.drawer-heder { |
||||
|
display: flex; |
||||
|
padding: 15px 10px; |
||||
|
justify-content: space-between; |
||||
|
align-items: center; |
||||
|
|
||||
|
.heder-left { |
||||
|
display: flex; |
||||
|
justify-content: space-between; |
||||
|
|
||||
|
.heder-img { |
||||
|
width: 40px; |
||||
|
height: 40px; |
||||
|
margin-right: 10px; |
||||
|
} |
||||
|
|
||||
|
.header-text { |
||||
|
padding:0 20px; |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
justify-content: space-between; |
||||
|
|
||||
|
span:nth-child(1) { |
||||
|
color: #333; |
||||
|
font-size: 22px; |
||||
|
} |
||||
|
|
||||
|
span:nth-child(2) { |
||||
|
color: #999; |
||||
|
font-size: 16px; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.Descriptions { |
||||
|
padding: 0 10px; |
||||
|
} |
||||
|
|
||||
|
.drawer-main { |
||||
|
// padding-top: 20px; |
||||
|
flex: 1; |
||||
|
overflow: hidden; |
||||
|
// background-color: #efefef; |
||||
|
padding: 10px 20px 20px 30px; |
||||
|
border-top: solid 5px #f6f6f6; |
||||
|
|
||||
|
.el-tabs { |
||||
|
height: 100%; |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
.el-tabs__header{ |
||||
|
// padding-bottom: 5px ; |
||||
|
.el-tabs__nav{ |
||||
|
z-index: auto !important; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.el-tabs__content { |
||||
|
flex: 1; |
||||
|
|
||||
|
.el-tab-pane { |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
overflow-y: auto; |
||||
|
} |
||||
|
|
||||
|
.el-descriptions-item__label { |
||||
|
padding-right: 40px; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.drawer-Shut { |
||||
|
width: 35px; |
||||
|
height: 100px; |
||||
|
position: absolute; |
||||
|
top: 200px; |
||||
|
left: -35px; |
||||
|
|
||||
|
.el-button { |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
display: flex; |
||||
|
justify-content: center; |
||||
|
align-items: center; |
||||
|
|
||||
|
::v-deep span { |
||||
|
font-size: 12px; |
||||
|
letter-spacing: 10px; |
||||
|
writing-mode: tb-rl; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
::v-deep .el-tabs__nav-wrap::after{ |
||||
|
content: unset !important; |
||||
|
} |
@ -0,0 +1,349 @@ |
|||||
|
<template> |
||||
|
<el-dialog |
||||
|
title="高级筛选" |
||||
|
v-if="displayDialog.screenDialog" |
||||
|
:visible="true" |
||||
|
:modal="false" |
||||
|
top="5vh" |
||||
|
width="950px" |
||||
|
> |
||||
|
<curren-Form |
||||
|
class="navFilter" |
||||
|
size="medium" |
||||
|
labelWidth="0" |
||||
|
:searchData="screenData" |
||||
|
:searchOptions="editOptions" |
||||
|
:searchHandle="editHandle" |
||||
|
@submitForm="screenFormClick(arguments)" |
||||
|
> |
||||
|
<template> |
||||
|
<el-row :gutter="20"> |
||||
|
<el-form-item |
||||
|
v-for="(item, index) in screenData.filters" |
||||
|
:key="index" |
||||
|
> |
||||
|
<el-col :span="5"> |
||||
|
<el-form-item |
||||
|
:prop="'filters.' + index + '.column'" |
||||
|
:rules="{ |
||||
|
required: true, |
||||
|
message: '请选择筛选对象', |
||||
|
trigger: 'change', |
||||
|
}" |
||||
|
> |
||||
|
<el-select |
||||
|
v-model="item.column" |
||||
|
placeholder="请选择筛选对象" |
||||
|
:disabled="item.hide" |
||||
|
:filterable="true" |
||||
|
@change="filterColumnChange(item)" |
||||
|
> |
||||
|
<el-option |
||||
|
v-for="(item, index) in tableColumnsOptions(tableColumns)" |
||||
|
:key="index" |
||||
|
:label="item.label" |
||||
|
:value=" |
||||
|
item.showProp |
||||
|
? item.prop + '.' + item.showProp |
||||
|
: item.prop |
||||
|
" |
||||
|
> |
||||
|
</el-option> |
||||
|
</el-select> |
||||
|
</el-form-item> |
||||
|
</el-col> |
||||
|
<el-col :span="5"> |
||||
|
<el-form-item |
||||
|
:prop="'filters.' + index + '.action'" |
||||
|
:rules="{ |
||||
|
required: true, |
||||
|
message: '请选择条件', |
||||
|
trigger: 'change', |
||||
|
}" |
||||
|
> |
||||
|
<el-select |
||||
|
v-model="item.action" |
||||
|
placeholder="请选择条件" |
||||
|
:disabled="item.column == '' || item.hide ? true : false" |
||||
|
> |
||||
|
<el-option |
||||
|
v-for="item in options.action" |
||||
|
:key="item.value" |
||||
|
:label="item.label" |
||||
|
:value="item.value" |
||||
|
> |
||||
|
</el-option> |
||||
|
</el-select> |
||||
|
</el-form-item> |
||||
|
</el-col> |
||||
|
<el-col :span="7"> |
||||
|
<el-form-item |
||||
|
:prop="'filters.' + index + '.value'" |
||||
|
:rules="{ |
||||
|
required: true, |
||||
|
message: '请输入内容', |
||||
|
trigger: 'blur', |
||||
|
}" |
||||
|
> |
||||
|
<el-select |
||||
|
v-if="Object.keys(inputOrSelect(item.column)).length > 0" |
||||
|
v-model="item.value" |
||||
|
placeholder="请选择内容" |
||||
|
:disabled="item.column == '' || item.hide ? true : false" |
||||
|
:filterable="true" |
||||
|
@change="inputOrSelect(item.column)" |
||||
|
clearable |
||||
|
> |
||||
|
<el-option |
||||
|
v-for="item in $staticOptions[ |
||||
|
inputOrSelect(item.column).filters |
||||
|
]()" |
||||
|
:key="item.value" |
||||
|
:label="item.label" |
||||
|
:disabled="item.disabled" |
||||
|
:value=" |
||||
|
typeof item.value == 'string' |
||||
|
? item.value |
||||
|
: String(item.value) |
||||
|
" |
||||
|
> |
||||
|
</el-option> |
||||
|
</el-select> |
||||
|
<el-input |
||||
|
v-else |
||||
|
v-model="item.value" |
||||
|
placeholder="请输入内容" |
||||
|
:disabled="item.column == '' || item.hide ? true : false" |
||||
|
clearable |
||||
|
></el-input> |
||||
|
</el-form-item> |
||||
|
</el-col> |
||||
|
<el-col :span="5"> |
||||
|
<el-form-item |
||||
|
:prop="'filters.' + index + '.logic'" |
||||
|
:rules="{ |
||||
|
required: true, |
||||
|
message: '请选择关系', |
||||
|
trigger: 'change', |
||||
|
}" |
||||
|
> |
||||
|
<el-select |
||||
|
v-model="item.logic" |
||||
|
placeholder="请选择关系" |
||||
|
:disabled="item.column == '' || item.hide ? true : false" |
||||
|
> |
||||
|
<el-option |
||||
|
v-for="item in options.logic" |
||||
|
:key="item.value" |
||||
|
:label="item.label" |
||||
|
:value="item.value" |
||||
|
> |
||||
|
</el-option> |
||||
|
</el-select> |
||||
|
</el-form-item> |
||||
|
</el-col> |
||||
|
<el-col :span="1" v-if="!item.hide"> |
||||
|
<el-button |
||||
|
type="danger" |
||||
|
icon="el-icon-minus" |
||||
|
circle |
||||
|
size="mini" |
||||
|
@click="screenDelete(index)" |
||||
|
></el-button> |
||||
|
</el-col> |
||||
|
</el-form-item> |
||||
|
</el-row> |
||||
|
</template> |
||||
|
<div class="screen-push"> |
||||
|
<span @click="screenPush">+ 添加筛选条件</span> |
||||
|
</div> |
||||
|
</curren-Form> |
||||
|
</el-dialog> |
||||
|
</template> |
||||
|
<script> |
||||
|
export default { |
||||
|
props: { |
||||
|
//displayDialog显示 |
||||
|
displayDialog: { |
||||
|
type: Object, |
||||
|
default: () => { |
||||
|
return { |
||||
|
screenDialog: false |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
// 筛选数据 |
||||
|
screenData: { |
||||
|
type: Object, |
||||
|
default: () => { |
||||
|
return {}; |
||||
|
} |
||||
|
}, |
||||
|
tableColumns: { |
||||
|
type: Array, |
||||
|
default: () => { |
||||
|
return [] |
||||
|
} |
||||
|
}, |
||||
|
//验证规则 |
||||
|
editOptions: { |
||||
|
type: Object, |
||||
|
default: () => { |
||||
|
return {} |
||||
|
} |
||||
|
}, |
||||
|
//挂载到body |
||||
|
modalAppendToBody: { |
||||
|
type: Boolean, |
||||
|
default: () => { |
||||
|
return true |
||||
|
} |
||||
|
}, |
||||
|
// 筛选条件自定义(等于/不等于/大于/小于等数据) |
||||
|
filterActionOptions:{ |
||||
|
type: Array, |
||||
|
default: null |
||||
|
} |
||||
|
// //按钮 |
||||
|
// editHandle: { |
||||
|
// type: Array, |
||||
|
// default: () => { |
||||
|
// return [] |
||||
|
// } |
||||
|
// } |
||||
|
}, |
||||
|
watch: { |
||||
|
// InputOrSelect (val) { |
||||
|
// if (val) { |
||||
|
// this.InputOrSelectHide = val |
||||
|
// } |
||||
|
// } |
||||
|
}, |
||||
|
computed: { |
||||
|
}, |
||||
|
data() { |
||||
|
return { |
||||
|
editHandle: [ |
||||
|
{ float: 'left', label: '重置', type: 'danger', name: 'reset' }, |
||||
|
{ label: "取消", name: "cancel" }, |
||||
|
{ label: "确定", type: "primary", name: "determine" }, |
||||
|
], |
||||
|
options: { |
||||
|
action: [{ |
||||
|
value: '==', |
||||
|
label: '等于' |
||||
|
}, { |
||||
|
value: '!=', |
||||
|
label: '不等于' |
||||
|
}, { |
||||
|
value: '>', |
||||
|
label: '大于' |
||||
|
}, { |
||||
|
value: '<', |
||||
|
label: '小于' |
||||
|
}, { |
||||
|
value: '>=', |
||||
|
label: '大于等于' |
||||
|
}, { |
||||
|
value: '<=', |
||||
|
label: '小于等于' |
||||
|
}, { |
||||
|
value: 'Like', |
||||
|
label: '包含' |
||||
|
}, { |
||||
|
value: 'NotLike', |
||||
|
label: '不包含' |
||||
|
}, |
||||
|
// { |
||||
|
// value: 'In', |
||||
|
// label: '包含' |
||||
|
// }, { |
||||
|
// value: 'NotIn', |
||||
|
// label: '不包含' |
||||
|
// } |
||||
|
], |
||||
|
logic: [ |
||||
|
{ |
||||
|
value: 'And', |
||||
|
label: '并且' |
||||
|
}, |
||||
|
{ |
||||
|
value: 'Or', |
||||
|
label: '或者' |
||||
|
} |
||||
|
], |
||||
|
}, |
||||
|
rules: |
||||
|
{ |
||||
|
column: [ |
||||
|
{ required: true, message: '请选择筛选对象', trigger: 'change' } |
||||
|
], |
||||
|
// value: [ |
||||
|
// { required: true, message: '请输入内容', trigger: 'change' } |
||||
|
// ], |
||||
|
action: [ |
||||
|
{ required: true, message: '请选择条件', trigger: 'change' } |
||||
|
], |
||||
|
logic: [ |
||||
|
{ required: true, message: '请选择关系', trigger: 'change' } |
||||
|
] |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
created() { |
||||
|
// this.form.exerciseType = this.typeOptions[0].value |
||||
|
|
||||
|
}, |
||||
|
mounted() { |
||||
|
if(this.filterActionOptions)this.options.action = this.filterActionOptions |
||||
|
}, |
||||
|
methods: { |
||||
|
// 选择对象更改 |
||||
|
filterColumnChange(item){ |
||||
|
// 筛选对象更改时候,清空value值 |
||||
|
item.value = "" |
||||
|
}, |
||||
|
tableColumnsOptions(val) { |
||||
|
const data = JSON.parse(JSON.stringify(val)); |
||||
|
let num = 0 |
||||
|
val.forEach((item, index) => { |
||||
|
if (item.showProp) { |
||||
|
data.splice(index - num, 1) |
||||
|
num++ |
||||
|
} |
||||
|
}) |
||||
|
return data |
||||
|
}, |
||||
|
inputOrSelect(val) { |
||||
|
let data |
||||
|
if (val) { |
||||
|
this.tableColumns.forEach((key) => { |
||||
|
if (val == key.prop) { |
||||
|
if (key.filters) { |
||||
|
data = key |
||||
|
} else { |
||||
|
data = {} |
||||
|
} |
||||
|
} |
||||
|
}) |
||||
|
} else { |
||||
|
data = {} |
||||
|
} |
||||
|
return data |
||||
|
}, |
||||
|
screenFormClick(val) { |
||||
|
this.$emit("screenFormClick", val) |
||||
|
}, |
||||
|
screenDelete(val) { |
||||
|
this.$emit("screenDelete", val) |
||||
|
}, |
||||
|
screenPush() { |
||||
|
this.$emit("screenPush") |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
</script> |
||||
|
<style lang="scss" scoped> |
||||
|
@import "./style/index.scss"; |
||||
|
</style> |
@ -0,0 +1,46 @@ |
|||||
|
.el-dialog__wrapper { |
||||
|
width:100% !important; |
||||
|
} |
||||
|
|
||||
|
::v-deep .el-dialog { |
||||
|
overflow: hidden; |
||||
|
overflow-x: auto; |
||||
|
} |
||||
|
|
||||
|
::v-deep .navFilter { |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
max-height: 50vh; |
||||
|
|
||||
|
.el-form { |
||||
|
flex: 1; |
||||
|
padding-left: 100px; |
||||
|
padding-right: 100px; |
||||
|
display: flex; |
||||
|
justify-content: center; |
||||
|
align-content: flex-start; |
||||
|
flex-wrap: wrap; |
||||
|
overflow: hidden; |
||||
|
overflow-y: auto; |
||||
|
} |
||||
|
|
||||
|
.screen-push { |
||||
|
width: 100%; |
||||
|
padding-left: 5px; |
||||
|
color: rgb(64, 158, 255); |
||||
|
|
||||
|
span { |
||||
|
cursor: pointer; |
||||
|
|
||||
|
&:hover { |
||||
|
color: blue; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.formButton { |
||||
|
padding: 20px 20px 20px 0; |
||||
|
} |
||||
|
} |
@ -0,0 +1,107 @@ |
|||||
|
<template> |
||||
|
<div class="tableNavBtnsContent"> |
||||
|
<div class="tableNavLeftBtns"> |
||||
|
<!-- 左侧按钮 --> |
||||
|
<innerButton :Butttondata="buttonsLeft" @tableButtonClick="tableButtonClick"></innerButton> |
||||
|
</div> |
||||
|
<div class="tableNavRightBtns"> |
||||
|
<!-- 快速搜索 --> |
||||
|
<searchNormal |
||||
|
ref="quicklySearchDomRef" |
||||
|
v-if="quicklySearchOption" |
||||
|
:searchNormalOption="quicklySearchOption" |
||||
|
@searchNormalClick="quicklySearchClick" |
||||
|
@searchNormalClear="quicklySearchClear" |
||||
|
></searchNormal> |
||||
|
<!-- 右侧按钮 --> |
||||
|
<innerButton :Butttondata="buttonsRight" @tableButtonClick="tableButtonClick"></innerButton> |
||||
|
</div> |
||||
|
<slot></slot> |
||||
|
</div> |
||||
|
</template> |
||||
|
<script> |
||||
|
import innerButton from "./innerButton.vue" |
||||
|
import searchNormal from "@/components/searchNormal/index.vue" |
||||
|
import permission from "@/directive/permission/index" |
||||
|
export default { |
||||
|
directives: { permission }, |
||||
|
components:{ |
||||
|
innerButton, |
||||
|
searchNormal |
||||
|
}, |
||||
|
props: { |
||||
|
Butttondata: { |
||||
|
type: Array, |
||||
|
default: () => { |
||||
|
return [] |
||||
|
} |
||||
|
}, |
||||
|
quicklySearchOption: { |
||||
|
type: Object, |
||||
|
default: null |
||||
|
}, |
||||
|
// 按钮整体靠右 |
||||
|
buttonsAllIsRight:{ |
||||
|
type: Boolean, |
||||
|
default: false |
||||
|
} |
||||
|
}, |
||||
|
data () { |
||||
|
return { |
||||
|
buttonsLeft:null,//左侧按钮数据 |
||||
|
buttonsRight:null,//右侧按钮数据 |
||||
|
} |
||||
|
}, |
||||
|
mounted(){ |
||||
|
this.initButtonsData() |
||||
|
}, |
||||
|
methods:{ |
||||
|
// 按钮数据处理(左右分开处理) |
||||
|
initButtonsData(){ |
||||
|
this.buttonsLeft = [] |
||||
|
this.buttonsRight = [] |
||||
|
if(this.buttonsAllIsRight){ |
||||
|
this.buttonsRight = this.Butttondata |
||||
|
return |
||||
|
} |
||||
|
this.Butttondata.forEach(item=>{ |
||||
|
if(item.float && item.float == 'right'){ |
||||
|
this.buttonsRight.push(item) |
||||
|
}else{ |
||||
|
this.buttonsLeft.push(item) |
||||
|
} |
||||
|
}) |
||||
|
}, |
||||
|
// 按钮事件 |
||||
|
tableButtonClick (val,item) { |
||||
|
this.$emit('tableButtonClick', val,item) |
||||
|
}, |
||||
|
// 搜索 |
||||
|
quicklySearchClick(val,option){ |
||||
|
this.$emit('quicklySearchClick', val,option) |
||||
|
}, |
||||
|
// 清除搜索 |
||||
|
quicklySearchClear(val,option){ |
||||
|
this.$emit('quicklySearchClear', val,option) |
||||
|
}, |
||||
|
// 获取快速搜索的节点,便于其他组件清空搜索值 |
||||
|
getQuicklySearchDom(){ |
||||
|
return this.$refs.quicklySearchDomRef |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
<style lang="scss"> |
||||
|
.tableNavBtnsContent{ |
||||
|
display: flex; |
||||
|
justify-content: space-between; |
||||
|
|
||||
|
.tableNavRightBtns{ |
||||
|
display: flex; |
||||
|
margin-left: 10px; |
||||
|
.currenButton .el-button { |
||||
|
margin-left: 10px !important; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</style> |
@ -0,0 +1,66 @@ |
|||||
|
<template> |
||||
|
<div class="currenButton clearfix"> |
||||
|
<el-button |
||||
|
v-for="(item, index) in Butttondata" :key="index" |
||||
|
v-show="typeof item.hide == 'function' ? !item.hide() : !item.hide" |
||||
|
:type="item.type" |
||||
|
:icon="item.icon" |
||||
|
:plain="item.plain" |
||||
|
:round="item.round" |
||||
|
:circle="item.circle" |
||||
|
:size="item.size" |
||||
|
:style="{ |
||||
|
float:item.float, |
||||
|
background:item.background, |
||||
|
borderColor:item.background, |
||||
|
}" |
||||
|
:class="item.class" |
||||
|
@click="tableButtonClick(item.name,item)" |
||||
|
v-permission="item.permission || []" |
||||
|
>{{ item.label }}</el-button> |
||||
|
</div> |
||||
|
</template> |
||||
|
<script> |
||||
|
import permission from "@/directive/permission/index" |
||||
|
export default { |
||||
|
directives: { permission }, |
||||
|
props: { |
||||
|
Butttondata: { |
||||
|
type: Array, |
||||
|
default: () => { |
||||
|
return [] |
||||
|
} |
||||
|
}, |
||||
|
}, |
||||
|
mounted(){ |
||||
|
window.addEventListener('setItemEvent', (item) => { |
||||
|
if (item.key.indexOf('tableColumns') > -1) { |
||||
|
this.initButtonType(item) |
||||
|
} |
||||
|
}) |
||||
|
}, |
||||
|
methods:{ |
||||
|
initButtonType(changeItem){ |
||||
|
let _num = 0 |
||||
|
let _new = JSON.parse(changeItem.newValue) |
||||
|
_new.forEach((item) => { |
||||
|
if(item.istrue)_num ++ |
||||
|
}) |
||||
|
this.Butttondata.forEach(item=>{ |
||||
|
// 监听本地缓存【字段配置】缓存,更改按钮type |
||||
|
if(item.name == 'field'){ |
||||
|
return item.type = (_num >= _new.length) ? '' : 'warning'; |
||||
|
} |
||||
|
}) |
||||
|
}, |
||||
|
tableButtonClick (val,item) { |
||||
|
this.$emit('tableButtonClick', val,item) |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
<style lang="scss" scoped> |
||||
|
.el-button{ |
||||
|
margin-left: 10px; |
||||
|
} |
||||
|
</style> |
@ -0,0 +1,181 @@ |
|||||
|
<template> |
||||
|
<el-descriptions |
||||
|
class="currenDescriptionsPage" |
||||
|
:title="title" |
||||
|
:column="column" |
||||
|
:direction="direction" |
||||
|
:colon="colon" |
||||
|
:border="border" |
||||
|
v-loading="currenDescriptionsLoading" |
||||
|
> |
||||
|
<template> |
||||
|
<el-descriptions-item |
||||
|
:label="item.label" |
||||
|
v-for="(item, index) in tabsDesTions" |
||||
|
:key="index" |
||||
|
:labelStyle="{'text-align': 'right','padding-right':'10px'}" |
||||
|
> |
||||
|
<span v-if="item.type && item.type == 'date'">{{ |
||||
|
propsData[item.prop] | formatOnlyDate |
||||
|
}}</span> |
||||
|
<span v-else-if="item.type && item.type == 'dateTime'">{{ |
||||
|
propsData[item.prop] | formatDate |
||||
|
}}</span> |
||||
|
<span v-else-if="item.type && item.type == 'objectDateTime'">{{ |
||||
|
propsData[item.prop]?propsData[item.prop][item.showProp]:"" | formatDate |
||||
|
}}</span> |
||||
|
<span v-else-if="item.type && item.type == 'object'"> |
||||
|
{{ propsData[item.prop]?propsData[item.prop][item.showProp]:"" }} |
||||
|
</span> |
||||
|
<span v-else-if="item.type && item.type == 'filter'"> |
||||
|
{{ propsData[item.prop] | trigger(item.filters,"label", item.dictType) }} |
||||
|
</span> |
||||
|
<span v-else-if="item.type && item.type == 'objectFilter'"> |
||||
|
{{ propsData[item.prop]?propsData[item.prop][item.showProp]:false | trigger(item.filters,"label") }} |
||||
|
</span> |
||||
|
<span v-else-if="item.type && item.type == 'percent'"> |
||||
|
{{ propsData[item.prop] +'%' }} |
||||
|
</span> |
||||
|
<span v-else-if="item.type && item.type == 'uploadPictureCard'"> |
||||
|
<div id="uploadPictureCardRef">{{propsData[item.prop] | formatDatePicture}}</div> |
||||
|
</span> |
||||
|
<span v-else-if="item.type == 'filterList'" > |
||||
|
{{ propsData[item.prop] | triggerList(item.filters, "label") }} |
||||
|
</span> |
||||
|
<!-- 文本域 --> |
||||
|
<span v-else-if="item.type == 'textarea'"> |
||||
|
<template> |
||||
|
<el-input |
||||
|
:type="item.type" |
||||
|
v-model="propsData[item.prop]" |
||||
|
:rows="item.rows" |
||||
|
:readonly="item.readonly" |
||||
|
></el-input> |
||||
|
</template> |
||||
|
</span> |
||||
|
<span v-else>{{ propsData[item.prop] ? propsData[item.prop] + "" : propsData[item.prop] }}</span> |
||||
|
</el-descriptions-item> |
||||
|
</template> |
||||
|
<el-descriptions-item |
||||
|
v-for="item in descriptionsData" |
||||
|
:label="item.label" |
||||
|
:key="item.label" |
||||
|
>{{ item.data }}</el-descriptions-item |
||||
|
> |
||||
|
<slot></slot> |
||||
|
</el-descriptions> |
||||
|
</template> |
||||
|
<script> |
||||
|
import { parseTime } from "@/utils/formatTime" |
||||
|
import { formatTimeStrToStr } from "@/utils/formatTime" |
||||
|
import { fileStorage } from "@/api/wms-api" |
||||
|
|
||||
|
let that |
||||
|
export default { |
||||
|
name:'curren-descriptions', |
||||
|
data () { |
||||
|
return { |
||||
|
// 临时存储文件编号 防止重复请求图片 |
||||
|
blobName: '', |
||||
|
currenDescriptionsLoading: false |
||||
|
} |
||||
|
}, |
||||
|
beforeCreate () { |
||||
|
that = this; |
||||
|
}, |
||||
|
filters: { |
||||
|
formatDate (time) { |
||||
|
if (time == null) { |
||||
|
return '-' |
||||
|
} |
||||
|
return formatTimeStrToStr(time) |
||||
|
}, |
||||
|
formatOnlyDate (time) { |
||||
|
var date = new Date(time); |
||||
|
return parseTime(date).substring(0,10) |
||||
|
}, |
||||
|
formatDatePicture(val) { |
||||
|
if (val !== undefined && that.blobName !== val) { |
||||
|
that.blobName = val |
||||
|
that.currenDescriptionsLoading = true |
||||
|
fileStorage({blobName: val}).then(res => { |
||||
|
var byteString = atob(res.bytes) |
||||
|
var arrayBuffer = new ArrayBuffer(byteString.length) // 创建缓冲数组 |
||||
|
var intArray = new Uint8Array(arrayBuffer) // 创建视图 |
||||
|
for (var i = 0; i < byteString.length; i++) { |
||||
|
intArray[i] = byteString.charCodeAt(i) |
||||
|
} |
||||
|
const blob = new Blob([intArray], { type: '' }) |
||||
|
var img = new Image() |
||||
|
img.width="100" |
||||
|
img.height="100" |
||||
|
img.src = URL.createObjectURL(blob) |
||||
|
var otest = document.getElementById("uploadPictureCardRef") |
||||
|
otest.innerHTML = '' |
||||
|
otest.appendChild(img) |
||||
|
that.currenDescriptionsLoading = false |
||||
|
}).catch(err => { |
||||
|
console.log(err) |
||||
|
that.currenDescriptionsLoading = false |
||||
|
}) |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
props: { |
||||
|
title: { |
||||
|
type: String, |
||||
|
default: '' |
||||
|
}, |
||||
|
colon: { |
||||
|
type: Boolean, |
||||
|
default: true |
||||
|
}, |
||||
|
column: { |
||||
|
type: Number, |
||||
|
default: 1 |
||||
|
}, |
||||
|
border: { |
||||
|
type: Boolean, |
||||
|
default: false |
||||
|
}, |
||||
|
descriptionsData: { |
||||
|
type: Array, |
||||
|
default: () => { |
||||
|
return [] |
||||
|
} |
||||
|
}, |
||||
|
direction: { |
||||
|
type: String, |
||||
|
default: 'horizontal' |
||||
|
}, |
||||
|
tabsDesTions: { |
||||
|
type: Array, |
||||
|
default: () => { |
||||
|
return [] |
||||
|
} |
||||
|
}, |
||||
|
propsData: { |
||||
|
type: Object, |
||||
|
default: () => { |
||||
|
return {} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
<style lang="scss"> |
||||
|
.currenDescriptionsPage{ |
||||
|
th{ |
||||
|
min-width: 200px !important; |
||||
|
width: auto; |
||||
|
} |
||||
|
td{ |
||||
|
span{ |
||||
|
display: inline-block; |
||||
|
max-height: 150px; |
||||
|
overflow: auto; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</style> |
@ -0,0 +1,174 @@ |
|||||
|
<template> |
||||
|
<el-descriptions |
||||
|
class="currenDescriptionsPage" |
||||
|
:title="title" |
||||
|
:column="column" |
||||
|
:direction="direction" |
||||
|
:colon="colon" |
||||
|
:border="border" |
||||
|
v-loading="currenDescriptionsLoading" |
||||
|
> |
||||
|
<template> |
||||
|
<el-descriptions-item |
||||
|
:label="item.label" |
||||
|
v-for="(item, index) in tabsDesTions" |
||||
|
:key="index" |
||||
|
:labelStyle="{'text-align': 'right','padding-right':'10px'}" |
||||
|
> |
||||
|
<!-- 时间转换 --> |
||||
|
<span v-if="item.apiBaseType && item.apiBaseType == 'datetime'">{{ |
||||
|
propsData[item.prop] | formatDate |
||||
|
}}</span> |
||||
|
<!-- 枚举 --> |
||||
|
<span v-else-if="item.isEnums"> |
||||
|
{{ initApiEnumList(item,propsData[item.prop]) }} |
||||
|
</span> |
||||
|
<!-- 布尔 --> |
||||
|
<span v-else-if="item.apiBaseType == 'boolean'"> |
||||
|
{{ propsData[item.prop] ? '是' : '否' }} |
||||
|
</span> |
||||
|
<!-- 数值 --> |
||||
|
<span v-else-if="item.apiBaseType == 'number'"> |
||||
|
{{ propsData[item.prop] }} |
||||
|
</span> |
||||
|
<span v-else> |
||||
|
{{ propsData[item.prop] ? propsData[item.prop] + "" : propsData[item.prop] }} |
||||
|
</span> |
||||
|
</el-descriptions-item> |
||||
|
</template> |
||||
|
<el-descriptions-item |
||||
|
v-for="item in descriptionsData" |
||||
|
:label="item.label" |
||||
|
:key="item.label" |
||||
|
>{{ item.data }}</el-descriptions-item |
||||
|
> |
||||
|
<slot></slot> |
||||
|
</el-descriptions> |
||||
|
</template> |
||||
|
<script> |
||||
|
import { parseTime } from "@/utils/formatTime" |
||||
|
import { formatTimeStrToStr } from "@/utils/formatTime" |
||||
|
import { fileStorage } from "@/api/wms-api" |
||||
|
|
||||
|
let that |
||||
|
export default { |
||||
|
name:'curren-descriptions', |
||||
|
data () { |
||||
|
return { |
||||
|
// 临时存储文件编号 防止重复请求图片 |
||||
|
blobName: '', |
||||
|
currenDescriptionsLoading: false |
||||
|
} |
||||
|
}, |
||||
|
beforeCreate () { |
||||
|
that = this; |
||||
|
}, |
||||
|
filters: { |
||||
|
formatDate (time) { |
||||
|
if (time == null) { |
||||
|
return '-' |
||||
|
} |
||||
|
return formatTimeStrToStr(time) |
||||
|
}, |
||||
|
formatOnlyDate (time) { |
||||
|
var date = new Date(time); |
||||
|
return parseTime(date).substring(0,10) |
||||
|
}, |
||||
|
formatDatePicture(val) { |
||||
|
if (val !== undefined && that.blobName !== val) { |
||||
|
that.blobName = val |
||||
|
that.currenDescriptionsLoading = true |
||||
|
fileStorage({blobName: val}).then(res => { |
||||
|
var byteString = atob(res.bytes) |
||||
|
var arrayBuffer = new ArrayBuffer(byteString.length) // 创建缓冲数组 |
||||
|
var intArray = new Uint8Array(arrayBuffer) // 创建视图 |
||||
|
for (var i = 0; i < byteString.length; i++) { |
||||
|
intArray[i] = byteString.charCodeAt(i) |
||||
|
} |
||||
|
const blob = new Blob([intArray], { type: '' }) |
||||
|
var img = new Image() |
||||
|
img.width="100" |
||||
|
img.height="100" |
||||
|
img.src = URL.createObjectURL(blob) |
||||
|
var otest = document.getElementById("uploadPictureCardRef") |
||||
|
otest.innerHTML = '' |
||||
|
otest.appendChild(img) |
||||
|
that.currenDescriptionsLoading = false |
||||
|
}).catch(err => { |
||||
|
console.log(err) |
||||
|
that.currenDescriptionsLoading = false |
||||
|
}) |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
props: { |
||||
|
title: { |
||||
|
type: String, |
||||
|
default: '' |
||||
|
}, |
||||
|
colon: { |
||||
|
type: Boolean, |
||||
|
default: true |
||||
|
}, |
||||
|
column: { |
||||
|
type: Number, |
||||
|
default: 1 |
||||
|
}, |
||||
|
border: { |
||||
|
type: Boolean, |
||||
|
default: false |
||||
|
}, |
||||
|
descriptionsData: { |
||||
|
type: Array, |
||||
|
default: () => { |
||||
|
return [] |
||||
|
} |
||||
|
}, |
||||
|
direction: { |
||||
|
type: String, |
||||
|
default: 'horizontal' |
||||
|
}, |
||||
|
tabsDesTions: { |
||||
|
type: Array, |
||||
|
default: () => { |
||||
|
return [] |
||||
|
} |
||||
|
}, |
||||
|
propsData: { |
||||
|
type: Object, |
||||
|
default: () => { |
||||
|
return {} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
}, |
||||
|
methods:{ |
||||
|
// 转义枚举值 |
||||
|
initApiEnumList(item,data){ |
||||
|
let _item_enumList = {} |
||||
|
if(item.enums_list){ |
||||
|
item.enums_list.forEach((item,key)=>{ |
||||
|
_item_enumList[item.value] = item.label |
||||
|
}) |
||||
|
} |
||||
|
return _item_enumList[data] || '未定义' |
||||
|
}, |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
<style lang="scss"> |
||||
|
.currenDescriptionsPage{ |
||||
|
th{ |
||||
|
min-width: 200px !important; |
||||
|
width: auto; |
||||
|
} |
||||
|
td{ |
||||
|
span{ |
||||
|
display: inline-block; |
||||
|
max-height: 150px; |
||||
|
overflow: auto; |
||||
|
min-width: 200px; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</style> |
@ -0,0 +1,888 @@ |
|||||
|
<template> |
||||
|
<div class="currenForm"> |
||||
|
<!-- @submit.native.prevent 阻止form只有一个input输入框回车触发提交事件 --> |
||||
|
<el-form |
||||
|
ref="form" |
||||
|
:size="size" |
||||
|
:label-position="labelPosition" |
||||
|
:inline="inline" |
||||
|
:label-width="labelWidth" |
||||
|
:rules="rules" |
||||
|
:model="searchData" |
||||
|
@submit.native.prevent |
||||
|
v-if="!hide ? true : false" |
||||
|
> |
||||
|
<el-row :gutter="40"> |
||||
|
<el-col |
||||
|
:span="item.colSpan" |
||||
|
v-for="(item, index) in searchForm" |
||||
|
:key="index" |
||||
|
> |
||||
|
<el-form-item |
||||
|
:label="item.label" |
||||
|
:prop="item.showProp ? item.prop + '.' + item.showProp : item.prop" |
||||
|
v-if="!item.hide ? true : false" |
||||
|
> |
||||
|
<!-- 输入框 onkeyup: 正则表达式,用于前端输入校验工作--> |
||||
|
<!-- :onkeyup="item.onkeyup" --> |
||||
|
<el-input |
||||
|
v-if="item.type === 'input'" |
||||
|
v-model="searchData[item.prop]" |
||||
|
:maxlength="item.maxlength" |
||||
|
:onkeyup="itemOnKeyUp(item,searchData[item.prop])" |
||||
|
clearable |
||||
|
:disabled="Boolean(item.disabled)" |
||||
|
:placeholder="item.placeholder || '请输入' + item.label" |
||||
|
:prefix-icon="item.icon" |
||||
|
:show-password="item.showPassword" |
||||
|
@change="changeInput(item.prop,$event)" |
||||
|
@clear="clearInput(item.prop,$event)" |
||||
|
@blur=" |
||||
|
inputPlaceholder($event, item, 'blur',searchData) |
||||
|
" |
||||
|
@focus="inputPlaceholder($event, item, 'focus')" |
||||
|
></el-input> |
||||
|
<!-- 输入框(有上下增加按钮框) onkeyup: 正则表达式,用于前端输入校验工作--> |
||||
|
<el-input-number |
||||
|
v-if="item.type === 'number'" |
||||
|
v-model="searchData[item.prop]" |
||||
|
:onkeyup="item.onkeyup" |
||||
|
:disabled="Boolean(item.disabled)" |
||||
|
@change="changeInput(item.prop,$event)" |
||||
|
@clear="clearInput(item.prop,$event)" |
||||
|
:min="item.min" |
||||
|
:max="item.max" |
||||
|
:precision="item.precision" |
||||
|
class="inputNameberClass" |
||||
|
@blur=" |
||||
|
inputPlaceholder($event, item, 'blur',searchData) |
||||
|
" |
||||
|
@focus="inputPlaceholder($event, item, 'focus')" |
||||
|
></el-input-number> |
||||
|
<!-- 输入框(只能输入数字) onkeyup: 正则表达式,用于前端输入校验工作--> |
||||
|
<!-- oninput="value=value.replace(/[^\d]/g,'')" --> |
||||
|
<el-input |
||||
|
v-if="item.type === 'inputNumber'" |
||||
|
v-model="searchData[item.prop]" |
||||
|
:maxlength="item.maxlength" |
||||
|
:onkeyup="typeNumberOnkeyup(item,searchData[item.prop])" |
||||
|
clearable |
||||
|
:disabled="Boolean(item.disabled)" |
||||
|
:placeholder="item.placeholder || '请输入' + item.label" |
||||
|
:prefix-icon="item.icon" |
||||
|
:show-password="item.showPassword" |
||||
|
@change="changeInput(item.prop,$event)" |
||||
|
@clear="clearInput(item.prop,$event)" |
||||
|
@blur=" |
||||
|
inputPlaceholder($event, item, 'blur',searchData) |
||||
|
" |
||||
|
@focus="inputPlaceholder($event, item, 'focus')" |
||||
|
></el-input> |
||||
|
<!-- 对象输入框 --> |
||||
|
<el-input |
||||
|
v-if="item.type === 'objectInput'" |
||||
|
v-model="searchData[item.prop][item.showProp]" |
||||
|
:maxlength="item.maxlength" |
||||
|
clearable |
||||
|
:disabled="Boolean(item.disabled)" |
||||
|
:placeholder="item.placeholder || '请输入' + item.label" |
||||
|
:prefix-icon="item.icon" |
||||
|
:show-password="item.showPassword" |
||||
|
@blur=" |
||||
|
inputPlaceholder($event, item, 'blur',searchData) |
||||
|
" |
||||
|
@focus="inputPlaceholder($event, item, 'focus')" |
||||
|
></el-input> |
||||
|
<!-- 对象富文本框 --> |
||||
|
<el-input |
||||
|
v-if="item.type === 'objectTextarea'" |
||||
|
type="textarea" |
||||
|
v-model="searchData[item.prop][item.showProp]" |
||||
|
:placeholder="item.placeholder || '请输入' + item.label" |
||||
|
></el-input> |
||||
|
<!--查询下拉--> |
||||
|
<el-autocomplete |
||||
|
v-if="item.type === 'autocomplete'" |
||||
|
class="inline-input" |
||||
|
style="width: 100%" |
||||
|
v-model="searchData[item.prop]" |
||||
|
:disabled="Boolean(item.disabled)" |
||||
|
:fetch-suggestions=" |
||||
|
(queryString, cb) => { |
||||
|
querySearch(queryString, cb, item); |
||||
|
} |
||||
|
" |
||||
|
:placeholder="item.placeholder || '请输入' + item.label" |
||||
|
@select="handleSelect($event, item)" |
||||
|
> |
||||
|
<el-button |
||||
|
slot="append" |
||||
|
icon="el-icon-search" |
||||
|
v-if="item.click" |
||||
|
@click="item.click(item)" |
||||
|
style="color: #1890ff; background-color: #ffffff" |
||||
|
></el-button> |
||||
|
</el-autocomplete> |
||||
|
<!--对象查询下拉--> |
||||
|
<el-autocomplete |
||||
|
v-if="item.type === 'objectAutocomplete'" |
||||
|
class="inline-input" |
||||
|
style="width: 100%" |
||||
|
v-model="searchData[item.prop][item.showProp]" |
||||
|
:fetch-suggestions=" |
||||
|
(queryString, cb) => { |
||||
|
querySearch(queryString, cb, item); |
||||
|
} |
||||
|
" |
||||
|
:placeholder="item.placeholder || '请输入' + item.label" |
||||
|
@select="handleSelect($event, item)" |
||||
|
> |
||||
|
<el-button |
||||
|
slot="append" |
||||
|
icon="el-icon-search" |
||||
|
v-if="item.click" |
||||
|
@click="item.click(item)" |
||||
|
style="color: #1890ff; background-color: #ffffff" |
||||
|
></el-button> |
||||
|
</el-autocomplete> |
||||
|
<!-- 文本框 --> |
||||
|
<el-input |
||||
|
v-if="item.type === 'textarea'" |
||||
|
:type="item.type" |
||||
|
v-model="searchData[item.prop]" |
||||
|
:rows="item.rows" |
||||
|
:placeholder="item.placeholder || '请输入' + item.label" |
||||
|
:maxlength="item.maxlength" |
||||
|
show-word-limit |
||||
|
></el-input> |
||||
|
<!-- 下拉框 --> |
||||
|
<el-select |
||||
|
v-if="item.type === 'select'" |
||||
|
v-model="searchData[item.prop]" |
||||
|
:loading="selectLoading" |
||||
|
:clearable="item.clearable" |
||||
|
:multiple="item.multiple" |
||||
|
:disabled="Boolean(item.disabled)" |
||||
|
:filterable="item.filterable" |
||||
|
:allow-create="item.allowCreate" |
||||
|
style="width: 100%" |
||||
|
:placeholder="item.placeholder || '请输入' + item.label" |
||||
|
@change="changeSelect(item.prop,$event)" |
||||
|
> |
||||
|
<el-option |
||||
|
v-for="(op, index) in selectOptions(item.options) || |
||||
|
item.userOptions" |
||||
|
:label="op[item.optionsLabel] || op.label" |
||||
|
:value="op[item.optionsValue] || op.value" |
||||
|
:key="index" |
||||
|
></el-option> |
||||
|
</el-select> |
||||
|
<!-- 链接接口filter下拉框 --> |
||||
|
<filterSelect |
||||
|
v-if="item.type === 'filterSelect'" |
||||
|
:selectModel="searchData[item.prop]" |
||||
|
:selectItem="item" |
||||
|
@filterOptionSelectHandle="filterOptionSelectHandle" |
||||
|
@filterClearHandle="filterClearHandle(item)" |
||||
|
></filterSelect> |
||||
|
<!--对象下拉框 --> |
||||
|
<el-select |
||||
|
v-if="item.type === 'objectSelect'" |
||||
|
v-model="searchData[item.prop][item.showProp]" |
||||
|
:loading="selectLoading" |
||||
|
:clearable="item.clearable" |
||||
|
:multiple="item.multiple" |
||||
|
:disabled="Boolean(item.disabled)" |
||||
|
:filterable="item.filterable" |
||||
|
:allow-create="item.allowCreate" |
||||
|
style="width: 100%" |
||||
|
:placeholder="item.placeholder || '请输入' + item.label" |
||||
|
> |
||||
|
<el-option |
||||
|
v-for="(op, index) in selectOptions(item.options) || |
||||
|
searchOptions['options']" |
||||
|
:label="op[item.optionsLabel] || op.label" |
||||
|
:value="op[item.optionsValue] || op.value" |
||||
|
:key="index" |
||||
|
></el-option> |
||||
|
</el-select> |
||||
|
<!-- 下拉框多选 --> |
||||
|
<el-select |
||||
|
v-if="item.type === 'selectArray'" |
||||
|
v-model="searchData[item.prop]" |
||||
|
multiple |
||||
|
:placeholder="item.placeholder || '请选择' + item.label" |
||||
|
style="width: 100%" |
||||
|
> |
||||
|
<el-option |
||||
|
v-for="(op, index) in selectOptions(item.options) || |
||||
|
item.searchOptions" |
||||
|
:label="op[item.optionsLabel] || op.label" |
||||
|
:value="op[item.optionsValue] || op.value" |
||||
|
:key="index" |
||||
|
></el-option> |
||||
|
</el-select> |
||||
|
<!-- 单选 --> |
||||
|
<el-radio-group |
||||
|
v-if="item.type === 'radio'" |
||||
|
v-model="searchData[item.prop]" |
||||
|
:disabled="Boolean(item.disabled)" |
||||
|
@change="radioChange(item.prop,$event)" |
||||
|
> |
||||
|
<el-radio |
||||
|
v-for="ra in searchOptions[item.radio]" |
||||
|
:label="ra.id" |
||||
|
:key="ra.value" |
||||
|
>{{ ra.label }}</el-radio |
||||
|
> |
||||
|
</el-radio-group> |
||||
|
<!-- 单选按钮 --> |
||||
|
<el-radio-group |
||||
|
v-if="item.type === 'radioButton'" |
||||
|
v-model="searchData[item.prop]" |
||||
|
@change="item.change && item.change(searchData[item.prop])" |
||||
|
> |
||||
|
<el-radio-button |
||||
|
v-for="ra in searchOptions[item.radios]" |
||||
|
:label="ra.value" |
||||
|
:key="ra.value" |
||||
|
>{{ ra.label }}</el-radio-button |
||||
|
> |
||||
|
</el-radio-group> |
||||
|
<!-- 复选框 --> |
||||
|
<el-checkbox v-if="item.type === 'checkbox'" :indeterminate="indeterminate" v-model="item.checkAll" @change="handleCheckAllChange($event,item)">全选</el-checkbox> |
||||
|
<el-checkbox-group |
||||
|
v-if="item.type === 'checkbox'" |
||||
|
v-model="searchData[item.prop]" |
||||
|
@change="handleCheckedCitiesChange($event,item)" |
||||
|
> |
||||
|
<el-checkbox |
||||
|
v-for="ch in searchOptions[item.checkboxs]" |
||||
|
:label="ch" |
||||
|
:key="ch" |
||||
|
>{{ ch }}</el-checkbox |
||||
|
> |
||||
|
</el-checkbox-group> |
||||
|
<!-- 日期 --> |
||||
|
<el-date-picker |
||||
|
v-if="item.type === 'date'" |
||||
|
v-model="searchData[item.prop]" |
||||
|
style="width: 100%" |
||||
|
:disabled="Boolean(item.disabled)" |
||||
|
:placeholder="item.placeholder || '选择日期'" |
||||
|
value-format="yyyy-MM-dd" |
||||
|
></el-date-picker> |
||||
|
<!-- 时间 --> |
||||
|
<el-time-picker |
||||
|
v-if="item.type === 'time'" |
||||
|
v-model="searchData[item.prop]" |
||||
|
:placeholder="item.placeholder || '选择时间'" |
||||
|
style="width: 100%" |
||||
|
:picker-options="{ |
||||
|
selectableRange: '00:00:00 - 23:59:00', |
||||
|
}" |
||||
|
:disabled="Boolean(item.disabled)" |
||||
|
format="HH:mm" |
||||
|
value-format="yyyy-MM-ddTHH:mm:ss" |
||||
|
></el-time-picker> |
||||
|
<!-- 日期时间 --> |
||||
|
<el-date-picker |
||||
|
v-if="item.type === 'dateTime'" |
||||
|
type="datetime" |
||||
|
v-model="searchData[item.prop]" |
||||
|
:placeholder="item.placeholder || '选择日期时间'" |
||||
|
style="width: 100%" |
||||
|
format="yyyy-MM-dd HH:mm:ss" |
||||
|
value-format="yyyy-MM-ddTHH:mm:ss" |
||||
|
:disabled="Boolean(item.disabled)" |
||||
|
></el-date-picker> |
||||
|
<!-- 日期时间 日期有限制 选择范围:当前天及以后--> |
||||
|
<el-date-picker |
||||
|
v-if="item.type === 'dateTimelimit'" |
||||
|
type="datetime" |
||||
|
v-model="searchData[item.prop]" |
||||
|
:placeholder="item.placeholder || '选择日期时间'" |
||||
|
style="width: 100%" |
||||
|
format="yyyy-MM-dd HH:mm:ss" |
||||
|
value-format="yyyy-MM-ddTHH:mm:ss" |
||||
|
:disabled="Boolean(item.disabled)" |
||||
|
:pickerOptions="endDateTimeLimitPickerOptions()" |
||||
|
></el-date-picker> |
||||
|
<!-- 对象日期时间 --> |
||||
|
<el-date-picker |
||||
|
v-if="item.type === 'objectDateTime'" |
||||
|
type="datetime" |
||||
|
v-model="searchData[item.prop][item.showProp]" |
||||
|
:placeholder="item.placeholder || '选择日期'" |
||||
|
style="width: 100%" |
||||
|
value-format="yyyy-MM-ddTHH:mm:ss" |
||||
|
:disabled="Boolean(item.disabled)" |
||||
|
></el-date-picker> |
||||
|
<!--开始时间结束时间--> |
||||
|
<div |
||||
|
class="RangeDateTime" |
||||
|
v-if="item.type === 'rangeDateTime'" |
||||
|
style="width: 100%; height: 100%" |
||||
|
> |
||||
|
<el-col :span="10"> |
||||
|
<el-form-item :prop="item.prop + '.' + item.startDate"> |
||||
|
<el-date-picker |
||||
|
type="datetime" |
||||
|
:placeholder="item.placeholder || '开始日期'" |
||||
|
v-model="searchData[item.prop][item.startDate]" |
||||
|
style="width: 100%" |
||||
|
:disabled="Boolean(item.disabled)" |
||||
|
value-format="yyyy-MM-ddTHH:mm:ss" |
||||
|
:pickerOptions=" |
||||
|
startPickerOptions(searchData[item.prop][item.endDate]) |
||||
|
" |
||||
|
></el-date-picker> |
||||
|
</el-form-item> |
||||
|
</el-col> |
||||
|
<el-col class="line" :span="4">-</el-col> |
||||
|
<el-col :span="10"> |
||||
|
<el-form-item :prop="item.prop + '.' + item.endDate"> |
||||
|
<el-date-picker |
||||
|
type="datetime" |
||||
|
:placeholder="item.placeholder || '结束日期'" |
||||
|
v-model="searchData[item.prop][item.endDate]" |
||||
|
style="width: 100%" |
||||
|
:disabled="Boolean(item.disabled)" |
||||
|
value-format="yyyy-MM-ddTHH:mm:ss" |
||||
|
:pickerOptions=" |
||||
|
endPickerOptions(searchData[item.prop][item.startDate]) |
||||
|
" |
||||
|
></el-date-picker> |
||||
|
</el-form-item> |
||||
|
</el-col> |
||||
|
</div> |
||||
|
<!-- 开关 --> |
||||
|
<el-switch |
||||
|
v-if="item.type === 'switch'" |
||||
|
v-model="searchData[item.prop]" |
||||
|
></el-switch> |
||||
|
<!--文件上传--> |
||||
|
<currenUpload |
||||
|
v-if="item.type === 'upload'" |
||||
|
:limit="item.limit" |
||||
|
:beforeUpload="beforeAvatarUpload" |
||||
|
:searchData="searchData[item.prop]" |
||||
|
@httpRequestfiles="httpRequestfiles($event, item.prop)" |
||||
|
@handleRemove="handleRemove($event, item.prop)" |
||||
|
> |
||||
|
</currenUpload> |
||||
|
<!--文件上传——列表形式--> |
||||
|
<currenUploadList |
||||
|
v-if="item.type === 'uploadList'" |
||||
|
:limit="item.limit" |
||||
|
:picExt="item.picExt" |
||||
|
:searchData="searchData[item.prop]" |
||||
|
@uploadListView="uploadListView" |
||||
|
@changeUpload="changeUpload($event, item)" |
||||
|
@handleRemove="handleRemove($event, item.prop)" |
||||
|
> |
||||
|
</currenUploadList> |
||||
|
<!-- 缩略图上传 --> |
||||
|
<currenUploadPictureCard |
||||
|
v-if="item.type === 'uploadPictureCard'" |
||||
|
:limit="item.limit" |
||||
|
:multiple="item.multiple" |
||||
|
:picExt="item.picExt" |
||||
|
:searchData="searchData[item.prop]" |
||||
|
@changeUpload="changeUpload($event, item)" |
||||
|
@handleRemove="handleRemove($event, item.prop)" |
||||
|
> |
||||
|
</currenUploadPictureCard> |
||||
|
<el-button |
||||
|
v-if="item.type === 'button'" |
||||
|
type="primary" |
||||
|
size="mini" |
||||
|
@click="item.click(item)" |
||||
|
> |
||||
|
{{item.buttonText}} |
||||
|
</el-button> |
||||
|
</el-form-item> |
||||
|
</el-col> |
||||
|
</el-row> |
||||
|
<slot></slot> |
||||
|
</el-form> |
||||
|
<div v-if="isHandle" class="formButton"> |
||||
|
<!-- :style="{float:item.float}" 自定义按钮显示位置 --> |
||||
|
<el-button |
||||
|
v-for="(item, index) in searchHandle" |
||||
|
:key="item.label" |
||||
|
:type="item.type" |
||||
|
:size="item.size || size" |
||||
|
:loading="loading" |
||||
|
:style="{float:item.float}" |
||||
|
@click="submitForm(index,item)" |
||||
|
>{{ item.label }}</el-button |
||||
|
> |
||||
|
</div> |
||||
|
</div> |
||||
|
</template> |
||||
|
<script> |
||||
|
import currenUpload from "@/components/currenUpload"; |
||||
|
import currenUploadList from "@/components/currenUploadList"; |
||||
|
import currenUploadPictureCard from "@/components/currenUploadPictureCard"; |
||||
|
import filterSelect from "@/components/filterSelect" |
||||
|
import { getMatchRegConformValue } from "@/utils/index" |
||||
|
export default { |
||||
|
name: "currenForm", |
||||
|
components: { |
||||
|
currenUpload, |
||||
|
currenUploadList, |
||||
|
currenUploadPictureCard, |
||||
|
filterSelect |
||||
|
}, |
||||
|
props: { |
||||
|
loading: { |
||||
|
type: Boolean, |
||||
|
default: false, |
||||
|
}, |
||||
|
labelPosition: { |
||||
|
type: String, |
||||
|
default: "right", |
||||
|
}, |
||||
|
isHandle: { |
||||
|
type: Boolean, |
||||
|
default: true, |
||||
|
}, |
||||
|
inline: { |
||||
|
type: Boolean, |
||||
|
default: false, |
||||
|
}, |
||||
|
labelWidth: { |
||||
|
type: String, |
||||
|
default: "140px", |
||||
|
}, |
||||
|
size: { |
||||
|
type: String, |
||||
|
default: "mini", |
||||
|
}, |
||||
|
searchForm: { |
||||
|
type: Array, |
||||
|
default: () => { |
||||
|
return []; |
||||
|
}, |
||||
|
}, |
||||
|
searchHandle: { |
||||
|
type: Array, |
||||
|
default: () => { |
||||
|
return []; |
||||
|
}, |
||||
|
}, |
||||
|
searchData: { |
||||
|
type: Object, |
||||
|
default: () => { |
||||
|
return {}; |
||||
|
}, |
||||
|
}, |
||||
|
searchOptions: { |
||||
|
type: Object, |
||||
|
default: () => { |
||||
|
return {}; |
||||
|
}, |
||||
|
}, |
||||
|
rules: { |
||||
|
type: Object, |
||||
|
default: () => { |
||||
|
return {}; |
||||
|
}, |
||||
|
}, |
||||
|
formSpan: { |
||||
|
type: Number, |
||||
|
default: 24, |
||||
|
}, |
||||
|
hide: { |
||||
|
type: Boolean, |
||||
|
default: false, |
||||
|
}, |
||||
|
}, |
||||
|
data() { |
||||
|
return { |
||||
|
restaurants: [], |
||||
|
indeterminate: false, |
||||
|
selectLoading: false, |
||||
|
}; |
||||
|
}, |
||||
|
computed: { |
||||
|
startPickerOptions() { |
||||
|
return function (val) { |
||||
|
return { |
||||
|
disabledDate(time) { |
||||
|
if (val) { |
||||
|
return ( |
||||
|
// time.getTime() > Date.now() || |
||||
|
// time.getTime() > new Date(that.CreateFormData.endDate).getTime() |
||||
|
time.getTime() > val |
||||
|
); |
||||
|
} |
||||
|
// return time.getTime() > Date.now(); //实现1效果 |
||||
|
}, |
||||
|
}; |
||||
|
}; |
||||
|
}, |
||||
|
endPickerOptions() { |
||||
|
// const that = this; |
||||
|
return function (val) { |
||||
|
return { |
||||
|
disabledDate(time) { |
||||
|
if (val) { |
||||
|
return ( |
||||
|
// time.getTime() > Date.now() || |
||||
|
// time.getTime() < new Date(that.CreateFormData.startDate).getTime() |
||||
|
time.getTime() < val |
||||
|
); |
||||
|
} |
||||
|
// return time.getTime() > Date.now(); //实现1效果 |
||||
|
}, |
||||
|
}; |
||||
|
}; |
||||
|
}, |
||||
|
// 日期时间组件,选择范围:当前天及以后 |
||||
|
endDateTimeLimitPickerOptions() { |
||||
|
return function () { |
||||
|
return { |
||||
|
disabledDate(time) { |
||||
|
return ( |
||||
|
time.getTime() < Date.now() - 8.64e7 |
||||
|
); |
||||
|
}, |
||||
|
}; |
||||
|
}; |
||||
|
}, |
||||
|
selectOptions() { |
||||
|
return (val) => { |
||||
|
if (val) { |
||||
|
let options = this.$staticOptions[val]; |
||||
|
if (options) { |
||||
|
return options(); |
||||
|
} else { |
||||
|
return []; |
||||
|
} |
||||
|
} else { |
||||
|
return false; |
||||
|
} |
||||
|
}; |
||||
|
}, |
||||
|
}, |
||||
|
mounted() { |
||||
|
// 单选 , 默认设置 |
||||
|
this.searchForm.forEach(item => { |
||||
|
if (item.type === 'radio') { |
||||
|
this.searchData[item.prop] = item.value + '' |
||||
|
} |
||||
|
if (item.type === 'checkbox') { |
||||
|
this.searchData[item.prop].push(item.value) |
||||
|
} |
||||
|
}) |
||||
|
}, |
||||
|
methods: { |
||||
|
// type=input情况下,框实时校验 |
||||
|
itemOnKeyUp(item,value){ |
||||
|
if(item.onkeyup){ |
||||
|
return item.onkeyup() |
||||
|
}else{ |
||||
|
if(value && item.validType){ |
||||
|
this.searchData[item.prop]=getMatchRegConformValue(item.validType,value,item.pointNumberFixed) |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
// 数字类型input框onkeyup最大最小值处理 |
||||
|
typeNumberOnkeyup(item,value){ |
||||
|
if(value){ |
||||
|
// 添加pointNumberFixed 可以输入小数 |
||||
|
if (item.pointNumberFixed) { |
||||
|
let _fixed = item.pointNumberFixed ? Number(item.pointNumberFixed) : 100 |
||||
|
let reg = new RegExp(`\\d+\\.?\\d{0,${_fixed}}`); |
||||
|
let _match = String(value).match(reg) |
||||
|
this.searchData[item.prop] = _match ? _match[0] : _match |
||||
|
} else { |
||||
|
let _match = String(value).match(/\d+/)//正整数 |
||||
|
this.searchData[item.prop] = _match?_match[0]:_match |
||||
|
} |
||||
|
} |
||||
|
if(this.searchData[item.prop] > item.max){ |
||||
|
this.searchData[item.prop] = item.max |
||||
|
} |
||||
|
if(this.searchData[item.prop] && this.searchData[item.prop] < item.min){ |
||||
|
this.searchData[item.prop] = item.min |
||||
|
} |
||||
|
if(item.onkeyup)item.onkeyup() |
||||
|
}, |
||||
|
//复选框全选 |
||||
|
handleCheckAllChange(val,item) { |
||||
|
const options = [] |
||||
|
if(val){ |
||||
|
this.searchOptions[item.checkboxs].forEach(items=>{ |
||||
|
options.push(items) |
||||
|
}) |
||||
|
} |
||||
|
this.searchData[item.prop] = val ? options : []; |
||||
|
this.indeterminate = false; |
||||
|
}, |
||||
|
//取消全选 |
||||
|
handleCheckedCitiesChange(value,item) { |
||||
|
let checkedCount = value.length; |
||||
|
item.checkAll = checkedCount === this.searchOptions[item.checkboxs].length; |
||||
|
this.indeterminate = checkedCount > 0 && checkedCount < this.searchOptions[item.checkboxs].length; |
||||
|
}, |
||||
|
inputPlaceholder(val, item, type, func) { |
||||
|
if (item.valueType) { |
||||
|
if (type == "focus") { |
||||
|
console.log("focus") |
||||
|
//影响必填项,2023-1-3 placeholder不处理 |
||||
|
// val.target.placeholder = '0'; |
||||
|
// if (val.target.value != "") { |
||||
|
// val.target.placeholder = val.target.value; |
||||
|
// val.target.value = ""; |
||||
|
// } |
||||
|
} else if (type == "blur") { |
||||
|
console.log("blur") |
||||
|
// val.target.value = "0" |
||||
|
val.target.value = val.target.value.toString().replace(/[^\d.]/g,'') |
||||
|
// if (val.target.value == "") { |
||||
|
// // if (val.target.placeholder.indexOf('请输入') == -1) { |
||||
|
// val.target.value = val.target.placeholder; |
||||
|
// // } |
||||
|
// } |
||||
|
if(item.showProp){ |
||||
|
if(val.target.value != ""){func[item.prop][item.showProp]= Number(val.target.value)} |
||||
|
}else{ |
||||
|
if(val.target.value != ""){func[item.prop]= Number(val.target.value)} |
||||
|
} |
||||
|
// item.valueType |
||||
|
// ? (this.searchData[item.prop] = item.valueType( |
||||
|
// this.searchData[item.prop] |
||||
|
// )) |
||||
|
// : () => { |
||||
|
// return; |
||||
|
// } |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
querySearch(queryString, cb, val) { |
||||
|
const { options, optionsValue, optionsLabel } = val; |
||||
|
let func = val.focus; |
||||
|
let data = {}; |
||||
|
if (queryString) { |
||||
|
data.filter = [ |
||||
|
{ |
||||
|
logic: "And", |
||||
|
column: optionsValue, |
||||
|
action: "Like", |
||||
|
value: queryString, |
||||
|
}, |
||||
|
// { |
||||
|
// logic: "Or", |
||||
|
// column: optionsLabel, |
||||
|
// action: "Like", |
||||
|
// value: queryString |
||||
|
// } |
||||
|
]; |
||||
|
} |
||||
|
func(data).then((res) => { |
||||
|
var restaurants = this.searchOptions["options"]; |
||||
|
var results = queryString |
||||
|
? restaurants.filter( |
||||
|
this.createFilter(queryString, optionsValue, optionsLabel) |
||||
|
) |
||||
|
: restaurants; |
||||
|
results.forEach((key) => { |
||||
|
if (typeof optionsValue === "string") { |
||||
|
key.value = key[optionsValue] + "----" + key[optionsLabel]; |
||||
|
} else { |
||||
|
key.value = |
||||
|
key[optionsValue[0]][optionsValue[1]] + |
||||
|
"----" + |
||||
|
key[optionsLabel]; |
||||
|
} |
||||
|
}); |
||||
|
// 调用 callback 返回建议列表的数据 |
||||
|
cb(results); |
||||
|
}); |
||||
|
}, |
||||
|
createFilter(queryString, optionsValue, optionsLabel) { |
||||
|
return (restaurant) => { |
||||
|
if (typeof optionsValue === "string") { |
||||
|
restaurant.value = |
||||
|
restaurant[optionsValue] + "----" + restaurant[optionsLabel]; |
||||
|
} else { |
||||
|
restaurant.value = |
||||
|
restaurant[optionsValue[0]][optionsValue[1]] + |
||||
|
"----" + |
||||
|
restaurant[optionsLabel]; |
||||
|
} |
||||
|
return ( |
||||
|
restaurant.value.toLowerCase().indexOf(queryString.toLowerCase()) != |
||||
|
-1 |
||||
|
); |
||||
|
}; |
||||
|
}, |
||||
|
handleSelect(item, val) { |
||||
|
let data = this.searchData; |
||||
|
if (!val.showProp) { |
||||
|
if (typeof val.optionsValue === "string") { |
||||
|
data[val.prop] = item[val.optionsValue]; |
||||
|
} else { |
||||
|
data[val.prop] = item[val.optionsValue[0]][val.optionsValue[1]]; |
||||
|
} |
||||
|
} else { |
||||
|
if (typeof val.optionsValue === "string") { |
||||
|
data[val.prop][val.showProp] = item[val.optionsValue]; |
||||
|
} else { |
||||
|
data[val.prop][val.showProp] = |
||||
|
item[val.optionsValue[0]][val.optionsValue[1]]; |
||||
|
} |
||||
|
} |
||||
|
this.$emit("push", item, val); |
||||
|
}, |
||||
|
// filterSelect点击option事件 |
||||
|
filterOptionSelectHandle(item,props,val){ |
||||
|
this.searchData[props['prop']] = val |
||||
|
this.$emit("push", item, props); |
||||
|
}, |
||||
|
// filterSelect点击清除事件 |
||||
|
filterClearHandle(item){ |
||||
|
this.searchData[item['prop']] = "" |
||||
|
this.$emit("clear",item) |
||||
|
}, |
||||
|
// selectFocus (val, item) { |
||||
|
// this.selectLoading = true; |
||||
|
// let func = item.focus |
||||
|
// func({}).then(res => { |
||||
|
// this.selectLoading = false; |
||||
|
// }) |
||||
|
// }, |
||||
|
// dataFilter (query, item) { |
||||
|
// const { options, optionsValue, optionsLabel } = item |
||||
|
// let func = item.focus |
||||
|
// let data = {} |
||||
|
// this.selectLoading = true; |
||||
|
// if (query) { |
||||
|
// data.filter = { |
||||
|
// logic: "And", |
||||
|
// column: optionsLabel, |
||||
|
// action: "Like", |
||||
|
// value: query |
||||
|
// } |
||||
|
// } |
||||
|
// setTimeout(() => { |
||||
|
// func(data).then(res => { |
||||
|
// this.selectLoading = false; |
||||
|
// }) |
||||
|
// }, 200); |
||||
|
// // this.options = []; |
||||
|
// }, |
||||
|
submitForm(val,item) { |
||||
|
this.$emit("submitForm", val, this.$refs.form,item); |
||||
|
}, |
||||
|
getDom(){ |
||||
|
return this.$refs.form |
||||
|
}, |
||||
|
handleClick(val) { |
||||
|
this.$emit("handleClick", val); |
||||
|
}, |
||||
|
httpRequestfiles(val, item) { |
||||
|
this.searchData[item].push(val); |
||||
|
}, |
||||
|
beforeAvatarUpload(val, data) { |
||||
|
const repeat = data.filter((item) => { |
||||
|
return item.name == val.name; |
||||
|
}); |
||||
|
if (repeat.length != 0) { |
||||
|
this.$errorMsg("文件重复"); |
||||
|
return false; |
||||
|
} else { |
||||
|
return true; |
||||
|
} |
||||
|
}, |
||||
|
handleRemove(val, item) { |
||||
|
this.searchData[item] = val |
||||
|
}, |
||||
|
changeUpload(val, item){ |
||||
|
// 判断上传文件是否满足类型 |
||||
|
let suffix = val.name.substring(val.name.lastIndexOf('.') + 1) |
||||
|
if (item.picExt.indexOf(suffix) === -1) { |
||||
|
this.$warningMsg('上传文件只能是 ' + item.picExt + '格式!') |
||||
|
this.searchData[item.prop] = [] |
||||
|
return false |
||||
|
} else { |
||||
|
this.searchData[item.prop].push(val); |
||||
|
} |
||||
|
}, |
||||
|
uploadListView() { |
||||
|
this.$emit('uploadListView') |
||||
|
}, |
||||
|
radioChange(prop, val) { |
||||
|
this.$emit("radioChange", prop, val) |
||||
|
}, |
||||
|
changeInput(prop, val) { |
||||
|
this.$emit("changeInput", prop, val) |
||||
|
}, |
||||
|
clearInput(prop, val) { |
||||
|
this.$emit("clearInput", prop, val) |
||||
|
}, |
||||
|
changeSelect(prop, val) { |
||||
|
this.$emit("changeSelect", prop, val) |
||||
|
}, |
||||
|
|
||||
|
restrictionRule(item, prop) { |
||||
|
|
||||
|
if(prop) { |
||||
|
console.log('item',item) |
||||
|
console.log('prop', prop) |
||||
|
console.log('this.searchData', this.searchData) |
||||
|
console.log(this.searchData[prop]) |
||||
|
if (this.searchData[prop]) { |
||||
|
return false |
||||
|
} else { |
||||
|
return true |
||||
|
} |
||||
|
} else { |
||||
|
return true |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// 单一文件上传输入框——上传文件提示 |
||||
|
// handleExceed (val) { |
||||
|
// this.$warningMsg('最多上传1个文件') |
||||
|
// } |
||||
|
// //自定义select搜索 |
||||
|
// dataFilter (val, data) { |
||||
|
// if (!data) { |
||||
|
// return; |
||||
|
// } else { |
||||
|
// this.$emit(data, val); |
||||
|
// } |
||||
|
// }, |
||||
|
}, |
||||
|
}; |
||||
|
</script> |
||||
|
<style lang="scss" scoped> |
||||
|
// .formButton { |
||||
|
// text-align: right; |
||||
|
// } |
||||
|
.inputNameberClass { |
||||
|
width: 100%; |
||||
|
} |
||||
|
.el-row { |
||||
|
::v-deep .el-form-item__content { |
||||
|
position: relative; |
||||
|
font-size: 14px; |
||||
|
} |
||||
|
.RangeDateTime { |
||||
|
::v-deep .el-col { |
||||
|
padding: 0 !important; |
||||
|
} |
||||
|
.line { |
||||
|
text-align: center; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
::v-deep .el-form-item__label{ |
||||
|
color: #999 !important; |
||||
|
font-weight: normal !important; |
||||
|
} |
||||
|
</style> |
@ -0,0 +1,888 @@ |
|||||
|
<template> |
||||
|
<div class="currenForm"> |
||||
|
<!-- @submit.native.prevent 阻止form只有一个input输入框回车触发提交事件 --> |
||||
|
<el-form |
||||
|
ref="form" |
||||
|
:size="size" |
||||
|
:label-position="labelPosition" |
||||
|
:inline="inline" |
||||
|
:label-width="labelWidth" |
||||
|
:rules="rules" |
||||
|
:model="searchData" |
||||
|
@submit.native.prevent |
||||
|
v-if="!hide ? true : false" |
||||
|
> |
||||
|
<el-row :gutter="40"> |
||||
|
<el-col |
||||
|
:span="item.colSpan" |
||||
|
v-for="(item, index) in searchForm" |
||||
|
:key="index" |
||||
|
> |
||||
|
<el-form-item |
||||
|
:label="item.label" |
||||
|
:prop="item.showProp ? item.prop + '.' + item.showProp : item.prop" |
||||
|
v-if="!item.hide ? true : false" |
||||
|
> |
||||
|
<!-- 输入框 onkeyup: 正则表达式,用于前端输入校验工作--> |
||||
|
<!-- :onkeyup="item.onkeyup" --> |
||||
|
<el-input |
||||
|
v-if="item.type === 'input'" |
||||
|
v-model="searchData[item.prop]" |
||||
|
:maxlength="item.maxlength" |
||||
|
:onkeyup="itemOnKeyUp(item,searchData[item.prop])" |
||||
|
clearable |
||||
|
:disabled="Boolean(item.disabled)" |
||||
|
:placeholder="item.placeholder || '请输入' + item.label" |
||||
|
:prefix-icon="item.icon" |
||||
|
:show-password="item.showPassword" |
||||
|
@change="changeInput(item.prop,$event)" |
||||
|
@clear="clearInput(item.prop,$event)" |
||||
|
@blur=" |
||||
|
inputPlaceholder($event, item, 'blur',searchData) |
||||
|
" |
||||
|
@focus="inputPlaceholder($event, item, 'focus')" |
||||
|
></el-input> |
||||
|
<!-- 输入框(有上下增加按钮框) onkeyup: 正则表达式,用于前端输入校验工作--> |
||||
|
<el-input-number |
||||
|
v-if="item.type === 'number'" |
||||
|
v-model="searchData[item.prop]" |
||||
|
:onkeyup="item.onkeyup" |
||||
|
:disabled="Boolean(item.disabled)" |
||||
|
@change="changeInput(item.prop,$event)" |
||||
|
@clear="clearInput(item.prop,$event)" |
||||
|
:min="item.min" |
||||
|
:max="item.max" |
||||
|
:precision="item.precision" |
||||
|
class="inputNameberClass" |
||||
|
@blur=" |
||||
|
inputPlaceholder($event, item, 'blur',searchData) |
||||
|
" |
||||
|
@focus="inputPlaceholder($event, item, 'focus')" |
||||
|
></el-input-number> |
||||
|
<!-- 输入框(只能输入数字) onkeyup: 正则表达式,用于前端输入校验工作--> |
||||
|
<!-- oninput="value=value.replace(/[^\d]/g,'')" --> |
||||
|
<el-input |
||||
|
v-if="item.type === 'inputNumber'" |
||||
|
v-model="searchData[item.prop]" |
||||
|
:maxlength="item.maxlength" |
||||
|
:onkeyup="typeNumberOnkeyup(item,searchData[item.prop])" |
||||
|
clearable |
||||
|
:disabled="Boolean(item.disabled)" |
||||
|
:placeholder="item.placeholder || '请输入' + item.label" |
||||
|
:prefix-icon="item.icon" |
||||
|
:show-password="item.showPassword" |
||||
|
@change="changeInput(item.prop,$event)" |
||||
|
@clear="clearInput(item.prop,$event)" |
||||
|
@blur=" |
||||
|
inputPlaceholder($event, item, 'blur',searchData) |
||||
|
" |
||||
|
@focus="inputPlaceholder($event, item, 'focus')" |
||||
|
></el-input> |
||||
|
<!-- 对象输入框 --> |
||||
|
<el-input |
||||
|
v-if="item.type === 'objectInput'" |
||||
|
v-model="searchData[item.prop][item.showProp]" |
||||
|
:maxlength="item.maxlength" |
||||
|
clearable |
||||
|
:disabled="Boolean(item.disabled)" |
||||
|
:placeholder="item.placeholder || '请输入' + item.label" |
||||
|
:prefix-icon="item.icon" |
||||
|
:show-password="item.showPassword" |
||||
|
@blur=" |
||||
|
inputPlaceholder($event, item, 'blur',searchData) |
||||
|
" |
||||
|
@focus="inputPlaceholder($event, item, 'focus')" |
||||
|
></el-input> |
||||
|
<!-- 对象富文本框 --> |
||||
|
<el-input |
||||
|
v-if="item.type === 'objectTextarea'" |
||||
|
type="textarea" |
||||
|
v-model="searchData[item.prop][item.showProp]" |
||||
|
:placeholder="item.placeholder || '请输入' + item.label" |
||||
|
></el-input> |
||||
|
<!--查询下拉--> |
||||
|
<el-autocomplete |
||||
|
v-if="item.type === 'autocomplete'" |
||||
|
class="inline-input" |
||||
|
style="width: 100%" |
||||
|
v-model="searchData[item.prop]" |
||||
|
:disabled="Boolean(item.disabled)" |
||||
|
:fetch-suggestions=" |
||||
|
(queryString, cb) => { |
||||
|
querySearch(queryString, cb, item); |
||||
|
} |
||||
|
" |
||||
|
:placeholder="item.placeholder || '请输入' + item.label" |
||||
|
@select="handleSelect($event, item)" |
||||
|
> |
||||
|
<el-button |
||||
|
slot="append" |
||||
|
icon="el-icon-search" |
||||
|
v-if="item.click" |
||||
|
@click="item.click(item)" |
||||
|
style="color: #1890ff; background-color: #ffffff" |
||||
|
></el-button> |
||||
|
</el-autocomplete> |
||||
|
<!--对象查询下拉--> |
||||
|
<el-autocomplete |
||||
|
v-if="item.type === 'objectAutocomplete'" |
||||
|
class="inline-input" |
||||
|
style="width: 100%" |
||||
|
v-model="searchData[item.prop][item.showProp]" |
||||
|
:fetch-suggestions=" |
||||
|
(queryString, cb) => { |
||||
|
querySearch(queryString, cb, item); |
||||
|
} |
||||
|
" |
||||
|
:placeholder="item.placeholder || '请输入' + item.label" |
||||
|
@select="handleSelect($event, item)" |
||||
|
> |
||||
|
<el-button |
||||
|
slot="append" |
||||
|
icon="el-icon-search" |
||||
|
v-if="item.click" |
||||
|
@click="item.click(item)" |
||||
|
style="color: #1890ff; background-color: #ffffff" |
||||
|
></el-button> |
||||
|
</el-autocomplete> |
||||
|
<!-- 文本框 --> |
||||
|
<el-input |
||||
|
v-if="item.type === 'textarea'" |
||||
|
:type="item.type" |
||||
|
v-model="searchData[item.prop]" |
||||
|
:rows="item.rows" |
||||
|
:placeholder="item.placeholder || '请输入' + item.label" |
||||
|
:maxlength="item.maxlength" |
||||
|
show-word-limit |
||||
|
></el-input> |
||||
|
<!-- 下拉框 --> |
||||
|
<el-select |
||||
|
v-if="item.type === 'select'" |
||||
|
v-model="searchData[item.prop]" |
||||
|
:loading="selectLoading" |
||||
|
:clearable="item.clearable" |
||||
|
:multiple="item.multiple" |
||||
|
:disabled="Boolean(item.disabled)" |
||||
|
:filterable="item.filterable" |
||||
|
:allow-create="item.allowCreate" |
||||
|
style="width: 100%" |
||||
|
:placeholder="item.placeholder || '请输入' + item.label" |
||||
|
@change="changeSelect(item.prop,$event)" |
||||
|
> |
||||
|
<el-option |
||||
|
v-for="(op, index) in selectOptions(item.options) || |
||||
|
item.userOptions" |
||||
|
:label="op[item.optionsLabel] || op.label" |
||||
|
:value="op[item.optionsValue] || op.value" |
||||
|
:key="index" |
||||
|
></el-option> |
||||
|
</el-select> |
||||
|
<!-- 链接接口filter下拉框 --> |
||||
|
<filterSelect |
||||
|
v-if="item.type === 'filterSelect'" |
||||
|
:selectModel="searchData[item.prop]" |
||||
|
:selectItem="item" |
||||
|
@filterOptionSelectHandle="filterOptionSelectHandle" |
||||
|
@filterClearHandle="filterClearHandle(item)" |
||||
|
></filterSelect> |
||||
|
<!--对象下拉框 --> |
||||
|
<el-select |
||||
|
v-if="item.type === 'objectSelect'" |
||||
|
v-model="searchData[item.prop][item.showProp]" |
||||
|
:loading="selectLoading" |
||||
|
:clearable="item.clearable" |
||||
|
:multiple="item.multiple" |
||||
|
:disabled="Boolean(item.disabled)" |
||||
|
:filterable="item.filterable" |
||||
|
:allow-create="item.allowCreate" |
||||
|
style="width: 100%" |
||||
|
:placeholder="item.placeholder || '请输入' + item.label" |
||||
|
> |
||||
|
<el-option |
||||
|
v-for="(op, index) in selectOptions(item.options) || |
||||
|
searchOptions['options']" |
||||
|
:label="op[item.optionsLabel] || op.label" |
||||
|
:value="op[item.optionsValue] || op.value" |
||||
|
:key="index" |
||||
|
></el-option> |
||||
|
</el-select> |
||||
|
<!-- 下拉框多选 --> |
||||
|
<el-select |
||||
|
v-if="item.type === 'selectArray'" |
||||
|
v-model="searchData[item.prop]" |
||||
|
multiple |
||||
|
:placeholder="item.placeholder || '请选择' + item.label" |
||||
|
style="width: 100%" |
||||
|
> |
||||
|
<el-option |
||||
|
v-for="(op, index) in selectOptions(item.options) || |
||||
|
item.searchOptions" |
||||
|
:label="op[item.optionsLabel] || op.label" |
||||
|
:value="op[item.optionsValue] || op.value" |
||||
|
:key="index" |
||||
|
></el-option> |
||||
|
</el-select> |
||||
|
<!-- 单选 --> |
||||
|
<el-radio-group |
||||
|
v-if="item.type === 'radio'" |
||||
|
v-model="searchData[item.prop]" |
||||
|
:disabled="Boolean(item.disabled)" |
||||
|
@change="radioChange(item.prop,$event)" |
||||
|
> |
||||
|
<el-radio |
||||
|
v-for="ra in searchOptions[item.radio]" |
||||
|
:label="ra.id" |
||||
|
:key="ra.value" |
||||
|
>{{ ra.label }}</el-radio |
||||
|
> |
||||
|
</el-radio-group> |
||||
|
<!-- 单选按钮 --> |
||||
|
<el-radio-group |
||||
|
v-if="item.type === 'radioButton'" |
||||
|
v-model="searchData[item.prop]" |
||||
|
@change="item.change && item.change(searchData[item.prop])" |
||||
|
> |
||||
|
<el-radio-button |
||||
|
v-for="ra in searchOptions[item.radios]" |
||||
|
:label="ra.value" |
||||
|
:key="ra.value" |
||||
|
>{{ ra.label }}</el-radio-button |
||||
|
> |
||||
|
</el-radio-group> |
||||
|
<!-- 复选框 --> |
||||
|
<el-checkbox v-if="item.type === 'checkbox'" :indeterminate="indeterminate" v-model="item.checkAll" @change="handleCheckAllChange($event,item)">全选</el-checkbox> |
||||
|
<el-checkbox-group |
||||
|
v-if="item.type === 'checkbox'" |
||||
|
v-model="searchData[item.prop]" |
||||
|
@change="handleCheckedCitiesChange($event,item)" |
||||
|
> |
||||
|
<el-checkbox |
||||
|
v-for="ch in searchOptions[item.checkboxs]" |
||||
|
:label="ch" |
||||
|
:key="ch" |
||||
|
>{{ ch }}</el-checkbox |
||||
|
> |
||||
|
</el-checkbox-group> |
||||
|
<!-- 日期 --> |
||||
|
<el-date-picker |
||||
|
v-if="item.type === 'date'" |
||||
|
v-model="searchData[item.prop]" |
||||
|
style="width: 100%" |
||||
|
:disabled="Boolean(item.disabled)" |
||||
|
:placeholder="item.placeholder || '选择日期'" |
||||
|
value-format="yyyy-MM-dd" |
||||
|
></el-date-picker> |
||||
|
<!-- 时间 --> |
||||
|
<el-time-picker |
||||
|
v-if="item.type === 'time'" |
||||
|
v-model="searchData[item.prop]" |
||||
|
:placeholder="item.placeholder || '选择时间'" |
||||
|
style="width: 100%" |
||||
|
:picker-options="{ |
||||
|
selectableRange: '00:00:00 - 23:59:00', |
||||
|
}" |
||||
|
:disabled="Boolean(item.disabled)" |
||||
|
format="HH:mm" |
||||
|
value-format="yyyy-MM-ddTHH:mm:ss" |
||||
|
></el-time-picker> |
||||
|
<!-- 日期时间 --> |
||||
|
<el-date-picker |
||||
|
v-if="item.type === 'dateTime'" |
||||
|
type="datetime" |
||||
|
v-model="searchData[item.prop]" |
||||
|
:placeholder="item.placeholder || '选择日期时间'" |
||||
|
style="width: 100%" |
||||
|
format="yyyy-MM-dd HH:mm:ss" |
||||
|
value-format="yyyy-MM-ddTHH:mm:ss" |
||||
|
:disabled="Boolean(item.disabled)" |
||||
|
></el-date-picker> |
||||
|
<!-- 日期时间 日期有限制 选择范围:当前天及以后--> |
||||
|
<el-date-picker |
||||
|
v-if="item.type === 'dateTimelimit'" |
||||
|
type="datetime" |
||||
|
v-model="searchData[item.prop]" |
||||
|
:placeholder="item.placeholder || '选择日期时间'" |
||||
|
style="width: 100%" |
||||
|
format="yyyy-MM-dd HH:mm:ss" |
||||
|
value-format="yyyy-MM-ddTHH:mm:ss" |
||||
|
:disabled="Boolean(item.disabled)" |
||||
|
:pickerOptions="endDateTimeLimitPickerOptions()" |
||||
|
></el-date-picker> |
||||
|
<!-- 对象日期时间 --> |
||||
|
<el-date-picker |
||||
|
v-if="item.type === 'objectDateTime'" |
||||
|
type="datetime" |
||||
|
v-model="searchData[item.prop][item.showProp]" |
||||
|
:placeholder="item.placeholder || '选择日期'" |
||||
|
style="width: 100%" |
||||
|
value-format="yyyy-MM-ddTHH:mm:ss" |
||||
|
:disabled="Boolean(item.disabled)" |
||||
|
></el-date-picker> |
||||
|
<!--开始时间结束时间--> |
||||
|
<div |
||||
|
class="RangeDateTime" |
||||
|
v-if="item.type === 'rangeDateTime'" |
||||
|
style="width: 100%; height: 100%" |
||||
|
> |
||||
|
<el-col :span="10"> |
||||
|
<el-form-item :prop="item.prop + '.' + item.startDate"> |
||||
|
<el-date-picker |
||||
|
type="datetime" |
||||
|
:placeholder="item.placeholder || '开始日期'" |
||||
|
v-model="searchData[item.prop][item.startDate]" |
||||
|
style="width: 100%" |
||||
|
:disabled="Boolean(item.disabled)" |
||||
|
value-format="yyyy-MM-ddTHH:mm:ss" |
||||
|
:pickerOptions=" |
||||
|
startPickerOptions(searchData[item.prop][item.endDate]) |
||||
|
" |
||||
|
></el-date-picker> |
||||
|
</el-form-item> |
||||
|
</el-col> |
||||
|
<el-col class="line" :span="4">-</el-col> |
||||
|
<el-col :span="10"> |
||||
|
<el-form-item :prop="item.prop + '.' + item.endDate"> |
||||
|
<el-date-picker |
||||
|
type="datetime" |
||||
|
:placeholder="item.placeholder || '结束日期'" |
||||
|
v-model="searchData[item.prop][item.endDate]" |
||||
|
style="width: 100%" |
||||
|
:disabled="Boolean(item.disabled)" |
||||
|
value-format="yyyy-MM-ddTHH:mm:ss" |
||||
|
:pickerOptions=" |
||||
|
endPickerOptions(searchData[item.prop][item.startDate]) |
||||
|
" |
||||
|
></el-date-picker> |
||||
|
</el-form-item> |
||||
|
</el-col> |
||||
|
</div> |
||||
|
<!-- 开关 --> |
||||
|
<el-switch |
||||
|
v-if="item.type === 'switch'" |
||||
|
v-model="searchData[item.prop]" |
||||
|
></el-switch> |
||||
|
<!--文件上传--> |
||||
|
<currenUpload |
||||
|
v-if="item.type === 'upload'" |
||||
|
:limit="item.limit" |
||||
|
:beforeUpload="beforeAvatarUpload" |
||||
|
:searchData="searchData[item.prop]" |
||||
|
@httpRequestfiles="httpRequestfiles($event, item.prop)" |
||||
|
@handleRemove="handleRemove($event, item.prop)" |
||||
|
> |
||||
|
</currenUpload> |
||||
|
<!--文件上传——列表形式--> |
||||
|
<currenUploadList |
||||
|
v-if="item.type === 'uploadList'" |
||||
|
:limit="item.limit" |
||||
|
:picExt="item.picExt" |
||||
|
:searchData="searchData[item.prop]" |
||||
|
@uploadListView="uploadListView" |
||||
|
@changeUpload="changeUpload($event, item)" |
||||
|
@handleRemove="handleRemove($event, item.prop)" |
||||
|
> |
||||
|
</currenUploadList> |
||||
|
<!-- 缩略图上传 --> |
||||
|
<currenUploadPictureCard |
||||
|
v-if="item.type === 'uploadPictureCard'" |
||||
|
:limit="item.limit" |
||||
|
:multiple="item.multiple" |
||||
|
:picExt="item.picExt" |
||||
|
:searchData="searchData[item.prop]" |
||||
|
@changeUpload="changeUpload($event, item)" |
||||
|
@handleRemove="handleRemove($event, item.prop)" |
||||
|
> |
||||
|
</currenUploadPictureCard> |
||||
|
<el-button |
||||
|
v-if="item.type === 'button'" |
||||
|
type="primary" |
||||
|
size="mini" |
||||
|
@click="item.click(item)" |
||||
|
> |
||||
|
{{item.buttonText}} |
||||
|
</el-button> |
||||
|
</el-form-item> |
||||
|
</el-col> |
||||
|
</el-row> |
||||
|
<slot></slot> |
||||
|
</el-form> |
||||
|
<div v-if="isHandle" class="formButton"> |
||||
|
<!-- :style="{float:item.float}" 自定义按钮显示位置 --> |
||||
|
<el-button |
||||
|
v-for="(item, index) in searchHandle" |
||||
|
:key="item.label" |
||||
|
:type="item.type" |
||||
|
:size="item.size || size" |
||||
|
:loading="loading" |
||||
|
:style="{float:item.float}" |
||||
|
@click="submitForm(index,item)" |
||||
|
>{{ item.label }}</el-button |
||||
|
> |
||||
|
</div> |
||||
|
</div> |
||||
|
</template> |
||||
|
<script> |
||||
|
import currenUpload from "@/components/currenUpload"; |
||||
|
import currenUploadList from "@/components/currenUploadList"; |
||||
|
import currenUploadPictureCard from "@/components/currenUploadPictureCard"; |
||||
|
import filterSelect from "@/components/filterSelect" |
||||
|
import { getMatchRegConformValue } from "@/utils/index" |
||||
|
export default { |
||||
|
name: "currenForm", |
||||
|
components: { |
||||
|
currenUpload, |
||||
|
currenUploadList, |
||||
|
currenUploadPictureCard, |
||||
|
filterSelect |
||||
|
}, |
||||
|
props: { |
||||
|
loading: { |
||||
|
type: Boolean, |
||||
|
default: false, |
||||
|
}, |
||||
|
labelPosition: { |
||||
|
type: String, |
||||
|
default: "right", |
||||
|
}, |
||||
|
isHandle: { |
||||
|
type: Boolean, |
||||
|
default: true, |
||||
|
}, |
||||
|
inline: { |
||||
|
type: Boolean, |
||||
|
default: false, |
||||
|
}, |
||||
|
labelWidth: { |
||||
|
type: String, |
||||
|
default: "140px", |
||||
|
}, |
||||
|
size: { |
||||
|
type: String, |
||||
|
default: "mini", |
||||
|
}, |
||||
|
searchForm: { |
||||
|
type: Array, |
||||
|
default: () => { |
||||
|
return []; |
||||
|
}, |
||||
|
}, |
||||
|
searchHandle: { |
||||
|
type: Array, |
||||
|
default: () => { |
||||
|
return []; |
||||
|
}, |
||||
|
}, |
||||
|
searchData: { |
||||
|
type: Object, |
||||
|
default: () => { |
||||
|
return {}; |
||||
|
}, |
||||
|
}, |
||||
|
searchOptions: { |
||||
|
type: Object, |
||||
|
default: () => { |
||||
|
return {}; |
||||
|
}, |
||||
|
}, |
||||
|
rules: { |
||||
|
type: Object, |
||||
|
default: () => { |
||||
|
return {}; |
||||
|
}, |
||||
|
}, |
||||
|
formSpan: { |
||||
|
type: Number, |
||||
|
default: 24, |
||||
|
}, |
||||
|
hide: { |
||||
|
type: Boolean, |
||||
|
default: false, |
||||
|
}, |
||||
|
}, |
||||
|
data() { |
||||
|
return { |
||||
|
restaurants: [], |
||||
|
indeterminate: false, |
||||
|
selectLoading: false, |
||||
|
}; |
||||
|
}, |
||||
|
computed: { |
||||
|
startPickerOptions() { |
||||
|
return function (val) { |
||||
|
return { |
||||
|
disabledDate(time) { |
||||
|
if (val) { |
||||
|
return ( |
||||
|
// time.getTime() > Date.now() || |
||||
|
// time.getTime() > new Date(that.CreateFormData.endDate).getTime() |
||||
|
time.getTime() > val |
||||
|
); |
||||
|
} |
||||
|
// return time.getTime() > Date.now(); //实现1效果 |
||||
|
}, |
||||
|
}; |
||||
|
}; |
||||
|
}, |
||||
|
endPickerOptions() { |
||||
|
// const that = this; |
||||
|
return function (val) { |
||||
|
return { |
||||
|
disabledDate(time) { |
||||
|
if (val) { |
||||
|
return ( |
||||
|
// time.getTime() > Date.now() || |
||||
|
// time.getTime() < new Date(that.CreateFormData.startDate).getTime() |
||||
|
time.getTime() < val |
||||
|
); |
||||
|
} |
||||
|
// return time.getTime() > Date.now(); //实现1效果 |
||||
|
}, |
||||
|
}; |
||||
|
}; |
||||
|
}, |
||||
|
// 日期时间组件,选择范围:当前天及以后 |
||||
|
endDateTimeLimitPickerOptions() { |
||||
|
return function () { |
||||
|
return { |
||||
|
disabledDate(time) { |
||||
|
return ( |
||||
|
time.getTime() < Date.now() - 8.64e7 |
||||
|
); |
||||
|
}, |
||||
|
}; |
||||
|
}; |
||||
|
}, |
||||
|
selectOptions() { |
||||
|
return (val) => { |
||||
|
if (val) { |
||||
|
let options = this.$staticOptions[val]; |
||||
|
if (options) { |
||||
|
return options(); |
||||
|
} else { |
||||
|
return []; |
||||
|
} |
||||
|
} else { |
||||
|
return false; |
||||
|
} |
||||
|
}; |
||||
|
}, |
||||
|
}, |
||||
|
mounted() { |
||||
|
// 单选 , 默认设置 |
||||
|
this.searchForm.forEach(item => { |
||||
|
if (item.type === 'radio') { |
||||
|
this.searchData[item.prop] = item.value + '' |
||||
|
} |
||||
|
if (item.type === 'checkbox') { |
||||
|
this.searchData[item.prop].push(item.value) |
||||
|
} |
||||
|
}) |
||||
|
}, |
||||
|
methods: { |
||||
|
// type=input情况下,框实时校验 |
||||
|
itemOnKeyUp(item,value){ |
||||
|
if(item.onkeyup){ |
||||
|
return item.onkeyup() |
||||
|
}else{ |
||||
|
if(value && item.validType){ |
||||
|
this.searchData[item.prop]=getMatchRegConformValue(item.validType,value,item.pointNumberFixed) |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
// 数字类型input框onkeyup最大最小值处理 |
||||
|
typeNumberOnkeyup(item,value){ |
||||
|
if(value){ |
||||
|
// 添加pointNumberFixed 可以输入小数 |
||||
|
if (item.pointNumberFixed) { |
||||
|
let _fixed = item.pointNumberFixed ? Number(item.pointNumberFixed) : 100 |
||||
|
let reg = new RegExp(`\\d+\\.?\\d{0,${_fixed}}`); |
||||
|
let _match = String(value).match(reg) |
||||
|
this.searchData[item.prop] = _match ? _match[0] : _match |
||||
|
} else { |
||||
|
let _match = String(value).match(/\d+/)//正整数 |
||||
|
this.searchData[item.prop] = _match?_match[0]:_match |
||||
|
} |
||||
|
} |
||||
|
if(this.searchData[item.prop] > item.max){ |
||||
|
this.searchData[item.prop] = item.max |
||||
|
} |
||||
|
if(this.searchData[item.prop] && this.searchData[item.prop] < item.min){ |
||||
|
this.searchData[item.prop] = item.min |
||||
|
} |
||||
|
if(item.onkeyup)item.onkeyup() |
||||
|
}, |
||||
|
//复选框全选 |
||||
|
handleCheckAllChange(val,item) { |
||||
|
const options = [] |
||||
|
if(val){ |
||||
|
this.searchOptions[item.checkboxs].forEach(items=>{ |
||||
|
options.push(items) |
||||
|
}) |
||||
|
} |
||||
|
this.searchData[item.prop] = val ? options : []; |
||||
|
this.indeterminate = false; |
||||
|
}, |
||||
|
//取消全选 |
||||
|
handleCheckedCitiesChange(value,item) { |
||||
|
let checkedCount = value.length; |
||||
|
item.checkAll = checkedCount === this.searchOptions[item.checkboxs].length; |
||||
|
this.indeterminate = checkedCount > 0 && checkedCount < this.searchOptions[item.checkboxs].length; |
||||
|
}, |
||||
|
inputPlaceholder(val, item, type, func) { |
||||
|
if (item.valueType) { |
||||
|
if (type == "focus") { |
||||
|
console.log("focus") |
||||
|
//影响必填项,2023-1-3 placeholder不处理 |
||||
|
// val.target.placeholder = '0'; |
||||
|
// if (val.target.value != "") { |
||||
|
// val.target.placeholder = val.target.value; |
||||
|
// val.target.value = ""; |
||||
|
// } |
||||
|
} else if (type == "blur") { |
||||
|
console.log("blur") |
||||
|
// val.target.value = "0" |
||||
|
val.target.value = val.target.value.toString().replace(/[^\d.]/g,'') |
||||
|
// if (val.target.value == "") { |
||||
|
// // if (val.target.placeholder.indexOf('请输入') == -1) { |
||||
|
// val.target.value = val.target.placeholder; |
||||
|
// // } |
||||
|
// } |
||||
|
if(item.showProp){ |
||||
|
if(val.target.value != ""){func[item.prop][item.showProp]= Number(val.target.value)} |
||||
|
}else{ |
||||
|
if(val.target.value != ""){func[item.prop]= Number(val.target.value)} |
||||
|
} |
||||
|
// item.valueType |
||||
|
// ? (this.searchData[item.prop] = item.valueType( |
||||
|
// this.searchData[item.prop] |
||||
|
// )) |
||||
|
// : () => { |
||||
|
// return; |
||||
|
// } |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
querySearch(queryString, cb, val) { |
||||
|
const { options, optionsValue, optionsLabel } = val; |
||||
|
let func = val.focus; |
||||
|
let data = {}; |
||||
|
if (queryString) { |
||||
|
data.filter = [ |
||||
|
{ |
||||
|
logic: "And", |
||||
|
column: optionsValue, |
||||
|
action: "Like", |
||||
|
value: queryString, |
||||
|
}, |
||||
|
// { |
||||
|
// logic: "Or", |
||||
|
// column: optionsLabel, |
||||
|
// action: "Like", |
||||
|
// value: queryString |
||||
|
// } |
||||
|
]; |
||||
|
} |
||||
|
func(data).then((res) => { |
||||
|
var restaurants = this.searchOptions["options"]; |
||||
|
var results = queryString |
||||
|
? restaurants.filter( |
||||
|
this.createFilter(queryString, optionsValue, optionsLabel) |
||||
|
) |
||||
|
: restaurants; |
||||
|
results.forEach((key) => { |
||||
|
if (typeof optionsValue === "string") { |
||||
|
key.value = key[optionsValue] + "----" + key[optionsLabel]; |
||||
|
} else { |
||||
|
key.value = |
||||
|
key[optionsValue[0]][optionsValue[1]] + |
||||
|
"----" + |
||||
|
key[optionsLabel]; |
||||
|
} |
||||
|
}); |
||||
|
// 调用 callback 返回建议列表的数据 |
||||
|
cb(results); |
||||
|
}); |
||||
|
}, |
||||
|
createFilter(queryString, optionsValue, optionsLabel) { |
||||
|
return (restaurant) => { |
||||
|
if (typeof optionsValue === "string") { |
||||
|
restaurant.value = |
||||
|
restaurant[optionsValue] + "----" + restaurant[optionsLabel]; |
||||
|
} else { |
||||
|
restaurant.value = |
||||
|
restaurant[optionsValue[0]][optionsValue[1]] + |
||||
|
"----" + |
||||
|
restaurant[optionsLabel]; |
||||
|
} |
||||
|
return ( |
||||
|
restaurant.value.toLowerCase().indexOf(queryString.toLowerCase()) != |
||||
|
-1 |
||||
|
); |
||||
|
}; |
||||
|
}, |
||||
|
handleSelect(item, val) { |
||||
|
let data = this.searchData; |
||||
|
if (!val.showProp) { |
||||
|
if (typeof val.optionsValue === "string") { |
||||
|
data[val.prop] = item[val.optionsValue]; |
||||
|
} else { |
||||
|
data[val.prop] = item[val.optionsValue[0]][val.optionsValue[1]]; |
||||
|
} |
||||
|
} else { |
||||
|
if (typeof val.optionsValue === "string") { |
||||
|
data[val.prop][val.showProp] = item[val.optionsValue]; |
||||
|
} else { |
||||
|
data[val.prop][val.showProp] = |
||||
|
item[val.optionsValue[0]][val.optionsValue[1]]; |
||||
|
} |
||||
|
} |
||||
|
this.$emit("push", item, val); |
||||
|
}, |
||||
|
// filterSelect点击option事件 |
||||
|
filterOptionSelectHandle(item,props,val){ |
||||
|
this.searchData[props['prop']] = val |
||||
|
this.$emit("push", item, props); |
||||
|
}, |
||||
|
// filterSelect点击清除事件 |
||||
|
filterClearHandle(item){ |
||||
|
this.searchData[item['prop']] = "" |
||||
|
this.$emit("clear",item) |
||||
|
}, |
||||
|
// selectFocus (val, item) { |
||||
|
// this.selectLoading = true; |
||||
|
// let func = item.focus |
||||
|
// func({}).then(res => { |
||||
|
// this.selectLoading = false; |
||||
|
// }) |
||||
|
// }, |
||||
|
// dataFilter (query, item) { |
||||
|
// const { options, optionsValue, optionsLabel } = item |
||||
|
// let func = item.focus |
||||
|
// let data = {} |
||||
|
// this.selectLoading = true; |
||||
|
// if (query) { |
||||
|
// data.filter = { |
||||
|
// logic: "And", |
||||
|
// column: optionsLabel, |
||||
|
// action: "Like", |
||||
|
// value: query |
||||
|
// } |
||||
|
// } |
||||
|
// setTimeout(() => { |
||||
|
// func(data).then(res => { |
||||
|
// this.selectLoading = false; |
||||
|
// }) |
||||
|
// }, 200); |
||||
|
// // this.options = []; |
||||
|
// }, |
||||
|
submitForm(val,item) { |
||||
|
this.$emit("submitForm", val, this.$refs.form,item); |
||||
|
}, |
||||
|
getDom(){ |
||||
|
return this.$refs.form |
||||
|
}, |
||||
|
handleClick(val) { |
||||
|
this.$emit("handleClick", val); |
||||
|
}, |
||||
|
httpRequestfiles(val, item) { |
||||
|
this.searchData[item].push(val); |
||||
|
}, |
||||
|
beforeAvatarUpload(val, data) { |
||||
|
const repeat = data.filter((item) => { |
||||
|
return item.name == val.name; |
||||
|
}); |
||||
|
if (repeat.length != 0) { |
||||
|
this.$errorMsg("文件重复"); |
||||
|
return false; |
||||
|
} else { |
||||
|
return true; |
||||
|
} |
||||
|
}, |
||||
|
handleRemove(val, item) { |
||||
|
this.searchData[item] = val |
||||
|
}, |
||||
|
changeUpload(val, item){ |
||||
|
// 判断上传文件是否满足类型 |
||||
|
let suffix = val.name.substring(val.name.lastIndexOf('.') + 1) |
||||
|
if (item.picExt.indexOf(suffix) === -1) { |
||||
|
this.$warningMsg('上传文件只能是 ' + item.picExt + '格式!') |
||||
|
this.searchData[item.prop] = [] |
||||
|
return false |
||||
|
} else { |
||||
|
this.searchData[item.prop].push(val); |
||||
|
} |
||||
|
}, |
||||
|
uploadListView() { |
||||
|
this.$emit('uploadListView') |
||||
|
}, |
||||
|
radioChange(prop, val) { |
||||
|
this.$emit("radioChange", prop, val) |
||||
|
}, |
||||
|
changeInput(prop, val) { |
||||
|
this.$emit("changeInput", prop, val) |
||||
|
}, |
||||
|
clearInput(prop, val) { |
||||
|
this.$emit("clearInput", prop, val) |
||||
|
}, |
||||
|
changeSelect(prop, val) { |
||||
|
this.$emit("changeSelect", prop, val) |
||||
|
}, |
||||
|
|
||||
|
restrictionRule(item, prop) { |
||||
|
|
||||
|
if(prop) { |
||||
|
console.log('item',item) |
||||
|
console.log('prop', prop) |
||||
|
console.log('this.searchData', this.searchData) |
||||
|
console.log(this.searchData[prop]) |
||||
|
if (this.searchData[prop]) { |
||||
|
return false |
||||
|
} else { |
||||
|
return true |
||||
|
} |
||||
|
} else { |
||||
|
return true |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// 单一文件上传输入框——上传文件提示 |
||||
|
// handleExceed (val) { |
||||
|
// this.$warningMsg('最多上传1个文件') |
||||
|
// } |
||||
|
// //自定义select搜索 |
||||
|
// dataFilter (val, data) { |
||||
|
// if (!data) { |
||||
|
// return; |
||||
|
// } else { |
||||
|
// this.$emit(data, val); |
||||
|
// } |
||||
|
// }, |
||||
|
}, |
||||
|
}; |
||||
|
</script> |
||||
|
<style lang="scss" scoped> |
||||
|
// .formButton { |
||||
|
// text-align: right; |
||||
|
// } |
||||
|
.inputNameberClass { |
||||
|
width: 100%; |
||||
|
} |
||||
|
.el-row { |
||||
|
::v-deep .el-form-item__content { |
||||
|
position: relative; |
||||
|
font-size: 14px; |
||||
|
} |
||||
|
.RangeDateTime { |
||||
|
::v-deep .el-col { |
||||
|
padding: 0 !important; |
||||
|
} |
||||
|
.line { |
||||
|
text-align: center; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
::v-deep .el-form-item__label{ |
||||
|
color: #999 !important; |
||||
|
font-weight: normal !important; |
||||
|
} |
||||
|
</style> |
@ -0,0 +1,761 @@ |
|||||
|
<template> |
||||
|
<!-- <div> --> |
||||
|
<el-table |
||||
|
:id="_uid" |
||||
|
v-loading="tableLoading" |
||||
|
element-loading-text="拼命加载中..." |
||||
|
@sort-change="sortChange" |
||||
|
@selection-change="handleSelectionChange" |
||||
|
ref="multipleTable" |
||||
|
:data="tableData" |
||||
|
height="85%" |
||||
|
row-key="id" |
||||
|
stripe |
||||
|
border |
||||
|
style="width: 100%" |
||||
|
:tree-props="treeProps" |
||||
|
:cell-style="cellStyle" |
||||
|
> |
||||
|
<el-table-column v-if="selectionTable" fixed="left" type="selection" /> |
||||
|
<el-table-column v-if="isShowIndex" type="index" fixed="left" label="序号" width="50" /> |
||||
|
<el-table-column |
||||
|
v-for="(item, index) in TableSize" |
||||
|
:key="index" |
||||
|
:prop="item.showProp ? item.prop + '.' + item.showProp : item.prop" |
||||
|
:sortable="item.sortable" |
||||
|
:fixed="item.fixed" |
||||
|
:show-overflow-tooltip="true" |
||||
|
:width="item.width" |
||||
|
align="center" |
||||
|
> |
||||
|
<template #header> |
||||
|
<span>{{ item.label }}</span> |
||||
|
<i style="color: #f56c6c" v-if="item.rules && requiredRules">*</i> |
||||
|
</template> |
||||
|
<template slot-scope="scope"> |
||||
|
<el-form> |
||||
|
<el-form-item |
||||
|
v-if="item.type == 'input'" |
||||
|
:onkeyup="itemOnKeyUp(item,item.prop,scope.$index)" |
||||
|
:prop="'details.' + scope.$index + '.' + item.prop" |
||||
|
:rules="item.rules" |
||||
|
> |
||||
|
<el-input |
||||
|
:placeholder="'请输入' + item.label" |
||||
|
:disabled="Boolean(item.disabled) || Boolean(scope.row['disabled'])" |
||||
|
v-model="scope.row[item.prop]" |
||||
|
@blur=" |
||||
|
inputPlaceholder($event, item, 'blur',scope.row) |
||||
|
" |
||||
|
@focus="inputPlaceholder($event, item, 'focus')" |
||||
|
clearable |
||||
|
> |
||||
|
</el-input> |
||||
|
</el-form-item> |
||||
|
<!-- 输入框(数字) onkeyup: 正则表达式,用于前端输入校验工作--> |
||||
|
<el-form-item |
||||
|
v-if="item.type == 'inputNumber'" |
||||
|
:prop="'details.' + scope.$index + '.' + item.prop" |
||||
|
:rules="item.rules" |
||||
|
> |
||||
|
<el-input |
||||
|
v-model="scope.row[item.prop]" |
||||
|
:maxlength="item.maxlength" |
||||
|
:onkeyup="typeNumberOnkeyup(item,item.prop,scope.$index)" |
||||
|
clearable |
||||
|
:disabled="Boolean(item.disabled)" |
||||
|
:placeholder="'请输入' + item.label" |
||||
|
:prefix-icon="item.icon" |
||||
|
:show-password="item.showPassword" |
||||
|
@clear="clearInput(item.prop,$event)" |
||||
|
@blur=" |
||||
|
inputPlaceholder($event, item, 'blur',scope.row) |
||||
|
" |
||||
|
@focus="inputPlaceholder($event, item, 'focus')" |
||||
|
></el-input> |
||||
|
</el-form-item> |
||||
|
<el-form-item |
||||
|
v-if="item.type == 'objectInput'" |
||||
|
:prop=" |
||||
|
'details.' + scope.$index + '.' + item.prop + '.' + item.showProp |
||||
|
" |
||||
|
:rules="item.rules" |
||||
|
> |
||||
|
<el-input |
||||
|
:placeholder="'请输入' + item.label" |
||||
|
v-model="scope.row[item.prop][item.showProp]" |
||||
|
:disabled="Boolean(item.disabled) || Boolean(scope.row['disabled'])" |
||||
|
@blur=" |
||||
|
inputPlaceholder($event, item, 'blur', scope.row) |
||||
|
" |
||||
|
@focus="inputPlaceholder($event, item, 'focus')" |
||||
|
clearable |
||||
|
> |
||||
|
</el-input> |
||||
|
</el-form-item> |
||||
|
<!-- 下拉框 --> |
||||
|
<el-select |
||||
|
v-if="item.type === 'select'" |
||||
|
v-model="scope.row[item.prop]" |
||||
|
:loading="selectLoading" |
||||
|
:clearable="item.clearable" |
||||
|
:multiple="item.multiple" |
||||
|
:disabled="Boolean(item.disabled) || Boolean(scope.row['disabled'])" |
||||
|
:filterable="item.filterable" |
||||
|
:allow-create="item.allowCreate" |
||||
|
style="width: 100%" |
||||
|
:placeholder="'请输入' + item.label" |
||||
|
> |
||||
|
<el-option |
||||
|
v-for="(op, index) in selectOptions(item.options) || |
||||
|
searchOptions['options']" |
||||
|
:label="op[item.optionsLabel] || op.label" |
||||
|
:value="op[item.optionsValue] || op.value" |
||||
|
:key="index" |
||||
|
></el-option> |
||||
|
</el-select> |
||||
|
<!--对象下拉框 --> |
||||
|
<el-select |
||||
|
v-if="item.type === 'objectSelect'" |
||||
|
v-model="scope.row[item.prop][item.showProp]" |
||||
|
:loading="selectLoading" |
||||
|
:clearable="item.clearable" |
||||
|
:multiple="item.multiple" |
||||
|
:disabled="Boolean(item.disabled) || Boolean(scope.row['disabled'])" |
||||
|
:filterable="item.filterable" |
||||
|
:allow-create="item.allowCreate" |
||||
|
style="width: 100%" |
||||
|
:placeholder="'请输入' + item.label" |
||||
|
> |
||||
|
<el-option |
||||
|
v-for="(op, index) in selectOptions(item.options) || |
||||
|
searchOptions['options']" |
||||
|
:label="op[item.optionsLabel] || op.label" |
||||
|
:value="op[item.optionsValue] || op.value" |
||||
|
:key="index" |
||||
|
></el-option> |
||||
|
</el-select> |
||||
|
<!--查询下拉--> |
||||
|
<el-form-item |
||||
|
v-if="item.type === 'autocomplete'" |
||||
|
:prop="'details.' + scope.$index + '.' + item.prop" |
||||
|
:rules="item.rules" |
||||
|
> |
||||
|
<el-autocomplete |
||||
|
class="inline-input" |
||||
|
style="width: 100%" |
||||
|
:disabled="Boolean(item.disabled) || Boolean(scope.row['disabled'])" |
||||
|
v-model="scope.row[item.prop]" |
||||
|
:fetch-suggestions=" |
||||
|
(queryString, cb) => { |
||||
|
querySearch(queryString, cb, item, scope); |
||||
|
} |
||||
|
" |
||||
|
:placeholder="'请输入' + item.label" |
||||
|
@select="handleSelect($event, item, scope)" |
||||
|
> |
||||
|
<!-- <template slot-scope="{item}"> |
||||
|
<div class="name" style="color:green">{{item.value = item.name}}</div> |
||||
|
<div class="name" >{{item.address = item.code}}</div> |
||||
|
</template> --> |
||||
|
<el-button |
||||
|
v-if="item.click" |
||||
|
slot="append" |
||||
|
icon="el-icon-search" |
||||
|
@click="item.click({ scope, item })" |
||||
|
style="color: #1890ff; background-color: #ffffff" |
||||
|
></el-button> |
||||
|
</el-autocomplete> |
||||
|
</el-form-item> |
||||
|
<!-- 对象查询下拉 --> |
||||
|
<el-form-item |
||||
|
v-if="item.type === 'objectAutocomplete'" |
||||
|
:prop=" |
||||
|
'details.' + scope.$index + '.' + item.prop + '.' + item.showProp |
||||
|
" |
||||
|
:rules="item.rules" |
||||
|
> |
||||
|
<el-autocomplete |
||||
|
class="inline-input" |
||||
|
style="width: 100%" |
||||
|
:disabled="Boolean(item.disabled) || Boolean(scope.row['disabled'])" |
||||
|
v-model="scope.row[item.prop][item.showProp]" |
||||
|
:fetch-suggestions=" |
||||
|
(queryString, cb) => { |
||||
|
querySearch(queryString, cb, item, scope); |
||||
|
} |
||||
|
" |
||||
|
:placeholder="'请输入' + item.label" |
||||
|
@select="handleSelect($event, item, scope)" |
||||
|
> |
||||
|
<!-- <template slot-scope="{item}"> |
||||
|
<div class="name" style="color:green">{{item.value = item.name}}</div> |
||||
|
<div class="name" >{{item.address = item.code}}</div> |
||||
|
</template> --> |
||||
|
<el-button |
||||
|
v-if="item.click" |
||||
|
slot="append" |
||||
|
icon="el-icon-search" |
||||
|
@click="item.click({ scope, item })" |
||||
|
style="color: #1890ff; background-color: #ffffff" |
||||
|
></el-button> |
||||
|
</el-autocomplete> |
||||
|
</el-form-item> |
||||
|
<!-- <el-form-item v-if="item.type == 'inputEnum'" :prop="item.prop"> |
||||
|
<el-input |
||||
|
placeholder="请输入内容" |
||||
|
v-model="scope.row[item.prop]" |
||||
|
clearable |
||||
|
> |
||||
|
</el-input> |
||||
|
</el-form-item> --> |
||||
|
|
||||
|
<el-form-item |
||||
|
v-if="item.type == 'dateTimeInput'" |
||||
|
:prop="'details.' + scope.$index + '.' + item.prop" |
||||
|
:rules="item.rules" |
||||
|
> |
||||
|
<el-date-picker |
||||
|
type="datetime" |
||||
|
v-model="scope.row[item.prop]" |
||||
|
placeholder="选择日期" |
||||
|
style="width: 100%" |
||||
|
:disabled="Boolean(item.disabled) || Boolean(scope.row['disabled'])" |
||||
|
value-format="yyyy-MM-ddTHH:mm:ss.sssZ" |
||||
|
format="yyyy-MM-dd" |
||||
|
></el-date-picker> |
||||
|
</el-form-item> |
||||
|
<el-form-item |
||||
|
v-if="item.type == 'objectDateTimeInput'" |
||||
|
:prop="'details.' + scope.$index + '.' + item.prop + '.' + item.showProp" |
||||
|
:rules="item.rules" |
||||
|
> |
||||
|
<el-date-picker |
||||
|
type="datetime" |
||||
|
v-model="scope.row[item.prop][item.showProp]" |
||||
|
placeholder="选择日期" |
||||
|
style="width: 100%" |
||||
|
:disabled="Boolean(item.disabled) || Boolean(scope.row['disabled'])" |
||||
|
value-format="yyyy-MM-ddTHH:mm:ss.sssZ" |
||||
|
format="yyyy-MM-dd" |
||||
|
></el-date-picker> |
||||
|
</el-form-item> |
||||
|
<!-- table表添加按钮事件 v-show="scope.row.number == 'PRJ202210060001'" --> |
||||
|
<el-form-item v-if="item.type == 'button'" > |
||||
|
<el-button |
||||
|
v-show="scope.row[item.prop]==undefined?true:false" |
||||
|
type="primary" |
||||
|
size="mini" |
||||
|
@click="buttonClick(scope.row, scope.$index, item.label)" |
||||
|
>{{item.label}}</el-button> |
||||
|
</el-form-item> |
||||
|
|
||||
|
<span v-if="item.type == 'object'"> |
||||
|
{{ scope.row[item.prop] ? scope.row[item.prop][item.showProp] : "" }} |
||||
|
</span> |
||||
|
<span v-if="item.type == 'objectDateTime'"> |
||||
|
{{ scope.row[item.prop]? scope.row[item.prop][item.showProp]: "" | formatDate }} |
||||
|
</span> |
||||
|
<span v-if="item.type == 'dateTime'"> |
||||
|
{{ scope.row[item.prop] | formatDate }} |
||||
|
</span> |
||||
|
<!-- 调用主表信息 --> |
||||
|
<span v-else-if="item.type && item.type == 'outerMainFilter'"> |
||||
|
{{ propsData[item.showProp] }} |
||||
|
</span> |
||||
|
<el-tag |
||||
|
v-if="item.type == 'tagFilter'" |
||||
|
:effect="'dark'" |
||||
|
size="medium" |
||||
|
class="tagFilterTypeDarkItem" |
||||
|
:color="scope.row[item.prop] | trigger(item.filters, 'background')" |
||||
|
> |
||||
|
{{ scope.row[item.prop] | trigger(item.filters, "label") }} |
||||
|
</el-tag> |
||||
|
<span |
||||
|
v-if="item.type == 'filter'" |
||||
|
:style="scope.row[item.prop]" |
||||
|
> |
||||
|
{{ scope.row[item.prop] | trigger(item.filters, "label", item.dictType) }} |
||||
|
</span> |
||||
|
<span |
||||
|
v-if="item.type == 'objectFilter'" |
||||
|
:style="scope.row[item.prop][item.showProp]" |
||||
|
> |
||||
|
{{ scope.row[item.prop][item.showProp] | trigger(item.filters, "label") }} |
||||
|
</span> |
||||
|
<span |
||||
|
v-if="item.type == 'name' || !item.type" |
||||
|
@click="item.type == 'name' && inlineDialog(scope.row)" |
||||
|
:class="{ spamHover: item.type == 'name' }" |
||||
|
>{{ scope.row[item.prop] }}</span |
||||
|
> |
||||
|
</el-form> |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
<slot></slot> |
||||
|
</el-table> |
||||
|
<!-- <pre style="text-align: left"> |
||||
|
{{ tableColumns }} |
||||
|
</pre> |
||||
|
<hr /> |
||||
|
<pre style="text-align: left"> |
||||
|
{{ tableData }} |
||||
|
</pre> --> |
||||
|
<!-- </div> --> |
||||
|
</template> |
||||
|
<script> |
||||
|
import Sortable from "sortablejs"; |
||||
|
import { formatTimeStrToStr } from "@/utils/formatTime"; |
||||
|
import { getMatchRegConformValue } from "@/utils/index" |
||||
|
import _ from "lodash"; |
||||
|
export default { |
||||
|
name: "currenTable", |
||||
|
filters: { |
||||
|
formatDate(time) { |
||||
|
if (time == null) { |
||||
|
return '-' |
||||
|
} |
||||
|
return formatTimeStrToStr(time) |
||||
|
}, |
||||
|
}, |
||||
|
props: { |
||||
|
propsData: { |
||||
|
type: Object, |
||||
|
default: () => { |
||||
|
return {}; |
||||
|
}, |
||||
|
}, |
||||
|
tableData: { |
||||
|
type: Array, |
||||
|
default: () => { |
||||
|
return []; |
||||
|
}, |
||||
|
}, |
||||
|
tableLoading: { |
||||
|
type: Boolean, |
||||
|
default: false, |
||||
|
}, |
||||
|
tableColumns: { |
||||
|
type: Array, |
||||
|
default: () => { |
||||
|
return []; |
||||
|
}, |
||||
|
}, |
||||
|
selectionTable: { |
||||
|
type: Boolean, |
||||
|
default: true, |
||||
|
}, |
||||
|
requiredRules: { |
||||
|
type: Boolean, |
||||
|
default: true, |
||||
|
}, |
||||
|
searchOptions: { |
||||
|
type: Object, |
||||
|
default: () => { |
||||
|
return {}; |
||||
|
}, |
||||
|
}, |
||||
|
treeProps: { |
||||
|
type: Object, |
||||
|
default: () => { |
||||
|
return {}; |
||||
|
} |
||||
|
}, |
||||
|
isShowIndex: { |
||||
|
type: Boolean, |
||||
|
default: false, |
||||
|
}, |
||||
|
cellStyle: { |
||||
|
type: Function, |
||||
|
default: () => { |
||||
|
return Function; |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
data() { |
||||
|
return { |
||||
|
dropCol: null, |
||||
|
selectLoading: false, |
||||
|
// TableSize: [], |
||||
|
random: '' |
||||
|
}; |
||||
|
}, |
||||
|
computed: { |
||||
|
selectOptions() { |
||||
|
return (val) => { |
||||
|
if (val) { |
||||
|
let options = this.$staticOptions[val]; |
||||
|
if (options) { |
||||
|
return options(); |
||||
|
} else { |
||||
|
return []; |
||||
|
} |
||||
|
} else { |
||||
|
return false; |
||||
|
} |
||||
|
}; |
||||
|
}, |
||||
|
TableSize(){ |
||||
|
return this.tableColumnsFilter() |
||||
|
} |
||||
|
}, |
||||
|
watch: { |
||||
|
tableData: { |
||||
|
handler(val, oldVal) { |
||||
|
this.$nextTick(() => { |
||||
|
this.$refs.multipleTable.doLayout(); |
||||
|
// this.$forceUpdate() |
||||
|
}); |
||||
|
}, |
||||
|
immediate: false, |
||||
|
} |
||||
|
}, |
||||
|
activated() { |
||||
|
this.$refs.multipleTable.doLayout(); |
||||
|
}, |
||||
|
created() { |
||||
|
|
||||
|
}, |
||||
|
// beforeUpdate () { |
||||
|
// this.$nextTick(() => { |
||||
|
// this.$refs.multipleTable.doLayout() |
||||
|
// }) |
||||
|
// }, |
||||
|
mounted() { |
||||
|
// this.tableColumnsFilter() |
||||
|
this.random = this._uid |
||||
|
// this.rowDrop() |
||||
|
// this.columnDrop(); |
||||
|
// this.tableColumns.forEach(item => { |
||||
|
// if (item.focus) { |
||||
|
// item.focus() |
||||
|
// } |
||||
|
// }) |
||||
|
}, |
||||
|
methods: { |
||||
|
// type=input情况下,框实时校验 |
||||
|
itemOnKeyUp(item,value,index){ |
||||
|
if(item.onkeyup){ |
||||
|
return item.onkeyup() |
||||
|
}else{ |
||||
|
if(this.tableData[index][value] && item.validType){ |
||||
|
this.tableData[index][value]=getMatchRegConformValue(item.validType,this.tableData[index][value],item.pointNumberFixed) |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
// 数字类型input框onkeyup最大最小值处理 |
||||
|
typeNumberOnkeyup(item,value,index){ |
||||
|
if(this.tableData[index][value]){ |
||||
|
let _match = String(this.tableData[index][value]).match(/\d+/)//正整数 |
||||
|
this.tableData[index][value] = _match?_match[0]:_match |
||||
|
} |
||||
|
if(this.tableData[index][value] > item.max){ |
||||
|
this.tableData[index][value] = item.max |
||||
|
} |
||||
|
if(this.tableData[index][value] && this.tableData[index][value] < item.min){ |
||||
|
this.tableData[index][value] = item.min |
||||
|
} |
||||
|
if(item.onkeyup)item.onkeyup() |
||||
|
}, |
||||
|
tableColumnsFilter() { |
||||
|
let widthSize = _.cloneDeep(this.tableColumns); |
||||
|
for(let i = 0;i<widthSize.length;i++){ |
||||
|
let item = widthSize[i] |
||||
|
if (item.type == "autocomplete" || item.type == "objectAutocomplete") { |
||||
|
item.width = item.width ? item.width: "300px"; |
||||
|
} else if (item.type == "input" || item.type == "objectInput") { |
||||
|
if (item.width == '100%') { |
||||
|
item.width = '' |
||||
|
} else { |
||||
|
item.width = item.width ? item.width: "200px"; |
||||
|
} |
||||
|
} else if ( |
||||
|
item.type == "dateTimeInput" || |
||||
|
item.type == "objectDateTimeInput" |
||||
|
) { |
||||
|
item.width =item.width ? item.width: "200px"; |
||||
|
} else if (item.type == "objectDateTime" || item.type == "dateTime") { |
||||
|
item.width =item.width ? item.width: "200px"; |
||||
|
} else if (item.width == '100%') { |
||||
|
item.width = '' |
||||
|
} else { |
||||
|
item.width =item.width ? item.width: "150px"; |
||||
|
} |
||||
|
} |
||||
|
// this.TableSize = widthSize; |
||||
|
return widthSize |
||||
|
}, |
||||
|
inputPlaceholder(val, item, type, func) { |
||||
|
if (item.valueType) { |
||||
|
if (type == "focus") { |
||||
|
val.target.placeholder = "请输入" + item.label; |
||||
|
if (val.target.value != "") { |
||||
|
val.target.placeholder = val.target.value; |
||||
|
val.target.value = ""; |
||||
|
} |
||||
|
} else if (type == "blur") { |
||||
|
// val.target.value = "0" |
||||
|
val.target.value = val.target.value.toString().replace(/[^\d.]/g,'') |
||||
|
if (val.target.value == "") { |
||||
|
// if (val.target.placeholder.indexOf('请输入') == -1) { |
||||
|
val.target.value = val.target.placeholder; |
||||
|
// } |
||||
|
} |
||||
|
if(item.showProp){ |
||||
|
func[item.prop][item.showProp]= Number(val.target.value) |
||||
|
}else{ |
||||
|
func[item.prop]= Number(val.target.value) |
||||
|
} |
||||
|
// item.valueType |
||||
|
// ? (this.tableData[index][value] = item.valueType( |
||||
|
// this.tableData[index][value] |
||||
|
// )) |
||||
|
// : () => { |
||||
|
// return; |
||||
|
// } |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
// handeleInput (et, item) { |
||||
|
// const { optionsValue } = item |
||||
|
// let func = item.focus |
||||
|
// let filter = { |
||||
|
// logic: "And", |
||||
|
// column: optionsValue, |
||||
|
// action: "Like", |
||||
|
// value: et |
||||
|
// } |
||||
|
// debounce(func(filter), 2000,true) |
||||
|
// }, |
||||
|
//autocomplete下拉 |
||||
|
querySearch(queryString, cb, val, row) { |
||||
|
const { options, optionsValue, optionsLabel } = val; |
||||
|
let func = val.focus; |
||||
|
let data = { |
||||
|
scope: row, |
||||
|
}; |
||||
|
if (queryString) { |
||||
|
data.filter = [ |
||||
|
{ |
||||
|
logic: "And", |
||||
|
column: optionsValue, |
||||
|
action: "Like", |
||||
|
value: queryString, |
||||
|
}, |
||||
|
// { |
||||
|
// logic: "Or", |
||||
|
// column: optionsLabel, |
||||
|
// action: "Like", |
||||
|
// value: queryString |
||||
|
// } |
||||
|
]; |
||||
|
} |
||||
|
func(data).then((res) => { |
||||
|
var restaurants = this.searchOptions["options"]; |
||||
|
let results = queryString |
||||
|
? restaurants.filter( |
||||
|
this.createFilter(queryString, optionsValue, optionsLabel) |
||||
|
) |
||||
|
: restaurants; |
||||
|
results.forEach((key) => { |
||||
|
if (typeof optionsValue === "string") { |
||||
|
key.value = key[optionsValue] + "----" + key[optionsLabel]; |
||||
|
} else { |
||||
|
key.value = |
||||
|
key[optionsValue[0]][optionsValue[1]] + |
||||
|
"----" + |
||||
|
key[optionsLabel]; |
||||
|
} |
||||
|
}); |
||||
|
// 调用 callback 返回建议列表的数据 |
||||
|
cb(results); |
||||
|
}); |
||||
|
}, |
||||
|
createFilter(queryString, optionsValue, optionsLabel) { |
||||
|
return (restaurant) => { |
||||
|
if (typeof optionsValue === "string") { |
||||
|
restaurant.value = |
||||
|
restaurant[optionsValue] + "----" + restaurant[optionsLabel]; |
||||
|
} else { |
||||
|
restaurant.value = |
||||
|
restaurant[optionsValue[0]][optionsValue[1]] + |
||||
|
"----" + |
||||
|
restaurant[optionsLabel]; |
||||
|
} |
||||
|
return ( |
||||
|
restaurant.value.toLowerCase().indexOf(queryString.toLowerCase()) != |
||||
|
-1 |
||||
|
); |
||||
|
}; |
||||
|
}, |
||||
|
handleSelect(item, val, scope) { |
||||
|
let data = this.tableData[scope.$index]; |
||||
|
if (!val.showProp) { |
||||
|
if (typeof val.optionsValue === "string") { |
||||
|
data[val.prop] = item[val.optionsValue]; |
||||
|
} else { |
||||
|
data[val.prop] = item[val.optionsValue[0]][val.optionsValue[1]]; |
||||
|
} |
||||
|
} else { |
||||
|
if (typeof val.optionsValue === "string") { |
||||
|
data[val.prop][val.showProp] = item[val.optionsValue]; |
||||
|
} else { |
||||
|
data[val.prop][val.showProp] = |
||||
|
item[val.optionsValue[0]][val.optionsValue[1]]; |
||||
|
} |
||||
|
} |
||||
|
this.$emit("push", item, scope, val); |
||||
|
}, |
||||
|
// selectFocus (val, item) { |
||||
|
// this.selectLoading = true; |
||||
|
// let func = item.focus |
||||
|
// func({}).then(res => { |
||||
|
// this.selectLoading = false; |
||||
|
// }) |
||||
|
// }, |
||||
|
// dataFilter (query, item, row) { |
||||
|
// const { options, optionsValue, optionsLabel } = item |
||||
|
// let func = item.focus |
||||
|
// let data = { |
||||
|
// scope: row |
||||
|
// } |
||||
|
// this.selectLoading = true; |
||||
|
// if (query) { |
||||
|
// data.filter = { |
||||
|
// logic: "And", |
||||
|
// column: optionsLabel, |
||||
|
// action: "Like", |
||||
|
// value: query |
||||
|
// } |
||||
|
// } |
||||
|
// setTimeout(() => { |
||||
|
// func(data).then(res => { |
||||
|
// this.selectLoading = false; |
||||
|
// }) |
||||
|
// }, 200); |
||||
|
// }, |
||||
|
getMaxLength(arr) { |
||||
|
return arr.reduce((acc, item) => { |
||||
|
if (item) { |
||||
|
const calcLen = this.getTexWidth(item); |
||||
|
if (acc < calcLen) { |
||||
|
acc = calcLen; |
||||
|
} |
||||
|
} |
||||
|
return acc; |
||||
|
}, 0); |
||||
|
}, |
||||
|
getTexWidth(str) { |
||||
|
let width = 0; |
||||
|
const html = document.createElement("span"); |
||||
|
html.innerText = str; |
||||
|
html.className = "getTextWidth"; |
||||
|
document.querySelector("body").appendChild(html); |
||||
|
width = document.querySelector(".getTextWidth").offsetWidth; |
||||
|
document.querySelector(".getTextWidth").remove(); |
||||
|
return width; |
||||
|
}, |
||||
|
flexColumnWidth(label, prop) { |
||||
|
const arr = this.tableData.map((x) => { |
||||
|
if (typeof prop !== "string") { |
||||
|
return x[prop[0]][prop[1]]; |
||||
|
} else { |
||||
|
return x[prop]; |
||||
|
} |
||||
|
}); |
||||
|
arr.push(label); |
||||
|
return this.getMaxLength(arr) + 60 + "px"; |
||||
|
}, |
||||
|
//排序 |
||||
|
sortChange(data) { |
||||
|
this.$emit("sortChange", data); |
||||
|
}, |
||||
|
//点击selection框 |
||||
|
handleSelectionChange(val) { |
||||
|
this.$emit("handleSelectionChange", val); |
||||
|
}, |
||||
|
//点击name提交emit打开编辑页面 |
||||
|
inlineDialog(row) { |
||||
|
this.$emit("inlineDialog", row); |
||||
|
}, |
||||
|
//点击按钮打开自定义弹窗 |
||||
|
buttonClick(row, index, label) { |
||||
|
this.$emit("buttonClick", row, index, label); |
||||
|
}, |
||||
|
rowDrop() { |
||||
|
const tbody = this.$refs.multipleTable.$el.querySelector( |
||||
|
".el-table__body-wrapper tbody" |
||||
|
); |
||||
|
const _this = this; |
||||
|
Sortable.create(tbody, { |
||||
|
onEnd({ newIndex, oldIndex }) { |
||||
|
const currRow = _this.tableData.splice(oldIndex, 1)[0]; |
||||
|
_this.tableData.splice(newIndex, 0, currRow); |
||||
|
}, |
||||
|
}); |
||||
|
}, |
||||
|
//列拖拽 |
||||
|
columnDrop() { |
||||
|
const wrapperTr = this.$refs.multipleTable.$el.querySelector( |
||||
|
".el-table__header-wrapper tr" |
||||
|
); |
||||
|
let bomIndex = this.selectionTable ? 1 : 0; |
||||
|
this.sortable = Sortable.create(wrapperTr, { |
||||
|
animation: 180, |
||||
|
delay: 0, |
||||
|
onEnd: (evt) => { |
||||
|
const oldItem = this.TableSize[evt.oldIndex - bomIndex]; |
||||
|
this.TableSize.splice(evt.oldIndex - bomIndex, 1); |
||||
|
this.TableSize.splice(evt.newIndex - bomIndex, 0, oldItem); |
||||
|
}, |
||||
|
}); |
||||
|
}, |
||||
|
}, |
||||
|
}; |
||||
|
</script> |
||||
|
<style lang="scss" scoped> |
||||
|
::v-deep .el-form-item__error{ |
||||
|
position: relative; |
||||
|
} |
||||
|
::v-deep .el-table__fixed { |
||||
|
display: block-inline !important; |
||||
|
height: auto !important; |
||||
|
bottom: 13px !important; |
||||
|
.el-table__fixed-header-wrapper { |
||||
|
z-index: auto !important; |
||||
|
} |
||||
|
.el-table__fixed-body-wrapper { |
||||
|
z-index: auto !important; |
||||
|
} |
||||
|
} |
||||
|
::v-deep .el-table__fixed::before, |
||||
|
.el-table__fixed-right::before { |
||||
|
z-index: auto !important; |
||||
|
} |
||||
|
.spamHover { |
||||
|
color: #409eff; |
||||
|
cursor: pointer; |
||||
|
} |
||||
|
.spamHover:hover { |
||||
|
border-bottom: 1px solid #409eff; |
||||
|
color: blue; |
||||
|
} |
||||
|
span { |
||||
|
white-space: pre; |
||||
|
} |
||||
|
::v-deep .el-select { |
||||
|
.el-input__inner { |
||||
|
padding: 0 30px 0 15px; |
||||
|
} |
||||
|
.el-input__prefix { |
||||
|
width: 100% !important; |
||||
|
left: 0; |
||||
|
.el-button { |
||||
|
position: absolute; |
||||
|
top: 0; |
||||
|
right: 0; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</style> |
@ -0,0 +1,322 @@ |
|||||
|
<template> |
||||
|
<div class="currenTableFlex"> |
||||
|
<div class="headerButtons"> |
||||
|
<el-button |
||||
|
type="primary" |
||||
|
v-if="showAddBtn" |
||||
|
@click="flexOpenAddNew" |
||||
|
icon="el-icon-plus" |
||||
|
size="mini" |
||||
|
>添加一行</el-button> |
||||
|
<slot name="headerBtns"></slot> |
||||
|
</div> |
||||
|
<!-- todo:多选处理【selectionTable】 --> |
||||
|
<umyTable |
||||
|
:isEditable="isEditable" |
||||
|
class="flexTable" |
||||
|
:tableData="flexTableData" |
||||
|
:searchOptions="flexSearchOptions" |
||||
|
:tableColumns="flexTableColumns" |
||||
|
:selectionTable="selectionTable" |
||||
|
:isShowIndex="isShowIndex" |
||||
|
:setUTableHeight="setUTableHeight" |
||||
|
@push="detailsDataPush(arguments)" |
||||
|
> |
||||
|
<template v-if="showAllDeleteButton"> |
||||
|
<el-table-column |
||||
|
label="操作" |
||||
|
align="center" |
||||
|
fixed="right" |
||||
|
width="100px" |
||||
|
> |
||||
|
<template slot-scope="scope"> |
||||
|
<div |
||||
|
v-if="!scope.row.hide" |
||||
|
class="childTable" |
||||
|
@click="flexRowRemove($event, scope)" |
||||
|
> |
||||
|
<span style="color:red">删除</span> |
||||
|
</div> |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
</template> |
||||
|
</umyTable> |
||||
|
</div> |
||||
|
</template> |
||||
|
<script> |
||||
|
import currenTable from "@/components/currenTable" |
||||
|
import { mixins } from "@/mixins/mixins" |
||||
|
export default { |
||||
|
name: 'currenTableFlex', |
||||
|
components: { |
||||
|
currenTable |
||||
|
}, |
||||
|
mixins: [ |
||||
|
mixins, |
||||
|
], |
||||
|
filters: { |
||||
|
// formData (val) { |
||||
|
// let data = JSON.parse(JSON.stringify(val)) |
||||
|
// val.forEach((key, index) => { |
||||
|
// data[index].disabled = "true" |
||||
|
// delete data[index].focus |
||||
|
// if (key.type == "autocomplete" || key.type == "import") { |
||||
|
// data[index].type = "input" |
||||
|
// } |
||||
|
// }); |
||||
|
// return data |
||||
|
// }, |
||||
|
// formDataDetails (val) { |
||||
|
// let data = JSON.parse(JSON.stringify(val)) |
||||
|
// val.forEach((key, index) => { |
||||
|
// data[index].disabled = true |
||||
|
// delete data[index].focus |
||||
|
// delete data[index].rules |
||||
|
// if (key.type == "autocomplete" || key.type == "import") { |
||||
|
// delete data[index].type |
||||
|
// } else if (key.type == "objectAutocomplete") { |
||||
|
// data[index].type = "object" |
||||
|
// } else if (key.prop == "containerCode" && key.type == "input") { |
||||
|
// data[index].disabled = false |
||||
|
// } else if (key.isChange) { |
||||
|
// // 针对第三步预览特殊情况处理 |
||||
|
// data[index].disabled = false |
||||
|
// } |
||||
|
// }); |
||||
|
// return data |
||||
|
// } |
||||
|
}, |
||||
|
props: { |
||||
|
// table内表单数据是否可编辑 |
||||
|
isEditable:{ |
||||
|
type: Boolean, |
||||
|
default: false |
||||
|
}, |
||||
|
// 已app-main高度为100% 需要减掉的高度 |
||||
|
setUTableHeight: { |
||||
|
type: Number, |
||||
|
default: () => { |
||||
|
return 280; |
||||
|
} |
||||
|
}, |
||||
|
// 是否显示添加一行按钮 |
||||
|
showAddBtn:{ |
||||
|
type: Boolean, |
||||
|
default: true |
||||
|
}, |
||||
|
// 是否显示删除按钮(控制全部列) |
||||
|
showAllDeleteButton:{ |
||||
|
type: Boolean, |
||||
|
default: true |
||||
|
}, |
||||
|
// 是否禁止编辑行(控制全部行) |
||||
|
disableAllRow:{ |
||||
|
type: Boolean, |
||||
|
default: false |
||||
|
}, |
||||
|
flexTableData: { |
||||
|
type: Array, |
||||
|
default: () => { |
||||
|
return []; |
||||
|
}, |
||||
|
}, |
||||
|
flexSearchOptions: { |
||||
|
type: Object, |
||||
|
default: () => { |
||||
|
return {}; |
||||
|
}, |
||||
|
}, |
||||
|
flexTableColumns: { |
||||
|
type: Array, |
||||
|
default: () => { |
||||
|
return []; |
||||
|
}, |
||||
|
}, |
||||
|
// 是否显示多选 |
||||
|
selectionTable: { |
||||
|
type: Boolean, |
||||
|
default: false, |
||||
|
}, |
||||
|
// 是否显示序号列 |
||||
|
isShowIndex: { |
||||
|
type: Boolean, |
||||
|
default: false, |
||||
|
}, |
||||
|
//名称 |
||||
|
// formTitle: { |
||||
|
// type: String, |
||||
|
// default: '' |
||||
|
// }, |
||||
|
// //是否弹窗 |
||||
|
// displayDialog: { |
||||
|
// type: Object, |
||||
|
// default: () => { |
||||
|
// return { |
||||
|
// newDialog: false |
||||
|
// } |
||||
|
// } |
||||
|
// }, |
||||
|
// //主表提交数据 |
||||
|
// CreateFormData: { |
||||
|
// type: Object, |
||||
|
// default: () => { |
||||
|
// return {} |
||||
|
// } |
||||
|
// }, |
||||
|
// //主表显示form |
||||
|
// CreateForm: { |
||||
|
// type: Array, |
||||
|
// default: () => { |
||||
|
// return [] |
||||
|
// } |
||||
|
// }, |
||||
|
// //预览数据 |
||||
|
// previewFormData: { |
||||
|
// type: Object, |
||||
|
// default: () => { |
||||
|
// return {} |
||||
|
// } |
||||
|
// }, |
||||
|
// Rules: { |
||||
|
// type: Object, |
||||
|
// default: () => { |
||||
|
// return {} |
||||
|
// } |
||||
|
// }, |
||||
|
// //下拉选择 |
||||
|
// Options: { |
||||
|
// type: Object, |
||||
|
// default: () => { |
||||
|
// return {} |
||||
|
// } |
||||
|
// }, |
||||
|
// //子表table显示 |
||||
|
// detailsTableColumns: { |
||||
|
// type: Array, |
||||
|
// default: () => { |
||||
|
// return [] |
||||
|
// } |
||||
|
// }, |
||||
|
// //子表提交数据 |
||||
|
// childTableData: { |
||||
|
// type: Array, |
||||
|
// default: () => { |
||||
|
// return [] |
||||
|
// } |
||||
|
// }, |
||||
|
// //成功后的操作 |
||||
|
// successHandle: { |
||||
|
// type: Array, |
||||
|
// default: () => { |
||||
|
// return [] |
||||
|
// } |
||||
|
// }, |
||||
|
// //步骤标题 |
||||
|
// stepArray: { |
||||
|
// type: Array, |
||||
|
// default: () => { |
||||
|
// return ["总体信息", "明细", "预览", "结果"] |
||||
|
// } |
||||
|
// }, |
||||
|
// //添加一行 |
||||
|
// addClickButton: { |
||||
|
// type: Boolean, |
||||
|
// default: () => { |
||||
|
// return true |
||||
|
// } |
||||
|
// }, |
||||
|
// //删除行记录 |
||||
|
// isShowDeleteButton: { |
||||
|
// type: Boolean, |
||||
|
// default: () => { |
||||
|
// return true |
||||
|
// } |
||||
|
// }, |
||||
|
// // 隐藏第一步骤的取消按钮 |
||||
|
// isHideFirstActiveCancel:{ |
||||
|
// type: Boolean, |
||||
|
// default: () => { |
||||
|
// return false |
||||
|
// } |
||||
|
// }, |
||||
|
// // 预览视图显示删除按钮 |
||||
|
// showPreviewFormDeleteButton:{ |
||||
|
// type: Boolean, |
||||
|
// default: () => { |
||||
|
// return false |
||||
|
// } |
||||
|
// } |
||||
|
}, |
||||
|
data () { |
||||
|
return { |
||||
|
// 添加一行的空置 |
||||
|
addEmptyRow:null, |
||||
|
// active: 0, |
||||
|
// formReveal: 1, |
||||
|
// activeStep: 1, |
||||
|
// pageStatus: '', |
||||
|
// addClick: this.addClickButton,//添加一行按钮 |
||||
|
// showDeleteButton: this.isShowDeleteButton,//操作-删除按钮 |
||||
|
// hideFirstActiveCancel:this.isHideFirstActiveCancel,// 隐藏第一步骤的取消按钮 |
||||
|
// loading: false, |
||||
|
// session: null, |
||||
|
// step: this.stepArray, |
||||
|
// editHandle: [ |
||||
|
// { label: "取消", name: "cancel" }, |
||||
|
// { label: "下一步", type: "primary", name: "determine" }, |
||||
|
// ], |
||||
|
} |
||||
|
}, |
||||
|
mounted () { |
||||
|
// this.session = JSON.parse(JSON.stringify(this.CreateFormData)) |
||||
|
// if(this.hideFirstActiveCancel){ |
||||
|
// this.editHandle=[ |
||||
|
// { label: "下一步", type: "primary", name: "determine" }, |
||||
|
// ]; |
||||
|
// } |
||||
|
}, |
||||
|
methods: { |
||||
|
//添加行 |
||||
|
flexOpenAddNew() { |
||||
|
let _oneRow = Object.assign({}, this.flexTableData[0]) |
||||
|
for(let key in _oneRow){ |
||||
|
_oneRow[key] = null |
||||
|
} |
||||
|
this.flexTableData.push(_oneRow) |
||||
|
// if(this.flexTableData.length <= 0)return |
||||
|
// if(!this.addEmptyRow){ |
||||
|
// let _oneRow = Object.assign({}, this.flexTableData[0]) |
||||
|
// for(let key in _oneRow){ |
||||
|
// _oneRow[key] = null |
||||
|
// } |
||||
|
// this.addEmptyRow = _oneRow |
||||
|
// this.addEmptyRow['disabled']=false |
||||
|
// } |
||||
|
// this.flexTableData.push(this.addEmptyRow) |
||||
|
}, |
||||
|
//删除行 |
||||
|
flexRowRemove(e, val) { |
||||
|
this.$confirm('您确定删除吗, 是否继续?', '提示', { |
||||
|
confirmButtonText: '确定', |
||||
|
cancelButtonText: '取消', |
||||
|
type: 'warning' |
||||
|
}).then(() => { |
||||
|
this.flexTableData.splice(val.$index, 1) |
||||
|
}).catch(() => { |
||||
|
|
||||
|
}); |
||||
|
}, |
||||
|
//点击selection框 |
||||
|
handleSelectionChange(val) { |
||||
|
this.$emit("handleSelectionChange", val); |
||||
|
}, |
||||
|
// //autoComplete子表 |
||||
|
detailsDataPush (val) { |
||||
|
this.$emit("detailsDataPush", val) |
||||
|
}, |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
<style lang="scss" scoped> |
||||
|
@import "./style/index.scss"; |
||||
|
</style> |
@ -0,0 +1,12 @@ |
|||||
|
.currenTableFlex{ |
||||
|
height: 100%; |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
.flexTable{ |
||||
|
height: 100%; |
||||
|
} |
||||
|
.headerButtons{ |
||||
|
text-align: center; |
||||
|
margin-bottom: 20px; |
||||
|
} |
||||
|
} |
@ -0,0 +1,57 @@ |
|||||
|
<template> |
||||
|
<el-tabs |
||||
|
v-model="tabsName" |
||||
|
@tab-click="handleClick" |
||||
|
:tab-position="tabPosition" |
||||
|
> |
||||
|
<el-tab-pane |
||||
|
v-for="(item, index) in tabsData" |
||||
|
:key="index" |
||||
|
:label="item.label" |
||||
|
:name="item.name" |
||||
|
> |
||||
|
<span slot="label"><i :class="item.icon"></i>{{ item.label }}</span> |
||||
|
<slot :value="item.name"></slot> |
||||
|
</el-tab-pane> |
||||
|
</el-tabs> |
||||
|
</template> |
||||
|
<script> |
||||
|
export default { |
||||
|
name: 'currenTabs', |
||||
|
watch: { |
||||
|
activeName(newVal, oldVal){ |
||||
|
this.tabsName = newVal |
||||
|
} |
||||
|
}, |
||||
|
props: { |
||||
|
activeName: { |
||||
|
type: String, |
||||
|
default: 'first' |
||||
|
}, |
||||
|
tabsData: { |
||||
|
type: Array, |
||||
|
default: () => { |
||||
|
return [] |
||||
|
} |
||||
|
}, |
||||
|
type: { |
||||
|
type: String, |
||||
|
default: 'border-card' //card/border-card |
||||
|
}, |
||||
|
tabPosition: { |
||||
|
type: String, |
||||
|
default: 'top' |
||||
|
} |
||||
|
}, |
||||
|
data () { |
||||
|
return { |
||||
|
tabsName: this.activeName |
||||
|
} |
||||
|
}, |
||||
|
methods: { |
||||
|
handleClick (val) { |
||||
|
this.$emit("handleClick", val) |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
@ -0,0 +1,82 @@ |
|||||
|
<template> |
||||
|
<div class="curren-upload"> |
||||
|
<el-upload |
||||
|
ref="upload" |
||||
|
class="avatar-uploader" |
||||
|
drag |
||||
|
action="#" |
||||
|
:http-request="httpRequestfiles" |
||||
|
:file-list="searchData" |
||||
|
:before-upload="beforeAvatarUpload" |
||||
|
:before-remove="beforeRemove" |
||||
|
:on-remove="handleRemove" |
||||
|
:on-exceed="handleExceed" |
||||
|
multiple |
||||
|
:limit="limit" |
||||
|
:accept="picExt" |
||||
|
> |
||||
|
<i class="el-icon-upload"></i> |
||||
|
<div class="el-upload__text"> |
||||
|
将文件拖到此处,或 |
||||
|
<em>点击上传</em> |
||||
|
</div> |
||||
|
</el-upload> |
||||
|
</div> |
||||
|
</template> |
||||
|
<script> |
||||
|
export default { |
||||
|
name: "currenUpload", |
||||
|
props: { |
||||
|
limit: { |
||||
|
type: Number, |
||||
|
default: 0 |
||||
|
}, |
||||
|
searchData: { |
||||
|
type: Array, |
||||
|
default: () => { |
||||
|
return [] |
||||
|
} |
||||
|
}, |
||||
|
beforeUpload: { |
||||
|
type: Function, |
||||
|
default: () => { |
||||
|
return Function |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
data () { |
||||
|
return { |
||||
|
isFileType: '', |
||||
|
picExt:'.xlsx' |
||||
|
} |
||||
|
}, |
||||
|
methods: { |
||||
|
httpRequestfiles (val) { |
||||
|
let rd = new FileReader(); // 创建文件读取对象 |
||||
|
let file = val.file; |
||||
|
this.$emit('httpRequestfiles', file) |
||||
|
rd.readAsDataURL(file); // 文件读取装换为base64类型 |
||||
|
}, |
||||
|
beforeAvatarUpload (val) { |
||||
|
let suffix = val.name.substring(val.name.lastIndexOf('.') + 1) |
||||
|
if (this.picExt.indexOf(suffix) === -1) { |
||||
|
this.$warningMsg('上传文件只能是 ' + this.picExt + '格式!') |
||||
|
return false |
||||
|
} |
||||
|
return this.beforeUpload(val, this.searchData) |
||||
|
|
||||
|
}, |
||||
|
beforeRemove (val) { |
||||
|
// if (val && val.status === "success") { |
||||
|
// return this.$confirm(`确定移除 ${val.name}?`); |
||||
|
// } |
||||
|
}, |
||||
|
handleRemove (file, fileList) { |
||||
|
this.$emit('handleRemove', fileList) |
||||
|
}, |
||||
|
handleExceed (val) { |
||||
|
this.$warningMsg('最多上传' + this.limit + '个文件') |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
@ -0,0 +1,72 @@ |
|||||
|
<template> |
||||
|
<div> |
||||
|
<el-upload |
||||
|
ref="uploadPicture" |
||||
|
class="upload-demo" |
||||
|
action="#" |
||||
|
:file-list="searchData" |
||||
|
:on-remove="handleRemove" |
||||
|
:on-exceed="handleExceed" |
||||
|
:on-change="changeUpload" |
||||
|
multiple |
||||
|
:limit="limit" |
||||
|
:accept="picExt" |
||||
|
:auto-upload="false" |
||||
|
> |
||||
|
<el-button slot="trigger" size="mini" type="primary">上传</el-button> |
||||
|
<el-button style="margin-left: 10px;" size="mini" type="info" @click="uploadListView">查看</el-button> |
||||
|
</el-upload> |
||||
|
|
||||
|
</div> |
||||
|
</template> |
||||
|
<script> |
||||
|
export default { |
||||
|
name: "currenUploadList", |
||||
|
props: { |
||||
|
limit: { |
||||
|
type: Number, |
||||
|
default: 0 |
||||
|
}, |
||||
|
searchData: { |
||||
|
type: Array, |
||||
|
default: () => { |
||||
|
return [] |
||||
|
} |
||||
|
}, |
||||
|
picExt: { |
||||
|
type: String, |
||||
|
default: "", |
||||
|
} |
||||
|
}, |
||||
|
data () { |
||||
|
return { |
||||
|
isFileType: '', |
||||
|
} |
||||
|
}, |
||||
|
methods: { |
||||
|
changeUpload (val) { |
||||
|
// let suffix = val.name.substring(val.name.lastIndexOf('.') + 1) |
||||
|
// if (this.picExt.indexOf(suffix) === -1) { |
||||
|
// this.$warningMsg('上传文件只能是 ' + this.picExt + '格式!') |
||||
|
// return false |
||||
|
// } |
||||
|
let rd = new FileReader(); // 创建文件读取对象 |
||||
|
let file = val.raw; |
||||
|
this.$emit('changeUpload', file) |
||||
|
rd.readAsDataURL(file); // 文件读取装换为base64类型 |
||||
|
}, |
||||
|
handleRemove (file, fileList) { |
||||
|
this.$emit('handleRemove', fileList) |
||||
|
}, |
||||
|
handleExceed (val) { |
||||
|
this.$warningMsg('最多上传' + this.limit + '个文件') |
||||
|
}, |
||||
|
uploadListView() { |
||||
|
this.$emit('uploadListView') |
||||
|
}, |
||||
|
submitUpload() { |
||||
|
this.$refs.upload.submit(); |
||||
|
}, |
||||
|
} |
||||
|
} |
||||
|
</script> |
@ -0,0 +1,100 @@ |
|||||
|
<template> |
||||
|
<div class="curren-upload"> |
||||
|
<el-upload |
||||
|
action="#" |
||||
|
list-type="picture-card" |
||||
|
:auto-upload="false" |
||||
|
:multiple="multiple" |
||||
|
:limit="limit" |
||||
|
:accept="picExt" |
||||
|
:file-list="searchData" |
||||
|
:on-exceed="handleExceed" |
||||
|
:on-remove="handleRemove" |
||||
|
:on-preview="handlePictureCardPreview" |
||||
|
:on-change="changeUpload" |
||||
|
> |
||||
|
<i slot="default" class="el-icon-plus"></i> |
||||
|
<!-- <div slot="file" slot-scope="{file}"> |
||||
|
<img |
||||
|
class="el-upload-list__item-thumbnail" |
||||
|
:src="file.url" alt="" |
||||
|
> |
||||
|
<span class="el-upload-list__item-actions"> |
||||
|
<span |
||||
|
class="el-upload-list__item-preview" |
||||
|
@click="handlePictureCardPreview(file)" |
||||
|
> |
||||
|
<i class="el-icon-zoom-in"></i> |
||||
|
</span> |
||||
|
<span |
||||
|
v-if="!disabled" |
||||
|
class="el-upload-list__item-delete" |
||||
|
@click="handleRemove(file)" |
||||
|
> |
||||
|
<i class="el-icon-delete"></i> |
||||
|
</span> |
||||
|
</span> |
||||
|
</div> --> |
||||
|
</el-upload> |
||||
|
<el-dialog |
||||
|
:visible.sync="dialogVisible" |
||||
|
top="1vh" |
||||
|
width="35%" |
||||
|
:modal-append-to-body="false" |
||||
|
:append-to-body="true" |
||||
|
:show-close="true" |
||||
|
> |
||||
|
<img width="100%" :src="dialogImageUrl" alt=""> |
||||
|
</el-dialog> |
||||
|
</div> |
||||
|
</template> |
||||
|
<script> |
||||
|
export default { |
||||
|
name: "currenUploadPictureCard", |
||||
|
props: { |
||||
|
limit: { |
||||
|
type: Number, |
||||
|
default: 0 |
||||
|
}, |
||||
|
multiple:{ |
||||
|
type: Boolean, |
||||
|
default:false |
||||
|
}, |
||||
|
searchData: { |
||||
|
type: Array, |
||||
|
default: () => { |
||||
|
return [] |
||||
|
} |
||||
|
}, |
||||
|
picExt: { |
||||
|
type: String, |
||||
|
default: "", |
||||
|
} |
||||
|
}, |
||||
|
data () { |
||||
|
return { |
||||
|
dialogImageUrl: '', |
||||
|
dialogVisible: false, |
||||
|
disabled: false |
||||
|
} |
||||
|
}, |
||||
|
methods: { |
||||
|
handlePictureCardPreview(file) { |
||||
|
this.dialogImageUrl = file.url; |
||||
|
this.dialogVisible = true; |
||||
|
}, |
||||
|
// handleDownload(file) { |
||||
|
// console.log(file); |
||||
|
// }, |
||||
|
changeUpload (val) { |
||||
|
this.$emit('changeUpload', val) |
||||
|
}, |
||||
|
handleRemove (file, fileList) { |
||||
|
this.$emit('handleRemove', fileList) |
||||
|
}, |
||||
|
handleExceed (val) { |
||||
|
this.$warningMsg('最多上传' + this.limit + '个文件') |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
@ -0,0 +1,89 @@ |
|||||
|
<template> |
||||
|
<div> |
||||
|
<el-dialog |
||||
|
title="导出" |
||||
|
:visible.sync="show" |
||||
|
:append-to-body="true" |
||||
|
:modal-append-to-body="false" |
||||
|
width="800px" |
||||
|
:show-close="true" |
||||
|
@close="close" |
||||
|
> |
||||
|
<div class="formItem"> |
||||
|
<span class="title">是否显示明细:</span> |
||||
|
<el-radio-group v-model="form.isDetail" > |
||||
|
<el-radio :label="true">是</el-radio> |
||||
|
<el-radio :label="false">否</el-radio> |
||||
|
</el-radio-group> |
||||
|
</div> |
||||
|
<div class="formItem"> |
||||
|
<span class="title">是否冗余主表数据:</span> |
||||
|
<el-radio-group v-model="form.isRedundance" > |
||||
|
<el-radio :label="true">是</el-radio> |
||||
|
<el-radio :label="false">否</el-radio> |
||||
|
</el-radio-group> |
||||
|
</div> |
||||
|
<span slot="footer" class="dialog-footer"> |
||||
|
<el-button @click="submit('page')">本页导出</el-button> |
||||
|
<el-button |
||||
|
:spinner="'el-icon-loading'" |
||||
|
type="primary" |
||||
|
@click="submit('all')" |
||||
|
>全部导出</el-button> |
||||
|
</span> |
||||
|
</el-dialog> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
export default { |
||||
|
name: 'exportDrop', |
||||
|
props: { |
||||
|
// 导出是【否冗余主表数据】配置 |
||||
|
isDetail:{ |
||||
|
type: Boolean, |
||||
|
default: true, |
||||
|
}, |
||||
|
// 导出是【显示明细】配置 |
||||
|
isRedundance:{ |
||||
|
type: Boolean, |
||||
|
default: true, |
||||
|
}, |
||||
|
}, |
||||
|
data () { |
||||
|
return { |
||||
|
show:true, |
||||
|
form:{ |
||||
|
isDetail:null, |
||||
|
isRedundance:null, |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
mounted () { |
||||
|
this.form={ |
||||
|
isDetail:this.isDetail, |
||||
|
isRedundance:this.isRedundance, |
||||
|
} |
||||
|
}, |
||||
|
methods: { |
||||
|
close() { |
||||
|
this.show = false |
||||
|
this.$emit("closeDialog") |
||||
|
}, |
||||
|
submit(type){ |
||||
|
this.$emit("exportDropSubmit",type,this.form) |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
<style lang="scss" scoped> |
||||
|
.formItem{ |
||||
|
padding-bottom: 15px; |
||||
|
display: flex; |
||||
|
.title{ |
||||
|
width: 180px; |
||||
|
text-align: right; |
||||
|
padding-right: 10px; |
||||
|
} |
||||
|
} |
||||
|
</style> |
@ -0,0 +1,338 @@ |
|||||
|
<template> |
||||
|
<div class="filterForDetailPage" v-if="dialogShow"> |
||||
|
<el-dialog |
||||
|
title="明细查询" |
||||
|
:visible.sync="dialogShow" |
||||
|
top="5vh" |
||||
|
width="96%" |
||||
|
:modal-append-to-body="false" |
||||
|
:append-to-body="false" |
||||
|
:show-close="true" |
||||
|
@close="closeDialog(false)" |
||||
|
class="mainTable-dialog" |
||||
|
> |
||||
|
<div |
||||
|
class="filterForDetailPage-list" |
||||
|
v-loading="Loading.tableLoading" |
||||
|
> |
||||
|
<!-- 列表 --> |
||||
|
<tablePagination |
||||
|
v-if="dialogShow && listColumns && listColumns.length > 0" |
||||
|
:currenButtonData="currenButtonData" |
||||
|
:tableData="tableData" |
||||
|
:tableLoading="Loading.tableLoading" |
||||
|
@rowDrop="rowDropForDetail" |
||||
|
:rowSource="'detailPage_api'" |
||||
|
:searchOverallCoverHeight="'calc(100vh - 380px)'" |
||||
|
:rowMaxHeight="rowMaxHeight" |
||||
|
:tableColumns="listColumns" |
||||
|
:totalCount="totalCount" |
||||
|
:multipleSelection="multipleSelection" |
||||
|
:MaxResultCount="PageListParams.MaxResultCount" |
||||
|
:setUTableHeight="setUTableHeight" |
||||
|
:selectMaxHeight="'116px'" |
||||
|
@topbutton="topbutton" |
||||
|
@inlineDialog="inlineDialog" |
||||
|
@sortChange="sortChange" |
||||
|
@alertoldSkipCount="alertoldSkipCount" |
||||
|
@alterResultCount="alterResultCount" |
||||
|
@handleSelectionChange="handleSelectionChange" |
||||
|
:currentPageProps="oldSkipCount" |
||||
|
:quicklySearchOption="quicklySearchOption" |
||||
|
@quicklySearchClick="quicklySearchClick" |
||||
|
@quicklySearchClear="quicklySearchClear" |
||||
|
:primarySearchOption="primarySearchOption" |
||||
|
@overallSearchFormClick="overallSearchFormClick" |
||||
|
:httpOverallSearchData="httpOverallSearchData" |
||||
|
> |
||||
|
<template> |
||||
|
<!-- todo:width处理 --> |
||||
|
<el-table-column |
||||
|
v-if="operaButtons && operaButtons.length > 0" |
||||
|
label="操作" |
||||
|
:align="'center'" |
||||
|
width="150" |
||||
|
fixed="left" |
||||
|
> |
||||
|
<template slot-scope="scope"> |
||||
|
<span v-for="item in operaButtons" style="margin: 0 10px;"> |
||||
|
<!-- 查看主表信息 --> |
||||
|
<el-button |
||||
|
v-if="item == 'showParent'" |
||||
|
type="text" |
||||
|
@click="showParentHandleForDetail(scope.row)" |
||||
|
>查看主表信息</el-button> |
||||
|
<!-- 编辑 --> |
||||
|
<el-button |
||||
|
v-if="item == 'edit'" |
||||
|
type="text" |
||||
|
style="color: #ff9000;" |
||||
|
@click="editHandleForDetail(scope.row)" |
||||
|
>编辑</el-button> |
||||
|
<!-- 删除 --> |
||||
|
<el-popover |
||||
|
v-if="item == 'delete'" |
||||
|
placement="left" |
||||
|
width="260" |
||||
|
v-model="scope.row.deleteTipVisible" |
||||
|
> |
||||
|
<p>此操作将永久删除该消息, 是否继续?</p> |
||||
|
<div style="text-align: right; margin: 0"> |
||||
|
<el-button size="mini" type="text" style="margin-right: 20px;" @click="scope.row.deleteTipVisible = false">取消</el-button> |
||||
|
<el-button type="primary" size="mini" @click="deleteHandleForDetail(scope.row)">确定</el-button> |
||||
|
</div> |
||||
|
<el-button type="text" slot="reference" style="color: red;">删除</el-button> |
||||
|
</el-popover> |
||||
|
</span> |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
</template> |
||||
|
</tablePagination> |
||||
|
</div> |
||||
|
</el-dialog> |
||||
|
<!-- 主表信息 --> |
||||
|
<el-dialog |
||||
|
:modal-append-to-body="false" |
||||
|
:append-to-body="false" |
||||
|
:title="showParentTitle" |
||||
|
:visible.sync="showParentDialog" |
||||
|
:close-on-click-modal="true" |
||||
|
:close-on-press-escape="true" |
||||
|
:show-close="true" |
||||
|
width="70%" |
||||
|
> |
||||
|
<div v-loading="showParentLoading"> |
||||
|
<curren-descriptions |
||||
|
v-if="showParentTableData" |
||||
|
border |
||||
|
:column="column" |
||||
|
:direction="direction" |
||||
|
:colon="false" |
||||
|
:tabsDesTions="parentColumns" |
||||
|
:propsData="showParentTableData" |
||||
|
style="padding-bottom: 20px;" |
||||
|
></curren-descriptions> |
||||
|
</div> |
||||
|
<!-- <el-table :data="showParentTableData"> |
||||
|
<el-table-column property="date" label="日期" width="150"></el-table-column> |
||||
|
<el-table-column property="name" label="姓名" width="200"></el-table-column> |
||||
|
<el-table-column property="address" label="地址"></el-table-column> |
||||
|
</el-table> --> |
||||
|
</el-dialog> |
||||
|
</div> |
||||
|
</template> |
||||
|
<script> |
||||
|
import currenDescriptions from "@/components/currenDescriptions" |
||||
|
import { tableMixins } from "@/mixins/TableMixins"; |
||||
|
import { TableHeaderMixins } from "@/mixins/TableHeaderMixins"; |
||||
|
import { LoadingMixins } from "@/mixins/LoadingMixins"; |
||||
|
import { mixins } from "@/mixins/mixins"; |
||||
|
import { filterSelectMixins } from '@/mixins/filter-Select' |
||||
|
import {getListDesById,getPageListForDetail} from "@/api/wms-api" |
||||
|
export default { |
||||
|
name: 'filterForDetailPage', |
||||
|
mixins: [ |
||||
|
tableMixins, |
||||
|
TableHeaderMixins, |
||||
|
mixins, |
||||
|
filterSelectMixins, |
||||
|
LoadingMixins |
||||
|
], |
||||
|
components:{ |
||||
|
currenDescriptions |
||||
|
}, |
||||
|
props: { |
||||
|
// 已app-main高度为100% 需要减掉的高度 |
||||
|
setUTableHeight: { |
||||
|
type: Number, |
||||
|
default: 340 |
||||
|
}, |
||||
|
// 是否显示序号 |
||||
|
isShowIndex:{ |
||||
|
type: Boolean, |
||||
|
default: false |
||||
|
}, |
||||
|
// 复选框 |
||||
|
tableSelection: { |
||||
|
type: Boolean, |
||||
|
default: false |
||||
|
}, |
||||
|
cellStyle: { |
||||
|
type: Function, |
||||
|
default: () => { |
||||
|
return Function; |
||||
|
} |
||||
|
}, |
||||
|
// 超出内容是否提示 |
||||
|
showOverflowTooltip:{ |
||||
|
type: Boolean, |
||||
|
default: false, |
||||
|
}, |
||||
|
// 删除api |
||||
|
DeleteApi: { |
||||
|
type: String, |
||||
|
default: null |
||||
|
}, |
||||
|
// 主表数据-表头 |
||||
|
parentColumns:{ |
||||
|
type: Array, |
||||
|
default: null |
||||
|
}, |
||||
|
showHandleButtons:{ |
||||
|
type:Array, |
||||
|
default:() => { |
||||
|
//'add','edit'暂未处理操作 'delete'暂时隐藏 |
||||
|
// showParent查看主表信息,fresh刷新,filter筛选,field字段设置 |
||||
|
return ['showParent','fresh','filter','field']; |
||||
|
} |
||||
|
}, |
||||
|
// 父级展现列数,默认为2列展现 |
||||
|
column: { |
||||
|
type: Number, |
||||
|
default: 2 |
||||
|
}, |
||||
|
// 父级展示方式,默认水平分布 |
||||
|
direction: { |
||||
|
type: String, |
||||
|
default: 'horizontal' |
||||
|
}, |
||||
|
rowMaxHeight:{ |
||||
|
type:String, |
||||
|
default:'calc(90vh - 450px)' |
||||
|
}, |
||||
|
}, |
||||
|
data () { |
||||
|
return { |
||||
|
dialogShow:true, |
||||
|
// URLOption_detailList:allUrlOption[this.$route.name].detailListURL,//明细-列表 |
||||
|
// URLOption_masterId:allUrlOption[this.$route.name].masterId || 'masterId',//明细-查看主表的连接id |
||||
|
// URLOption_masterName:allUrlOption[this.$route.name].masterName,//明细-列表//明细-查看主表的连接title名称 |
||||
|
// URLOption_parent:allUrlOption[this.$route.name].parentURL ? allUrlOption[this.$route.name].parentURL : allUrlOption[this.$route.name].detailURL,//明细-查看主表 |
||||
|
currenButtonData: [],//头部按钮 |
||||
|
operaButtons:[],//操作列按钮 |
||||
|
showParentDialog:false,//显示父级数据弹窗 |
||||
|
showParentTitle:null,//显示父级数据弹窗-title |
||||
|
showParentTableData:null,//显示父级数据弹窗-数据 |
||||
|
showParentLoading:false,//显示父级数据弹窗-加载 |
||||
|
listColumns:[],//表头数据 |
||||
|
} |
||||
|
}, |
||||
|
activated(){ |
||||
|
// 解决切换页面的时候,遮罩层消失的问题 |
||||
|
this.dialogShow = false |
||||
|
this.$nextTick(() => { |
||||
|
this.dialogShow = true |
||||
|
}); |
||||
|
}, |
||||
|
mounted(){ |
||||
|
this.paging() |
||||
|
this.initHandleButtons() |
||||
|
}, |
||||
|
methods: { |
||||
|
rowDropForDetail(data,type){ |
||||
|
this.listColumns = data |
||||
|
this.$emit("rowDropForDetail", data,type) |
||||
|
}, |
||||
|
// 初始化显示按钮 |
||||
|
initHandleButtons(){ |
||||
|
// 头部按钮 |
||||
|
let _arr_header = [] |
||||
|
if(this.showHandleButtons.indexOf('add') >= 0){_arr_header.push(this.defaultAddBtn())} |
||||
|
if(this.showHandleButtons.indexOf('field') >= 0){_arr_header.push(this.defaultFieldSettingBtn())} |
||||
|
if(this.showHandleButtons.indexOf('fresh') >= 0){_arr_header.push(this.defaultFreshBtn())} |
||||
|
if(this.showHandleButtons.indexOf('filter') >= 0){_arr_header.push(this.defaultFilterBtn())} |
||||
|
this.currenButtonData = _arr_header |
||||
|
|
||||
|
// 操作列按钮 |
||||
|
let _arr_op = [] |
||||
|
if(this.showHandleButtons.indexOf('edit') >= 0){_arr_op.push('edit')} |
||||
|
if(this.showHandleButtons.indexOf('delete') >= 0){_arr_op.push('delete')} |
||||
|
if(this.showHandleButtons.indexOf('showParent') >= 0){_arr_op.push('showParent')} |
||||
|
this.operaButtons = _arr_op |
||||
|
}, |
||||
|
// 关闭明细查询弹窗 |
||||
|
closeDialog(data){ |
||||
|
this.dialogShow = false |
||||
|
this.$emit("closeDialog", data) |
||||
|
}, |
||||
|
// 获取列表 |
||||
|
paging(callback){ |
||||
|
this.Loading.tableLoading = true; |
||||
|
this.PageListParams.SkipCount = (this.oldSkipCount - 1) * this.PageListParams.MaxResultCount |
||||
|
getPageListForDetail(this.PageListParams,this.URLOption_detailList) |
||||
|
.then(res=>{ |
||||
|
// 表头处理 |
||||
|
let _parentName = this.URLOption_detailList.substr(0,this.URLOption_detailList.indexOf('/')) |
||||
|
let _Columns = this.initApiColumnsForDto(res.items[0],_parentName) |
||||
|
this.listColumns = this.initTableColumns(_Columns,'detailPage_api') |
||||
|
// 页面数据处理 |
||||
|
if(res){ |
||||
|
this.Loading.tableLoading = false |
||||
|
this.tableData = [] |
||||
|
res.items.forEach(item=>{ |
||||
|
item.deleteTipVisible = false |
||||
|
this.tableData.push(item) |
||||
|
}) |
||||
|
this.totalCount = res.totalCount |
||||
|
} |
||||
|
this.pagingCallback(callback) |
||||
|
}) |
||||
|
.catch(err=>{ |
||||
|
this.Loading.tableLoading = false |
||||
|
this.$message.error("数据获取失败") |
||||
|
}) |
||||
|
}, |
||||
|
// 查看主表信息 |
||||
|
showParentHandleForDetail(data){ |
||||
|
this.showParentTitle = `${data[this.URLOption_masterName] || ''} 主表信息` |
||||
|
this.showParentDialog = true |
||||
|
this.showParentLoading = true |
||||
|
getListDesById(this.URLOption_parent,data[this.URLOption_masterId]) |
||||
|
.then(res => { |
||||
|
this.showParentTableData = res |
||||
|
this.showParentLoading = false |
||||
|
}) |
||||
|
.catch(err => { |
||||
|
this.showParentLoading = false |
||||
|
this.$message.error("主表信息获取失败!") |
||||
|
}) |
||||
|
}, |
||||
|
// 编辑 |
||||
|
editHandleForDetail(data){ |
||||
|
console.log(data) |
||||
|
}, |
||||
|
// 删除 |
||||
|
deleteHandleForDetail(data){ |
||||
|
this.Loading.appMainLoading = true |
||||
|
data.deleteTipVisible = false |
||||
|
// interfaceApi[this.DeleteApi](data.id).then(res => { |
||||
|
// this.$successMsg('删除成功!') |
||||
|
// this.oldSkipCount = 1 |
||||
|
// this.Loading.appMainLoading = false |
||||
|
// this.paging() |
||||
|
// }).catch(err => { |
||||
|
// this.Loading.appMainLoading = false |
||||
|
// this.$message.error("删除失败!") |
||||
|
// }) |
||||
|
}, |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
<style lang="scss"> |
||||
|
.filterForDetailPage { |
||||
|
|
||||
|
.mainTable-dialog{ |
||||
|
.el-dialog{ |
||||
|
height: calc(100% - 100px); |
||||
|
} |
||||
|
} |
||||
|
.el-dialog__body{ |
||||
|
min-height: 200px; |
||||
|
padding-bottom: 20px !important; |
||||
|
} |
||||
|
} |
||||
|
.filterForDetailPage-list{ |
||||
|
height: calc(100%); |
||||
|
overflow: auto; |
||||
|
} |
||||
|
</style> |
@ -0,0 +1,214 @@ |
|||||
|
<template> |
||||
|
<div class="filterSelectComponents"> |
||||
|
<el-select |
||||
|
ref="filterSelect" |
||||
|
v-model="value" |
||||
|
:placeholder="'请选择'+selectItem.label" |
||||
|
:disabled="selectItem.disabled" |
||||
|
:clearable="true" |
||||
|
:multiple="selectItem.multiple" |
||||
|
:multiple-limit="selectItem.multipleLimit" |
||||
|
:collapse-tags="selectItem.collapseTags" |
||||
|
:filterable="!selectItem.noFilter" |
||||
|
:remote="isRemote" |
||||
|
:remote-method="inputChangeHandle" |
||||
|
:style="{width:selectItem.width || '100%'}" |
||||
|
@visible-change="visibleChangeHandle(arguments)" |
||||
|
@clear="clearHandle()" |
||||
|
:loading="loading" |
||||
|
:loading-text="loadingText" |
||||
|
@change="changeHandle(arguments)" |
||||
|
:class="[selectItem.searchButton ? 'hasSearchButton' : '']" |
||||
|
> |
||||
|
<el-option |
||||
|
v-for="item in options" |
||||
|
:key="item.value" |
||||
|
:label="item[selectItem.optionsValue] || item.value" |
||||
|
:value="item[selectItem.optionsValue] || item.value" |
||||
|
:disabled="item.disabled" |
||||
|
> |
||||
|
<div class="optionsRow clearfix" > |
||||
|
<div class="left">{{item[selectItem.optionsValue] || item.value}}</div> |
||||
|
<div class="right" v-if="selectItem.optionsLabel">{{item[selectItem.optionsLabel]}}</div> |
||||
|
</div> |
||||
|
</el-option> |
||||
|
</el-select> |
||||
|
<!-- 搜索按钮 --> |
||||
|
<div class="filterSelectButton"> |
||||
|
<el-button |
||||
|
:disabled=selectItem.disabled |
||||
|
slot="append" |
||||
|
icon="el-icon-search" |
||||
|
v-if="selectItem.searchButton" |
||||
|
@click="selectItem.searchButton(selectItem)" |
||||
|
></el-button> |
||||
|
</div> |
||||
|
</div> |
||||
|
</template> |
||||
|
<script> |
||||
|
export default { |
||||
|
watch: { |
||||
|
selectModel (val) { |
||||
|
this.value = val |
||||
|
} |
||||
|
}, |
||||
|
props: { |
||||
|
// 数据类型基础配置 |
||||
|
selectModel: { |
||||
|
type: String, |
||||
|
default: "" |
||||
|
}, |
||||
|
// 数据类型基础配置 |
||||
|
selectItem: { |
||||
|
type: Object, |
||||
|
default: () => { |
||||
|
return {} |
||||
|
} |
||||
|
}, |
||||
|
}, |
||||
|
data () { |
||||
|
return { |
||||
|
loading:false, |
||||
|
loadingText:"正在加载", |
||||
|
options:[], |
||||
|
value:"", |
||||
|
optionsCopy:[], |
||||
|
//控制是否远程,filterable、remote都为true时候,remote-method才生效(搜索时候走remote-method方法,否则走下拉内容搜索) |
||||
|
// 【目前getPageList方式为远程】 |
||||
|
// 显示差异:为true时候加载显示加载false显示无数据,true时候无数据无下拉,false出下拉 |
||||
|
isRemote:false, |
||||
|
} |
||||
|
}, |
||||
|
created () { |
||||
|
if(this.selectItem){ |
||||
|
this.value = this.selectModel |
||||
|
this.options = this.selectItem.options |
||||
|
this.isRemoteReset() |
||||
|
} |
||||
|
}, |
||||
|
methods: { |
||||
|
changeHandle(value){ |
||||
|
if(!value[0] || value[0].length <= 0)return |
||||
|
let _options = JSON.parse(JSON.stringify(this.selectItem)) |
||||
|
let _item = {} |
||||
|
let _prop = this.selectItem.optionsValue || this.selectItem.prop |
||||
|
this.options.forEach(item=>{ |
||||
|
if(item[_prop] == value[0])_item = item |
||||
|
}) |
||||
|
this.$emit("filterOptionSelectHandle",_item,_options,value[0]) |
||||
|
}, |
||||
|
isRemoteReset(){ |
||||
|
this.isRemote = (!this.selectItem.noFilter && (!this.selectItem.getType || this.selectItem.getType== 'getPageList')) |
||||
|
}, |
||||
|
clearHandle(){ |
||||
|
this.$emit("filterClearHandle",JSON.parse(JSON.stringify(this.selectItem))) |
||||
|
}, |
||||
|
// 给focus返回参数操作 |
||||
|
getHttpData(query){ |
||||
|
if(this.selectItem.beforeFocus && !this.selectItem.beforeFocus()){ |
||||
|
return |
||||
|
} |
||||
|
if(this.selectItem.focus){ |
||||
|
// 当前项的搜索条件 |
||||
|
let _value = query ? query : this.value || "" |
||||
|
let _params = null; |
||||
|
this.loading = true |
||||
|
this.loadingText="正在加载" |
||||
|
// api中《getPageList》方式: |
||||
|
if(!this.selectItem.getType || this.selectItem.getType== "getPageList"){ |
||||
|
_params = { |
||||
|
SkipCount: 0, |
||||
|
MaxResultCount: 100, |
||||
|
condition: { |
||||
|
filters: [] |
||||
|
} |
||||
|
} |
||||
|
if(_value.length > 0 && !this.selectItem.noFilter){ |
||||
|
let _column = this.selectItem.optionsValue || this.selectItem.prop |
||||
|
_params.condition.filters.push({logic:"And",column:_column,action:"Like",value:_value}) |
||||
|
} |
||||
|
} |
||||
|
// api中《getPage》方式:在业务页面调用getFilterList时候 自行传第二个val值 |
||||
|
// 执行方法并传参 |
||||
|
this.selectItem.focus(this.selectItem.getType,_params) |
||||
|
.then(res=>{ |
||||
|
this.options = res |
||||
|
if(!res || res.length <= 0){ |
||||
|
this.isRemoteReset() |
||||
|
this.loadingText="无数据" |
||||
|
}else{ |
||||
|
this.loading = false |
||||
|
this.isRemoteReset() |
||||
|
if(!this.selectItem.filterShowEmpty){ |
||||
|
// 为空的值去掉 |
||||
|
let _noEmpty = [] |
||||
|
this.options.forEach((item,key)=>{ |
||||
|
let _key = this.selectItem.optionsValue || this.selectItem.prop |
||||
|
if(item[_key] && item[_key].length > 0){ |
||||
|
_noEmpty.push(item) |
||||
|
} |
||||
|
}) |
||||
|
this.options = _noEmpty |
||||
|
} |
||||
|
} |
||||
|
this.optionsCopy = this.options |
||||
|
}) |
||||
|
.catch((err)=>{ |
||||
|
this.loading = false |
||||
|
}) |
||||
|
} |
||||
|
}, |
||||
|
inputChangeHandle(query){ |
||||
|
// 目的:假设防止前100个中没有包含A的字符,再次输入时候从后台重新获取 |
||||
|
if(!this.selectItem.getType || this.selectItem.getType== "getPageList"){ |
||||
|
this.getHttpData(query) |
||||
|
} |
||||
|
}, |
||||
|
visibleChangeHandle(val){ |
||||
|
// 展开/focus |
||||
|
if(val[0]){ |
||||
|
this.isRemote = true |
||||
|
this.getHttpData() |
||||
|
} |
||||
|
// 隐藏 |
||||
|
else{ |
||||
|
this.options = [] |
||||
|
this.loading = false |
||||
|
if(this.selectItem.hide){ |
||||
|
this.selectItem.hide(this.$refs.filterSelect) |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
<style lang="scss"> |
||||
|
.filterSelectComponents{ |
||||
|
position: relative; |
||||
|
.filterSelectButton{ |
||||
|
position: absolute; |
||||
|
right: 0; |
||||
|
top: 0; |
||||
|
button{ |
||||
|
display: block; |
||||
|
} |
||||
|
} |
||||
|
.hasSearchButton .el-input__suffix{ |
||||
|
right: 65px !important; |
||||
|
} |
||||
|
.el-input--medium .el-input__icon{ |
||||
|
height: 30px !important; |
||||
|
line-height: 30px !important; |
||||
|
} |
||||
|
} |
||||
|
.optionsRow{ |
||||
|
.left{ |
||||
|
float: left; |
||||
|
} |
||||
|
.right{ |
||||
|
float: right; |
||||
|
padding-left: 20px; |
||||
|
color: #C0C4CC; |
||||
|
} |
||||
|
} |
||||
|
</style> |
@ -0,0 +1,298 @@ |
|||||
|
<template> |
||||
|
<div> |
||||
|
<el-dialog |
||||
|
title="导入" |
||||
|
v-loading="loading" |
||||
|
element-loading-text="正在导入..." |
||||
|
:visible.sync="show" |
||||
|
:append-to-body="true" |
||||
|
:modal-append-to-body="false" |
||||
|
width="800px" |
||||
|
:show-close="false" |
||||
|
> |
||||
|
<div class="body_header"> |
||||
|
<span>上传模板下载:</span> |
||||
|
<el-button |
||||
|
type="success" |
||||
|
size="mini" |
||||
|
icon="el-icon-download" |
||||
|
@click="postImportDown" |
||||
|
>获取模板</el-button |
||||
|
> |
||||
|
</div> |
||||
|
<div class="body_header"> |
||||
|
<span> 导 入 模 式:</span> |
||||
|
<el-radio-group v-model="method" > |
||||
|
<el-radio label="1" :disabled="disabledMethod.method2">追加式</el-radio> |
||||
|
<el-radio label="0" :disabled="disabledMethod.method1">更新式</el-radio> |
||||
|
<el-radio label="2" :disabled="disabledMethod.method3">覆盖式</el-radio> |
||||
|
</el-radio-group> |
||||
|
</div> |
||||
|
<div class="body_header"> |
||||
|
<span>是否部分导入:</span> |
||||
|
<el-radio-group v-model="isAllowPartImport" > |
||||
|
<el-radio label="0" :disabled="disabledIsAllowPartImport.isAllowPartImport1">是</el-radio> |
||||
|
<el-radio label="1" :disabled="disabledIsAllowPartImport.isAllowPartImport2">否</el-radio> |
||||
|
</el-radio-group> |
||||
|
</div> |
||||
|
<curren-Form |
||||
|
class="importFile" |
||||
|
size="medium" |
||||
|
:searchData="FormData" |
||||
|
:searchForm="Form" |
||||
|
:searchHandle="editHandle" |
||||
|
:rules="Rules" |
||||
|
@submitForm="formClick(arguments)" |
||||
|
> |
||||
|
</curren-Form> |
||||
|
</el-dialog> |
||||
|
<!-- 导入预览 --> |
||||
|
<el-dialog |
||||
|
class="previewClass" |
||||
|
title="导入预览" |
||||
|
:visible.sync="previewShow" |
||||
|
:append-to-body="true" |
||||
|
:modal-append-to-body="false" |
||||
|
:show-close="false" |
||||
|
width="70%" |
||||
|
> |
||||
|
<div > |
||||
|
<el-table |
||||
|
:data="excelData.results" |
||||
|
:border="true" |
||||
|
highlight-current-row |
||||
|
style="width: 100%; |
||||
|
margin-top:10px;" |
||||
|
max-height="400" |
||||
|
> |
||||
|
<el-table-column |
||||
|
v-if="excelData.header.length > 0" |
||||
|
type="index" |
||||
|
fixed="left" |
||||
|
label="序号" |
||||
|
width="50" |
||||
|
/> |
||||
|
<el-table-column |
||||
|
v-for="(item,index) of excelData.header" |
||||
|
:key="index" |
||||
|
:prop="item" |
||||
|
:label="item" |
||||
|
/> |
||||
|
</el-table> |
||||
|
</div> |
||||
|
<span slot="footer" class="dialog-footer"> |
||||
|
<el-button @click="submitForm(0)">取 消</el-button> |
||||
|
<el-button type="primary" @click="submitForm(1)">确 定</el-button> |
||||
|
</span> |
||||
|
</el-dialog> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import XLSX from 'xlsx' |
||||
|
import currenForm from "@/components/currenForm" |
||||
|
export default { |
||||
|
name: 'importFile', |
||||
|
components: { |
||||
|
currenForm |
||||
|
}, |
||||
|
props: { |
||||
|
loading: { |
||||
|
type: Boolean, |
||||
|
default: false |
||||
|
}, |
||||
|
show: { |
||||
|
type: Boolean, |
||||
|
default: false |
||||
|
}, |
||||
|
url: { |
||||
|
type: String |
||||
|
}, |
||||
|
postImport: { |
||||
|
type: Function, |
||||
|
default: () => { } |
||||
|
}, |
||||
|
disabledMethod:{ |
||||
|
type: Object, |
||||
|
default: () => { |
||||
|
return {} |
||||
|
} |
||||
|
}, |
||||
|
disabledIsAllowPartImport:{ |
||||
|
type: Object, |
||||
|
default: () => { |
||||
|
return {} |
||||
|
} |
||||
|
}, |
||||
|
methodValue:{ |
||||
|
type: String, |
||||
|
default:'1' |
||||
|
}, |
||||
|
isAllowPartImportValue:{ |
||||
|
type: String |
||||
|
} |
||||
|
}, |
||||
|
data () { |
||||
|
return { |
||||
|
previewShow: false, |
||||
|
// exel表头及数据 |
||||
|
excelData: { |
||||
|
header: [], |
||||
|
results: [] |
||||
|
}, |
||||
|
//表格流体最大高度 |
||||
|
tableMaxHeight:null, |
||||
|
// 临时存储提交数据 |
||||
|
submitDataLS: null, |
||||
|
method: '1', |
||||
|
isAllowPartImport: '1', |
||||
|
editHandle: [ |
||||
|
{ label: "取消", name: "cancel" }, |
||||
|
{ label: "确定", type: "primary", name: "determine" }, |
||||
|
], |
||||
|
FormData: { |
||||
|
formFile: [] |
||||
|
}, |
||||
|
Form: [ |
||||
|
{ type: "upload", label: "文件导入", prop: "formFile", limit: 1, colSpan: 24 } |
||||
|
], |
||||
|
Rules: { |
||||
|
formFile: { required: true, trigger: "change", message: "不可为空" } |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
mounted () { |
||||
|
this.method = this.methodValue |
||||
|
this.isAllowPartImport = this.isAllowPartImportValue |
||||
|
}, |
||||
|
methods: { |
||||
|
postImportDown () { |
||||
|
this.$emit('postImportDown') |
||||
|
}, |
||||
|
// postImport () { |
||||
|
// this.$emit('postImport') |
||||
|
// }, |
||||
|
// methodValueChane() { |
||||
|
// this.$emit("methodChange", this.methodValue); // 用 $emit 通知父组件去修改 |
||||
|
// }, |
||||
|
// isAllowPartImportValueChane() { |
||||
|
// this.$emit("isAllowPartImportChange", this.isAllowPartImportValue); // 用 $emit 通知父组件去修改 |
||||
|
// }, |
||||
|
readerData(rawFile) { |
||||
|
if (rawFile) { |
||||
|
return new Promise((resolve, reject) => { |
||||
|
const reader = new FileReader() |
||||
|
reader.onload = e => { |
||||
|
const data = e.target.result |
||||
|
// const workbook = XLSX.read(data, { type: 'array',cellText:false,cellDates:true }) |
||||
|
const workbook = XLSX.read(data, { type: 'array'}) |
||||
|
const firstSheetName = workbook.SheetNames[0] |
||||
|
const worksheet = workbook.Sheets[firstSheetName] |
||||
|
const header = this.getHeaderRow(worksheet) |
||||
|
const results = XLSX.utils.sheet_to_json(worksheet,{raw:false}) |
||||
|
// const results = XLSX.utils.sheet_to_json(worksheet,{raw:false,dateNF:'yyyy-mm-dd'}) //yyyy-MM-dd HH:mm:ss |
||||
|
if(results.length <= 0){ |
||||
|
this.$message.error('导入表格内无数据,请确认后重新导入'); |
||||
|
this.loading = false |
||||
|
return |
||||
|
} |
||||
|
// this.generateData({ header, results }) |
||||
|
this.excelData.header = header |
||||
|
this.excelData.results = results |
||||
|
// this.tableMaxHeight = document.getElementById("tableOuter").clientHeight |
||||
|
resolve() |
||||
|
this.tab |
||||
|
} |
||||
|
reader.readAsArrayBuffer(rawFile) |
||||
|
}) |
||||
|
} |
||||
|
}, |
||||
|
getHeaderRow(sheet) { |
||||
|
const headers = [] |
||||
|
const range = XLSX.utils.decode_range(sheet['!ref']) |
||||
|
let C |
||||
|
const R = range.s.r |
||||
|
/* start in the first row */ |
||||
|
for (C = range.s.c; C <= range.e.c; ++C) { /* walk every column in the range */ |
||||
|
const cell = sheet[XLSX.utils.encode_cell({ c: C, r: R })] |
||||
|
/* find the cell in the first row */ |
||||
|
let hdr = 'UNKNOWN ' + C // <-- replace with your desired default |
||||
|
if (cell && cell.t) hdr = XLSX.utils.format_cell(cell) |
||||
|
headers.push(hdr) |
||||
|
} |
||||
|
return headers |
||||
|
}, |
||||
|
// 文件预览 |
||||
|
submitForm(val) { |
||||
|
if (val == 0) { |
||||
|
this.previewShow = false |
||||
|
} else { |
||||
|
this.submiData(this.submitDataLS) |
||||
|
this.previewShow = false |
||||
|
} |
||||
|
}, |
||||
|
// formClick(val) { |
||||
|
// this.FormData.method = this.method |
||||
|
// this.FormData.isAllowPartImport = this.isAllowPartImport |
||||
|
// this.$emit('importClick', val, this.FormData) |
||||
|
// } |
||||
|
formClick (val) { |
||||
|
if (val[0] == 0) { |
||||
|
this.submiData(val) |
||||
|
} else { |
||||
|
// 显示预览页 |
||||
|
// 没上传文件时 不显示预览界面 |
||||
|
if (val[1].fields[0].fieldValue[0]) { |
||||
|
this.previewShow = true |
||||
|
this.submitDataLS = val |
||||
|
// 文件数据展示 |
||||
|
this.readerData(val[1].fields[0].fieldValue[0]) |
||||
|
} else { |
||||
|
this.$message.error('请上传文件!'); |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
// 提交数据 |
||||
|
submiData(val) { |
||||
|
this.FormData.method = this.method |
||||
|
this.FormData.isAllowPartImport = this.isAllowPartImport |
||||
|
this.$emit('importClick', val, this.FormData) |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
<style lang="scss" scoped> |
||||
|
::v-deep .el-dialog__body { |
||||
|
max-height: 100vh; |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
} |
||||
|
.body_header { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
padding: 0 0 20px 100px; |
||||
|
} |
||||
|
::v-deep .importFile { |
||||
|
flex: 1; |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
overflow: hidden; |
||||
|
|
||||
|
.el-form { |
||||
|
flex: 1; |
||||
|
padding-left: 70px; |
||||
|
padding-right: 70px; |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
overflow-y: auto; |
||||
|
.el-row { |
||||
|
flex: 2; |
||||
|
padding-left: 30px; |
||||
|
padding-right: 30px; |
||||
|
} |
||||
|
} |
||||
|
.formButton { |
||||
|
padding: 20px 20px 20px 0; |
||||
|
} |
||||
|
} |
||||
|
</style> |
@ -0,0 +1,278 @@ |
|||||
|
<template> |
||||
|
<el-dialog |
||||
|
v-loading="loading" |
||||
|
element-loading-text="加载中..." |
||||
|
v-if="displayDialog" |
||||
|
:visible="true" |
||||
|
:fullscreen="true" |
||||
|
:modal="false" |
||||
|
:modal-append-to-body="false" |
||||
|
:show-close="false" |
||||
|
style="width:calc(100% - 28px);left:14px;top:14px;height:calc(100% - 28px)" |
||||
|
> |
||||
|
<div class="dialogOuterTitle">{{formTitle}}</div> |
||||
|
<curren-Form |
||||
|
v-if="active === 0" |
||||
|
size="medium" |
||||
|
class="newAndEdiDialog" |
||||
|
:searchData="FormData" |
||||
|
:searchForm="Form" |
||||
|
:searchOptions="Options" |
||||
|
:searchHandle="Handle" |
||||
|
:rules="Rules" |
||||
|
@changeInput="changeInput" |
||||
|
@push="DataPush(arguments)" |
||||
|
@submitForm="FormClick(arguments)" |
||||
|
@radioChange="radioChange" |
||||
|
@changeSelect="changeSelect" |
||||
|
> |
||||
|
<template v-if="showmyTable"> |
||||
|
<el-form-item class="formTable-box" prop="details"> |
||||
|
<currenTable |
||||
|
:tableData="FormData.details" |
||||
|
:tableColumns="myTableColumns" |
||||
|
:selectionTable="selectionTable" |
||||
|
:tableLoading="tableLoading" |
||||
|
:isShowIndex="isShowIndex" |
||||
|
@handleSelectionChange="handleSelectionChange" |
||||
|
> |
||||
|
<template> |
||||
|
<el-table-column |
||||
|
fixed="right" |
||||
|
label="操作" |
||||
|
width="120"> |
||||
|
<template slot-scope="scope"> |
||||
|
<el-button |
||||
|
@click.native.prevent="deleteRow(scope.$index, FormData.details)" |
||||
|
type="text" |
||||
|
size="small"> |
||||
|
删除 |
||||
|
</el-button> |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
</template> |
||||
|
</currenTable> |
||||
|
</el-form-item> |
||||
|
</template> |
||||
|
</curren-Form> |
||||
|
<div v-if="active === 1 && pageStatus == 'success'" class="page4"> |
||||
|
<el-result icon="success" title="成功提示" :subTitle="formTitle + '成功'"> |
||||
|
<template slot="extra"> |
||||
|
<el-button type="primary" size="medium" @click="close" |
||||
|
>退出</el-button |
||||
|
> |
||||
|
</template> |
||||
|
</el-result> |
||||
|
</div> |
||||
|
<div v-if="active === 2 && pageStatus == 'error'" class="page4"> |
||||
|
<el-result icon="error" title="错误提示" :subTitle="formTitle + '失败'"> |
||||
|
<template slot="extra"> |
||||
|
<el-button type="primary" size="medium" @click="goBack" |
||||
|
>返回</el-button |
||||
|
> |
||||
|
<el-button type="primary" size="medium" @click="close" |
||||
|
>退出</el-button |
||||
|
> |
||||
|
</template> |
||||
|
</el-result> |
||||
|
</div> |
||||
|
</el-dialog> |
||||
|
</template> |
||||
|
<script> |
||||
|
export default { |
||||
|
props: { |
||||
|
loading: { |
||||
|
type: Boolean, |
||||
|
default: false |
||||
|
}, |
||||
|
//控制步骤 |
||||
|
active: { |
||||
|
type: Number, |
||||
|
default: 0 |
||||
|
}, |
||||
|
//结合active控制返回结果 |
||||
|
pageStatus: { |
||||
|
type: String, |
||||
|
default: "" |
||||
|
}, |
||||
|
//显示返回结果 |
||||
|
formReveal: { |
||||
|
type: Boolean, |
||||
|
}, |
||||
|
//dialog标题 |
||||
|
formTitle: { |
||||
|
type: String, |
||||
|
default: '' |
||||
|
}, |
||||
|
//dialog是否显示 |
||||
|
displayDialog: { |
||||
|
type: Boolean, |
||||
|
default: () => { |
||||
|
return false |
||||
|
} |
||||
|
}, |
||||
|
//表单数据 |
||||
|
FormData: { |
||||
|
type: Object, |
||||
|
default: () => { |
||||
|
return {} |
||||
|
} |
||||
|
}, |
||||
|
//绑定表单数据 |
||||
|
Form: { |
||||
|
type: Array, |
||||
|
default: () => { |
||||
|
return [] |
||||
|
} |
||||
|
}, |
||||
|
//下拉框数据 |
||||
|
Options: { |
||||
|
type: Object, |
||||
|
default: () => { |
||||
|
return {} |
||||
|
} |
||||
|
}, |
||||
|
//表单按钮 |
||||
|
Handle: { |
||||
|
type: Array, |
||||
|
default: () => { |
||||
|
return [] |
||||
|
} |
||||
|
}, |
||||
|
//表单验证 |
||||
|
Rules: { |
||||
|
type: Object, |
||||
|
default: () => { |
||||
|
return {} |
||||
|
} |
||||
|
}, |
||||
|
// 列表字段 |
||||
|
myTableColumns: { |
||||
|
type: Array, |
||||
|
default: () => { |
||||
|
return [] |
||||
|
} |
||||
|
}, |
||||
|
showmyTable: { |
||||
|
type: Boolean, |
||||
|
default: () => { |
||||
|
return false |
||||
|
} |
||||
|
}, |
||||
|
selectionTable: { |
||||
|
type: Boolean, |
||||
|
default: () => { |
||||
|
return false |
||||
|
} |
||||
|
}, |
||||
|
tableLoading: { |
||||
|
type: Boolean, |
||||
|
default: false |
||||
|
}, |
||||
|
isShowIndex: { |
||||
|
type: Boolean, |
||||
|
default: false, |
||||
|
} |
||||
|
}, |
||||
|
data () { |
||||
|
return { |
||||
|
session: null |
||||
|
} |
||||
|
}, |
||||
|
mounted () { |
||||
|
this.session = JSON.parse(JSON.stringify(this.FormData)) |
||||
|
}, |
||||
|
methods: { |
||||
|
//点击表单提交(新增或编辑) |
||||
|
FormClick (val) { |
||||
|
if (val[0] == 0) { |
||||
|
this.close() |
||||
|
} else { |
||||
|
val[1].validate((valid) => { |
||||
|
if (valid) { |
||||
|
this.$emit('FormSubmit', val); |
||||
|
} else { |
||||
|
this.$errorMsg('请按照提示继续操作') |
||||
|
return false; |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
}, |
||||
|
close () { |
||||
|
const data = JSON.parse(JSON.stringify(this.session)) |
||||
|
this.$emit('close', data) |
||||
|
}, |
||||
|
goBack () { |
||||
|
this.$emit('goBack') |
||||
|
}, |
||||
|
DataPush (val) { |
||||
|
this.$emit('push', val) |
||||
|
}, |
||||
|
deleteRow(index, tableData) { |
||||
|
this.$emit('deleteRow', index, tableData) |
||||
|
}, |
||||
|
radioChange(prop,val){ |
||||
|
this.$emit('radioChange', prop, val) |
||||
|
}, |
||||
|
changeInput(prop, val) { |
||||
|
this.$emit("changeInput", prop, val) |
||||
|
}, |
||||
|
//点击selection框 |
||||
|
handleSelectionChange(val) { |
||||
|
this.$emit("handleSelectionChange", val); |
||||
|
}, |
||||
|
// form表单下拉框change事件 |
||||
|
changeSelect(prop,val ) { |
||||
|
this.$emit("changeSelect", prop, val) |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
<style lang="scss" scoped> |
||||
|
::v-deep .el-dialog__header{ |
||||
|
padding: 0 !important; |
||||
|
} |
||||
|
::v-deep .el-dialog__body{ |
||||
|
padding-top: 0; |
||||
|
} |
||||
|
::v-deep .newAndEdiDialog { |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
width: 100%; |
||||
|
height: calc(100% - 60px); |
||||
|
.el-form { |
||||
|
flex: 1; |
||||
|
display: flex; |
||||
|
justify-content: flex-start; |
||||
|
align-content: flex-start; |
||||
|
flex-wrap: wrap; |
||||
|
overflow: hidden; |
||||
|
overflow-y: auto; |
||||
|
padding-right: 40px; |
||||
|
} |
||||
|
.screen-push { |
||||
|
color: rgb(64, 158, 255); |
||||
|
span { |
||||
|
cursor: pointer; |
||||
|
&:hover { |
||||
|
color: blue; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
.formButton { |
||||
|
padding: 20px 20px 20px 0; |
||||
|
} |
||||
|
.formTable-box { |
||||
|
height: 40%; |
||||
|
|
||||
|
.el-form-item__content { |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
overflow: hidden; |
||||
|
margin: 0 !important; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</style> |
@ -0,0 +1,81 @@ |
|||||
|
<template> |
||||
|
<el-dialog |
||||
|
:title="title" |
||||
|
:v-loading="loadingPDF" |
||||
|
:visible.sync="isShowPDF" |
||||
|
:modal-append-to-body="false" |
||||
|
:append-to-body="true" |
||||
|
top="1vh" |
||||
|
> |
||||
|
<div> |
||||
|
<el-button-group> |
||||
|
<el-button type="primary" icon="el-icon-arrow-left" size="mini" @click="prePage">上一页</el-button> |
||||
|
<el-button type="primary" size="mini" @click="nextPage">下一页<i class="el-icon-arrow-right el-icon--right"></i></el-button> |
||||
|
</el-button-group> |
||||
|
<div style="marginTop: 10px; color: #409EFF">{{ pageNum }} / {{ pageTotalNum }}</div> |
||||
|
<pdf |
||||
|
:page="pageNum" |
||||
|
:src="urlPDF" |
||||
|
@progress="loadedRatio = $event" |
||||
|
@num-pages="pageTotalNum=$event" |
||||
|
></pdf> |
||||
|
</div> |
||||
|
<span slot="footer" class="dialog-footer"> |
||||
|
<el-button @click="close">取 消</el-button> |
||||
|
</span> |
||||
|
</el-dialog> |
||||
|
</template> |
||||
|
<script> |
||||
|
|
||||
|
import pdf from 'vue-pdf' |
||||
|
|
||||
|
export default { |
||||
|
name: 'Pdf', |
||||
|
components: { |
||||
|
pdf, |
||||
|
}, |
||||
|
data() { |
||||
|
return { |
||||
|
// urlPDF: 'http://mozilla.github.io/pdf.js/web/compressed.tracemonkey-pldi-09.pdf', |
||||
|
pageNum: 1, |
||||
|
pageTotalNum: 1, //总页数 |
||||
|
loadedRatio: 0, // 当前页面的加载进度,范围是0-1 ,等于1的时候代表当前页已经完全加载完成了 |
||||
|
} |
||||
|
}, |
||||
|
props: { |
||||
|
urlPDF: { |
||||
|
type: String, |
||||
|
default: '', |
||||
|
}, |
||||
|
title: { |
||||
|
type: String, |
||||
|
default: '', |
||||
|
}, |
||||
|
isShowPDF: { |
||||
|
type: Boolean, |
||||
|
default: false |
||||
|
}, |
||||
|
loadingPDF: { |
||||
|
type: Boolean, |
||||
|
default: false |
||||
|
} |
||||
|
}, |
||||
|
methods: { |
||||
|
// 上一页 |
||||
|
prePage() { |
||||
|
let page = this.pageNum |
||||
|
page = page > 1 ? page - 1 : this.pageTotalNum |
||||
|
this.pageNum = page |
||||
|
}, |
||||
|
// 下一页 |
||||
|
nextPage() { |
||||
|
let page = this.pageNum |
||||
|
page = page < this.pageTotalNum ? page + 1 : 1 |
||||
|
this.pageNum = page |
||||
|
}, |
||||
|
close(){ |
||||
|
this.$emit('closePDF') |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
@ -0,0 +1,43 @@ |
|||||
|
<template> |
||||
|
<div class="resultStatusComponents"> |
||||
|
<!-- // todo-An icon插槽组件化 --> |
||||
|
<el-result |
||||
|
:icon="status" |
||||
|
:title="title" |
||||
|
:subTitle="subTitle" |
||||
|
> |
||||
|
<template slot="extra"> |
||||
|
<slot></slot> |
||||
|
</template> |
||||
|
</el-result> |
||||
|
</div> |
||||
|
</template> |
||||
|
<script> |
||||
|
export default { |
||||
|
name: 'resultStatus', |
||||
|
props: { |
||||
|
// 状态 success / warning / info / error |
||||
|
status: { |
||||
|
type: String, |
||||
|
default: 'success' |
||||
|
}, |
||||
|
// 主标题 |
||||
|
title:{ |
||||
|
type: String, |
||||
|
default: '成功' |
||||
|
}, |
||||
|
//次标题 |
||||
|
subTitle:{ |
||||
|
type: String, |
||||
|
default: '' |
||||
|
}, |
||||
|
}, |
||||
|
data () { |
||||
|
return { |
||||
|
|
||||
|
} |
||||
|
}, |
||||
|
methods: { |
||||
|
} |
||||
|
} |
||||
|
</script> |
@ -0,0 +1,265 @@ |
|||||
|
<template> |
||||
|
<el-popover |
||||
|
placement="top" |
||||
|
v-model="visible" |
||||
|
class="rowDropContain rowDropNotHideItem" |
||||
|
width="270" |
||||
|
> |
||||
|
<div class="test_wrapper" @dragover="dragover($event)"> |
||||
|
<div class="text" >字段设置</div> |
||||
|
<el-divider></el-divider> |
||||
|
<!-- 全选 --> |
||||
|
<div class="allSelectContent" @click="redioAllChange()"> |
||||
|
<i class="el-icon-success icon" v-if="allSeletType == 'allSelect'"></i> |
||||
|
<i class="el-icon-remove icon" v-if="allSeletType == 'hasSelect'"></i> |
||||
|
<i class="el-icon-success icon" v-if="allSeletType == 'NoSelect'" style="color:#999" ></i> |
||||
|
全选 |
||||
|
</div> |
||||
|
<transition-group class="transition-wrapper" :style="{maxHeight:innerMaxHeight}" name="sort"> |
||||
|
<div |
||||
|
v-for="(item,index) in dataList" |
||||
|
:key='index+item.label' |
||||
|
class="sort-item" |
||||
|
:draggable="true" |
||||
|
@dragstart="dragstart(item)" |
||||
|
@dragenter="dragenter(item,$event)" |
||||
|
@dragend="dragend(item,$event)" |
||||
|
@dragover="dragover($event)" |
||||
|
> |
||||
|
<svg-icon |
||||
|
class="checkbox-svg" |
||||
|
:class="{'show': dataList[index].istrue}" |
||||
|
@click="rediochange(index)" |
||||
|
:icon-class="dataList[index].istrue ? 'svg_show' : 'svg_hide'" |
||||
|
/> |
||||
|
<div class="lable">{{ item.label }}</div> |
||||
|
</div> |
||||
|
</transition-group> |
||||
|
</div> |
||||
|
<div class="buttonsBox"> |
||||
|
<el-button size="mini" @click="reset">重置</el-button> |
||||
|
<el-button size="mini" @click="close">关闭</el-button> |
||||
|
<!-- <el-button type="primary" size="mini" @click="save">保存</el-button> --> |
||||
|
</div> |
||||
|
</el-popover> |
||||
|
|
||||
|
</template> |
||||
|
<script> |
||||
|
import draggable from "vuedraggable"; |
||||
|
import Sortable from "sortablejs"; |
||||
|
import { getLoginName } from "@/utils/auth" |
||||
|
export default { |
||||
|
components: { |
||||
|
draggable, |
||||
|
Sortable, |
||||
|
}, |
||||
|
data() { |
||||
|
return { |
||||
|
historyTableColumns:null, |
||||
|
name: null, |
||||
|
oldData: null, |
||||
|
newData: null, |
||||
|
dataList: [], |
||||
|
// 全选 allSelect hasSelect NoSelect |
||||
|
allSeletType:'NoSelect', |
||||
|
userName: getLoginName() |
||||
|
} |
||||
|
}, |
||||
|
props: { |
||||
|
innerMaxHeight:{ |
||||
|
type:String, |
||||
|
default:'calc(90vh - 280px)' |
||||
|
}, |
||||
|
visible: { |
||||
|
type: Boolean, |
||||
|
default: () => { |
||||
|
return false |
||||
|
} |
||||
|
}, |
||||
|
tableColumns: { |
||||
|
type: Array, |
||||
|
default: () => { |
||||
|
return []; |
||||
|
}, |
||||
|
}, |
||||
|
// list_api detail_api detailPage_api list detail detailPage |
||||
|
source:{ |
||||
|
type:String, |
||||
|
default:'list_api' |
||||
|
} |
||||
|
}, |
||||
|
mounted() { |
||||
|
this.historyTableColumns = JSON.parse(JSON.stringify(this.tableColumns)) |
||||
|
this.formatData(this.tableColumns) |
||||
|
this.initSelectSta() |
||||
|
}, |
||||
|
methods: { |
||||
|
reset() { |
||||
|
this.$confirm('重置后,字段设置将恢复初始设置,是否继续?', '提示', { |
||||
|
confirmButtonText: '确定', |
||||
|
cancelButtonText: '取消', |
||||
|
type: 'warning', |
||||
|
cancelButtonClass:'rowDropNotHideItem' |
||||
|
}).then(() => { |
||||
|
// 先set是为了字段设置按钮可以监听到缓存变化,之后在移除缓存 |
||||
|
localStorage.setItem('file_Columns_' + this.source + '_' + this.userName + '_' + this.$route.name, JSON.stringify([])) |
||||
|
localStorage.removeItem('file_Columns_' + this.source + '_' +this.userName + '_' + this.$route.name) |
||||
|
// let _resetCol = this.$isTableColumns[this.$route.name] |
||||
|
let _resetCol = this.historyTableColumns |
||||
|
_resetCol.forEach(item => { |
||||
|
item.istrue = true |
||||
|
}) |
||||
|
this.dataList = _resetCol |
||||
|
this.initSelectSta() |
||||
|
this.$emit('radio',_resetCol,this.source) |
||||
|
this.close() |
||||
|
}).catch(() => { |
||||
|
|
||||
|
}); |
||||
|
}, |
||||
|
close() { |
||||
|
this.$emit('closeRowDrop') |
||||
|
}, |
||||
|
// 格式化表头数据 |
||||
|
formatData (val) { |
||||
|
this.dataList = JSON.parse(JSON.stringify(val)) |
||||
|
this.dataList.forEach(item => { |
||||
|
if (item.istrue == undefined) { |
||||
|
item.istrue = true |
||||
|
} |
||||
|
}) |
||||
|
}, |
||||
|
save () { |
||||
|
this.$forceUpdate() |
||||
|
this.$emit('radio',this.dataList,this.source) |
||||
|
// 本地缓存 当前用户名 + 路由名称 |
||||
|
localStorage.setItem('file_Columns_' + this.source + '_' + this.userName + '_' + this.$route.name, JSON.stringify(this.dataList)) |
||||
|
}, |
||||
|
dragstart(value) { |
||||
|
this.oldData = value |
||||
|
}, |
||||
|
// 记录移动过程中信息 |
||||
|
dragenter(value, e) { |
||||
|
this.newData = value |
||||
|
e.preventDefault() |
||||
|
}, |
||||
|
// 拖拽最终操作 |
||||
|
dragend(value, e) { |
||||
|
if (this.oldData !== this.newData) { |
||||
|
let oldIndex = this.dataList.indexOf(this.oldData) |
||||
|
let newIndex = this.dataList.indexOf(this.newData) |
||||
|
let newItems = [...this.dataList] |
||||
|
// 删除老的节点 |
||||
|
newItems.splice(oldIndex, 1) |
||||
|
// 在列表中目标位置增加新的节点 |
||||
|
newItems.splice(newIndex, 0, this.oldData) |
||||
|
this.dataList = [...newItems] |
||||
|
this.save() |
||||
|
} |
||||
|
}, |
||||
|
// 拖动事件(主要是为了拖动时鼠标光标不变为禁止) |
||||
|
dragover(e) { |
||||
|
e.preventDefault() |
||||
|
}, |
||||
|
// item元素点击眼睛事件 |
||||
|
rediochange(index){ |
||||
|
// this.dataList[index].istrue = !this.dataList[index].istrue |
||||
|
this.$set(this.dataList[index],'istrue', !this.dataList[index].istrue) |
||||
|
this.initSelectSta() |
||||
|
this.$nextTick(()=>{ |
||||
|
this.save() |
||||
|
}) |
||||
|
}, |
||||
|
// 初始化当前全选状态 |
||||
|
initSelectSta(){ |
||||
|
let _num = 0 |
||||
|
this.dataList.forEach(item=>{ |
||||
|
if(item.istrue){ |
||||
|
_num ++ |
||||
|
} |
||||
|
}) |
||||
|
if(_num == 0){this.allSeletType = 'NoSelect'} |
||||
|
if(_num == this.dataList.length){this.allSeletType = 'allSelect'} |
||||
|
if(_num > 0 && _num != this.dataList.length){this.allSeletType = 'hasSelect'} |
||||
|
}, |
||||
|
// 全选点击事件 |
||||
|
redioAllChange(){ |
||||
|
let isSelectAll = !(this.allSeletType == 'allSelect') |
||||
|
this.allSeletType = isSelectAll ? 'allSelect' : 'NoSelect'; |
||||
|
this.dataList.forEach(item=>{ |
||||
|
return item.istrue = isSelectAll |
||||
|
}) |
||||
|
this.save() |
||||
|
}, |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
<style lang="scss"> |
||||
|
$paddingSize:20px; |
||||
|
.rowDropContain{ |
||||
|
.el-popover{ |
||||
|
position: fixed; |
||||
|
right: 30px; |
||||
|
padding: 0; |
||||
|
} |
||||
|
.transition-wrapper { |
||||
|
display: block; |
||||
|
// max-height: calc(90vh - 280px); |
||||
|
overflow: auto; |
||||
|
padding: 0 0 $paddingSize $paddingSize; |
||||
|
|
||||
|
.sort-item{ |
||||
|
margin-bottom: 6px; |
||||
|
display: flex; |
||||
|
cursor: grab; |
||||
|
align-items: center; |
||||
|
|
||||
|
&:last-child{ |
||||
|
margin-bottom: 0; |
||||
|
} |
||||
|
|
||||
|
.lable{ |
||||
|
padding: 0 15px 0 10px; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
.el-divider--horizontal { |
||||
|
margin: $paddingSize; |
||||
|
width: calc(100% - 40px); |
||||
|
} |
||||
|
.text { |
||||
|
color: #333; |
||||
|
font-weight: bold; |
||||
|
padding: $paddingSize 0 0 $paddingSize; |
||||
|
} |
||||
|
.allSelectContent{ |
||||
|
user-select: none; |
||||
|
cursor: pointer; |
||||
|
padding:0 0 10px $paddingSize; |
||||
|
.icon{ |
||||
|
font-size:18px; |
||||
|
vertical-align: middle; |
||||
|
color: #409EFF; |
||||
|
margin-right: 5px; |
||||
|
} |
||||
|
} |
||||
|
.buttonsBox{ |
||||
|
text-align: center; |
||||
|
margin: 0; |
||||
|
padding: 15px; |
||||
|
border-top: #eee solid 1px; |
||||
|
} |
||||
|
.checkbox-svg{ |
||||
|
width: 20px; |
||||
|
flex-shrink: 0; |
||||
|
fill:currentColor; |
||||
|
color:#999; |
||||
|
font-size: 18px; |
||||
|
cursor: pointer; |
||||
|
|
||||
|
&.show{ |
||||
|
color: #409EFF; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</style> |
@ -0,0 +1,66 @@ |
|||||
|
<template> |
||||
|
<!-- 组件功能:普通搜索(列表中的快速搜索) --> |
||||
|
<div class="normalSearchComponentsContain"> |
||||
|
<div class="leftInputBox"> |
||||
|
<i class="el-icon-search searchIcon"></i> |
||||
|
<el-input |
||||
|
v-model="searchValue" |
||||
|
:placeholder="searchNormalOption && searchNormalOption.placeholder ? searchNormalOption.placeholder : '这里是快速搜索'" |
||||
|
clearable |
||||
|
@keyup.enter.native="searchNormalClick" |
||||
|
@clear="searchNormalClear" |
||||
|
></el-input> |
||||
|
</div> |
||||
|
<el-button |
||||
|
class="searchButton" |
||||
|
size="mini" |
||||
|
@click="searchNormalClick" |
||||
|
>搜索</el-button> |
||||
|
</div> |
||||
|
</template> |
||||
|
<script> |
||||
|
export default { |
||||
|
props: { |
||||
|
// 格式:{ |
||||
|
// prop:'asnNumber',//查询的接口过滤数据 |
||||
|
// placeholder:'请输入发货单号',//placeholder |
||||
|
// }, |
||||
|
searchNormalOption: { |
||||
|
type: Object, |
||||
|
default: null |
||||
|
}, |
||||
|
}, |
||||
|
data () { |
||||
|
return { |
||||
|
searchValue:null,//搜索内容数据 |
||||
|
} |
||||
|
}, |
||||
|
methods:{ |
||||
|
// 搜索 |
||||
|
searchNormalClick(){ |
||||
|
this.$emit('searchNormalClick', this.searchValue, this.searchNormalOption) |
||||
|
}, |
||||
|
// 清除搜索 |
||||
|
searchNormalClear(noflesh){ |
||||
|
this.searchValue = "" |
||||
|
if(!noflesh){ |
||||
|
this.$emit('searchNormalClear',this.searchValue, this.searchNormalOption) |
||||
|
} |
||||
|
}, |
||||
|
// 设置值 |
||||
|
setSearchNormalValue(val,noflesh){ |
||||
|
this.searchValue = val |
||||
|
if(!noflesh){ |
||||
|
this.searchNormalClick() |
||||
|
} |
||||
|
}, |
||||
|
// 获取值 |
||||
|
getSearchNormalValue(){ |
||||
|
return this.searchValue |
||||
|
}, |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
<style lang="scss"> |
||||
|
@import "./style/index.scss"; |
||||
|
</style> |
@ -0,0 +1,63 @@ |
|||||
|
$searchWidth:60px; |
||||
|
.normalSearchComponentsContain{ |
||||
|
min-height: 29px; |
||||
|
width: 230px; |
||||
|
overflow: hidden; |
||||
|
position: relative; |
||||
|
caret-color:#ccc; |
||||
|
background: #fff; |
||||
|
|
||||
|
.leftInputBox{ |
||||
|
position: absolute; |
||||
|
left: 0; |
||||
|
right: $searchWidth; |
||||
|
top: 0; |
||||
|
bottom: 0; |
||||
|
border: #e8e8e8 solid 1px; |
||||
|
overflow: hidden; |
||||
|
border-radius: 4px; |
||||
|
} |
||||
|
|
||||
|
.searchIcon{ |
||||
|
display: block; |
||||
|
position: absolute; |
||||
|
left: 10px; |
||||
|
top: 0; |
||||
|
height: 100%; |
||||
|
line-height: 28px; |
||||
|
text-align: center; |
||||
|
color: #ccc; |
||||
|
} |
||||
|
|
||||
|
.el-input{ |
||||
|
position: absolute; |
||||
|
left: 30px; |
||||
|
right: 0; |
||||
|
height: 100%; |
||||
|
width: auto; |
||||
|
|
||||
|
input{ |
||||
|
border: none; |
||||
|
height: 100%; |
||||
|
padding: 0 30px 0 0; |
||||
|
} |
||||
|
|
||||
|
.el-input__icon{ |
||||
|
line-height: 28px; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.searchButton{ |
||||
|
position: absolute; |
||||
|
right: 0; |
||||
|
top: 0; |
||||
|
width: $searchWidth + 3px; |
||||
|
border-radius: 0 4px 4px 0; |
||||
|
border: none; |
||||
|
color: #1890ff; |
||||
|
height: 100%; |
||||
|
background: #d5eaff; |
||||
|
font-size: 13px; |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,611 @@ |
|||||
|
<template> |
||||
|
<!-- 全面的筛选组件:初级普通筛选 + 高级筛选(按照配置来判断显示情况)--> |
||||
|
<!-- todo:使用v-if每次重新赋值,与接口查询保持一致 --> |
||||
|
<div |
||||
|
class="searchOverallComponent" |
||||
|
:style="{height:componentsHeight+'px',overflow:isShowMoreList ? 'unset' : 'hidden'}" |
||||
|
v-show="isShow" |
||||
|
> |
||||
|
<div |
||||
|
class="border-outer" |
||||
|
> |
||||
|
<!-- 整体背景遮罩 --> |
||||
|
<div |
||||
|
v-if="isShow && isShowMoreList" |
||||
|
class="fullPageCover" |
||||
|
:style="{height:searchOverallCoverHeight}" |
||||
|
></div> |
||||
|
<div class="title" v-if="isShowMoreList">高级筛选</div> |
||||
|
<!-- 普通筛选界面 --> |
||||
|
<searchPrimary |
||||
|
v-if="primarySearchOption && primarySearchOption.length > 0" |
||||
|
ref="searchPrimaryRef" |
||||
|
:showBaseButton="!isShowMoreList" |
||||
|
:primarySearchOption="primarySearchOption" |
||||
|
:primarySearchButton="isShowMoreList ? primarySearchButton : primarySearchAllButton" |
||||
|
@primarySearchButtonClick="primarySearchButtonClick" |
||||
|
@primarySearchBaseHandle="primarySearchBaseHandle" |
||||
|
> |
||||
|
<slot></slot> |
||||
|
</searchPrimary> |
||||
|
<!-- 高级筛选界面 --> |
||||
|
<div v-if="isShow && isShowMoreList" class="moreListOuter"> |
||||
|
<curren-Form |
||||
|
class="navFilter" |
||||
|
size="medium" |
||||
|
labelWidth="0" |
||||
|
:searchData="moreListData" |
||||
|
> |
||||
|
<el-row :gutter="20"> |
||||
|
<el-form-item |
||||
|
v-for="(item, index) in moreListData.filters" |
||||
|
:key="index" |
||||
|
> |
||||
|
<el-col :span="5"> |
||||
|
<el-form-item |
||||
|
:prop="'filters.' + index + '.column'" |
||||
|
:rules="rules && rules.column ? rules.column : []" |
||||
|
> |
||||
|
<el-select |
||||
|
v-model="item.column" |
||||
|
placeholder="请选择筛选对象" |
||||
|
:disabled="item.hide" |
||||
|
:filterable="true" |
||||
|
@change="resetSelect(item)" |
||||
|
> |
||||
|
<el-option |
||||
|
v-for="(item, index) in tableColumnsOptions(tableColumns)" |
||||
|
:key="index" |
||||
|
:label="item.label" |
||||
|
:value=" |
||||
|
item.showProp |
||||
|
? item.prop + '.' + item.showProp |
||||
|
: item.prop |
||||
|
" |
||||
|
> |
||||
|
</el-option> |
||||
|
</el-select> |
||||
|
</el-form-item> |
||||
|
</el-col> |
||||
|
<el-col :span="5"> |
||||
|
<el-form-item |
||||
|
:prop="'filters.' + index + '.action'" |
||||
|
> |
||||
|
<el-select |
||||
|
v-model="item.action" |
||||
|
placeholder="请选择条件" |
||||
|
:disabled="disabledAction || item.column == '' || item.hide ? true : false" |
||||
|
> |
||||
|
<!-- moreListOptions.action --> |
||||
|
<el-option |
||||
|
v-for="item in formatMoreListOptions(item.column) " |
||||
|
:key="item.value" |
||||
|
:label="item.label" |
||||
|
:value="item.value" |
||||
|
> |
||||
|
</el-option> |
||||
|
</el-select> |
||||
|
</el-form-item> |
||||
|
</el-col> |
||||
|
<el-col :span="7"> |
||||
|
<el-form-item |
||||
|
:prop="'filters.' + index + '.value'" |
||||
|
:rules="rules && rules.value ? rules.value : []" |
||||
|
> |
||||
|
<el-select |
||||
|
v-if="Object.keys(inputOrSelect(item.column)).length > 0" |
||||
|
v-model="item.value" |
||||
|
placeholder="请选择内容" |
||||
|
:disabled="item.column == '' || item.hide ? true : false" |
||||
|
:filterable="true" |
||||
|
@change="inputOrSelect(item.column)" |
||||
|
clearable |
||||
|
> |
||||
|
<el-option |
||||
|
v-for="item in $staticOptions[ |
||||
|
inputOrSelect(item.column).filters |
||||
|
]()" |
||||
|
:key="item.value" |
||||
|
:label="item.label" |
||||
|
:value=" |
||||
|
typeof item.value == 'string' |
||||
|
? item.value |
||||
|
: String(item.value) |
||||
|
" |
||||
|
> |
||||
|
</el-option> |
||||
|
</el-select> |
||||
|
<!-- 日期时间 --> |
||||
|
<el-date-picker |
||||
|
v-else-if="getColumnType(item.column) == 'dateTime'" |
||||
|
type="datetime" |
||||
|
v-model="item.value" |
||||
|
:placeholder="'选择日期时间'" |
||||
|
style="width: 100%" |
||||
|
format="yyyy-MM-dd HH:mm:ss" |
||||
|
value-format="yyyy-MM-ddTHH:mm:ss" |
||||
|
></el-date-picker> |
||||
|
<el-input |
||||
|
v-else |
||||
|
v-model="item.value" |
||||
|
placeholder="请输入内容" |
||||
|
:disabled="item.column == '' || item.hide ? true : false" |
||||
|
clearable |
||||
|
></el-input> |
||||
|
</el-form-item> |
||||
|
</el-col> |
||||
|
<el-col :span="5"> |
||||
|
<el-form-item |
||||
|
:prop="'filters.' + index + '.logic'" |
||||
|
> |
||||
|
<el-select |
||||
|
v-model="item.logic" |
||||
|
placeholder="请选择关系" |
||||
|
:disabled="disabledLogic || item.column == '' || item.hide ? true : false" |
||||
|
> |
||||
|
<el-option |
||||
|
v-for="item in moreListOptions.logic" |
||||
|
:key="item.value" |
||||
|
:label="item.label" |
||||
|
:value="item.value" |
||||
|
> |
||||
|
</el-option> |
||||
|
</el-select> |
||||
|
</el-form-item> |
||||
|
</el-col> |
||||
|
<el-col :span="1" v-if="!item.hide"> |
||||
|
<!-- 删除条件按钮 --> |
||||
|
<el-button |
||||
|
type="danger" |
||||
|
icon="el-icon-minus" |
||||
|
circle |
||||
|
size="mini" |
||||
|
@click="moreListDelete(index,item)" |
||||
|
></el-button> |
||||
|
</el-col> |
||||
|
</el-form-item> |
||||
|
</el-row> |
||||
|
</curren-Form> |
||||
|
<!-- 添加筛选条件 --> |
||||
|
<div class="moreListPush-btn"> |
||||
|
<span @click="moreListPush">+ 添加筛选条件</span> |
||||
|
</div> |
||||
|
<!-- 按钮 --> |
||||
|
<div class="moreListBaseBts" v-if="moreListbuttons && moreListbuttons.length > 0" > |
||||
|
<el-button |
||||
|
v-for="(item,index) in moreListbuttons" |
||||
|
:key="index" |
||||
|
:type="item.type" |
||||
|
:size="item.size || 'medium'" |
||||
|
@click="moreListButtonHandle(item)" |
||||
|
:icon="item.iconRight ? '' : item.icon" |
||||
|
> |
||||
|
{{ item.label }} |
||||
|
<!-- 自定义右侧图标 --> |
||||
|
<i |
||||
|
style="margin-left:0" |
||||
|
v-if="item.iconRight" |
||||
|
:class="['el-icon--right',item.icon]" |
||||
|
></i> |
||||
|
</el-button> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</template> |
||||
|
<script> |
||||
|
import searchPrimary from "@/components/searchPrimary" |
||||
|
export default { |
||||
|
name:'searchOverallComponent', |
||||
|
components: { |
||||
|
searchPrimary, |
||||
|
}, |
||||
|
watch:{ |
||||
|
// 监听显示切换 |
||||
|
showSearchOverall(n){ |
||||
|
// 控制是否显示 + 动画效果处理 |
||||
|
// 没有普通查询配置 |
||||
|
if(this.primarySearchOption.length <= 0){ |
||||
|
this.changeSearchOverallShow(n) |
||||
|
this.changeMoreListShow(n) |
||||
|
return |
||||
|
} |
||||
|
// 有普通查询配置 |
||||
|
if(n){ |
||||
|
this.changeSearchOverallShow(n) |
||||
|
this.changeMoreListShow(false) |
||||
|
} |
||||
|
this.$nextTick(()=>{ |
||||
|
if(n){ |
||||
|
this.componentsHeight = this.getSearchPrimaryHeight() + 20 |
||||
|
}else{ |
||||
|
this.componentsHeight = 0 |
||||
|
this.changeMoreListShow(false) |
||||
|
// setTimeout(()=>{ |
||||
|
// this.changeSearchOverallShow(n) |
||||
|
// },500) |
||||
|
} |
||||
|
}) |
||||
|
this.setOverallSearchData(this.httpOverallSearchData) |
||||
|
}, |
||||
|
// 监听接口搜索的筛选数据 |
||||
|
httpOverallSearchData(n,o){ |
||||
|
this.setOverallSearchData(n) |
||||
|
}, |
||||
|
isShowMoreList(){ |
||||
|
this.setOverallSearchData(this.httpOverallSearchData) |
||||
|
} |
||||
|
}, |
||||
|
props: { |
||||
|
// 筛选遮罩高度 |
||||
|
searchOverallCoverHeight:{ |
||||
|
type: String, |
||||
|
default: 'calc(100vh - 200px)' |
||||
|
}, |
||||
|
// 禁用选择条件 |
||||
|
disabledAction:{ |
||||
|
type: Boolean, |
||||
|
default: false |
||||
|
}, |
||||
|
// 禁用选择关系 |
||||
|
disabledLogic:{ |
||||
|
type: Boolean, |
||||
|
default: false |
||||
|
}, |
||||
|
// 是否显示全面筛选组件 |
||||
|
showSearchOverall:{ |
||||
|
type: Boolean, |
||||
|
default: false |
||||
|
}, |
||||
|
// 是否显示高级筛选 |
||||
|
showMoreSearch:{ |
||||
|
type: Boolean, |
||||
|
default: true |
||||
|
}, |
||||
|
//普通筛选绑定表单数据 |
||||
|
primarySearchOption: { |
||||
|
type: Array, |
||||
|
default: () => { |
||||
|
return [] |
||||
|
} |
||||
|
}, |
||||
|
//普通筛选自定义按钮 |
||||
|
primarySearchButton:{ |
||||
|
type: Array, |
||||
|
default: () => { |
||||
|
return [] |
||||
|
} |
||||
|
}, |
||||
|
// 显示数据配置 |
||||
|
tableColumns: { |
||||
|
type: Array, |
||||
|
default: () => { |
||||
|
return [] |
||||
|
} |
||||
|
}, |
||||
|
// 当前接口中的筛选数据(用于同步全面筛选的数据) |
||||
|
httpOverallSearchData:{ |
||||
|
type: Object, |
||||
|
default: null |
||||
|
}, |
||||
|
// 自定义配置条件 |
||||
|
filterActionOptions:{ |
||||
|
type: Array, |
||||
|
default: null |
||||
|
}, |
||||
|
}, |
||||
|
data() { |
||||
|
return { |
||||
|
// 普通筛选自定义所有按钮(包括高级筛选) |
||||
|
primarySearchAllButton:[], |
||||
|
// 高级筛选列表是否显示 |
||||
|
isShowMoreList:false, |
||||
|
// 组件高度(用于动画效果) |
||||
|
componentsHeight:0, |
||||
|
// 是否显示总组件,与showSearchOverall相通(重新定义一遍目的是为了动画效果) |
||||
|
isShow:false, |
||||
|
// 高级筛选列表内部按钮 |
||||
|
moreListbuttons: [ |
||||
|
{ label: "搜索", type: "primary", name: "moreList-search" }, |
||||
|
{ label: '重置', name: 'moreList-reset' }, |
||||
|
{ label:'收起筛选', name:'moreList-up', type: 'text', icon:'el-icon-arrow-up', iconRight:true} |
||||
|
], |
||||
|
// 高级筛选数据列表/值 |
||||
|
moreListData: {filters:[]}, |
||||
|
// 高级筛选条件列表配置 |
||||
|
moreListOptions: { |
||||
|
action: [{ |
||||
|
value: '==', |
||||
|
label: '等于' |
||||
|
}, { |
||||
|
value: '!=', |
||||
|
label: '不等于' |
||||
|
}, { |
||||
|
value: '>', |
||||
|
label: '大于' |
||||
|
}, { |
||||
|
value: '<', |
||||
|
label: '小于' |
||||
|
}, { |
||||
|
value: '>=', |
||||
|
label: '大于等于' |
||||
|
}, { |
||||
|
value: '<=', |
||||
|
label: '小于等于' |
||||
|
}, { |
||||
|
value: 'Like', |
||||
|
label: '包含' |
||||
|
}, { |
||||
|
value: 'NotLike', |
||||
|
label: '不包含' |
||||
|
}, |
||||
|
// { |
||||
|
// value: 'In', |
||||
|
// label: '包含' |
||||
|
// }, { |
||||
|
// value: 'NotIn', |
||||
|
// label: '不包含' |
||||
|
// } |
||||
|
], |
||||
|
logic: [ |
||||
|
{ |
||||
|
value: 'And', |
||||
|
label: '并且' |
||||
|
}, |
||||
|
{ |
||||
|
value: 'Or', |
||||
|
label: '或者' |
||||
|
} |
||||
|
], |
||||
|
}, |
||||
|
// 高级筛选rules暂未使用验证,但是不能删除rules定义 |
||||
|
// todo:优化后放开,优化内容:如果选择了筛选对象【column】,则验证【value】,否则都不验证 |
||||
|
rules:{ |
||||
|
// column: [ |
||||
|
// { required: true, message: '请选择筛选对象', trigger: 'change' } |
||||
|
// ], |
||||
|
// value: [ |
||||
|
// { required: true, message: '请输入内容', trigger: 'blur' } |
||||
|
// ], |
||||
|
}, |
||||
|
} |
||||
|
}, |
||||
|
created() { |
||||
|
this.moreListPush() |
||||
|
}, |
||||
|
mounted() { |
||||
|
// 配置普通筛选默认按钮(是否包含高级筛选按钮) |
||||
|
this.setPrimarySearchAllButton() |
||||
|
}, |
||||
|
methods: { |
||||
|
// 获取普通筛选的高度,外部也有使用,用于动画样式 |
||||
|
getSearchPrimaryHeight(){ |
||||
|
return document.getElementsByClassName('searchPrimaryComponent')[0].clientHeight |
||||
|
}, |
||||
|
// 配置普通筛选自定义按钮 |
||||
|
setPrimarySearchAllButton(){ |
||||
|
let _more_btn = [{ |
||||
|
label:'高级筛选', |
||||
|
name:'more', |
||||
|
type: 'text', |
||||
|
icon:'el-icon-arrow-down', |
||||
|
iconRight:true |
||||
|
}] |
||||
|
if(this.showMoreSearch){ |
||||
|
this.primarySearchAllButton = _more_btn.concat(this.primarySearchButton) |
||||
|
}else{ |
||||
|
this.primarySearchAllButton= this.primarySearchButton |
||||
|
} |
||||
|
}, |
||||
|
// 普通查询基础按钮点击事件 |
||||
|
primarySearchBaseHandle(item,data, option, that){ |
||||
|
this.overallSearchFormClick(item,data, option, that) |
||||
|
}, |
||||
|
// 普通筛选自定义按钮点击事件 |
||||
|
primarySearchButtonClick( item,data, option,that){ |
||||
|
// 点击[高级筛选]按钮 |
||||
|
if(item.name == 'more'){ |
||||
|
this.changeMoreListShow(true) |
||||
|
} |
||||
|
this.overallSearchFormClick(item,data, option, that) |
||||
|
}, |
||||
|
// 高级筛选基础按钮点击事件 |
||||
|
moreListButtonHandle(item){ |
||||
|
this.overallSearchFormClick(item) |
||||
|
}, |
||||
|
// 设置moreList的列表值(默认按tableColumns设置) |
||||
|
tableColumnsOptions(val) { |
||||
|
const data = JSON.parse(JSON.stringify(val)); |
||||
|
let num = 0 |
||||
|
val.forEach((item, index) => { |
||||
|
if (item.showProp) { |
||||
|
data.splice(index - num, 1) |
||||
|
num++ |
||||
|
} |
||||
|
}) |
||||
|
return data |
||||
|
}, |
||||
|
// 判断筛选类型是否是时间格式 |
||||
|
getColumnType(val) { |
||||
|
var columnsType = this.tableColumns.filter(item => item.prop == val) |
||||
|
if (columnsType.length > 0) { |
||||
|
if (columnsType[0].type) { |
||||
|
return columnsType[0].type |
||||
|
} |
||||
|
} else { |
||||
|
return '' |
||||
|
} |
||||
|
}, |
||||
|
// 筛选条件改变重置其他项 |
||||
|
resetSelect(val) { |
||||
|
val.action = "==" |
||||
|
val.value = "" |
||||
|
}, |
||||
|
// 根据数据内容约束条件选项 |
||||
|
formatMoreListOptions(val) { |
||||
|
// 自定义配置条件filterActionOptions |
||||
|
if(this.filterActionOptions){ |
||||
|
this.moreListOptions.action = this.filterActionOptions |
||||
|
return this.moreListOptions.action |
||||
|
} |
||||
|
if (val) { |
||||
|
for(var i =0; i< this.tableColumns.length; i++) { |
||||
|
if (val == this.tableColumns[i].prop) { |
||||
|
if (this.tableColumns[i].filters) { |
||||
|
return this.moreListOptions.action.filter(item => item.value == '==' || item.value == '!=') |
||||
|
} else if (this.tableColumns[i].type == 'dateTime') { |
||||
|
return this.moreListOptions.action.filter(item => |
||||
|
item.value == '==' || |
||||
|
item.value == '!=' || |
||||
|
item.value == '>' || |
||||
|
item.value == '<' || |
||||
|
item.value == '>=' || |
||||
|
item.value == '<=' ) |
||||
|
} else { |
||||
|
return this.moreListOptions.action |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
return this.moreListOptions.action |
||||
|
}, |
||||
|
// 设置moreList列表的内容项是input还是select |
||||
|
inputOrSelect(val) { |
||||
|
let data |
||||
|
if (val) { |
||||
|
this.tableColumns.forEach((key) => { |
||||
|
if (val == key.prop) { |
||||
|
if (key.filters) { |
||||
|
data = key |
||||
|
} else { |
||||
|
data = {} |
||||
|
} |
||||
|
} |
||||
|
}) |
||||
|
} else { |
||||
|
data = {} |
||||
|
} |
||||
|
return data |
||||
|
}, |
||||
|
// 高级筛选列表-删除筛选条件行 |
||||
|
moreListDelete(val,item) { |
||||
|
if (this.moreListData.filters.length == 1) { |
||||
|
this.$warningMsg('必须保留一条筛选条件!') |
||||
|
} else { |
||||
|
this.$confirm('您确定删除吗, 是否继续?', '提示', { |
||||
|
confirmButtonText: '确定', |
||||
|
cancelButtonText: '取消', |
||||
|
type: 'warning' |
||||
|
}).then(() => { |
||||
|
this.moreListData.filters.splice(val, 1) |
||||
|
}).catch(() => { |
||||
|
// this.modalAppendToBody = false |
||||
|
}); |
||||
|
} |
||||
|
this.overallSearchFormClick({name:'moreList-deleteRow'}) |
||||
|
}, |
||||
|
// 高级筛选列表-添加筛选条件行 |
||||
|
moreListPush() { |
||||
|
let data = { |
||||
|
logic: "And", |
||||
|
column: "", |
||||
|
action: "==", |
||||
|
value: "" |
||||
|
} |
||||
|
this.moreListData.filters.push(data) |
||||
|
this.overallSearchFormClick({name:'moreList-addRow'}) |
||||
|
}, |
||||
|
// 重置数据,高级(单纯节点显示数据,不重新查询接口) |
||||
|
resetMoreListData(){ |
||||
|
this.moreListData = {filters:[]} |
||||
|
this.moreListPush() |
||||
|
}, |
||||
|
// 设置数据值,高级(单纯节点显示数据,不重新查询接口) |
||||
|
setMoreListData(val){ |
||||
|
this.moreListData = JSON.parse(JSON.stringify(val)) |
||||
|
}, |
||||
|
// 重置数据,普通+高级(单纯节点显示数据,不重新查询接口) |
||||
|
resetOverallSearchData(){ |
||||
|
if(this.$refs.searchPrimaryRef)this.$refs.searchPrimaryRef.resetPrimarySearchData(); |
||||
|
this.resetMoreListData() |
||||
|
}, |
||||
|
// 设置数据,普通+高级(单纯节点显示数据,不重新查询接口) |
||||
|
setOverallSearchData(data){ |
||||
|
// 普通筛选数据同步 |
||||
|
if(data && data.params){ |
||||
|
if(this.$refs.searchPrimaryRef)this.$refs.searchPrimaryRef.setPrimarySearchData(data.params) |
||||
|
}else{ |
||||
|
if(this.$refs.searchPrimaryRef)this.$refs.searchPrimaryRef.resetPrimarySearchData() |
||||
|
} |
||||
|
// 高级筛选数据同步 |
||||
|
if(data && data.moreList){ |
||||
|
let _list = {filters:[]} |
||||
|
data.moreList.filters.forEach(item=>{ |
||||
|
if(String(item.column).length > 0 && String(item.value).length > 0){ |
||||
|
_list.filters.push(item) |
||||
|
} |
||||
|
}) |
||||
|
if(_list.filters.length <= 0){ |
||||
|
_list.filters.push({ |
||||
|
logic: "And", |
||||
|
column: "", |
||||
|
action: "==", |
||||
|
value: "" |
||||
|
}) |
||||
|
} |
||||
|
this.setMoreListData(_list) |
||||
|
}else{ |
||||
|
this.resetMoreListData() |
||||
|
} |
||||
|
}, |
||||
|
// 展开-收缩高级筛选 |
||||
|
changeMoreListShow(val){ |
||||
|
this.isShowMoreList = val || false |
||||
|
// 如果没有初级筛选 |
||||
|
if(!this.primarySearchOption || this.primarySearchOption.length <= 0){ |
||||
|
// 关闭时候直接整个全面筛选组件 |
||||
|
if(!this.isShowMoreList){ |
||||
|
this.isShow = false |
||||
|
this.$emit("getShowSearchOverall",this.isShow) |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
// 关闭整个全面组件 |
||||
|
changeSearchOverallShow(val){ |
||||
|
if(!val){ |
||||
|
this.changeMoreListShow(false) |
||||
|
} |
||||
|
this.isShow = val || false |
||||
|
this.$emit("getShowSearchOverall",this.isShow) |
||||
|
}, |
||||
|
// 全面筛选组件所有按钮事件 |
||||
|
overallSearchFormClick(item,data, option) { |
||||
|
// 页面功能 |
||||
|
// 收缩筛选 |
||||
|
if(item.name == 'moreList-up'){ |
||||
|
this.changeMoreListShow(false) |
||||
|
} |
||||
|
// 高级筛选内-重置 || 普通格式-重置 |
||||
|
else if(item.name == "moreList-reset" || item.name == "reset"){ |
||||
|
this.resetOverallSearchData() |
||||
|
} |
||||
|
// 抛出函数传参 |
||||
|
let _searchPrimaryRef = this.$refs.searchPrimaryRef |
||||
|
let _options = { |
||||
|
item:item, |
||||
|
data_primary:_searchPrimaryRef ? _searchPrimaryRef.getPrimarySearchData() : null, |
||||
|
data_moreList:this.moreListData, |
||||
|
option_primary:this.primarySearchOption, |
||||
|
option_moreList:this.tableColumns, |
||||
|
vm_primary:_searchPrimaryRef, |
||||
|
vm_moreList:this |
||||
|
} |
||||
|
this.$emit("overallSearchFormClick",_options) |
||||
|
}, |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
</script> |
||||
|
<style lang="scss" scoped> |
||||
|
@import "./style/index.scss"; |
||||
|
</style> |
@ -0,0 +1,647 @@ |
|||||
|
<template> |
||||
|
<!-- 全面的筛选组件:初级普通筛选 + 高级筛选(按照配置来判断显示情况)--> |
||||
|
<!-- todo:使用v-if每次重新赋值,与接口查询保持一致 --> |
||||
|
<div |
||||
|
class="searchOverallComponent" |
||||
|
:style="{height:componentsHeight+'px',overflow:isShowMoreList ? 'unset' : 'hidden'}" |
||||
|
v-show="isShow" |
||||
|
> |
||||
|
<div |
||||
|
class="border-outer" |
||||
|
ref="searchOverallComponent_inner" |
||||
|
> |
||||
|
<!-- 整体背景遮罩 --> |
||||
|
<!-- <div |
||||
|
v-if="isShow && isShowMoreList" |
||||
|
class="fullPageCover" |
||||
|
:style="{height:searchOverallCoverHeight}" |
||||
|
></div> --> |
||||
|
<!-- <div class="title" v-if="isShowMoreList">高级筛选</div> --> |
||||
|
<!-- 普通筛选界面 --> |
||||
|
<searchPrimary |
||||
|
v-if="primarySearchOption && primarySearchOption.length > 0" |
||||
|
ref="searchPrimaryRef" |
||||
|
:showBaseButton="!isShowMoreList" |
||||
|
:primarySearchOption="primarySearchOption" |
||||
|
:primarySearchButton="isShowMoreList ? primarySearchButton : primarySearchAllButton" |
||||
|
@primarySearchButtonClick="primarySearchButtonClick" |
||||
|
@primarySearchBaseHandle="primarySearchBaseHandle" |
||||
|
> |
||||
|
<slot></slot> |
||||
|
</searchPrimary> |
||||
|
<!-- 高级筛选界面 --> |
||||
|
<div v-if="isShow && isShowMoreList" class="moreListOuter"> |
||||
|
<curren-Form |
||||
|
:style="`--navFilterMaxHeight: ${selectMaxHeight};`" |
||||
|
class="navFilter" |
||||
|
size="medium" |
||||
|
labelWidth="0" |
||||
|
:searchData="moreListData" |
||||
|
> |
||||
|
<el-row :gutter="20"> |
||||
|
<el-form-item |
||||
|
v-for="(item, index) in moreListData.filters" |
||||
|
:key="index" |
||||
|
> |
||||
|
<el-col :span="5"> |
||||
|
<el-form-item |
||||
|
:prop="'filters.' + index + '.column'" |
||||
|
:rules="rules && rules.column ? rules.column : []" |
||||
|
> |
||||
|
<el-select |
||||
|
v-model="item.column" |
||||
|
placeholder="请选择筛选对象" |
||||
|
:disabled="item.hide" |
||||
|
:filterable="true" |
||||
|
@change="resetSelect(item)" |
||||
|
> |
||||
|
<el-option |
||||
|
v-for="(item, index) in tableColumnsOptions(tableColumns)" |
||||
|
:key="index" |
||||
|
:label="item.label" |
||||
|
:value=" |
||||
|
item.showProp |
||||
|
? item.prop + '.' + item.showProp |
||||
|
: item.prop |
||||
|
" |
||||
|
> |
||||
|
</el-option> |
||||
|
</el-select> |
||||
|
</el-form-item> |
||||
|
</el-col> |
||||
|
<el-col :span="5"> |
||||
|
<el-form-item |
||||
|
:prop="'filters.' + index + '.action'" |
||||
|
> |
||||
|
<el-select |
||||
|
v-model="item.action" |
||||
|
placeholder="请选择条件" |
||||
|
:disabled="disabledAction || item.column == '' || item.hide ? true : false" |
||||
|
> |
||||
|
<!-- moreListOptions.action --> |
||||
|
<el-option |
||||
|
v-for="item in formatMoreListOptions(item.column) " |
||||
|
:key="item.value" |
||||
|
:label="item.label" |
||||
|
:value="item.value" |
||||
|
> |
||||
|
</el-option> |
||||
|
</el-select> |
||||
|
</el-form-item> |
||||
|
</el-col> |
||||
|
<el-col :span="7"> |
||||
|
<el-form-item |
||||
|
:prop="'filters.' + index + '.value'" |
||||
|
:rules="rules && rules.value ? rules.value : []" |
||||
|
> |
||||
|
<el-select |
||||
|
v-if="inputOrSelect(item.column)" |
||||
|
v-model="item.value" |
||||
|
placeholder="请选择内容" |
||||
|
:disabled="item.column == '' || item.hide ? true : false" |
||||
|
:filterable="true" |
||||
|
@change="inputOrSelect(item.column)" |
||||
|
clearable |
||||
|
> |
||||
|
<el-option |
||||
|
v-for="item in inputOrSelect(item.column)" |
||||
|
:key="item.value" |
||||
|
:label="item.label" |
||||
|
:value=" |
||||
|
typeof item.value == 'string' |
||||
|
? item.value |
||||
|
: String(item.value) |
||||
|
" |
||||
|
> |
||||
|
</el-option> |
||||
|
</el-select> |
||||
|
<!-- 日期时间 --> |
||||
|
<el-date-picker |
||||
|
v-else-if="getColumnType(item.column) == 'datetime'" |
||||
|
type="datetime" |
||||
|
v-model="item.value" |
||||
|
:placeholder="'选择日期时间'" |
||||
|
style="width: 100%" |
||||
|
format="yyyy-MM-dd HH:mm:ss" |
||||
|
value-format="yyyy-MM-ddTHH:mm:ss" |
||||
|
></el-date-picker> |
||||
|
<el-input |
||||
|
v-else |
||||
|
v-model="item.value" |
||||
|
placeholder="请输入内容" |
||||
|
:disabled="item.column == '' || item.hide ? true : false" |
||||
|
clearable |
||||
|
></el-input> |
||||
|
</el-form-item> |
||||
|
</el-col> |
||||
|
<el-col :span="5"> |
||||
|
<el-form-item |
||||
|
:prop="'filters.' + index + '.logic'" |
||||
|
> |
||||
|
<el-select |
||||
|
v-model="item.logic" |
||||
|
placeholder="请选择关系" |
||||
|
:disabled="disabledLogic || item.column == '' || item.hide ? true : false" |
||||
|
> |
||||
|
<el-option |
||||
|
v-for="item in moreListOptions.logic" |
||||
|
:key="item.value" |
||||
|
:label="item.label" |
||||
|
:value="item.value" |
||||
|
> |
||||
|
</el-option> |
||||
|
</el-select> |
||||
|
</el-form-item> |
||||
|
</el-col> |
||||
|
<el-col :span="1" v-if="!item.hide"> |
||||
|
<!-- 删除条件按钮 --> |
||||
|
<el-button |
||||
|
type="danger" |
||||
|
icon="el-icon-minus" |
||||
|
circle |
||||
|
size="mini" |
||||
|
@click="moreListDelete(index,item)" |
||||
|
></el-button> |
||||
|
</el-col> |
||||
|
</el-form-item> |
||||
|
</el-row> |
||||
|
</curren-Form> |
||||
|
<div class="buttonsContent"> |
||||
|
<div class="leftButtons"> |
||||
|
<!-- 添加筛选条件 --> |
||||
|
<el-button size="small" @click="moreListPush(true)">+ 添加筛选条件</el-button> |
||||
|
<!-- 收起 --> |
||||
|
<el-button |
||||
|
type="text" |
||||
|
size="small" |
||||
|
@click="moreListButtonHandle({ label:'收起筛选', name:'moreList-up', type: 'text', icon:'el-icon-arrow-up', iconRight:true})" |
||||
|
> |
||||
|
收起筛选 |
||||
|
<i |
||||
|
style="margin-left:0" |
||||
|
:class="['el-icon--right','el-icon-arrow-up']" |
||||
|
></i> |
||||
|
</el-button> |
||||
|
</div> |
||||
|
<!-- 按钮 --> |
||||
|
<div class="rightButtons" v-if="moreListbuttons && moreListbuttons.length > 0" > |
||||
|
<el-button |
||||
|
v-for="(item,index) in moreListbuttons" |
||||
|
:key="index" |
||||
|
:type="item.type" |
||||
|
:size="item.size || 'small'" |
||||
|
@click="moreListButtonHandle(item)" |
||||
|
:icon="item.iconRight ? '' : item.icon" |
||||
|
> |
||||
|
{{ item.label }} |
||||
|
<!-- 自定义右侧图标 --> |
||||
|
<i |
||||
|
style="margin-left:0" |
||||
|
v-if="item.iconRight" |
||||
|
:class="['el-icon--right',item.icon]" |
||||
|
></i> |
||||
|
</el-button> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</template> |
||||
|
<script> |
||||
|
import searchPrimary from "@/components/searchPrimary" |
||||
|
export default { |
||||
|
name:'searchOverallComponent', |
||||
|
components: { |
||||
|
searchPrimary, |
||||
|
}, |
||||
|
watch:{ |
||||
|
// 监听显示切换 |
||||
|
showSearchOverall(n){ |
||||
|
// 控制是否显示 + 动画效果处理 |
||||
|
// 没有普通查询配置 |
||||
|
if(this.primarySearchOption.length <= 0){ |
||||
|
this.changeSearchOverallShow(n) |
||||
|
this.changeMoreListShow(n) |
||||
|
this.$nextTick(()=>{ |
||||
|
this.componentsHeight = this.getAllSearchInnerHeight() + 20 |
||||
|
// 收起 |
||||
|
if(!n && this.$parent.changeTableHeight){ |
||||
|
this.$parent.changeTableHeight() |
||||
|
} |
||||
|
}) |
||||
|
return |
||||
|
} |
||||
|
// 有普通查询配置 |
||||
|
if(n){ |
||||
|
this.changeSearchOverallShow(n) |
||||
|
this.changeMoreListShow(false) |
||||
|
} |
||||
|
this.$nextTick(()=>{ |
||||
|
if(n){ |
||||
|
this.componentsHeight = this.getSearchPrimaryHeight() + 20 |
||||
|
}else{ |
||||
|
this.componentsHeight = 0 |
||||
|
this.changeMoreListShow(false) |
||||
|
// setTimeout(()=>{ |
||||
|
// this.changeSearchOverallShow(n) |
||||
|
// },500) |
||||
|
} |
||||
|
}) |
||||
|
this.setOverallSearchData(this.httpOverallSearchData) |
||||
|
}, |
||||
|
// 监听接口搜索的筛选数据 |
||||
|
httpOverallSearchData(n,o){ |
||||
|
this.setOverallSearchData(n) |
||||
|
}, |
||||
|
isShowMoreList(){ |
||||
|
this.setOverallSearchData(this.httpOverallSearchData) |
||||
|
} |
||||
|
}, |
||||
|
props: { |
||||
|
// 筛选条件最大高度 |
||||
|
selectMaxHeight:{ |
||||
|
type: String, |
||||
|
default: '174px' |
||||
|
}, |
||||
|
// 筛选遮罩高度 |
||||
|
searchOverallCoverHeight:{ |
||||
|
type: String, |
||||
|
default: 'calc(100vh - 200px)' |
||||
|
}, |
||||
|
// 禁用选择条件 |
||||
|
disabledAction:{ |
||||
|
type: Boolean, |
||||
|
default: false |
||||
|
}, |
||||
|
// 禁用选择关系 |
||||
|
disabledLogic:{ |
||||
|
type: Boolean, |
||||
|
default: false |
||||
|
}, |
||||
|
// 是否显示全面筛选组件 |
||||
|
showSearchOverall:{ |
||||
|
type: Boolean, |
||||
|
default: false |
||||
|
}, |
||||
|
// 是否显示高级筛选 |
||||
|
showMoreSearch:{ |
||||
|
type: Boolean, |
||||
|
default: true |
||||
|
}, |
||||
|
//普通筛选绑定表单数据 |
||||
|
primarySearchOption: { |
||||
|
type: Array, |
||||
|
default: () => { |
||||
|
return [] |
||||
|
} |
||||
|
}, |
||||
|
//普通筛选自定义按钮 |
||||
|
primarySearchButton:{ |
||||
|
type: Array, |
||||
|
default: () => { |
||||
|
return [] |
||||
|
} |
||||
|
}, |
||||
|
// 显示数据配置 |
||||
|
tableColumns: { |
||||
|
type: Array, |
||||
|
default: () => { |
||||
|
return [] |
||||
|
} |
||||
|
}, |
||||
|
// 当前接口中的筛选数据(用于同步全面筛选的数据) |
||||
|
httpOverallSearchData:{ |
||||
|
type: Object, |
||||
|
default: null |
||||
|
}, |
||||
|
// 自定义配置条件 |
||||
|
filterActionOptions:{ |
||||
|
type: Array, |
||||
|
default: null |
||||
|
}, |
||||
|
}, |
||||
|
data() { |
||||
|
return { |
||||
|
// 普通筛选自定义所有按钮(包括高级筛选) |
||||
|
primarySearchAllButton:[], |
||||
|
// 高级筛选列表是否显示 |
||||
|
isShowMoreList:false, |
||||
|
// 组件高度(用于动画效果) |
||||
|
componentsHeight:0, |
||||
|
// 是否显示总组件,与showSearchOverall相通(重新定义一遍目的是为了动画效果) |
||||
|
isShow:false, |
||||
|
// 高级筛选列表内部按钮 |
||||
|
moreListbuttons: [ |
||||
|
{ label: "搜索", type: "primary", name: "moreList-search" }, |
||||
|
{ label: '重置', name: 'moreList-reset' }, |
||||
|
// { label:'收起筛选', name:'moreList-up', type: 'text', icon:'el-icon-arrow-up', iconRight:true} |
||||
|
], |
||||
|
// 高级筛选数据列表/值 |
||||
|
moreListData: {filters:[]}, |
||||
|
// 高级筛选条件列表配置 |
||||
|
moreListOptions: { |
||||
|
action: [{ |
||||
|
value: '==', |
||||
|
label: '等于' |
||||
|
}, { |
||||
|
value: '!=', |
||||
|
label: '不等于' |
||||
|
}, { |
||||
|
value: '>', |
||||
|
label: '大于' |
||||
|
}, { |
||||
|
value: '<', |
||||
|
label: '小于' |
||||
|
}, { |
||||
|
value: '>=', |
||||
|
label: '大于等于' |
||||
|
}, { |
||||
|
value: '<=', |
||||
|
label: '小于等于' |
||||
|
}, { |
||||
|
value: 'Like', |
||||
|
label: '包含' |
||||
|
}, { |
||||
|
value: 'NotLike', |
||||
|
label: '不包含' |
||||
|
}, |
||||
|
// { |
||||
|
// value: 'In', |
||||
|
// label: '包含' |
||||
|
// }, { |
||||
|
// value: 'NotIn', |
||||
|
// label: '不包含' |
||||
|
// } |
||||
|
], |
||||
|
logic: [ |
||||
|
{ |
||||
|
value: 'And', |
||||
|
label: '并且' |
||||
|
}, |
||||
|
{ |
||||
|
value: 'Or', |
||||
|
label: '或者' |
||||
|
} |
||||
|
], |
||||
|
}, |
||||
|
// 高级筛选rules暂未使用验证,但是不能删除rules定义 |
||||
|
// todo:优化后放开,优化内容:如果选择了筛选对象【column】,则验证【value】,否则都不验证 |
||||
|
rules:{ |
||||
|
// column: [ |
||||
|
// { required: true, message: '请选择筛选对象', trigger: 'change' } |
||||
|
// ], |
||||
|
// value: [ |
||||
|
// { required: true, message: '请输入内容', trigger: 'blur' } |
||||
|
// ], |
||||
|
}, |
||||
|
} |
||||
|
}, |
||||
|
created() { |
||||
|
this.moreListPush() |
||||
|
}, |
||||
|
mounted() { |
||||
|
// 配置普通筛选默认按钮(是否包含高级筛选按钮) |
||||
|
this.setPrimarySearchAllButton() |
||||
|
}, |
||||
|
methods: { |
||||
|
// 获取普通筛选的高度,外部也有使用,用于动画样式 |
||||
|
getSearchPrimaryHeight(){ |
||||
|
return document.getElementsByClassName('searchPrimaryComponent')[0].clientHeight |
||||
|
}, |
||||
|
// 获取普高级筛选的高度,外部也有使用,用于动画样式 |
||||
|
getAllSearchInnerHeight(){ |
||||
|
return this.$refs.searchOverallComponent_inner ? this.$refs.searchOverallComponent_inner.clientHeight : 0 |
||||
|
}, |
||||
|
// 配置普通筛选自定义按钮 |
||||
|
setPrimarySearchAllButton(){ |
||||
|
let _more_btn = [{ |
||||
|
label:'高级筛选', |
||||
|
name:'more', |
||||
|
type: 'text', |
||||
|
icon:'el-icon-arrow-down', |
||||
|
iconRight:true |
||||
|
}] |
||||
|
if(this.showMoreSearch){ |
||||
|
this.primarySearchAllButton = _more_btn.concat(this.primarySearchButton) |
||||
|
}else{ |
||||
|
this.primarySearchAllButton= this.primarySearchButton |
||||
|
} |
||||
|
}, |
||||
|
// 普通查询基础按钮点击事件 |
||||
|
primarySearchBaseHandle(item,data, option, that){ |
||||
|
this.overallSearchFormClick(item,data, option, that) |
||||
|
}, |
||||
|
// 普通筛选自定义按钮点击事件 |
||||
|
primarySearchButtonClick( item,data, option,that){ |
||||
|
// 点击[高级筛选]按钮 |
||||
|
if(item.name == 'more'){ |
||||
|
this.changeMoreListShow(true) |
||||
|
} |
||||
|
this.overallSearchFormClick(item,data, option, that) |
||||
|
}, |
||||
|
// 高级筛选基础按钮点击事件 |
||||
|
moreListButtonHandle(item){ |
||||
|
this.overallSearchFormClick(item) |
||||
|
}, |
||||
|
// 设置moreList的列表值(默认按tableColumns设置) |
||||
|
tableColumnsOptions(val) { |
||||
|
const data = JSON.parse(JSON.stringify(val)); |
||||
|
let num = 0 |
||||
|
val.forEach((item, index) => { |
||||
|
if (item.showProp) { |
||||
|
data.splice(index - num, 1) |
||||
|
num++ |
||||
|
} |
||||
|
}) |
||||
|
return data |
||||
|
}, |
||||
|
// 判断筛选类型是否是时间格式 |
||||
|
getColumnType(val) { |
||||
|
var columnsType = this.tableColumns.filter(item => item.prop == val) |
||||
|
if (columnsType.length > 0) { |
||||
|
if (columnsType[0].apiBaseType) { |
||||
|
return columnsType[0].apiBaseType |
||||
|
} |
||||
|
} else { |
||||
|
return '' |
||||
|
} |
||||
|
}, |
||||
|
// 筛选条件改变重置其他项 |
||||
|
resetSelect(val) { |
||||
|
val.action = "==" |
||||
|
val.value = "" |
||||
|
}, |
||||
|
// 根据数据内容约束条件选项 |
||||
|
formatMoreListOptions(val) { |
||||
|
// 自定义配置条件filterActionOptions |
||||
|
if(this.filterActionOptions){ |
||||
|
this.moreListOptions.action = this.filterActionOptions |
||||
|
return this.moreListOptions.action |
||||
|
} |
||||
|
if (val) { |
||||
|
for(var i =0; i< this.tableColumns.length; i++) { |
||||
|
if (val == this.tableColumns[i].prop) { |
||||
|
if (this.tableColumns[i].filters) { |
||||
|
return this.moreListOptions.action.filter(item => item.value == '==' || item.value == '!=') |
||||
|
} else if (this.tableColumns[i].type == 'dateTime') { |
||||
|
return this.moreListOptions.action.filter(item => |
||||
|
item.value == '==' || |
||||
|
item.value == '!=' || |
||||
|
item.value == '>' || |
||||
|
item.value == '<' || |
||||
|
item.value == '>=' || |
||||
|
item.value == '<=' ) |
||||
|
} else { |
||||
|
return this.moreListOptions.action |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
return this.moreListOptions.action |
||||
|
}, |
||||
|
// 设置moreList列表的内容项是input还是select |
||||
|
inputOrSelect(val) { |
||||
|
let data = null |
||||
|
if (val) { |
||||
|
this.tableColumns.forEach((key) => { |
||||
|
if (val == key.prop) { |
||||
|
if (key.enums_list && key.enums_list.length > 0) { |
||||
|
data = key.enums_list |
||||
|
} |
||||
|
} |
||||
|
}) |
||||
|
} |
||||
|
return data |
||||
|
}, |
||||
|
// 高级筛选列表-删除筛选条件行 |
||||
|
moreListDelete(val,item) { |
||||
|
if (this.moreListData.filters.length == 1) { |
||||
|
this.$warningMsg('必须保留一条筛选条件!') |
||||
|
} else { |
||||
|
this.$confirm('您确定删除吗, 是否继续?', '提示', { |
||||
|
confirmButtonText: '确定', |
||||
|
cancelButtonText: '取消', |
||||
|
type: 'warning' |
||||
|
}).then(() => { |
||||
|
this.moreListData.filters.splice(val, 1) |
||||
|
this.$nextTick(()=>{ |
||||
|
this.componentsHeight = this.getAllSearchInnerHeight() + 20 |
||||
|
this.$parent.changeTableHeight(this.getAllSearchInnerHeight()) |
||||
|
}) |
||||
|
}).catch(() => { |
||||
|
// this.modalAppendToBody = false |
||||
|
}); |
||||
|
} |
||||
|
this.overallSearchFormClick({name:'moreList-deleteRow'}) |
||||
|
}, |
||||
|
// 高级筛选列表-添加筛选条件行 |
||||
|
moreListPush(handle) { |
||||
|
let data = { |
||||
|
logic: "And", |
||||
|
column: "", |
||||
|
action: "==", |
||||
|
value: "" |
||||
|
} |
||||
|
this.moreListData.filters.push(data) |
||||
|
this.overallSearchFormClick({name:'moreList-addRow'}) |
||||
|
if(handle){ |
||||
|
this.$nextTick(()=>{ |
||||
|
this.componentsHeight = this.getAllSearchInnerHeight() + 20 |
||||
|
this.$parent.changeTableHeight(this.getAllSearchInnerHeight()) |
||||
|
}) |
||||
|
} |
||||
|
}, |
||||
|
// 重置数据,高级(单纯节点显示数据,不重新查询接口) |
||||
|
resetMoreListData(){ |
||||
|
this.moreListData = {filters:[]} |
||||
|
this.moreListPush() |
||||
|
}, |
||||
|
// 设置数据值,高级(单纯节点显示数据,不重新查询接口) |
||||
|
setMoreListData(val){ |
||||
|
this.moreListData = JSON.parse(JSON.stringify(val)) |
||||
|
}, |
||||
|
// 重置数据,普通+高级(单纯节点显示数据,不重新查询接口) |
||||
|
resetOverallSearchData(){ |
||||
|
if(this.$refs.searchPrimaryRef)this.$refs.searchPrimaryRef.resetPrimarySearchData(); |
||||
|
this.resetMoreListData() |
||||
|
}, |
||||
|
// 设置数据,普通+高级(单纯节点显示数据,不重新查询接口) |
||||
|
setOverallSearchData(data){ |
||||
|
// 普通筛选数据同步 |
||||
|
if(data && data.params){ |
||||
|
if(this.$refs.searchPrimaryRef)this.$refs.searchPrimaryRef.setPrimarySearchData(data.params) |
||||
|
}else{ |
||||
|
if(this.$refs.searchPrimaryRef)this.$refs.searchPrimaryRef.resetPrimarySearchData() |
||||
|
} |
||||
|
// 高级筛选数据同步 |
||||
|
if(data && data.moreList){ |
||||
|
let _list = {filters:[]} |
||||
|
data.moreList.filters.forEach(item=>{ |
||||
|
if(String(item.column).length > 0 && String(item.value).length > 0){ |
||||
|
_list.filters.push(item) |
||||
|
} |
||||
|
}) |
||||
|
if(_list.filters.length <= 0){ |
||||
|
_list.filters.push({ |
||||
|
logic: "And", |
||||
|
column: "", |
||||
|
action: "==", |
||||
|
value: "" |
||||
|
}) |
||||
|
} |
||||
|
this.setMoreListData(_list) |
||||
|
}else{ |
||||
|
this.resetMoreListData() |
||||
|
} |
||||
|
}, |
||||
|
// 展开-收缩高级筛选 |
||||
|
changeMoreListShow(val){ |
||||
|
this.isShowMoreList = val || false |
||||
|
// 如果没有初级筛选 |
||||
|
if(!this.primarySearchOption || this.primarySearchOption.length <= 0){ |
||||
|
// 关闭时候直接整个全面筛选组件 |
||||
|
if(!this.isShowMoreList){ |
||||
|
this.isShow = false |
||||
|
this.$emit("getShowSearchOverall",this.isShow) |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
// 关闭整个全面组件 |
||||
|
changeSearchOverallShow(val){ |
||||
|
if(!val){ |
||||
|
this.changeMoreListShow(false) |
||||
|
} |
||||
|
this.isShow = val || false |
||||
|
this.$emit("getShowSearchOverall",this.isShow) |
||||
|
}, |
||||
|
// 全面筛选组件所有按钮事件 |
||||
|
overallSearchFormClick(item,data, option) { |
||||
|
// 页面功能 |
||||
|
// 收缩筛选 |
||||
|
if(item.name == 'moreList-up'){ |
||||
|
this.changeMoreListShow(false) |
||||
|
} |
||||
|
// 高级筛选内-重置 || 普通格式-重置 |
||||
|
else if(item.name == "moreList-reset" || item.name == "reset"){ |
||||
|
this.resetOverallSearchData() |
||||
|
} |
||||
|
// 抛出函数传参 |
||||
|
let _searchPrimaryRef = this.$refs.searchPrimaryRef |
||||
|
let _options = { |
||||
|
item:item, |
||||
|
data_primary:_searchPrimaryRef ? _searchPrimaryRef.getPrimarySearchData() : null, |
||||
|
data_moreList:this.moreListData, |
||||
|
option_primary:this.primarySearchOption, |
||||
|
option_moreList:this.tableColumns, |
||||
|
vm_primary:_searchPrimaryRef, |
||||
|
vm_moreList:this |
||||
|
} |
||||
|
this.$emit("overallSearchFormClick",_options) |
||||
|
}, |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
</script> |
||||
|
<style lang="scss" scoped> |
||||
|
@import "./style/index.scss"; |
||||
|
</style> |
@ -0,0 +1,83 @@ |
|||||
|
.searchOverallComponent{ |
||||
|
height: 0; |
||||
|
transition:all 0.5s; |
||||
|
z-index: 1; |
||||
|
overflow: hidden; |
||||
|
|
||||
|
.border-outer{ |
||||
|
position: relative; |
||||
|
background: #f8f9fb; |
||||
|
padding: 10px 20px 0; |
||||
|
border: #eff0f2 solid 1px; |
||||
|
margin-bottom: 10px; |
||||
|
} |
||||
|
|
||||
|
.fullPageCover{ |
||||
|
position: absolute; |
||||
|
background: rgba(255, 255, 255, 0.2); |
||||
|
left: 0; |
||||
|
right: 0; |
||||
|
// height: calc(100vh - 200px); |
||||
|
cursor: no-drop; |
||||
|
} |
||||
|
|
||||
|
.moreListOuter{ |
||||
|
margin-top: 10px; |
||||
|
position: relative; |
||||
|
} |
||||
|
|
||||
|
::v-deep .navFilter { |
||||
|
// display: flex; |
||||
|
// flex-direction: column; |
||||
|
// width: 100%; |
||||
|
// height: 100%; |
||||
|
max-height: 30vh; |
||||
|
overflow: auto; |
||||
|
|
||||
|
.el-form { |
||||
|
// flex: 1; |
||||
|
// padding-left: 100px; |
||||
|
// padding-right: 100px; |
||||
|
display: flex; |
||||
|
align-content: flex-start; |
||||
|
flex-wrap: wrap; |
||||
|
overflow: hidden; |
||||
|
overflow-y: auto; |
||||
|
|
||||
|
.el-row{ |
||||
|
margin: 0 !important; |
||||
|
margin-left: -5px !important; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
.el-select{ |
||||
|
width: 100%; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.title{ |
||||
|
padding: 10px 0 15px 0; |
||||
|
font-weight: bold; |
||||
|
color: #333; |
||||
|
} |
||||
|
|
||||
|
.moreListPush-btn { |
||||
|
width: 100%; |
||||
|
padding-left: 5px; |
||||
|
color: rgb(64, 158, 255); |
||||
|
|
||||
|
span { |
||||
|
cursor: pointer; |
||||
|
|
||||
|
&:hover { |
||||
|
color: blue; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.moreListBaseBts{ |
||||
|
padding: 20px 0; |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,89 @@ |
|||||
|
.searchOverallComponent{ |
||||
|
height: 0; |
||||
|
transition:all 0.5s; |
||||
|
z-index: 1; |
||||
|
overflow: hidden; |
||||
|
|
||||
|
.border-outer{ |
||||
|
position: relative; |
||||
|
background: #f8f9fb; |
||||
|
padding: 10px 20px 0; |
||||
|
border: #eff0f2 solid 1px; |
||||
|
margin-bottom: 10px; |
||||
|
} |
||||
|
|
||||
|
.fullPageCover{ |
||||
|
position: absolute; |
||||
|
background: rgba(255, 255, 255, 0.2); |
||||
|
left: 0; |
||||
|
right: 0; |
||||
|
// height: calc(100vh - 200px); |
||||
|
cursor: no-drop; |
||||
|
} |
||||
|
|
||||
|
.moreListOuter{ |
||||
|
margin-top: 10px; |
||||
|
position: relative; |
||||
|
} |
||||
|
|
||||
|
::v-deep .navFilter { |
||||
|
// display: flex; |
||||
|
// flex-direction: column; |
||||
|
// width: 100%; |
||||
|
// height: 100%; |
||||
|
max-height: var(--navFilterMaxHeight); |
||||
|
overflow: auto; |
||||
|
|
||||
|
.el-form { |
||||
|
// flex: 1; |
||||
|
// padding-left: 100px; |
||||
|
// padding-right: 100px; |
||||
|
display: flex; |
||||
|
align-content: flex-start; |
||||
|
flex-wrap: wrap; |
||||
|
overflow: hidden; |
||||
|
overflow-y: auto; |
||||
|
|
||||
|
.el-row{ |
||||
|
margin: 0 !important; |
||||
|
margin-left: -5px !important; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
.el-select{ |
||||
|
width: 100%; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.title{ |
||||
|
padding: 10px 0 15px 0; |
||||
|
font-weight: bold; |
||||
|
color: #333; |
||||
|
} |
||||
|
|
||||
|
.buttonsContent{ |
||||
|
justify-content: space-between; |
||||
|
display: flex; |
||||
|
padding-bottom: 20px; |
||||
|
width: 890px; |
||||
|
} |
||||
|
// .moreListPush-btn { |
||||
|
// width: 100%; |
||||
|
// padding-left: 5px; |
||||
|
// color: rgb(64, 158, 255); |
||||
|
|
||||
|
// span { |
||||
|
// cursor: pointer; |
||||
|
|
||||
|
// &:hover { |
||||
|
// color: blue; |
||||
|
// } |
||||
|
// } |
||||
|
// } |
||||
|
|
||||
|
// .moreListBaseBts{ |
||||
|
// padding: 20px 0; |
||||
|
// } |
||||
|
|
||||
|
} |
@ -0,0 +1,336 @@ |
|||||
|
<template> |
||||
|
<!-- 组件功能:搜索页面,filterSelect后面放大镜页面 --> |
||||
|
<el-dialog |
||||
|
class="searchPageComponents" |
||||
|
:title="formTitle" |
||||
|
v-if="displayDialog" |
||||
|
:visible="true" |
||||
|
:fullscreen="true" |
||||
|
:modal="false" |
||||
|
:modal-append-to-body="false" |
||||
|
:show-close="false" |
||||
|
> |
||||
|
<div class="searchDialog"> |
||||
|
<div class="searchSXButton"> |
||||
|
<el-button |
||||
|
type="primary" |
||||
|
icon="el-icon-finished" |
||||
|
size="mini" |
||||
|
@click="handleSubmit" |
||||
|
style="width:180px" |
||||
|
>筛选 |
||||
|
</el-button> |
||||
|
</div> |
||||
|
<umyTable |
||||
|
ref="searchTable" |
||||
|
:tableLoading="tableLoading" |
||||
|
:tableData="searchTableData" |
||||
|
:selectionTable="selectionTable" |
||||
|
:tableColumns="searchTableColumns | DialogTable" |
||||
|
:setUTableHeight="setUTableHeight" |
||||
|
@handleSelectionChange="prepareFormData" |
||||
|
></umyTable> |
||||
|
<pagination |
||||
|
:totalCount="searchTotalCount" |
||||
|
:pagesizeProps="supplierItemPage.MaxResultCount" |
||||
|
@SizeChange="SizeChange" |
||||
|
@CurrentChange="CurrentChange" |
||||
|
></pagination> |
||||
|
<div class="formButton"> |
||||
|
<currenButton |
||||
|
:buttonsAllIsRight="buttonsAllIsRight" |
||||
|
:Butttondata="editHandle" |
||||
|
@tableButtonClick="tableButtonClick" |
||||
|
></currenButton> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="filterPage" v-if="modal"> |
||||
|
<!-- 筛选 --> |
||||
|
<conditionFilters |
||||
|
:displayDialog="dialog" |
||||
|
:screenData="screenData" |
||||
|
:tableColumns="searchTableColumns" |
||||
|
@screenFormClick="screenFormClick" |
||||
|
@screenDelete="screenDelete" |
||||
|
@screenPush="screenPush" |
||||
|
:filterActionOptions="filterActionOptions" |
||||
|
></conditionFilters> |
||||
|
</div> |
||||
|
</el-dialog> |
||||
|
</template> |
||||
|
<script> |
||||
|
export default { |
||||
|
props: { |
||||
|
//是否需要遮罩层 |
||||
|
// modal: { |
||||
|
// type: Boolean, |
||||
|
// default: () => { |
||||
|
// return true |
||||
|
// } |
||||
|
// }, |
||||
|
//loading |
||||
|
tableLoading: { |
||||
|
type: Boolean, |
||||
|
default: () => { |
||||
|
return false |
||||
|
} |
||||
|
}, |
||||
|
// 已app-main高度为100% 需要减掉的高度 |
||||
|
setUTableHeight: { |
||||
|
type: Number, |
||||
|
default: () => { |
||||
|
return 220; |
||||
|
} |
||||
|
}, |
||||
|
// 按钮整体靠右 |
||||
|
buttonsAllIsRight:{ |
||||
|
type: Boolean, |
||||
|
default: false |
||||
|
}, |
||||
|
//名称 |
||||
|
formTitle: { |
||||
|
type: String, |
||||
|
default: '' |
||||
|
}, |
||||
|
//是否弹窗 |
||||
|
displayDialog: { |
||||
|
type: Boolean, |
||||
|
default: () => { |
||||
|
return false |
||||
|
} |
||||
|
}, |
||||
|
//Table表头数据 |
||||
|
searchTableData: { |
||||
|
type: Array, |
||||
|
default: () => { |
||||
|
return [] |
||||
|
} |
||||
|
}, |
||||
|
//Table表身绑定 |
||||
|
searchTableColumns: { |
||||
|
type: Array, |
||||
|
default: () => { |
||||
|
return [] |
||||
|
} |
||||
|
}, |
||||
|
//Table总数 |
||||
|
searchTotalCount: { |
||||
|
type: Number, |
||||
|
default: () => { |
||||
|
return 0 |
||||
|
} |
||||
|
}, |
||||
|
//Table每页显示数量 |
||||
|
supplierItemPage: { |
||||
|
type: Object, |
||||
|
default: () => { |
||||
|
return { |
||||
|
MaxResultCount: 20, |
||||
|
SkipCount: 0 |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
//Table选中数据 |
||||
|
selectionTable: { |
||||
|
type: Boolean, |
||||
|
default: true |
||||
|
}, |
||||
|
//Table是否支持多选 |
||||
|
isMoreSelectTable: { |
||||
|
type: Boolean, |
||||
|
default: false |
||||
|
}, |
||||
|
// 筛选条件自定义(等于/不等于/大于/小于等数据) |
||||
|
filterActionOptions:{ |
||||
|
type: Array, |
||||
|
default: null |
||||
|
}, |
||||
|
//确认筛选后续操作 |
||||
|
advancedFilter: { |
||||
|
type: Function, |
||||
|
default: () => { |
||||
|
return () => { |
||||
|
return {} |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
//初始化筛选数据 |
||||
|
filterPageListParams: { |
||||
|
type: Array, |
||||
|
default: () => { |
||||
|
return [] |
||||
|
} |
||||
|
}, |
||||
|
editHandle: { |
||||
|
type: Array, |
||||
|
default: () => { |
||||
|
return [ |
||||
|
{ label: "取消", name: "cancel" }, |
||||
|
{ label: "确定", type: "primary", name: "determine" }, |
||||
|
] |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
data () { |
||||
|
return { |
||||
|
modal: false, |
||||
|
dialog: { |
||||
|
screenDialog: false |
||||
|
}, |
||||
|
//筛选 |
||||
|
screenData: { |
||||
|
filters: [{ |
||||
|
logic: "And", |
||||
|
column: "", |
||||
|
action: "==", |
||||
|
value: "" |
||||
|
}] |
||||
|
}, |
||||
|
} |
||||
|
}, |
||||
|
methods: { |
||||
|
//table选择当前行数据 |
||||
|
prepareFormData (val) { |
||||
|
this.$parent.isMoreSelectTable = this.isMoreSelectTable |
||||
|
this.$emit('handleSelectionChange', val) |
||||
|
}, |
||||
|
//改变每页最大数 |
||||
|
SizeChange (val) { |
||||
|
this.$emit('SizeChange', val) |
||||
|
}, |
||||
|
//改变当前页 |
||||
|
CurrentChange (val) { |
||||
|
this.$emit('CurrentChange', val) |
||||
|
}, |
||||
|
//table按钮点击事件 |
||||
|
tableButtonClick (val) { |
||||
|
this.$emit('tableButtonClick', val, this.$refs.searchTable) |
||||
|
}, |
||||
|
//点击筛选按钮 |
||||
|
handleSubmit () { |
||||
|
let filter = JSON.parse(JSON.stringify(this.filterPageListParams)) |
||||
|
let newFilter = this.supplierItemPage.condition.filters |
||||
|
this.dialog.screenDialog = true |
||||
|
this.screenData.filters = [] |
||||
|
if (newFilter.length != 0) { |
||||
|
filter.forEach((element, index) => { |
||||
|
newFilter[index].hide = true |
||||
|
}); |
||||
|
this.screenData.filters.push(...newFilter) |
||||
|
} else { |
||||
|
let data = [{ |
||||
|
logic: "And", |
||||
|
column: "", |
||||
|
action: "==", |
||||
|
value: "" |
||||
|
}] |
||||
|
this.screenData.filters = data |
||||
|
} |
||||
|
this.$emit('sxBtnClickHandle',this.screenData.filters) |
||||
|
this.modal = true |
||||
|
}, |
||||
|
// 设置this.screenData.filters的值 |
||||
|
setScreenDataFilters (data){ |
||||
|
this.screenData.filters = data |
||||
|
}, |
||||
|
//筛选 |
||||
|
screenFormClick (val) { |
||||
|
let filter = JSON.parse(JSON.stringify(this.filterPageListParams)) |
||||
|
if (val[0] == 0) { |
||||
|
if (filter.length != 0) { |
||||
|
this.supplierItemPage.condition.filters = filter |
||||
|
} else { |
||||
|
this.supplierItemPage.condition.filters = [] |
||||
|
} |
||||
|
this.dialog.screenDialog = false; |
||||
|
this.advancedFilter() |
||||
|
} else if (val[0] == 1) { |
||||
|
val[1].clearValidate() |
||||
|
this.dialog.screenDialog = false; |
||||
|
} else { |
||||
|
val[1].validate((valid, newFilter) => { |
||||
|
if (valid) { |
||||
|
this.supplierItemPage.condition.filters = [] |
||||
|
this.screenData.filters.forEach((element, index) => { |
||||
|
this.supplierItemPage.condition.filters.push(element) |
||||
|
}) |
||||
|
this.dialog.screenDialog = false; |
||||
|
this.advancedFilter() |
||||
|
} else { |
||||
|
this.$errorMsg('请按照提示继续操作') |
||||
|
return false; |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
this.modal = false |
||||
|
}, |
||||
|
//添加筛选条件 |
||||
|
screenPush () { |
||||
|
let data = { |
||||
|
logic: "And", |
||||
|
column: "", |
||||
|
action: "==", |
||||
|
value: "" |
||||
|
} |
||||
|
// if (this.screenData.filters.length <= this.searchTableColumns.length) { |
||||
|
this.screenData.filters.push(data) |
||||
|
// } else { |
||||
|
// this.$errorMsg('筛选条件数不足!') |
||||
|
// } |
||||
|
}, |
||||
|
//删除筛选条件 |
||||
|
screenDelete (val) { |
||||
|
if (this.screenData.filters.length == 1) { |
||||
|
this.$warningMsg('必须保留一条筛选条件!') |
||||
|
} else { |
||||
|
this.$confirm('您确定删除吗, 是否继续?', '提示', { |
||||
|
confirmButtonText: '确定', |
||||
|
cancelButtonText: '取消', |
||||
|
type: 'warning' |
||||
|
}).then(() => { |
||||
|
this.screenData.filters.splice(val, 1) |
||||
|
}).catch((err) => { |
||||
|
console.log(err) |
||||
|
}); |
||||
|
} |
||||
|
}, |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss"> |
||||
|
.searchPageComponents { |
||||
|
.el-dialog__body{ |
||||
|
height: calc(100% - 55px) !important; |
||||
|
padding: 0 20px; |
||||
|
} |
||||
|
.currenButton{ |
||||
|
padding: 0; |
||||
|
} |
||||
|
.searchDialog{ |
||||
|
height: 100%; |
||||
|
} |
||||
|
.pagination{ |
||||
|
padding: 30px 10px 20px 10px; |
||||
|
} |
||||
|
.formButton{ |
||||
|
padding-top: 0 !important; |
||||
|
} |
||||
|
.el-dialog__header{ |
||||
|
padding-top: 10px; |
||||
|
} |
||||
|
.currenButton .el-button{ |
||||
|
margin: 0; |
||||
|
margin-left: 10px; |
||||
|
} |
||||
|
} |
||||
|
</style> |
||||
|
<style lang="scss" scoped> |
||||
|
.searchSXButton { |
||||
|
padding-bottom: 10px |
||||
|
} |
||||
|
.el-dialog__wrapper{ |
||||
|
position: absolute !important; |
||||
|
} |
||||
|
</style> |
@ -0,0 +1,242 @@ |
|||||
|
<template> |
||||
|
<!-- 普通筛选:列表点击筛选下的普通筛选 --> |
||||
|
<div class="searchPrimaryComponent" > |
||||
|
<!-- @submit.native.prevent 阻止form只有一个input输入框回车触发提交事件 --> |
||||
|
<el-form |
||||
|
class="searchPrimaryForm" |
||||
|
ref="searchPrimaryForm" |
||||
|
:size="primarySearchSize" |
||||
|
:inline="true" |
||||
|
:model="primarySearchData_inner" |
||||
|
@submit.native.prevent |
||||
|
> |
||||
|
<el-form-item |
||||
|
v-for="(item, index) in primarySearchOption" |
||||
|
:key="index" |
||||
|
:label="item.label" |
||||
|
:prop="item.showProp ? item.prop + '.' + item.showProp : item.prop" |
||||
|
v-show="!item.hide ? true : false" |
||||
|
> |
||||
|
<!-- type === 'input' 输入框 onkeyup: 正则表达式,用于前端输入校验工作--> |
||||
|
<el-input |
||||
|
v-if="item.type === 'input'" |
||||
|
v-model="primarySearchData_inner[item.prop]" |
||||
|
:maxlength="item.maxlength" |
||||
|
:onkeyup="item.onkeyup" |
||||
|
:clearable="!item.noClearable" |
||||
|
:disabled="Boolean(item.disabled)" |
||||
|
:placeholder="item.placeholder || '请输入' + item.label" |
||||
|
:prefix-icon="item.icon" |
||||
|
:show-password="item.showPassword" |
||||
|
></el-input> |
||||
|
<!-- item.type === 'select' 下拉框 --> |
||||
|
<el-select |
||||
|
v-if="item.type === 'select'" |
||||
|
v-model="primarySearchData_inner[item.prop]" |
||||
|
:clearable="!item.noClearable" |
||||
|
:multiple="item.multiple" |
||||
|
:disabled="Boolean(item.disabled)" |
||||
|
:filterable="item.filterable" |
||||
|
:allow-create="item.allowCreate" |
||||
|
:placeholder="item.placeholder || '请输入' + item.label" |
||||
|
> |
||||
|
<el-option |
||||
|
v-for="(op, index) in selectOptions(item.options) || |
||||
|
item.userOptions" |
||||
|
:label="op[item.optionsLabel] || op.label" |
||||
|
:value="op[item.optionsValue] || op.value" |
||||
|
:key="index" |
||||
|
></el-option> |
||||
|
</el-select> |
||||
|
<!-- item.type === 'date' 日期 --> |
||||
|
<el-date-picker |
||||
|
v-if="item.type === 'date'" |
||||
|
v-model="primarySearchData_inner[item.prop]" |
||||
|
:disabled="Boolean(item.disabled)" |
||||
|
:placeholder="item.placeholder || '选择日期'" |
||||
|
value-format="yyyy-MM-dd" |
||||
|
></el-date-picker> |
||||
|
<!-- item.type === 'time' 时间 --> |
||||
|
<el-time-picker |
||||
|
v-if="item.type === 'time'" |
||||
|
v-model="primarySearchData_inner[item.prop]" |
||||
|
:placeholder="item.placeholder || '选择时间'" |
||||
|
:picker-options="{ |
||||
|
selectableRange: '00:00:00 - 23:59:00', |
||||
|
}" |
||||
|
:disabled="Boolean(item.disabled)" |
||||
|
format="HH:mm" |
||||
|
value-format="HH:mm" |
||||
|
></el-time-picker> |
||||
|
<!-- item.type === 'dateTime' 日期时间 --> |
||||
|
<el-date-picker |
||||
|
v-if="item.type === 'dateTime'" |
||||
|
type="datetime" |
||||
|
v-model="primarySearchData_inner[item.prop]" |
||||
|
:placeholder="item.placeholder || '选择日期时间'" |
||||
|
format="yyyy-MM-dd HH:mm:ss" |
||||
|
value-format="yyyy-MM-ddTHH:mm:ss" |
||||
|
:disabled="Boolean(item.disabled)" |
||||
|
></el-date-picker> |
||||
|
<!-- item.type === 'dateTimelimit' 日期时间 日期有限制 选择范围:当前天及以后--> |
||||
|
<el-date-picker |
||||
|
v-if="item.type === 'dateTimelimit'" |
||||
|
type="datetime" |
||||
|
v-model="primarySearchData_inner[item.prop]" |
||||
|
:placeholder="item.placeholder || '选择日期时间'" |
||||
|
format="yyyy-MM-dd HH:mm:ss" |
||||
|
value-format="yyyy-MM-ddTHH:mm:ss" |
||||
|
:disabled="Boolean(item.disabled)" |
||||
|
:pickerOptions="endDateTimeLimitPickerOptions()" |
||||
|
></el-date-picker> |
||||
|
</el-form-item> |
||||
|
<!-- 自定义插槽 --> |
||||
|
<slot></slot> |
||||
|
<!-- 基础按钮 --> |
||||
|
<el-form-item v-if="showBaseButton" class="el-form-item__buttonbox"> |
||||
|
<el-button |
||||
|
v-for="(item,index) in baseButton" |
||||
|
:key="index" |
||||
|
:type="item.type" |
||||
|
:size="primarySearchSize" |
||||
|
@click="primarySearchBaseHandle(item)" |
||||
|
>{{item.label}}</el-button> |
||||
|
</el-form-item> |
||||
|
<!-- 自定义按钮 --> |
||||
|
<el-form-item |
||||
|
class="el-form-item__buttonbox" |
||||
|
v-for="(item,index) in primarySearchButton" |
||||
|
:key="item.name + '' + index" |
||||
|
> |
||||
|
<el-button |
||||
|
:type="item.type" |
||||
|
:size="item.size || primarySearchSize" |
||||
|
@click="primarySearchButtonClick(item)" |
||||
|
:icon="item.iconRight ? '' : item.icon" |
||||
|
> |
||||
|
{{ item.label }} |
||||
|
<!-- 自定义右侧图标 --> |
||||
|
<i |
||||
|
style="margin-left:0" |
||||
|
v-if="item.iconRight" |
||||
|
:class="['el-icon--right',item.icon]" |
||||
|
></i> |
||||
|
</el-button> |
||||
|
</el-form-item> |
||||
|
</el-form> |
||||
|
</div> |
||||
|
</template> |
||||
|
<script> |
||||
|
export default { |
||||
|
name: "searchPrimaryComponent", |
||||
|
props: { |
||||
|
// 查询表单配置(@utils/primarySearchOption/index.js) |
||||
|
primarySearchOption: { |
||||
|
type: Array, |
||||
|
default: () => { |
||||
|
return []; |
||||
|
}, |
||||
|
}, |
||||
|
// 是否显示基础按钮(查询、重置) |
||||
|
showBaseButton:{ |
||||
|
type: Boolean, |
||||
|
default: true |
||||
|
}, |
||||
|
// 查询表单自定义按钮(业务线页面内定义) |
||||
|
primarySearchButton: { |
||||
|
type: Array, |
||||
|
default: () => { |
||||
|
return [] |
||||
|
}, |
||||
|
}, |
||||
|
}, |
||||
|
data() { |
||||
|
return { |
||||
|
// 最初记录的值,(用于普通筛选自带默认值) |
||||
|
initialPrimarySearchData:null, |
||||
|
// 绑定的值 |
||||
|
primarySearchData_inner:{}, |
||||
|
// 初级筛选内容大小 |
||||
|
primarySearchSize:'medium', |
||||
|
// 默认基础按钮配置(同【高级筛选】等按钮,与初级筛选内部无关,属于自定义按钮,在primarySearchButton中配置) |
||||
|
baseButton:[ |
||||
|
{label:"搜索",name:"search",type: "primary"}, |
||||
|
{label:"重置",name:"reset"}, |
||||
|
], |
||||
|
}; |
||||
|
}, |
||||
|
computed: { |
||||
|
// 日期时间组件,选择范围:当前天及以后 |
||||
|
endDateTimeLimitPickerOptions() { |
||||
|
return function () { |
||||
|
return { |
||||
|
disabledDate(time) { |
||||
|
return ( |
||||
|
time.getTime() < Date.now() - 8.64e7 |
||||
|
); |
||||
|
}, |
||||
|
}; |
||||
|
}; |
||||
|
}, |
||||
|
// 获取statu.js中配置的options |
||||
|
selectOptions() { |
||||
|
return (val) => { |
||||
|
if (val) { |
||||
|
let options = this.$staticOptions[val]; |
||||
|
if (options) { |
||||
|
return options(); |
||||
|
} else { |
||||
|
return []; |
||||
|
} |
||||
|
} else { |
||||
|
return false; |
||||
|
} |
||||
|
}; |
||||
|
}, |
||||
|
}, |
||||
|
created(){ |
||||
|
// 默认设置值 initialPrimarySearchData + primarySearchData_inner |
||||
|
this.initialPrimarySearchData = {} |
||||
|
this.primarySearchOption.forEach(item => { |
||||
|
this.initialPrimarySearchData[item.prop] = item.value || null |
||||
|
}) |
||||
|
this.setPrimarySearchData(this.initialPrimarySearchData) |
||||
|
}, |
||||
|
methods: { |
||||
|
// 基础按钮操作 |
||||
|
primarySearchBaseHandle(item){ |
||||
|
this.$emit("primarySearchBaseHandle", item,this.primarySearchData_inner, this.primarySearchOption, this ) |
||||
|
}, |
||||
|
// 重置数据(单纯节点显示数据,不重新查询接口) |
||||
|
resetPrimarySearchData(){ |
||||
|
this.primarySearchData_inner = JSON.parse(JSON.stringify(this.initialPrimarySearchData)) |
||||
|
}, |
||||
|
// 获取普通搜索数据值 |
||||
|
getPrimarySearchData(){ |
||||
|
return this.primarySearchData_inner |
||||
|
}, |
||||
|
// 设置普通搜索数据值 |
||||
|
setPrimarySearchData(data){ |
||||
|
this.primarySearchData_inner = JSON.parse(JSON.stringify(data)) |
||||
|
}, |
||||
|
// 自定义按钮点击事件 |
||||
|
primarySearchButtonClick(item){ |
||||
|
this.$emit("primarySearchButtonClick", item,this.primarySearchData_inner, this.primarySearchOption,this) |
||||
|
}, |
||||
|
}, |
||||
|
}; |
||||
|
</script> |
||||
|
<style lang="scss" scoped> |
||||
|
.searchPrimaryComponent{ |
||||
|
.el-input{ |
||||
|
width: auto !important; |
||||
|
} |
||||
|
.el-form-item{ |
||||
|
margin-bottom: 10px !important; |
||||
|
|
||||
|
&:not(.el-form-item__buttonbox){ |
||||
|
margin-right: 30px !important; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</style> |
@ -0,0 +1,284 @@ |
|||||
|
<template> |
||||
|
<!-- 组件功能:查看json及复制 --> |
||||
|
<div class="showCopyJsonPop"> |
||||
|
|
||||
|
<!-- 点开查看Json转换后table弹窗 --> |
||||
|
<el-dialog |
||||
|
top="50px" |
||||
|
:visible.sync="JsonTableShow" |
||||
|
:modal-append-to-body="true" |
||||
|
:append-to-body="true" |
||||
|
:show-close="true" |
||||
|
:close-on-click-modal="true" |
||||
|
:close-on-press-escape="true" |
||||
|
width="90%" |
||||
|
@close="closePop" |
||||
|
> |
||||
|
<template #title> |
||||
|
内容详情 |
||||
|
<el-button |
||||
|
size="mini" |
||||
|
@click="copyJsonHandle()" |
||||
|
type="primary" |
||||
|
style="margin-right: 30px;float: right;" |
||||
|
>复制JSON</el-button> |
||||
|
</template> |
||||
|
<el-table |
||||
|
height="calc(100vh - 220px)" |
||||
|
:data="JsonTableData" |
||||
|
:border="true" |
||||
|
style="width: 100%"> |
||||
|
<el-table-column |
||||
|
prop="name" |
||||
|
width="220" |
||||
|
label="属性" |
||||
|
> |
||||
|
<template slot-scope="scope"> |
||||
|
{{ scope.row.name }} |
||||
|
<el-button |
||||
|
type="primary" |
||||
|
v-if="(scope.row.name).toUpperCase() == 'DETAILS'" |
||||
|
size="mini" |
||||
|
style="margin-left: 20px;" |
||||
|
@click="showDetailTableHandle(scope.row)" |
||||
|
>查看详情</el-button> |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
<el-table-column |
||||
|
label="值" |
||||
|
> |
||||
|
<template slot-scope="scope"> |
||||
|
<!-- DETAILS todo:DETAILS判断条件需要优化,使用传参的方式 --> |
||||
|
<span v-if="(scope.row.name).toUpperCase() != 'DETAILS'">{{scope.row.value}}</span> |
||||
|
<el-table |
||||
|
v-else |
||||
|
:data="scope.row.value" |
||||
|
stripe |
||||
|
:border="true" |
||||
|
style="width: 100%" |
||||
|
height="300" |
||||
|
> |
||||
|
<el-table-column |
||||
|
label="序号" |
||||
|
fixed="left" |
||||
|
type="index" |
||||
|
width="50"> |
||||
|
</el-table-column> |
||||
|
<el-table-column |
||||
|
v-for="(head,h_key) in detailTableHeader" |
||||
|
:key="h_key" |
||||
|
min-width="120" |
||||
|
> |
||||
|
<template #header> |
||||
|
<span :title="head">{{ head }}</span> |
||||
|
</template> |
||||
|
<template slot-scope="scope2"> |
||||
|
<div v-if="typeof scope2.row[head] == 'object'"> |
||||
|
<div v-for="(o,o_key) in scope2.row[head]"> |
||||
|
{{ o_key }}:{{ o }} |
||||
|
<div style="border-bottom: dashed 1px #ddd;"></div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div v-else>{{ scope2.row[head] }}</div> |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
</el-table> |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
</el-table> |
||||
|
</el-dialog> |
||||
|
|
||||
|
<!-- json复制内容弹窗 --> |
||||
|
<el-dialog |
||||
|
top="50px" |
||||
|
:visible.sync="JsonCopyShow" |
||||
|
:modal-append-to-body="false" |
||||
|
:append-to-body="true" |
||||
|
:show-close="true" |
||||
|
:close-on-click-modal="true" |
||||
|
:close-on-press-escape="true" |
||||
|
:title="'JSON详情'" |
||||
|
> |
||||
|
<el-input |
||||
|
class="copyJsonTextarea" |
||||
|
ref="copyJsonTextarea_ref" |
||||
|
type="textarea" |
||||
|
readonly |
||||
|
autosize |
||||
|
resize="none" |
||||
|
v-model="JsonCopyData" |
||||
|
></el-input> |
||||
|
</el-dialog> |
||||
|
|
||||
|
<!-- details的table --> |
||||
|
<el-dialog |
||||
|
top="80px" |
||||
|
width="86%" |
||||
|
v-if="detailTableRow" |
||||
|
:visible.sync="detailsTableShow" |
||||
|
:modal-append-to-body="true" |
||||
|
:append-to-body="true" |
||||
|
:show-close="true" |
||||
|
:close-on-click-modal="true" |
||||
|
:close-on-press-escape="true" |
||||
|
:title="detailTableRow.name+' 详情'" |
||||
|
> |
||||
|
<!-- row-key 默认不处理,解决id可能重复问题,此处没有选择框,可以这么处理 --> |
||||
|
<umyTable |
||||
|
:isShowIndex="true" |
||||
|
:tableBorder="true" |
||||
|
:setUTableHeight="170" |
||||
|
:row-key="null" |
||||
|
:tableData="detailTableRow.value" |
||||
|
:tableColumns="detailTableColumns" |
||||
|
:selectionTable="false" |
||||
|
></umyTable> |
||||
|
</el-dialog> |
||||
|
</div> |
||||
|
</template> |
||||
|
<script> |
||||
|
import { LoadingMixins } from "@/mixins/LoadingMixins"; |
||||
|
import { tableMixins } from "@/mixins/TableMixins" |
||||
|
export default { |
||||
|
name:"showCopyJsonPop", |
||||
|
mixins:[ LoadingMixins,tableMixins ], |
||||
|
props: { |
||||
|
// Json数据 |
||||
|
JsonData:{ |
||||
|
type: Object, |
||||
|
default: null, |
||||
|
}, |
||||
|
}, |
||||
|
data () { |
||||
|
return { |
||||
|
JsonTableShow:true,//点开查看Json转换后table弹窗 |
||||
|
JsonTableData:null,//表格转义的json数据 |
||||
|
JsonCopyData:null,//复制的Json字符串 |
||||
|
JsonCopyShow:false,//复制json的Dialog显隐控制 |
||||
|
detailTableHeader:null,//details表格的Header |
||||
|
detailTableRow:null,//details的相关信息 |
||||
|
detailsTableShow:false,//details的详情 |
||||
|
detailTableColumns:false,//details的详情header表头 |
||||
|
} |
||||
|
}, |
||||
|
mounted(){ |
||||
|
this.initJsonData() |
||||
|
}, |
||||
|
methods: { |
||||
|
// 关闭整个弹窗 |
||||
|
closePop() { |
||||
|
this.JsonTableShow = false |
||||
|
this.$emit("closePop") |
||||
|
}, |
||||
|
// json数据转义 |
||||
|
initJsonData(){ |
||||
|
let _arr = [] |
||||
|
let __initJson = (data) => { |
||||
|
let _init = [] |
||||
|
for(let item in data){ |
||||
|
_init.push({name:item,value:data[item]}) |
||||
|
} |
||||
|
return _init |
||||
|
} |
||||
|
let _json = this.JsonData |
||||
|
for(let item in _json){ |
||||
|
// 直接输出 |
||||
|
if(!_json[item]){ |
||||
|
_arr.push({name:item,value:_json[item]}) |
||||
|
}else{ |
||||
|
if(typeof _json[item] != 'object'){ |
||||
|
_arr.push({name:item,value:_json[item] + ""}) |
||||
|
}else{ |
||||
|
// 如果是数组 |
||||
|
if(Array.isArray(_json[item])){ |
||||
|
// 如果是 DETAILS todo:DETAILS判断条件需要优化,使用传参的方式 |
||||
|
// let _value = (item).toUpperCase() == 'DETAILS' ? __initJson(_json[item][0]) : (_json[item]).join(",") |
||||
|
this.detailTableHeader = [] |
||||
|
for(let h in _json[item][0]){ |
||||
|
this.detailTableHeader.push(h) |
||||
|
} |
||||
|
let _value = (item).toUpperCase() == 'DETAILS' ? _json[item] : (_json[item]).join(",") |
||||
|
_arr.push({name:item,value:_value}) |
||||
|
} |
||||
|
// 如果是对象 |
||||
|
else{ |
||||
|
let _obj_arr = __initJson(_json[item]) |
||||
|
// 对象有数据 |
||||
|
if(_obj_arr.length > 0){ |
||||
|
_arr = [..._obj_arr] |
||||
|
}else{ |
||||
|
// 空对象 |
||||
|
_arr.push({name:item,value:""}) |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
this.JsonTableData = _arr |
||||
|
this.JsonCopyData = JSON.stringify(_json, null, '\t')//复制使用 |
||||
|
}, |
||||
|
// 复制后选择框处理 |
||||
|
copyJsonInputHandle(type){ |
||||
|
if(type == 'error')this.$message.error('复制失败'); |
||||
|
if(type == 'success')this.$message.success('复制成功'); |
||||
|
if(this.$refs.copyJsonTextarea_ref){ |
||||
|
this.$refs.copyJsonTextarea_ref.focus() |
||||
|
this.$refs.copyJsonTextarea_ref.$refs.textarea.scrollTop = 0 |
||||
|
} |
||||
|
}, |
||||
|
// 复制Json按钮 |
||||
|
copyJsonHandle(){ |
||||
|
this.JsonCopyShow = true |
||||
|
if (navigator.clipboard && window.isSecureContext) { |
||||
|
navigator.clipboard.writeText(this.JsonCopyData) |
||||
|
.then(() => { |
||||
|
this.copyJsonInputHandle('success') |
||||
|
}) |
||||
|
.catch(err => { |
||||
|
this.copyJsonInputHandle('error') |
||||
|
}); |
||||
|
}else { |
||||
|
// 创建text area |
||||
|
const textArea = document.createElement('textarea') |
||||
|
textArea.value = this.JsonCopyData |
||||
|
// 使text area不在viewport,同时设置不可见 |
||||
|
document.body.appendChild(textArea) |
||||
|
textArea.focus() |
||||
|
textArea.select() |
||||
|
return new Promise((resolve, reject) => { |
||||
|
// 执行复制命令并移除文本框 |
||||
|
document.execCommand('copy') ? resolve() : reject(new Error('出错了')) |
||||
|
textArea.remove() |
||||
|
}).then(() => { |
||||
|
this.$nextTick(()=>{ |
||||
|
this.copyJsonInputHandle('success') |
||||
|
}) |
||||
|
},() => { |
||||
|
this.copyJsonInputHandle('error') |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
}, |
||||
|
// detail的table详情 |
||||
|
showDetailTableHandle(row){ |
||||
|
this.detailTableRow = row |
||||
|
this.detailTableColumns = [] |
||||
|
this.detailTableHeader.forEach(item=>{ |
||||
|
this.detailTableColumns.push({ |
||||
|
prop:item, |
||||
|
label:item |
||||
|
}) |
||||
|
}) |
||||
|
this.detailsTableShow = true |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
<style lang="scss" scoped> |
||||
|
::v-deep .copyJsonTextarea{ |
||||
|
textarea{ |
||||
|
max-height: calc(100vh - 220px) !important; |
||||
|
overflow: auto !important; |
||||
|
} |
||||
|
} |
||||
|
</style> |
@ -0,0 +1,402 @@ |
|||||
|
<template> |
||||
|
<div class="tablePagination"> |
||||
|
<!-- 头部按钮 --> |
||||
|
<div class="table-nav"> |
||||
|
<curren-Button |
||||
|
ref="tablePagination_topNav" |
||||
|
:Butttondata="currenButtonData" |
||||
|
@tableButtonClick="topbutton" |
||||
|
@quicklySearchClick="quicklySearchClick" |
||||
|
@quicklySearchClear="quicklySearchClear" |
||||
|
:quicklySearchOption="quicklySearchOption" |
||||
|
> |
||||
|
</curren-Button> |
||||
|
<slot name="tableTopSlot"></slot> |
||||
|
</div> |
||||
|
<!-- 全面搜索(普通+高级整合) --> |
||||
|
<searchOverall |
||||
|
ref="searchOverallRef" |
||||
|
:searchOverallCoverHeight="searchOverallCoverHeight" |
||||
|
:showSearchOverall="showSearchOverall" |
||||
|
@getShowSearchOverall="getShowSearchOverall" |
||||
|
:primarySearchOption="primarySearchOption" |
||||
|
:primarySearchButton="primarySearchButton" |
||||
|
:showMoreSearch="showMoreSearch" |
||||
|
:tableColumns="tableColumns" |
||||
|
@overallSearchFormClick="overallSearchFormClick" |
||||
|
:httpOverallSearchData="httpOverallSearchData" |
||||
|
> |
||||
|
<!-- 插槽预留 --> |
||||
|
<slot name="searchPrimarySlot"></slot> |
||||
|
</searchOverall> |
||||
|
<!-- 字段设置弹窗 --> |
||||
|
<rowDrop |
||||
|
@radio="rowDrop" |
||||
|
:tableColumns="tableColumns" |
||||
|
:visible="rowDropVisible" |
||||
|
@closeRowDrop="closeRowDrop" |
||||
|
:source="rowSource" |
||||
|
:innerMaxHeight="rowMaxHeight" |
||||
|
></rowDrop> |
||||
|
<!-- 列表 --> |
||||
|
<div class="uTableOuter" ref="uTableOuterRef" :style="{height:uTableOuterHeight + 'px',overflow:'hidden'}"> |
||||
|
<umyTable |
||||
|
ref="tablePaginationTableRef" |
||||
|
:isUpdate="isUpdate" |
||||
|
:tableLoading="tableLoading" |
||||
|
:tableData="tableData" |
||||
|
:tableColumns="tableColumns | isTableColumns" |
||||
|
:isShowIndex="isShowIndex" |
||||
|
:selectionTable="tableSelection" |
||||
|
:setUTableHeight="setUTableHeight || uTableTopHeight" |
||||
|
@sortChange="sortChange" |
||||
|
@handleSelectionChange="handleSelectionChange" |
||||
|
@inlineDialog="inlineDialog" |
||||
|
:buttonOperationList_left="buttonOperationList_left" |
||||
|
@buttonOperationClick_left="buttonOperationClick_left" |
||||
|
:buttonOperationList_right="buttonOperationList_right" |
||||
|
@buttonOperationClick_right="buttonOperationClick_right" |
||||
|
:tableBorder="true" |
||||
|
:firstFixed="true" |
||||
|
:cellStyle = "cellStyle" |
||||
|
:showOverflowTooltip="showOverflowTooltip" |
||||
|
> |
||||
|
<template> |
||||
|
<slot></slot> |
||||
|
</template> |
||||
|
</umyTable> |
||||
|
</div> |
||||
|
<!-- 页码 --> |
||||
|
<pagination |
||||
|
:totalCount="totalCount" |
||||
|
:pagesizeProps="MaxResultCount" |
||||
|
:currentPageProps="currentPageProps" |
||||
|
@SizeChange="alterResultCount" |
||||
|
@CurrentChange="alertoldSkipCount" |
||||
|
></pagination> |
||||
|
</div> |
||||
|
</template> |
||||
|
<script> |
||||
|
import currenButton from "@/components/currenButton" |
||||
|
import pagination from "@/components/Pagination" |
||||
|
import searchOverall from "@/components/searchOverall" |
||||
|
import rowDrop from "@/components/rowDrop/index.vue" |
||||
|
import { getParentNode } from '@/utils' |
||||
|
export default { |
||||
|
name: 'tablePagination', |
||||
|
components: { |
||||
|
pagination, |
||||
|
currenButton, |
||||
|
searchOverall, |
||||
|
rowDrop |
||||
|
}, |
||||
|
props: { |
||||
|
rowMaxHeight:{ |
||||
|
type:String, |
||||
|
default:'calc(90vh - 280px)' |
||||
|
}, |
||||
|
// 筛选高度 |
||||
|
searchOverallCoverHeight:{ |
||||
|
type: String, |
||||
|
default: 'calc(100vh - 200px)' |
||||
|
}, |
||||
|
// 已app-main高度为100% 需要减掉的高度 |
||||
|
setUTableHeight: { |
||||
|
type: Number, |
||||
|
default: null |
||||
|
}, |
||||
|
// 超出内容是否提示 |
||||
|
showOverflowTooltip:{ |
||||
|
type: Boolean, |
||||
|
default: false, |
||||
|
}, |
||||
|
// 显示搜索配置 |
||||
|
quicklySearchOption:{ |
||||
|
type: Object, |
||||
|
default: null |
||||
|
}, |
||||
|
// 表格上方头部按钮配置 |
||||
|
currenButtonData: { |
||||
|
type: Array, |
||||
|
default: () => { |
||||
|
return [] |
||||
|
} |
||||
|
}, |
||||
|
// 操作列按钮(左侧) |
||||
|
buttonOperationList_left:{ |
||||
|
type: Array, |
||||
|
default: null, |
||||
|
}, |
||||
|
// 操作列按钮(右侧) |
||||
|
buttonOperationList_right:{ |
||||
|
type: Function, |
||||
|
default: null, |
||||
|
}, |
||||
|
// 列表数据 |
||||
|
tableData: { |
||||
|
type: Array, |
||||
|
default: () => { |
||||
|
return [] |
||||
|
} |
||||
|
}, |
||||
|
// 列表列配置 + 高级筛选配置 |
||||
|
tableColumns: { |
||||
|
type: Array, |
||||
|
default: () => { |
||||
|
return [] |
||||
|
} |
||||
|
}, |
||||
|
// 复选框 |
||||
|
tableSelection: { |
||||
|
type: Boolean, |
||||
|
default: false |
||||
|
}, |
||||
|
// table页码总数 |
||||
|
totalCount: { |
||||
|
type: Number, |
||||
|
default: 0 |
||||
|
}, |
||||
|
// table组件上的loading |
||||
|
tableLoading: { |
||||
|
type: Boolean, |
||||
|
default: true |
||||
|
}, |
||||
|
// 页码每页显示数 |
||||
|
MaxResultCount: { |
||||
|
type: Number, |
||||
|
default: 0 |
||||
|
}, |
||||
|
// 页码当前页配置 |
||||
|
currentPageProps: { |
||||
|
type: Number, |
||||
|
default: 1 |
||||
|
}, |
||||
|
// 是否显示序号 |
||||
|
isShowIndex: { |
||||
|
type: Boolean, |
||||
|
default: false, |
||||
|
}, |
||||
|
// 选择当前行数据 |
||||
|
multipleSelection: { |
||||
|
type: Array, |
||||
|
default: () => { |
||||
|
return [] |
||||
|
} |
||||
|
}, |
||||
|
// 以下为全面筛选组件配置 |
||||
|
//初级筛选绑定表单配置 |
||||
|
primarySearchOption: { |
||||
|
type: Array, |
||||
|
default: () => { |
||||
|
return [] |
||||
|
} |
||||
|
}, |
||||
|
//初级筛选表单自定义按钮 |
||||
|
primarySearchButton: { |
||||
|
type: Array, |
||||
|
default: () => { |
||||
|
return [] |
||||
|
} |
||||
|
}, |
||||
|
// 是否显示高级筛选 |
||||
|
showMoreSearch:{ |
||||
|
type: Boolean, |
||||
|
default: true, |
||||
|
}, |
||||
|
// 当前接口中的筛选数据(用于同步全面筛选的数据) |
||||
|
httpOverallSearchData:{ |
||||
|
type: Object, |
||||
|
default: null |
||||
|
}, |
||||
|
cellStyle: { |
||||
|
type: Function, |
||||
|
default: () => { |
||||
|
return Function; |
||||
|
} |
||||
|
}, |
||||
|
// 字段设置来源(列表、列表-明细、明细页面) |
||||
|
rowSource:{ |
||||
|
type:String, |
||||
|
default:'list_api' |
||||
|
} |
||||
|
}, |
||||
|
data () { |
||||
|
return { |
||||
|
// 字段设置是否显示 |
||||
|
rowDropVisible: false, |
||||
|
// table 重新渲染所需key |
||||
|
isUpdate: false, |
||||
|
// 除去table的高度 |
||||
|
uTableTopHeight:165, |
||||
|
// table外部高度控制,用于点击筛选动画处理 |
||||
|
uTableOuterHeight:null, |
||||
|
// table外部最初始化高度,用于点击筛选动画处理 |
||||
|
uTableOuterHeight_init:null, |
||||
|
//table操作按钮 |
||||
|
Butttondata: [ |
||||
|
{ |
||||
|
type: 'danger', |
||||
|
icon: 'el-icon-delete', |
||||
|
label: '批量删除', |
||||
|
size: 'mini' |
||||
|
}, |
||||
|
{ |
||||
|
type: 'warning', |
||||
|
icon: 'el-icon-edit', |
||||
|
label: '批量修改状态', |
||||
|
size: 'mini' |
||||
|
}, |
||||
|
{ |
||||
|
type: 'success', |
||||
|
icon: 'el-icon-upload2', |
||||
|
label: '批量导出', |
||||
|
size: 'mini' |
||||
|
}, |
||||
|
{ |
||||
|
type: 'info', |
||||
|
icon: 'el-icon-printer', |
||||
|
label: '批量打印', |
||||
|
size: 'mini' |
||||
|
}, |
||||
|
], |
||||
|
// 全面筛选组件配置 |
||||
|
// 显示全面筛选组件 |
||||
|
showSearchOverall:false, |
||||
|
} |
||||
|
}, |
||||
|
mounted(){ |
||||
|
this.uTableOuterHeight = this.$refs.tablePaginationTableRef.getTableHeight() |
||||
|
this.uTableOuterHeight_init = Number(JSON.stringify(this.uTableOuterHeight)) |
||||
|
|
||||
|
// 点击外部,字段设置弹窗隐藏 |
||||
|
document.addEventListener('click',(e)=>{ |
||||
|
if(!this.rowDropVisible)return |
||||
|
let _class = "rowDropNotHideItem" |
||||
|
let _hasParent = getParentNode(e.target,_class) |
||||
|
let _current_class = e.target._prevClass || e.target.className |
||||
|
let _hasCurrent = _current_class ? String(_current_class).includes(_class) : false |
||||
|
if(!_hasParent && !_hasCurrent){ |
||||
|
this.closeRowDrop() |
||||
|
} |
||||
|
}) |
||||
|
}, |
||||
|
methods: { |
||||
|
rowDrop(data,type) { |
||||
|
this.$emit('rowDrop',data,type) |
||||
|
this.$nextTick(()=>{ |
||||
|
this.isUpdate = !this.isUpdate |
||||
|
}) |
||||
|
}, |
||||
|
//点击常用按钮 |
||||
|
topbutton (val,item) { |
||||
|
// 筛选按钮 + table高度变化 + 动画效果(勿动顺序) |
||||
|
if(val=="filter"){ |
||||
|
this.showSearchOverall = !this.showSearchOverall |
||||
|
// 有普通查询配置 |
||||
|
if(this.primarySearchOption && this.primarySearchOption.length > 0){ |
||||
|
this.$nextTick(()=>{ |
||||
|
let _search_height = this.$refs.searchOverallRef.getSearchPrimaryHeight() |
||||
|
if(this.showSearchOverall){ |
||||
|
let _margin = 20 |
||||
|
this.uTableOuterHeight = this.uTableOuterHeight_init - _search_height - _margin |
||||
|
setTimeout(()=>{ |
||||
|
this.uTableTopHeight += _search_height + _margin |
||||
|
},0) |
||||
|
}else{ |
||||
|
this.uTableOuterHeight = this.uTableOuterHeight_init |
||||
|
setTimeout(()=>{ |
||||
|
this.uTableTopHeight = 165 |
||||
|
},0) |
||||
|
} |
||||
|
}) |
||||
|
} |
||||
|
} |
||||
|
// 字段设置 |
||||
|
else if (val == 'field') { |
||||
|
this.rowDropVisible = !this.rowDropVisible |
||||
|
} |
||||
|
this.$emit("topbutton", val,item) |
||||
|
}, |
||||
|
// 快速搜索 - 搜索按钮 |
||||
|
quicklySearchClick (val,option) { |
||||
|
this.$emit("quicklySearchClick", val,option,this.$refs.searchOverallRef) |
||||
|
}, |
||||
|
// 快速搜索 - 清除搜索 |
||||
|
quicklySearchClear (val,option) { |
||||
|
// 判断是否有筛选按钮 |
||||
|
let hasSearch = false |
||||
|
this.currenButtonData.forEach(item=>{ |
||||
|
if(item.name == 'filter'){ |
||||
|
hasSearch = true |
||||
|
return |
||||
|
} |
||||
|
}) |
||||
|
this.$emit("quicklySearchClear", val,option,this.$refs.searchOverallRef,hasSearch ) |
||||
|
}, |
||||
|
//接收分页组件emit改变每页最大页数 |
||||
|
alterResultCount (val) { |
||||
|
this.$emit('alterResultCount', val) |
||||
|
}, |
||||
|
//接收分页组件emit改变当前页 |
||||
|
alertoldSkipCount (val) { |
||||
|
this.$emit('alertoldSkipCount', val) |
||||
|
}, |
||||
|
//点击name提交emit打开编辑页面 |
||||
|
inlineDialog (row) { |
||||
|
this.$emit("inlineDialog", row) |
||||
|
}, |
||||
|
//点击selection框 |
||||
|
handleSelectionChange (val) { |
||||
|
this.$emit("handleSelectionChange", val) |
||||
|
}, |
||||
|
//排序 |
||||
|
sortChange (data) { |
||||
|
this.$emit('sortChange', data) |
||||
|
}, |
||||
|
//点击table操作列(左侧)按钮 |
||||
|
buttonOperationClick_left(row, item, index) { |
||||
|
this.$emit("buttonOperationClick_left", row, item, index); |
||||
|
}, |
||||
|
//点击table操作列(右侧)按钮 |
||||
|
buttonOperationClick_right(row, item, index) { |
||||
|
this.$emit("buttonOperationClick_right", row, item, index); |
||||
|
}, |
||||
|
// 全面筛选组件配置 |
||||
|
// 全面筛选组件内部显示/隐藏更改触发,同步当前的showSearchOverall值 |
||||
|
getShowSearchOverall(val){ |
||||
|
this.showSearchOverall = val || false |
||||
|
}, |
||||
|
// 全面筛选组件所有按钮事件 |
||||
|
overallSearchFormClick(options){ |
||||
|
//增加快速搜索实体 |
||||
|
options.vm_quickly = this.$refs.tablePagination_topNav.getQuicklySearchDom() |
||||
|
this.$emit("overallSearchFormClick", options) |
||||
|
}, |
||||
|
// 关闭字段设置 |
||||
|
closeRowDrop() { |
||||
|
this.rowDropVisible = false |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
<style lang="scss" scoped> |
||||
|
.uTableOuter{ |
||||
|
transition:all 0.5s; |
||||
|
overflow: hidden; |
||||
|
} |
||||
|
.tablePagination { |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
background-color: #fff; |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
|
||||
|
.table-nav { |
||||
|
padding-bottom: 15px; |
||||
|
} |
||||
|
|
||||
|
.el-table { |
||||
|
flex: 1; |
||||
|
} |
||||
|
} |
||||
|
</style> |
@ -0,0 +1,464 @@ |
|||||
|
<template> |
||||
|
<div class="tablePagination"> |
||||
|
<!-- 头部按钮 --> |
||||
|
<div class="table-nav"> |
||||
|
<curren-Button |
||||
|
v-if="headerButttondata" |
||||
|
ref="tablePagination_topNav" |
||||
|
:Butttondata="headerButttondata" |
||||
|
@tableButtonClick="topbutton" |
||||
|
@quicklySearchClick="quicklySearchClick" |
||||
|
@quicklySearchClear="quicklySearchClear" |
||||
|
:quicklySearchOption="quicklySearchOption" |
||||
|
> |
||||
|
</curren-Button> |
||||
|
<slot name="tableTopSlot"></slot> |
||||
|
</div> |
||||
|
<!-- 全面搜索(普通+高级整合) --> |
||||
|
<searchOverall |
||||
|
ref="searchOverallRef" |
||||
|
:searchOverallCoverHeight="searchOverallCoverHeight" |
||||
|
:showSearchOverall="showSearchOverall" |
||||
|
@getShowSearchOverall="getShowSearchOverall" |
||||
|
:primarySearchOption="primarySearchOption" |
||||
|
:primarySearchButton="primarySearchButton" |
||||
|
:showMoreSearch="showMoreSearch" |
||||
|
:tableColumns="tableColumns" |
||||
|
@overallSearchFormClick="overallSearchFormClick" |
||||
|
:httpOverallSearchData="httpOverallSearchData" |
||||
|
:selectMaxHeight="selectMaxHeight" |
||||
|
> |
||||
|
<!-- 插槽预留 --> |
||||
|
<slot name="searchPrimarySlot"></slot> |
||||
|
</searchOverall> |
||||
|
<!-- 字段设置弹窗 --> |
||||
|
<rowDrop |
||||
|
@radio="rowDrop" |
||||
|
:tableColumns="tableColumns" |
||||
|
:visible="rowDropVisible" |
||||
|
@closeRowDrop="closeRowDrop" |
||||
|
:source="rowSource" |
||||
|
:innerMaxHeight="rowMaxHeight" |
||||
|
></rowDrop> |
||||
|
<!-- 列表 --> |
||||
|
<div class="uTableOuter" ref="uTableOuterRef" :style="{height:uTableOuterHeight + 'px',overflow:'hidden'}"> |
||||
|
<umyTable |
||||
|
ref="tablePaginationTableRef" |
||||
|
:isUpdate="isUpdate" |
||||
|
:tableLoading="tableLoading" |
||||
|
:tableData="tableData" |
||||
|
:tableColumns="tableColumns | isTableColumns" |
||||
|
:isShowIndex="isShowIndex" |
||||
|
:selectionTable="tableSelection" |
||||
|
:setUTableHeight="uTableTopHeight" |
||||
|
@sortChange="sortChange" |
||||
|
@handleSelectionChange="handleSelectionChange" |
||||
|
@inlineDialog="inlineDialog" |
||||
|
:buttonOperationList_left="buttonOperationList_left" |
||||
|
@buttonOperationClick_left="buttonOperationClick_left" |
||||
|
:buttonOperationList_right="buttonOperationList_right" |
||||
|
@buttonOperationClick_right="buttonOperationClick_right" |
||||
|
:tableBorder="true" |
||||
|
:firstFixed="true" |
||||
|
:cellStyle = "cellStyle" |
||||
|
:showOverflowTooltip="showOverflowTooltip" |
||||
|
> |
||||
|
<template> |
||||
|
<slot></slot> |
||||
|
</template> |
||||
|
</umyTable> |
||||
|
</div> |
||||
|
<!-- 页码 --> |
||||
|
<pagination |
||||
|
:totalCount="totalCount" |
||||
|
:pagesizeProps="MaxResultCount" |
||||
|
:currentPageProps="currentPageProps" |
||||
|
@SizeChange="alterResultCount" |
||||
|
@CurrentChange="alertoldSkipCount" |
||||
|
></pagination> |
||||
|
</div> |
||||
|
</template> |
||||
|
<script> |
||||
|
import currenButton from "@/components/currenButton" |
||||
|
import pagination from "@/components/Pagination" |
||||
|
import searchOverall from "@/components/searchOverall" |
||||
|
import rowDrop from "@/components/rowDrop/index.vue" |
||||
|
import { getParentNode } from '@/utils' |
||||
|
export default { |
||||
|
name: 'tablePagination', |
||||
|
components: { |
||||
|
pagination, |
||||
|
currenButton, |
||||
|
searchOverall, |
||||
|
rowDrop |
||||
|
}, |
||||
|
props: { |
||||
|
// 不使用权限的按钮 |
||||
|
noUsePermissionBtn:{ |
||||
|
type: Array, |
||||
|
default: () => { |
||||
|
return ['refresh','field','filterForDetail','export','filter']//刷新,字段设置,明细查询,导出,筛选 |
||||
|
} |
||||
|
}, |
||||
|
rowMaxHeight:{ |
||||
|
type:String, |
||||
|
default:'calc(90vh - 280px)' |
||||
|
}, |
||||
|
// 筛选条件最大高度 |
||||
|
selectMaxHeight:{ |
||||
|
type: String, |
||||
|
default: '174px' |
||||
|
}, |
||||
|
// 筛选高度 |
||||
|
searchOverallCoverHeight:{ |
||||
|
type: String, |
||||
|
default: 'calc(100vh - 200px)' |
||||
|
}, |
||||
|
// 已app-main高度为100% 需要减掉的高度 |
||||
|
setUTableHeight: { |
||||
|
type: Number, |
||||
|
default: null |
||||
|
}, |
||||
|
// 超出内容是否提示 |
||||
|
showOverflowTooltip:{ |
||||
|
type: Boolean, |
||||
|
default: false, |
||||
|
}, |
||||
|
// 显示搜索配置 |
||||
|
quicklySearchOption:{ |
||||
|
type: Object, |
||||
|
default: null |
||||
|
}, |
||||
|
// 表格上方头部按钮配置 |
||||
|
currenButtonData: { |
||||
|
type: Array, |
||||
|
default: () => { |
||||
|
return [] |
||||
|
} |
||||
|
}, |
||||
|
// 操作列按钮(左侧) |
||||
|
buttonOperationList_left:{ |
||||
|
type: Array, |
||||
|
default: null, |
||||
|
}, |
||||
|
// 操作列按钮(右侧) |
||||
|
buttonOperationList_right:{ |
||||
|
type: Function, |
||||
|
default: null, |
||||
|
}, |
||||
|
// 列表数据 |
||||
|
tableData: { |
||||
|
type: Array, |
||||
|
default: () => { |
||||
|
return [] |
||||
|
} |
||||
|
}, |
||||
|
// 列表列配置 + 高级筛选配置 |
||||
|
tableColumns: { |
||||
|
type: Array, |
||||
|
default: () => { |
||||
|
return [] |
||||
|
} |
||||
|
}, |
||||
|
// 复选框 |
||||
|
tableSelection: { |
||||
|
type: Boolean, |
||||
|
default: false |
||||
|
}, |
||||
|
// table页码总数 |
||||
|
totalCount: { |
||||
|
type: Number, |
||||
|
default: 0 |
||||
|
}, |
||||
|
// table组件上的loading |
||||
|
tableLoading: { |
||||
|
type: Boolean, |
||||
|
default: true |
||||
|
}, |
||||
|
// 页码每页显示数 |
||||
|
MaxResultCount: { |
||||
|
type: Number, |
||||
|
default: 0 |
||||
|
}, |
||||
|
// 页码当前页配置 |
||||
|
currentPageProps: { |
||||
|
type: Number, |
||||
|
default: 1 |
||||
|
}, |
||||
|
// 是否显示序号 |
||||
|
isShowIndex: { |
||||
|
type: Boolean, |
||||
|
default: false, |
||||
|
}, |
||||
|
// 选择当前行数据 |
||||
|
multipleSelection: { |
||||
|
type: Array, |
||||
|
default: () => { |
||||
|
return [] |
||||
|
} |
||||
|
}, |
||||
|
// 以下为全面筛选组件配置 |
||||
|
//初级筛选绑定表单配置 |
||||
|
primarySearchOption: { |
||||
|
type: Array, |
||||
|
default: () => { |
||||
|
return [] |
||||
|
} |
||||
|
}, |
||||
|
//初级筛选表单自定义按钮 |
||||
|
primarySearchButton: { |
||||
|
type: Array, |
||||
|
default: () => { |
||||
|
return [] |
||||
|
} |
||||
|
}, |
||||
|
// 是否显示高级筛选 |
||||
|
showMoreSearch:{ |
||||
|
type: Boolean, |
||||
|
default: true, |
||||
|
}, |
||||
|
// 当前接口中的筛选数据(用于同步全面筛选的数据) |
||||
|
httpOverallSearchData:{ |
||||
|
type: Object, |
||||
|
default: null |
||||
|
}, |
||||
|
cellStyle: { |
||||
|
type: Function, |
||||
|
default: () => { |
||||
|
return Function; |
||||
|
} |
||||
|
}, |
||||
|
// 字段设置来源(列表、列表-明细、明细页面) |
||||
|
rowSource:{ |
||||
|
type:String, |
||||
|
default:'list_api' |
||||
|
} |
||||
|
}, |
||||
|
data () { |
||||
|
return { |
||||
|
headerButttondata:null, |
||||
|
// 字段设置是否显示 |
||||
|
rowDropVisible: false, |
||||
|
// table 重新渲染所需key |
||||
|
isUpdate: false, |
||||
|
appRemoveHeight:165, |
||||
|
// 除去table的高度 |
||||
|
uTableTopHeight:165, |
||||
|
// table外部高度控制,用于点击筛选动画处理 |
||||
|
uTableOuterHeight:null, |
||||
|
// table外部最初始化高度,用于点击筛选动画处理 |
||||
|
uTableOuterHeight_init:null, |
||||
|
//table操作按钮 |
||||
|
Butttondata: [ |
||||
|
{ |
||||
|
type: 'danger', |
||||
|
icon: 'el-icon-delete', |
||||
|
label: '批量删除', |
||||
|
size: 'mini' |
||||
|
}, |
||||
|
{ |
||||
|
type: 'warning', |
||||
|
icon: 'el-icon-edit', |
||||
|
label: '批量修改状态', |
||||
|
size: 'mini' |
||||
|
}, |
||||
|
{ |
||||
|
type: 'success', |
||||
|
icon: 'el-icon-upload2', |
||||
|
label: '批量导出', |
||||
|
size: 'mini' |
||||
|
}, |
||||
|
{ |
||||
|
type: 'info', |
||||
|
icon: 'el-icon-printer', |
||||
|
label: '批量打印', |
||||
|
size: 'mini' |
||||
|
}, |
||||
|
], |
||||
|
// 全面筛选组件配置 |
||||
|
// 显示全面筛选组件 |
||||
|
showSearchOverall:false, |
||||
|
} |
||||
|
}, |
||||
|
mounted(){ |
||||
|
this.appRemoveHeight = this.setUTableHeight || 165 |
||||
|
this.uTableTopHeight = this.appRemoveHeight |
||||
|
this.uTableOuterHeight = this.$refs.tablePaginationTableRef.getTableHeight() |
||||
|
this.uTableOuterHeight_init = Number(JSON.stringify(this.uTableOuterHeight)) |
||||
|
this.initButttondata() |
||||
|
|
||||
|
// 点击外部,字段设置弹窗隐藏 |
||||
|
document.addEventListener('click',(e)=>{ |
||||
|
if(!this.rowDropVisible)return |
||||
|
let _class = "rowDropNotHideItem" |
||||
|
let _hasParent = getParentNode(e.target,_class) |
||||
|
let _current_class = e.target._prevClass || e.target.className |
||||
|
let _hasCurrent = _current_class ? String(_current_class).includes(_class) : false |
||||
|
if(!_hasParent && !_hasCurrent){ |
||||
|
this.closeRowDrop() |
||||
|
} |
||||
|
}) |
||||
|
}, |
||||
|
methods: { |
||||
|
initButttondata(){ |
||||
|
let _list = [] |
||||
|
this.currenButtonData.forEach(item=>{ |
||||
|
if(item.permission){ |
||||
|
_list.push(item) |
||||
|
}else{ |
||||
|
if(this.noUsePermissionBtn.indexOf(item.name) < 0){ |
||||
|
let _scope = item.clientScope || localStorage.getItem('appClientScope') |
||||
|
item.permission = [_scope + '.' +this.$route.name+'.'+(item.permissionName || item.name)] |
||||
|
}else{ |
||||
|
item.permission = [] |
||||
|
} |
||||
|
_list.push(item) |
||||
|
} |
||||
|
}) |
||||
|
this.headerButttondata = _list |
||||
|
}, |
||||
|
// 重新渲染表格 |
||||
|
doFreshTableLayout(){ |
||||
|
if(this.$refs.tablePaginationTableRef && this.$refs.tablePaginationTableRef.doFreshLayout){ |
||||
|
this.$refs.tablePaginationTableRef.doFreshLayout() |
||||
|
} |
||||
|
}, |
||||
|
rowDrop(data,type) { |
||||
|
this.$emit('rowDrop',data,type) |
||||
|
this.$nextTick(()=>{ |
||||
|
this.isUpdate = !this.isUpdate |
||||
|
}) |
||||
|
}, |
||||
|
//点击常用按钮 |
||||
|
topbutton (val,item) { |
||||
|
// 筛选按钮 + table高度变化 + 动画效果(勿动顺序) |
||||
|
if(val=="filter"){ |
||||
|
this.showSearchOverall = !this.showSearchOverall |
||||
|
// 有普通查询配置 |
||||
|
if(this.primarySearchOption && this.primarySearchOption.length > 0){ |
||||
|
this.$nextTick(()=>{ |
||||
|
let _search_height = this.$refs.searchOverallRef.getSearchPrimaryHeight() |
||||
|
this.changeTableHeight(_search_height) |
||||
|
// if(this.showSearchOverall){ |
||||
|
// let _margin = 20 |
||||
|
// this.uTableOuterHeight = this.uTableOuterHeight_init - _search_height - _margin |
||||
|
// setTimeout(()=>{ |
||||
|
// this.uTableTopHeight += _search_height + _margin |
||||
|
// },0) |
||||
|
// }else{ |
||||
|
// this.uTableOuterHeight = this.uTableOuterHeight_init |
||||
|
// setTimeout(()=>{ |
||||
|
// this.uTableTopHeight = 165 |
||||
|
// },0) |
||||
|
// } |
||||
|
}) |
||||
|
} |
||||
|
this.$nextTick(()=>{ |
||||
|
let _search_height = this.$refs.searchOverallRef.getAllSearchInnerHeight() |
||||
|
this.changeTableHeight(_search_height) |
||||
|
}) |
||||
|
} |
||||
|
// 字段设置 |
||||
|
else if (val == 'field') { |
||||
|
this.rowDropVisible = !this.rowDropVisible |
||||
|
} |
||||
|
this.$emit("topbutton", val,item) |
||||
|
}, |
||||
|
// 更改筛选时候的table高度问题 |
||||
|
changeTableHeight(minusHeight=0){ |
||||
|
if(this.showSearchOverall){ |
||||
|
let _margin = 20 |
||||
|
this.uTableOuterHeight = this.uTableOuterHeight_init - minusHeight - _margin |
||||
|
setTimeout(()=>{ |
||||
|
this.uTableTopHeight = minusHeight + this.appRemoveHeight + _margin |
||||
|
},0) |
||||
|
}else{ |
||||
|
this.uTableOuterHeight = this.uTableOuterHeight_init |
||||
|
setTimeout(()=>{ |
||||
|
this.uTableTopHeight = this.appRemoveHeight |
||||
|
},0) |
||||
|
} |
||||
|
}, |
||||
|
// 快速搜索 - 搜索按钮 |
||||
|
quicklySearchClick (val,option) { |
||||
|
this.$emit("quicklySearchClick", val,option,this.$refs.searchOverallRef) |
||||
|
}, |
||||
|
// 快速搜索 - 清除搜索 |
||||
|
quicklySearchClear (val,option) { |
||||
|
// 判断是否有筛选按钮 |
||||
|
let hasSearch = false |
||||
|
this.currenButtonData.forEach(item=>{ |
||||
|
if(item.name == 'filter'){ |
||||
|
hasSearch = true |
||||
|
return |
||||
|
} |
||||
|
}) |
||||
|
this.$emit("quicklySearchClear", val,option,this.$refs.searchOverallRef,hasSearch ) |
||||
|
}, |
||||
|
//接收分页组件emit改变每页最大页数 |
||||
|
alterResultCount (val) { |
||||
|
this.$emit('alterResultCount', val) |
||||
|
}, |
||||
|
//接收分页组件emit改变当前页 |
||||
|
alertoldSkipCount (val) { |
||||
|
this.$emit('alertoldSkipCount', val) |
||||
|
}, |
||||
|
//点击name提交emit打开编辑页面 |
||||
|
inlineDialog (row) { |
||||
|
this.$emit("inlineDialog", row) |
||||
|
}, |
||||
|
//点击selection框 |
||||
|
handleSelectionChange (val) { |
||||
|
this.$emit("handleSelectionChange", val) |
||||
|
}, |
||||
|
//排序 |
||||
|
sortChange (data) { |
||||
|
this.$emit('sortChange', data) |
||||
|
}, |
||||
|
//点击table操作列(左侧)按钮 |
||||
|
buttonOperationClick_left(row, item, index) { |
||||
|
this.$emit("buttonOperationClick_left", row, item, index); |
||||
|
}, |
||||
|
//点击table操作列(右侧)按钮 |
||||
|
buttonOperationClick_right(row, item, index) { |
||||
|
this.$emit("buttonOperationClick_right", row, item, index); |
||||
|
}, |
||||
|
// 全面筛选组件配置 |
||||
|
// 全面筛选组件内部显示/隐藏更改触发,同步当前的showSearchOverall值 |
||||
|
getShowSearchOverall(val){ |
||||
|
this.showSearchOverall = val || false |
||||
|
}, |
||||
|
// 全面筛选组件所有按钮事件 |
||||
|
overallSearchFormClick(options){ |
||||
|
//增加快速搜索实体 |
||||
|
if(this.$refs.tablePagination_topNav)options.vm_quickly = this.$refs.tablePagination_topNav.getQuicklySearchDom() |
||||
|
this.$emit("overallSearchFormClick", options) |
||||
|
}, |
||||
|
// 关闭字段设置 |
||||
|
closeRowDrop() { |
||||
|
this.rowDropVisible = false |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
<style lang="scss" scoped> |
||||
|
.uTableOuter{ |
||||
|
transition:all 0.5s; |
||||
|
overflow: hidden; |
||||
|
} |
||||
|
.tablePagination { |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
background-color: #fff; |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
|
||||
|
.table-nav { |
||||
|
padding-bottom: 15px; |
||||
|
} |
||||
|
|
||||
|
.el-table { |
||||
|
flex: 1; |
||||
|
} |
||||
|
} |
||||
|
</style> |
@ -0,0 +1,542 @@ |
|||||
|
<template> |
||||
|
<div class="tableTreeComponents"> |
||||
|
<div class="table-tree-search" v-if="showQueryHeader"> |
||||
|
<div class="bttton-box"> |
||||
|
<!-- 左侧按钮 --> |
||||
|
<el-button |
||||
|
v-for="(item,index) in leftButtons" |
||||
|
v-show="queryHeaderBtn.indexOf(item.name) >= 0" |
||||
|
:key="index" |
||||
|
:type="item.type" |
||||
|
:icon="item.icon" |
||||
|
:size="item.size" |
||||
|
@click="headerButtonsHandle(item)" |
||||
|
v-permission="item.permission || []" |
||||
|
>{{item.label}}</el-button> |
||||
|
</div> |
||||
|
<div class="query-box"> |
||||
|
<!-- 搜索 --> |
||||
|
<searchNormal |
||||
|
v-if="queryHeaderBtn.indexOf('search') >= 0" |
||||
|
ref="searchNormalRef" |
||||
|
@searchNormalClick="headerButtonsHandle({name:'search'})" |
||||
|
@searchNormalClear="headerButtonsHandle({name:'reset'})" |
||||
|
></searchNormal> |
||||
|
<!-- 右侧其他按钮 --> |
||||
|
<el-button |
||||
|
v-for="(item,index) in rightButtons" |
||||
|
v-show="queryHeaderBtn.indexOf(item.name) >= 0 && item.name != 'search'" |
||||
|
:key="index" |
||||
|
:type="item.type" |
||||
|
:icon="item.icon" |
||||
|
:size="item.size" |
||||
|
@click="headerButtonsHandle(item)" |
||||
|
v-permission="item.permission || []" |
||||
|
>{{item.label}}</el-button> |
||||
|
</div> |
||||
|
</div> |
||||
|
<el-table |
||||
|
ref="treeTableRef" |
||||
|
:data="tableData" |
||||
|
:row-key="rowkey" |
||||
|
style="width: 100%" |
||||
|
height="calc(100%)" |
||||
|
border |
||||
|
> |
||||
|
<el-table-column |
||||
|
v-for="(item,index) in treeColumn" |
||||
|
:key="index" |
||||
|
:label="item.label" |
||||
|
:width="item.width" |
||||
|
:align="item.align || 'left'" |
||||
|
:header-align="item.headerAlign || 'left'" |
||||
|
:show-overflow-tooltip="!item.hideTooltip" |
||||
|
:fixed="item.fixed" |
||||
|
> |
||||
|
<template slot-scope="scope"> |
||||
|
<span v-if="!item.filters">{{scope.row[item.prop]}}</span> |
||||
|
<span v-else>{{item.filters[scope.row[item.prop]]}}</span> |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
<el-table-column |
||||
|
label="操作" |
||||
|
header-align="center" |
||||
|
:align="treeAlign" |
||||
|
:width="handleBtnsWidth || Number(btnsData.length) * 55" |
||||
|
fixed="right" |
||||
|
> |
||||
|
<template slot-scope="scope"> |
||||
|
<el-button |
||||
|
v-for="(item,index) in btnsData" |
||||
|
:key="index" |
||||
|
:type="item.type" |
||||
|
:size="item.size" |
||||
|
@click="btnHandle(item,scope.row)" |
||||
|
:style="item.style" |
||||
|
v-show="typeof item.hide == 'function' ? !item.hide(scope.row) : !item.hide" |
||||
|
:icon="item.icon" |
||||
|
v-permission="item.permission || []" |
||||
|
>{{item.label}}</el-button> |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
</el-table> |
||||
|
|
||||
|
<!-- 新增/编辑弹窗 --> |
||||
|
<el-dialog |
||||
|
:title="treeEditTitle" |
||||
|
:visible.sync="treeEditDialog" |
||||
|
width="600px" |
||||
|
:close-on-click-modal="false" |
||||
|
> |
||||
|
<curren-Form |
||||
|
v-if="treeEditDialog" |
||||
|
v-loading="dialogLoading" |
||||
|
size="medium" |
||||
|
ref="treeEditDialogRef" |
||||
|
:searchData="treeEditFormData" |
||||
|
:searchForm="treeEditForm" |
||||
|
:rules="treeEditRules" |
||||
|
:searchHandle="treeEditHandle" |
||||
|
@push="DataPush(arguments)" |
||||
|
@submitForm="treeEditFormClick(arguments)" |
||||
|
></curren-Form> |
||||
|
<!-- @changeInput="changeInput" |
||||
|
@radioChange="radioChange" --> |
||||
|
<!-- :searchOptions="treeEditOptions" --> |
||||
|
</el-dialog> |
||||
|
</div> |
||||
|
</template> |
||||
|
<script> |
||||
|
import permission from "@/utils/permission/index"; |
||||
|
import { treeDefalutButton,formatDefalutConfig,queryDefalutButtons } from "@/utils/tableTree" |
||||
|
import searchNormal from "@/components/searchNormal/index.vue" |
||||
|
export default { |
||||
|
name: 'tableTreeComponents', |
||||
|
directives: { permission }, |
||||
|
components:{ |
||||
|
searchNormal |
||||
|
}, |
||||
|
watch:{ |
||||
|
treeData(n,o){ |
||||
|
if(n){ |
||||
|
this.init() |
||||
|
} |
||||
|
}, |
||||
|
treeEditData:{ |
||||
|
handler(n,o){ |
||||
|
this.treeEditFormData = n |
||||
|
}, |
||||
|
deep:true |
||||
|
} |
||||
|
}, |
||||
|
props: { |
||||
|
// 是否显示Query头部 |
||||
|
showQueryHeader:{ |
||||
|
type: Boolean, |
||||
|
default: true |
||||
|
}, |
||||
|
// 查询参数 |
||||
|
searchParam:{ |
||||
|
type: Object, |
||||
|
default: ()=>{ |
||||
|
return {name:'name',label:'菜单名称'} |
||||
|
} |
||||
|
}, |
||||
|
// Query头部显示按钮 |
||||
|
queryHeaderBtn:{ |
||||
|
type: Array, |
||||
|
default: () => { |
||||
|
return ['addFirst','fresh','search'] |
||||
|
} |
||||
|
}, |
||||
|
// 搜索栏左侧按钮(默认【创建一级菜单】、【刷新】) |
||||
|
queryLeftButtons: { |
||||
|
type: Array, |
||||
|
default: null |
||||
|
}, |
||||
|
// 头部创建一级菜单按钮显示名称 |
||||
|
headerAddName:{ |
||||
|
type: String, |
||||
|
default: null |
||||
|
}, |
||||
|
// 搜索栏左侧按钮(默认【搜索框】、【搜索】、【重置】) |
||||
|
queryRightButtons: { |
||||
|
type: Array, |
||||
|
default: null |
||||
|
}, |
||||
|
// 搜索栏按钮操作 |
||||
|
queryButtonsHandle:Function, |
||||
|
|
||||
|
// 刷新table数据 |
||||
|
rowkey:{ |
||||
|
type: String, |
||||
|
default: 'id' |
||||
|
}, |
||||
|
// 操作栏宽度 |
||||
|
handleBtnsWidth:{ |
||||
|
type: String, |
||||
|
default: null |
||||
|
}, |
||||
|
// 默认展开类型 all:全部 first:第一层 |
||||
|
expandedType:{ |
||||
|
type:String, |
||||
|
default:null |
||||
|
}, |
||||
|
// tree数据 |
||||
|
treeData: { |
||||
|
type: Array, |
||||
|
default: () => { |
||||
|
return [] |
||||
|
} |
||||
|
}, |
||||
|
// tree配置 |
||||
|
treeColumn: { |
||||
|
type: Array, |
||||
|
default: () => { |
||||
|
return [] |
||||
|
} |
||||
|
}, |
||||
|
// 是否需要格式化数据 |
||||
|
needFormatData:{ |
||||
|
type: Boolean, |
||||
|
default:false |
||||
|
}, |
||||
|
// 格式化数据配置 |
||||
|
formatDataConfig:{ |
||||
|
type: Object, |
||||
|
default: () => { |
||||
|
return formatDefalutConfig() |
||||
|
} |
||||
|
}, |
||||
|
// table操作按钮 |
||||
|
treeButtons: { |
||||
|
type: Array, |
||||
|
default: null |
||||
|
}, |
||||
|
// table操作居中 |
||||
|
treeAlign:{ |
||||
|
type: String, |
||||
|
default: 'right' |
||||
|
}, |
||||
|
// 新增/操作数据 |
||||
|
treeEditData:{ |
||||
|
type: Object, |
||||
|
default: null |
||||
|
}, |
||||
|
// 新增/编辑显示 |
||||
|
treeEditForm:{ |
||||
|
type: Array, |
||||
|
default: ()=>{ |
||||
|
return [] |
||||
|
} |
||||
|
}, |
||||
|
// 新增/编辑Rules |
||||
|
treeEditRules:{ |
||||
|
type: Object, |
||||
|
default: ()=>{ |
||||
|
return {} |
||||
|
} |
||||
|
}, |
||||
|
// 新增/编辑Rules |
||||
|
treeEditHandle:{ |
||||
|
type: Array, |
||||
|
default: ()=>{ |
||||
|
return [ |
||||
|
{ label: "取消", name: "cancel" }, |
||||
|
{ label: "确认", name: "sure", type:"primary" }, |
||||
|
] |
||||
|
} |
||||
|
}, |
||||
|
// 点击编辑前 |
||||
|
treeEditBefore:Function, |
||||
|
// 取消提交前 |
||||
|
treeEditCancle:Function, |
||||
|
// 提交事件 |
||||
|
treeEditSubmit:Function, |
||||
|
// 删除事件 |
||||
|
treeEditDelete:Function, |
||||
|
}, |
||||
|
data () { |
||||
|
return { |
||||
|
leftButtons:[],//左侧按钮 |
||||
|
rightButtons:[],//右侧按钮 |
||||
|
|
||||
|
tableData: [],//table渲染 |
||||
|
tableDataCopy: [],//用于查询存储所有数据 |
||||
|
btnsData:[],//table中的按钮 |
||||
|
|
||||
|
treeEditDialog:false,//新增编辑弹窗显示 |
||||
|
dialogLoading:false,//编辑弹窗加载 |
||||
|
treeEditTitle:"",//新增编辑弹窗title |
||||
|
isEdit:false,//false:编辑 true:新建 |
||||
|
treeEditFormData:[],//编辑弹窗内数据 |
||||
|
} |
||||
|
}, |
||||
|
activated(){ |
||||
|
// 解决切换导航后,页面table窜行问题 |
||||
|
this.$refs.treeTableRef.doLayout(); |
||||
|
}, |
||||
|
created(){ |
||||
|
this.init() |
||||
|
}, |
||||
|
methods: { |
||||
|
init(){ |
||||
|
// 头部左侧的按钮 |
||||
|
if(this.queryLeftButtons){ |
||||
|
this.leftButtons = this.queryLeftButtons |
||||
|
}else{ |
||||
|
this.leftButtons = [ |
||||
|
...queryDefalutButtons("left",this.headerAddName) |
||||
|
] |
||||
|
} |
||||
|
// 头部右侧的按钮 |
||||
|
if(this.queryRightButtons){ |
||||
|
this.rightButtons = this.queryRightButtons |
||||
|
}else{ |
||||
|
this.rightButtons = [ |
||||
|
...queryDefalutButtons("right") |
||||
|
] |
||||
|
} |
||||
|
|
||||
|
// 数据 |
||||
|
if(this.treeData){ |
||||
|
if(!this.needFormatData){ |
||||
|
this.tableData = this.treeData |
||||
|
}else{ |
||||
|
let _tree = this.initTreeData(this.treeData).sort(this.sortData(this.formatDataConfig.sort)) |
||||
|
this.tableData = _tree |
||||
|
} |
||||
|
this.tableDataCopy = JSON.parse(JSON.stringify(this.tableData)) |
||||
|
// 展开情况 |
||||
|
this.$nextTick(()=>{ |
||||
|
this.initTreeExpanded() |
||||
|
}) |
||||
|
} |
||||
|
// table中的按钮 |
||||
|
if(this.treeButtons){ |
||||
|
this.btnsData = this.treeButtons |
||||
|
}else{ |
||||
|
this.btnsData = [ |
||||
|
...treeDefalutButton() |
||||
|
] |
||||
|
} |
||||
|
|
||||
|
// 新增/编辑数据 |
||||
|
this.treeEditFormData = this.treeEditData |
||||
|
}, |
||||
|
// 展开情况处理 |
||||
|
initTreeExpanded(type){ |
||||
|
let _type = type || this.expandedType |
||||
|
let _this = this |
||||
|
function __changHandle(exp){ |
||||
|
_this.tableData.forEach(item=>{ |
||||
|
item.children.forEach(item_c=>{ |
||||
|
_this.$refs.treeTableRef.toggleRowExpansion(item_c,Boolean(exp)); |
||||
|
}) |
||||
|
_this.$refs.treeTableRef.toggleRowExpansion(item,Boolean(exp)); |
||||
|
}) |
||||
|
} |
||||
|
if(!_type){ |
||||
|
__changHandle(false) |
||||
|
} |
||||
|
else if(_type == "all"){ |
||||
|
__changHandle(true) |
||||
|
} |
||||
|
else if(_type == "first"){ |
||||
|
this.tableData.forEach((item,key)=>{ |
||||
|
let _exp = key == 0 ? true : false |
||||
|
item.children.forEach(item_c=>{ |
||||
|
this.$refs.treeTableRef.toggleRowExpansion(item_c,_exp); |
||||
|
}) |
||||
|
this.$refs.treeTableRef.toggleRowExpansion(item,_exp); |
||||
|
}) |
||||
|
} |
||||
|
}, |
||||
|
// 刷新新增/查询显示配置,如何时更改disabled属性等 |
||||
|
freshTreeEditForm(item,row){ |
||||
|
this.$emit("freshTreeEditForm",item,row); |
||||
|
}, |
||||
|
// 树状图格式化数据 |
||||
|
initTreeData(list,code = ""){ |
||||
|
const children = [] |
||||
|
// 对于list,每个元素.如果他的parentCode==code,他就是当前的children |
||||
|
list.forEach(item => { |
||||
|
if (item[this.formatDataConfig.parentCode] == code) { |
||||
|
children.push(item) |
||||
|
//排序 |
||||
|
item.children=this.initTreeData(list,item[this.formatDataConfig.code]).sort(this.sortData(this.formatDataConfig.sort)) |
||||
|
} |
||||
|
}) |
||||
|
return children |
||||
|
}, |
||||
|
// table排序 |
||||
|
/** |
||||
|
* sort 按照排序字段(现在为数字) 默认sort |
||||
|
*/ |
||||
|
sortData(sort){ |
||||
|
return function(a,b){ |
||||
|
const val1 = a[sort]; |
||||
|
const val2 = b[sort]; |
||||
|
return val1 - val2; |
||||
|
} |
||||
|
}, |
||||
|
// 头部创建一级菜单 |
||||
|
createFirstTreeHandle(item) { |
||||
|
this.treeEditDialog = true |
||||
|
this.treeEditTitle = item.label |
||||
|
this.isEdit = false; |
||||
|
this.freshTreeEditForm(item) |
||||
|
}, |
||||
|
// 获取search的值 |
||||
|
getSearchValue(){ |
||||
|
return this.$refs.searchNormalRef.getSearchNormalValue() |
||||
|
}, |
||||
|
// 清除search的值 |
||||
|
clearSearchValue(){ |
||||
|
this.$refs.searchNormalRef.searchNormalClear(true) |
||||
|
}, |
||||
|
//头部刷新 |
||||
|
createView(){ |
||||
|
this.resetView() |
||||
|
this.$emit("freshTreeData",this.getSearchValue()); |
||||
|
}, |
||||
|
// 头部搜索 |
||||
|
querySearchHandle(data){ |
||||
|
this.tableData=[]; |
||||
|
let newarr = []; |
||||
|
let _data = data || this.tableDataCopy; |
||||
|
_data.forEach(element => { |
||||
|
if (String(element[this.searchParam.name]).indexOf(this.getSearchValue()) >= 0) { |
||||
|
newarr.push(element); |
||||
|
} |
||||
|
else { |
||||
|
if (element.children && element.children.length > 0) { |
||||
|
const newObj = this.querySearchHandle(element.children); |
||||
|
const obj = { |
||||
|
...element, |
||||
|
children: newObj |
||||
|
}; |
||||
|
if (newObj && newObj.length > 0) { |
||||
|
newarr.push(obj); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
this.tableData=newarr; |
||||
|
return newarr |
||||
|
}, |
||||
|
//头部重置 |
||||
|
resetView(){ |
||||
|
this.clearSearchValue() |
||||
|
this.querySearchHandle() |
||||
|
this.initTreeExpanded(null) |
||||
|
}, |
||||
|
// table中操作按钮 |
||||
|
btnHandle(item,row){ |
||||
|
// 创建子菜单 |
||||
|
if(item.name == "add"){ |
||||
|
this.treeEditDialog = true |
||||
|
this.treeEditTitle = item.label |
||||
|
this.isEdit = false; |
||||
|
this.freshTreeEditForm(item,row) |
||||
|
} |
||||
|
// 编辑 |
||||
|
if(item.name == "edit"){ |
||||
|
this.freshTreeEditForm(item,row) |
||||
|
this.treeEditDialog = true |
||||
|
this.treeEditTitle = item.label |
||||
|
this.isEdit = true; |
||||
|
if(this.treeEditBefore){ |
||||
|
this.dialogLoading = true |
||||
|
this.treeEditBefore(row) |
||||
|
.then((data)=>{ |
||||
|
this.dialogLoading = false |
||||
|
this.treeEditFormData = data; |
||||
|
row = data |
||||
|
}) |
||||
|
.catch(err=>{ |
||||
|
this.dialogLoading = false |
||||
|
}) |
||||
|
}else{ |
||||
|
this.treeEditFormData = JSON.parse(JSON.stringify(row)); |
||||
|
} |
||||
|
} |
||||
|
// 删除 |
||||
|
if(item.name == "delete"){ |
||||
|
this.$emit("treeEditDelete",row); |
||||
|
} |
||||
|
}, |
||||
|
// 头部查询按钮操作 |
||||
|
headerButtonsHandle(item){ |
||||
|
let _goon = true |
||||
|
if(this.queryButtonsHandle){ |
||||
|
_goon = this.queryButtonsHandle(item,this.getSearchValue()) |
||||
|
} |
||||
|
if(!_goon)return |
||||
|
if(item.name == "addFirst"){ |
||||
|
this.createFirstTreeHandle(item) |
||||
|
} |
||||
|
if(item.name == "fresh"){ |
||||
|
this.createView(item) |
||||
|
} |
||||
|
if(item.name == "search"){ |
||||
|
this.querySearchHandle() |
||||
|
let _exp = this.getSearchValue() && this.getSearchValue().length > 0 ? 'all' : null |
||||
|
this.initTreeExpanded(_exp) |
||||
|
} |
||||
|
if(item.name == "reset"){ |
||||
|
this.resetView(item) |
||||
|
} |
||||
|
}, |
||||
|
// 重置表单 |
||||
|
treeEditResetFields(){ |
||||
|
this.$refs.treeEditDialogRef.getDom().resetFields(); |
||||
|
this.$nextTick(()=>{ |
||||
|
this.treeEditDialog = false; |
||||
|
this.dialogLoading = false |
||||
|
}) |
||||
|
}, |
||||
|
// 新增/修改按钮事件 |
||||
|
treeEditFormClick(val,row){ |
||||
|
// 取消 |
||||
|
if(val[2].name == "cancel"){ |
||||
|
if(this.treeEditCancle){ |
||||
|
this.dialogLoading = true |
||||
|
this.treeEditCancle(this.isEdit,this.treeEditFormData,val) |
||||
|
.then(()=>{ |
||||
|
this.treeEditResetFields() |
||||
|
}) |
||||
|
.catch(err=>{ |
||||
|
this.dialogLoading = false |
||||
|
}) |
||||
|
}else{ |
||||
|
this.treeEditResetFields() |
||||
|
} |
||||
|
} |
||||
|
// 确定 |
||||
|
if(val[2].name == "sure"){ |
||||
|
this.$refs.treeEditDialogRef.getDom().validate((valid) => { |
||||
|
if(valid){ |
||||
|
if(this.treeEditSubmit){ |
||||
|
this.dialogLoading = true |
||||
|
this.treeEditSubmit(this.isEdit,this.treeEditFormData,val) |
||||
|
.then(()=>{ |
||||
|
this.clearSearchValue() |
||||
|
this.treeEditResetFields() |
||||
|
}) |
||||
|
.catch(err=>{ |
||||
|
this.dialogLoading = false |
||||
|
}) |
||||
|
}else{ |
||||
|
this.treeEditResetFields() |
||||
|
} |
||||
|
} |
||||
|
}) |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
<style lang="scss" scoped> |
||||
|
@import "./style/index.scss"; |
||||
|
</style> |
@ -0,0 +1,24 @@ |
|||||
|
.tableTreeComponents{ |
||||
|
height: 100%; |
||||
|
// background-color: #f2f2f2; |
||||
|
|
||||
|
.table-tree-search { |
||||
|
display: flex; |
||||
|
flex-wrap: wrap; |
||||
|
justify-content: space-between; |
||||
|
align-items: center; |
||||
|
padding: 20px 0; |
||||
|
|
||||
|
.bttton-box { |
||||
|
display: flex; |
||||
|
} |
||||
|
|
||||
|
.query-box { |
||||
|
display: flex; |
||||
|
|
||||
|
.el-input { |
||||
|
margin: 0 5px; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |