Browse Source

【inventory】项目初始化

master
安虹睿 1 year ago
parent
commit
88c673f017
  1. 14
      PC/UI.WinIn.FasterZ.Inventory/.editorconfig
  2. 8
      PC/UI.WinIn.FasterZ.Inventory/.env.development
  3. 14
      PC/UI.WinIn.FasterZ.Inventory/.env.production
  4. 8
      PC/UI.WinIn.FasterZ.Inventory/.env.staging
  5. 5
      PC/UI.WinIn.FasterZ.Inventory/.eslintignore
  6. 198
      PC/UI.WinIn.FasterZ.Inventory/.eslintrc.js
  7. 116
      PC/UI.WinIn.FasterZ.Inventory/.gitignore
  8. 0
      PC/UI.WinIn.FasterZ.Inventory/.gitkeep
  9. 1
      PC/UI.WinIn.FasterZ.Inventory/.npmrc
  10. 5
      PC/UI.WinIn.FasterZ.Inventory/.travis.yml
  11. 21
      PC/UI.WinIn.FasterZ.Inventory/LICENSE
  12. 126
      PC/UI.WinIn.FasterZ.Inventory/README.md
  13. 14
      PC/UI.WinIn.FasterZ.Inventory/babel.config.js
  14. 35
      PC/UI.WinIn.FasterZ.Inventory/build/index.js
  15. 24
      PC/UI.WinIn.FasterZ.Inventory/jest.config.js
  16. 9
      PC/UI.WinIn.FasterZ.Inventory/jsconfig.json
  17. 42687
      PC/UI.WinIn.FasterZ.Inventory/package-lock.json
  18. 123
      PC/UI.WinIn.FasterZ.Inventory/package.json
  19. 26
      PC/UI.WinIn.FasterZ.Inventory/plop-templates/component/index.hbs
  20. 55
      PC/UI.WinIn.FasterZ.Inventory/plop-templates/component/prompt.js
  21. 16
      PC/UI.WinIn.FasterZ.Inventory/plop-templates/store/index.hbs
  22. 62
      PC/UI.WinIn.FasterZ.Inventory/plop-templates/store/prompt.js
  23. 2
      PC/UI.WinIn.FasterZ.Inventory/plop-templates/utils.js
  24. 26
      PC/UI.WinIn.FasterZ.Inventory/plop-templates/view/index.hbs
  25. 55
      PC/UI.WinIn.FasterZ.Inventory/plop-templates/view/prompt.js
  26. 9
      PC/UI.WinIn.FasterZ.Inventory/plopfile.js
  27. 5
      PC/UI.WinIn.FasterZ.Inventory/postcss.config.js
  28. 1
      PC/UI.WinIn.FasterZ.Inventory/public/WMS.svg
  29. 26
      PC/UI.WinIn.FasterZ.Inventory/public/config.js
  30. BIN
      PC/UI.WinIn.FasterZ.Inventory/public/favicon.ico
  31. BIN
      PC/UI.WinIn.FasterZ.Inventory/public/img_login_bg.jpg
  32. 30
      PC/UI.WinIn.FasterZ.Inventory/public/index.html
  33. 3
      PC/UI.WinIn.FasterZ.Inventory/public/version.json
  34. 98
      PC/UI.WinIn.FasterZ.Inventory/src/App.vue
  35. 177
      PC/UI.WinIn.FasterZ.Inventory/src/api/wms-api.js
  36. 207
      PC/UI.WinIn.FasterZ.Inventory/src/api/wms-auth.js
  37. 49
      PC/UI.WinIn.FasterZ.Inventory/src/api/wms-job.js
  38. BIN
      PC/UI.WinIn.FasterZ.Inventory/src/assets/401_images/401.gif
  39. BIN
      PC/UI.WinIn.FasterZ.Inventory/src/assets/404_images/404.png
  40. BIN
      PC/UI.WinIn.FasterZ.Inventory/src/assets/404_images/404_cloud.png
  41. BIN
      PC/UI.WinIn.FasterZ.Inventory/src/assets/custom-theme/fonts/element-icons.ttf
  42. BIN
      PC/UI.WinIn.FasterZ.Inventory/src/assets/custom-theme/fonts/element-icons.woff
  43. 1
      PC/UI.WinIn.FasterZ.Inventory/src/assets/custom-theme/index.css
  44. 2
      PC/UI.WinIn.FasterZ.Inventory/src/assets/img/Profile.svg
  45. BIN
      PC/UI.WinIn.FasterZ.Inventory/src/assets/img/drawerHeader.png
  46. BIN
      PC/UI.WinIn.FasterZ.Inventory/src/assets/img/menuLogo.png
  47. 84
      PC/UI.WinIn.FasterZ.Inventory/src/components/Breadcrumb/index.vue
  48. 94
      PC/UI.WinIn.FasterZ.Inventory/src/components/ErrorLog/index.vue
  49. 44
      PC/UI.WinIn.FasterZ.Inventory/src/components/Hamburger/index.vue
  50. 190
      PC/UI.WinIn.FasterZ.Inventory/src/components/HeaderSearch/index.vue
  51. 82
      PC/UI.WinIn.FasterZ.Inventory/src/components/Pagination/index.vue
  52. 149
      PC/UI.WinIn.FasterZ.Inventory/src/components/RightPanel/index.vue
  53. 60
      PC/UI.WinIn.FasterZ.Inventory/src/components/Screenfull/index.vue
  54. 58
      PC/UI.WinIn.FasterZ.Inventory/src/components/SizeSelect/index.vue
  55. 213
      PC/UI.WinIn.FasterZ.Inventory/src/components/StepsFormAlone/index.vue
  56. 44
      PC/UI.WinIn.FasterZ.Inventory/src/components/StepsFormAlone/style/index.scss
  57. 62
      PC/UI.WinIn.FasterZ.Inventory/src/components/SvgIcon/index.vue
  58. 173
      PC/UI.WinIn.FasterZ.Inventory/src/components/ThemePicker/index.vue
  59. 324
      PC/UI.WinIn.FasterZ.Inventory/src/components/UploadExcel/index.vue
  60. 367
      PC/UI.WinIn.FasterZ.Inventory/src/components/addEditFromApiPop/index.vue
  61. 312
      PC/UI.WinIn.FasterZ.Inventory/src/components/addEditFromApiPop/index_mst.vue
  62. 77
      PC/UI.WinIn.FasterZ.Inventory/src/components/batchButton/index.vue
  63. 634
      PC/UI.WinIn.FasterZ.Inventory/src/components/commonTabel-drawer/index.vue
  64. 122
      PC/UI.WinIn.FasterZ.Inventory/src/components/commonTabel-drawer/style/index.scss
  65. 349
      PC/UI.WinIn.FasterZ.Inventory/src/components/conditionFilters/index.vue
  66. 46
      PC/UI.WinIn.FasterZ.Inventory/src/components/conditionFilters/style/index.scss
  67. 107
      PC/UI.WinIn.FasterZ.Inventory/src/components/currenButton/index.vue
  68. 66
      PC/UI.WinIn.FasterZ.Inventory/src/components/currenButton/innerButton.vue
  69. 181
      PC/UI.WinIn.FasterZ.Inventory/src/components/currenDescriptions/index copy.vue
  70. 174
      PC/UI.WinIn.FasterZ.Inventory/src/components/currenDescriptions/index.vue
  71. 888
      PC/UI.WinIn.FasterZ.Inventory/src/components/currenForm/index.vue
  72. 888
      PC/UI.WinIn.FasterZ.Inventory/src/components/currenFormApi/index.vue
  73. 761
      PC/UI.WinIn.FasterZ.Inventory/src/components/currenTable/index.vue
  74. 322
      PC/UI.WinIn.FasterZ.Inventory/src/components/currenTableFlex/index.vue
  75. 12
      PC/UI.WinIn.FasterZ.Inventory/src/components/currenTableFlex/style/index.scss
  76. 57
      PC/UI.WinIn.FasterZ.Inventory/src/components/currenTabs/index.vue
  77. 82
      PC/UI.WinIn.FasterZ.Inventory/src/components/currenUpload/index.vue
  78. 72
      PC/UI.WinIn.FasterZ.Inventory/src/components/currenUploadList/index.vue
  79. 100
      PC/UI.WinIn.FasterZ.Inventory/src/components/currenUploadPictureCard/index.vue
  80. 89
      PC/UI.WinIn.FasterZ.Inventory/src/components/exportDrop/index.vue
  81. 338
      PC/UI.WinIn.FasterZ.Inventory/src/components/filterForDetailPage/index.vue
  82. 214
      PC/UI.WinIn.FasterZ.Inventory/src/components/filterSelect/index.vue
  83. 298
      PC/UI.WinIn.FasterZ.Inventory/src/components/importFile/index.vue
  84. 278
      PC/UI.WinIn.FasterZ.Inventory/src/components/newAndEdiDialog/index.vue
  85. 81
      PC/UI.WinIn.FasterZ.Inventory/src/components/pdf/index.vue
  86. 43
      PC/UI.WinIn.FasterZ.Inventory/src/components/resultStatus/index.vue
  87. 265
      PC/UI.WinIn.FasterZ.Inventory/src/components/rowDrop/index.vue
  88. 66
      PC/UI.WinIn.FasterZ.Inventory/src/components/searchNormal/index.vue
  89. 63
      PC/UI.WinIn.FasterZ.Inventory/src/components/searchNormal/style/index.scss
  90. 611
      PC/UI.WinIn.FasterZ.Inventory/src/components/searchOverall/index copy.vue
  91. 647
      PC/UI.WinIn.FasterZ.Inventory/src/components/searchOverall/index.vue
  92. 83
      PC/UI.WinIn.FasterZ.Inventory/src/components/searchOverall/style/index copy.scss
  93. 89
      PC/UI.WinIn.FasterZ.Inventory/src/components/searchOverall/style/index.scss
  94. 336
      PC/UI.WinIn.FasterZ.Inventory/src/components/searchPage/index.vue
  95. 242
      PC/UI.WinIn.FasterZ.Inventory/src/components/searchPrimary/index.vue
  96. 284
      PC/UI.WinIn.FasterZ.Inventory/src/components/showCopyJsonPop/index.vue
  97. 402
      PC/UI.WinIn.FasterZ.Inventory/src/components/tablePagination/index copy.vue
  98. 464
      PC/UI.WinIn.FasterZ.Inventory/src/components/tablePagination/index.vue
  99. 542
      PC/UI.WinIn.FasterZ.Inventory/src/components/tableTree/index.vue
  100. 24
      PC/UI.WinIn.FasterZ.Inventory/src/components/tableTree/style/index.scss

14
PC/UI.WinIn.FasterZ.Inventory/.editorconfig

@ -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

8
PC/UI.WinIn.FasterZ.Inventory/.env.development

@ -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'

14
PC/UI.WinIn.FasterZ.Inventory/.env.production

@ -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'

8
PC/UI.WinIn.FasterZ.Inventory/.env.staging

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

5
PC/UI.WinIn.FasterZ.Inventory/.eslintignore

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

198
PC/UI.WinIn.FasterZ.Inventory/.eslintrc.js

@ -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']
}
}

116
PC/UI.WinIn.FasterZ.Inventory/.gitignore

@ -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
PC/UI.WinIn.FasterZ.Inventory/.gitkeep

1
PC/UI.WinIn.FasterZ.Inventory/.npmrc

@ -0,0 +1 @@
registry=https://registry.npm.taobao.org/

5
PC/UI.WinIn.FasterZ.Inventory/.travis.yml

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

21
PC/UI.WinIn.FasterZ.Inventory/LICENSE

@ -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.

126
PC/UI.WinIn.FasterZ.Inventory/README.md

@ -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},

14
PC/UI.WinIn.FasterZ.Inventory/babel.config.js

@ -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']
}
}
}

35
PC/UI.WinIn.FasterZ.Inventory/build/index.js

@ -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}`)
}

24
PC/UI.WinIn.FasterZ.Inventory/jest.config.js

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

9
PC/UI.WinIn.FasterZ.Inventory/jsconfig.json

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

42687
PC/UI.WinIn.FasterZ.Inventory/package-lock.json

File diff suppressed because it is too large

123
PC/UI.WinIn.FasterZ.Inventory/package.json

@ -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"
}
}

26
PC/UI.WinIn.FasterZ.Inventory/plop-templates/component/index.hbs

@ -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}}

55
PC/UI.WinIn.FasterZ.Inventory/plop-templates/component/prompt.js

@ -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
}
}

16
PC/UI.WinIn.FasterZ.Inventory/plop-templates/store/index.hbs

@ -0,0 +1,16 @@
{{#if state}}
const state = {}
{{/if}}
{{#if mutations}}
const mutations = {}
{{/if}}
{{#if actions}}
const actions = {}
{{/if}}
export default {
namespaced: true,
{{options}}
}

62
PC/UI.WinIn.FasterZ.Inventory/plop-templates/store/prompt.js

@ -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
}
}

2
PC/UI.WinIn.FasterZ.Inventory/plop-templates/utils.js

@ -0,0 +1,2 @@
exports.notEmpty = name => v =>
!v || v.trim() === '' ? `${name} is required` : true

26
PC/UI.WinIn.FasterZ.Inventory/plop-templates/view/index.hbs

@ -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}}

55
PC/UI.WinIn.FasterZ.Inventory/plop-templates/view/prompt.js

@ -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
}
}

9
PC/UI.WinIn.FasterZ.Inventory/plopfile.js

@ -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)
}

5
PC/UI.WinIn.FasterZ.Inventory/postcss.config.js

@ -0,0 +1,5 @@
module.exports = {
plugins: {
autoprefixer: {}
}
}

1
PC/UI.WinIn.FasterZ.Inventory/public/WMS.svg

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1642571135328" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2046" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M935.808 330.752c10.624 18.176 16.128 26.112 16.768 48.64V840.96c-1.152 35.712-7.296 59.264-30.848 82.944-23.552 23.68-46.976 29.952-82.432 30.976H184.704c-35.584-1.152-59.008-7.424-82.432-30.976C78.72 900.224 72.576 876.8 71.424 840.96V379.392c0-22.528 5.76-30.464 17.152-48.64 11.52-18.176 20.608-27.392 39.552-40.064L449.152 88.064c19.456-12.672 41.472-19.072 65.792-19.072s46.336 6.272 65.792 19.072l321.152 202.624c16.128 12.672 23.296 21.888 33.92 40.064z" fill="#319EEC" p-id="2047"></path><path d="M447.616 833.28H261.504c-27.52 0-50.048-22.528-50.048-50.048V595.584c0-27.52 22.528-50.048 50.048-50.048h186.112c27.52 0 50.048 22.528 50.048 50.048v187.648c0.128 27.52-22.4 50.048-50.048 50.048zM640.896 823.936h-80.896c-12.032 0-21.76-9.856-21.76-21.76V720.64c0-12.032 9.856-21.76 21.76-21.76h80.896c12.032 0 21.76 9.856 21.76 21.76v81.536c0 12.032-9.728 21.76-21.76 21.76zM640.896 670.72h-80.896c-12.032 0-21.76-9.856-21.76-21.76v-81.536c0-12.032 9.856-21.76 21.76-21.76h80.896c12.032 0 21.76 9.856 21.76 21.76V648.96c0 11.904-9.728 21.76-21.76 21.76zM802.944 823.936h-80.896c-12.032 0-21.76-9.856-21.76-21.76V720.64c0-12.032 9.856-21.76 21.76-21.76h80.896c12.032 0 21.76 9.856 21.76 21.76v81.536c0 12.032-9.728 21.76-21.76 21.76z" fill="#FFFFFF" p-id="2048"></path></svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

26
PC/UI.WinIn.FasterZ.Inventory/public/config.js

@ -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'] = []

BIN
PC/UI.WinIn.FasterZ.Inventory/public/favicon.ico

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

BIN
PC/UI.WinIn.FasterZ.Inventory/public/img_login_bg.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 303 KiB

30
PC/UI.WinIn.FasterZ.Inventory/public/index.html

@ -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>

3
PC/UI.WinIn.FasterZ.Inventory/public/version.json

@ -0,0 +1,3 @@
{
"version": "1.0.45"
}

98
PC/UI.WinIn.FasterZ.Inventory/src/App.vue

@ -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>

177
PC/UI.WinIn.FasterZ.Inventory/src/api/wms-api.js

@ -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}
})
}

207
PC/UI.WinIn.FasterZ.Inventory/src/api/wms-auth.js

@ -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
})
}

49
PC/UI.WinIn.FasterZ.Inventory/src/api/wms-job.js

@ -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
})
}

BIN
PC/UI.WinIn.FasterZ.Inventory/src/assets/401_images/401.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 KiB

BIN
PC/UI.WinIn.FasterZ.Inventory/src/assets/404_images/404.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

BIN
PC/UI.WinIn.FasterZ.Inventory/src/assets/404_images/404_cloud.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

BIN
PC/UI.WinIn.FasterZ.Inventory/src/assets/custom-theme/fonts/element-icons.ttf

Binary file not shown.

BIN
PC/UI.WinIn.FasterZ.Inventory/src/assets/custom-theme/fonts/element-icons.woff

Binary file not shown.

1
PC/UI.WinIn.FasterZ.Inventory/src/assets/custom-theme/index.css

File diff suppressed because one or more lines are too long

2
PC/UI.WinIn.FasterZ.Inventory/src/assets/img/Profile.svg

@ -0,0 +1,2 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1648694852408" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="64325" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css">@font-face { font-family: feedback-iconfont; src: url("//at.alicdn.com/t/font_1031158_u69w8yhxdu.woff2?t=1630033759944") format("woff2"), url("//at.alicdn.com/t/font_1031158_u69w8yhxdu.woff?t=1630033759944") format("woff"), url("//at.alicdn.com/t/font_1031158_u69w8yhxdu.ttf?t=1630033759944") format("truetype"); }
</style></defs><path d="M509.952 10.24C232.448 10.24 8.192 234.496 8.192 512s224.256 501.76 501.76 501.76 501.76-224.256 501.76-501.76-224.256-501.76-501.76-501.76z m0 152.576c84.992 0 153.6 68.608 153.6 153.6s-68.608 153.6-153.6 153.6-153.6-68.608-153.6-153.6 68.608-153.6 153.6-153.6z m-1.024 698.368c-177.152 0-320.512-80.896-320.512-168.96S331.776 532.48 509.952 532.48c177.152 0 321.536 71.68 321.536 159.744S686.08 861.184 508.928 861.184z" p-id="64326" fill="#1296db"></path></svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
PC/UI.WinIn.FasterZ.Inventory/src/assets/img/drawerHeader.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
PC/UI.WinIn.FasterZ.Inventory/src/assets/img/menuLogo.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

84
PC/UI.WinIn.FasterZ.Inventory/src/components/Breadcrumb/index.vue

@ -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>

94
PC/UI.WinIn.FasterZ.Inventory/src/components/ErrorLog/index.vue

@ -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>

44
PC/UI.WinIn.FasterZ.Inventory/src/components/Hamburger/index.vue

@ -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>

190
PC/UI.WinIn.FasterZ.Inventory/src/components/HeaderSearch/index.vue

@ -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>

82
PC/UI.WinIn.FasterZ.Inventory/src/components/Pagination/index.vue

@ -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>

149
PC/UI.WinIn.FasterZ.Inventory/src/components/RightPanel/index.vue

@ -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>

60
PC/UI.WinIn.FasterZ.Inventory/src/components/Screenfull/index.vue

@ -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>

58
PC/UI.WinIn.FasterZ.Inventory/src/components/SizeSelect/index.vue

@ -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>

213
PC/UI.WinIn.FasterZ.Inventory/src/components/StepsFormAlone/index.vue

@ -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},
]
}
},
// verticalstepsAlignCenter=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>

44
PC/UI.WinIn.FasterZ.Inventory/src/components/StepsFormAlone/style/index.scss

@ -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);
}
}
}
}

62
PC/UI.WinIn.FasterZ.Inventory/src/components/SvgIcon/index.vue

@ -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>

173
PC/UI.WinIn.FasterZ.Inventory/src/components/ThemePicker/index.vue

@ -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>

324
PC/UI.WinIn.FasterZ.Inventory/src/components/UploadExcel/index.vue

@ -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>

367
PC/UI.WinIn.FasterZ.Inventory/src/components/addEditFromApiPop/index.vue

@ -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>

312
PC/UI.WinIn.FasterZ.Inventory/src/components/addEditFromApiPop/index_mst.vue

@ -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>

77
PC/UI.WinIn.FasterZ.Inventory/src/components/batchButton/index.vue

@ -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>

634
PC/UI.WinIn.FasterZ.Inventory/src/components/commonTabel-drawer/index.vue

@ -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)
},
//nameemit
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>

122
PC/UI.WinIn.FasterZ.Inventory/src/components/commonTabel-drawer/style/index.scss

@ -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;
}

349
PC/UI.WinIn.FasterZ.Inventory/src/components/conditionFilters/index.vue

@ -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>

46
PC/UI.WinIn.FasterZ.Inventory/src/components/conditionFilters/style/index.scss

@ -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;
}
}

107
PC/UI.WinIn.FasterZ.Inventory/src/components/currenButton/index.vue

@ -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>

66
PC/UI.WinIn.FasterZ.Inventory/src/components/currenButton/innerButton.vue

@ -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>

181
PC/UI.WinIn.FasterZ.Inventory/src/components/currenDescriptions/index copy.vue

@ -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>

174
PC/UI.WinIn.FasterZ.Inventory/src/components/currenDescriptions/index.vue

@ -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>

888
PC/UI.WinIn.FasterZ.Inventory/src/components/currenForm/index.vue

@ -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)
}
}
},
// inputonkeyup
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);
},
// filterSelectoption
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>

888
PC/UI.WinIn.FasterZ.Inventory/src/components/currenFormApi/index.vue

@ -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)
}
}
},
// inputonkeyup
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);
},
// filterSelectoption
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>

761
PC/UI.WinIn.FasterZ.Inventory/src/components/currenTable/index.vue

@ -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)
}
}
},
// inputonkeyup
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);
},
//nameemit
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>

322
PC/UI.WinIn.FasterZ.Inventory/src/components/currenTableFlex/index.vue

@ -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-main100%
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>

12
PC/UI.WinIn.FasterZ.Inventory/src/components/currenTableFlex/style/index.scss

@ -0,0 +1,12 @@
.currenTableFlex{
height: 100%;
display: flex;
flex-direction: column;
.flexTable{
height: 100%;
}
.headerButtons{
text-align: center;
margin-bottom: 20px;
}
}

57
PC/UI.WinIn.FasterZ.Inventory/src/components/currenTabs/index.vue

@ -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>

82
PC/UI.WinIn.FasterZ.Inventory/src/components/currenUpload/index.vue

@ -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>

72
PC/UI.WinIn.FasterZ.Inventory/src/components/currenUploadList/index.vue

@ -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>

100
PC/UI.WinIn.FasterZ.Inventory/src/components/currenUploadPictureCard/index.vue

@ -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>

89
PC/UI.WinIn.FasterZ.Inventory/src/components/exportDrop/index.vue

@ -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>

338
PC/UI.WinIn.FasterZ.Inventory/src/components/filterForDetailPage/index.vue

@ -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-main100%
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'
// showParentfreshfilterfield
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>

214
PC/UI.WinIn.FasterZ.Inventory/src/components/filterSelect/index.vue

@ -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:[],
//filterableremotetrueremote-methodremote-method
// getPageList
// truefalsetruefalse
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="正在加载"
// apigetPageList
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})
}
}
// apigetPagegetFilterList 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){
// 100A
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>

298
PC/UI.WinIn.FasterZ.Inventory/src/components/importFile/index.vue

@ -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>

278
PC/UI.WinIn.FasterZ.Inventory/src/components/newAndEdiDialog/index.vue

@ -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);
},
// formchange
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>

81
PC/UI.WinIn.FasterZ.Inventory/src/components/pdf/index.vue

@ -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>

43
PC/UI.WinIn.FasterZ.Inventory/src/components/resultStatus/index.vue

@ -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>

265
PC/UI.WinIn.FasterZ.Inventory/src/components/rowDrop/index.vue

@ -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>

66
PC/UI.WinIn.FasterZ.Inventory/src/components/searchNormal/index.vue

@ -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>

63
PC/UI.WinIn.FasterZ.Inventory/src/components/searchNormal/style/index.scss

@ -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;
}
}

611
PC/UI.WinIn.FasterZ.Inventory/src/components/searchOverall/index copy.vue

@ -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:columnvalue
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)
},
// moreListtableColumns
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
},
// moreListinputselect
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>

647
PC/UI.WinIn.FasterZ.Inventory/src/components/searchOverall/index.vue

@ -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:columnvalue
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)
},
// moreListtableColumns
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
},
// moreListinputselect
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>

83
PC/UI.WinIn.FasterZ.Inventory/src/components/searchOverall/style/index copy.scss

@ -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;
}
}

89
PC/UI.WinIn.FasterZ.Inventory/src/components/searchOverall/style/index.scss

@ -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;
// }
}

336
PC/UI.WinIn.FasterZ.Inventory/src/components/searchPage/index.vue

@ -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-main100%
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>

242
PC/UI.WinIn.FasterZ.Inventory/src/components/searchPrimary/index.vue

@ -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.jsoptions
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>

284
PC/UI.WinIn.FasterZ.Inventory/src/components/showCopyJsonPop/index.vue

@ -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,//Jsontable
JsonTableData:null,//json
JsonCopyData:null,//Json
JsonCopyShow:false,//jsonDialog
detailTableHeader:null,//detailsHeader
detailTableRow:null,//details
detailsTableShow:false,//details
detailTableColumns:false,//detailsheader
}
},
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 areaviewport
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')
})
}
},
// detailtable
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>

402
PC/UI.WinIn.FasterZ.Inventory/src/components/tablePagination/index copy.vue

@ -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-main100%
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
},
// tableloading
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)
},
//nameemit
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>

464
PC/UI.WinIn.FasterZ.Inventory/src/components/tablePagination/index.vue

@ -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-main100%
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
},
// tableloading
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)
},
//nameemit
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>

542
PC/UI.WinIn.FasterZ.Inventory/src/components/tableTree/index.vue

@ -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>

24
PC/UI.WinIn.FasterZ.Inventory/src/components/tableTree/style/index.scss

@ -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;
}
}
}
}

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

Loading…
Cancel
Save