Browse Source

【埃驰-接口-新】初始化+页面

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

2
PC/InterFace.Dash/src/views/menuList/OutgoingData.vue

@ -107,6 +107,7 @@ export default {
}; };
}, },
mounted() { mounted() {
this.PageListParams.Sorting = "writeTime DESC"
this.paging(); this.paging();
}, },
methods:{ methods:{
@ -129,6 +130,7 @@ export default {
this.Loading.tableLoading = true; this.Loading.tableLoading = true;
resetHandle({remark:null},ids,'out-going-data').then(result => { resetHandle({remark:null},ids,'out-going-data').then(result => {
this.$successMsg("重推成功"); this.$successMsg("重推成功");
this.PageListParams.Sorting = "writeTime DESC"
this.paging() this.paging()
this.$refs.tablePagination_Ref.clearTableSelection(); this.$refs.tablePagination_Ref.clearTableSelection();
}).catch(()=>{ }).catch(()=>{

14
PC/InterFace.New/.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/InterFace.New/.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/InterFace.New/.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/InterFace.New/.env.staging

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

5
PC/InterFace.New/.eslintignore

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

198
PC/InterFace.New/.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']
}
}

17
PC/InterFace.New/.gitignore

@ -0,0 +1,17 @@
################################################################################
# 此 .gitignore 文件已由 Microsoft(R) Visual Studio 自动创建。
################################################################################
/SqlData/Faster.Zheng.Winin.mdf
/SqlData/Faster.Zheng.Winin_log.ldf
# vuepress build output
.vuepress/dist
# Nuxt.js build / generate output
.nuxt
dist
# Dependency directories
node_modules/
jspm_packages/

0
PC/InterFace.New/.gitkeep

1
PC/InterFace.New/.npmrc

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

5
PC/InterFace.New/.travis.yml

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

21
PC/InterFace.New/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.

150
PC/InterFace.New/README.md

@ -0,0 +1,150 @@
## 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},
[urlOpion示例]
// 添加页面需要配置位置
// 示例数据
export const TestSchool = {
baseURL:'TestSchool/base',//主表-列表
detailURL:'app/test-school',//主表-明细 + 明细-查看主表
// detailInfoName:'asnNbr',//主表-明细查看详情的title名称
detailListURL:'TestStudentDetail/base',//明细-列表,
masterId:'masterId',//明细获取主表信息的masterId,默认依次为[默认配置defalutMasterId,固定值masterId]
masterName:'studentName'//明细获取主表信息的title名称
// parentURL:null,//明细-查看主表:特殊接口,如果没有则走detailURL
// deleteURL:null,//删除特殊URL
// addURL:null,//新增特殊URL
// editURL:null,//编辑特殊URL
// exportURL:'exportURL',//导出特殊URL
<!-- 20231124 有主表的子列表 查看详情的主表信息处理 -->
//有主表的子表单页的主表信息接口,默认为当前的[detailURL]去掉[-Detail]
// mainShowMasterUrl:null,
//有主表的子表单页的主表链接参数,默认依次为[默认配置defalutMasterId,上方配置中masterId,固定值masterId]
// mainShowMasterId:'masterId',
//有主表的子表单页的主表路由[用于显示列转义],默认为[当前路由]去掉[Detail]
// masterRoute:null,
}

14
PC/InterFace.New/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/InterFace.New/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/InterFace.New/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/InterFace.New/jsconfig.json

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

42748
PC/InterFace.New/package-lock.json

File diff suppressed because it is too large

126
PC/InterFace.New/package.json

@ -0,0 +1,126 @@
{
"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",
"ag-grid-community": "^30.2.1",
"ag-grid-vue": "^30.2.1",
"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-property-decorator": "^8.0.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/InterFace.New/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/InterFace.New/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/InterFace.New/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/InterFace.New/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/InterFace.New/plop-templates/utils.js

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

26
PC/InterFace.New/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/InterFace.New/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/InterFace.New/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/InterFace.New/postcss.config.js

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

1
PC/InterFace.New/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/InterFace.New/public/config.js

@ -0,0 +1,26 @@
// dev_win
window.SITE_CONFIG['baseApi'] = 'http://192.168.1.75:60081'
window.SITE_CONFIG['authApi'] = 'http://192.168.1.75:60080'
window.SITE_CONFIG['businessApi'] = 'http://dev.ccwin-in.com:20003'
//是否登录配置信息【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'] = 'InterFaceCenter_ScpWms'
// 项目配置内部名称
window.SITE_CONFIG['appClientScope'] = 'InterFaceCenter_ScpWms'
// 浏览器名称
window.SITE_CONFIG['browserTitle'] = '接口看板-NEV'
// 单点登录使用数据
window.SITE_CONFIG['oidcLogin_url'] = 'http://dev.ccwin-in.com:20006',
window.SITE_CONFIG['oidcLogin_clientId'] = 'InterfaceDash_App'
window.SITE_CONFIG['oidcLogin_scopes'] = 'offline_access Z profile'
// 隐藏的页面
window.SITE_CONFIG['menuHiddenConfig'] = []
// window.SITE_CONFIG['isAutoLogin'] = true

BIN
PC/InterFace.New/public/favicon.ico

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

BIN
PC/InterFace.New/public/img_login_bg.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 303 KiB

30
PC/InterFace.New/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/InterFace.New/public/version.json

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

96
PC/InterFace.New/src/App.vue

@ -0,0 +1,96 @@
<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'])
//
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/InterFace.New/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:'post',
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: 'post',
})
}
//获取分页+筛选(只查询)
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/InterFace.New/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
})
}

11
PC/InterFace.New/src/api/wms-business.js

@ -0,0 +1,11 @@
// 外部业务数据接口
import request from '@/utils/request'
let baseAPI = localStorage.getItem('baseApi') + '/'
// DataExchangeInterfaceConfig-初始化到关闭状态
export function DEInterfaceConfigReSet() {
return request({
method:'post',
url: baseAPI + 'api/DataExchangeInterfaceConfig/ReSetAsync',
})
}

BIN
PC/InterFace.New/src/assets/401_images/401.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 KiB

BIN
PC/InterFace.New/src/assets/404_images/404.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

BIN
PC/InterFace.New/src/assets/404_images/404_cloud.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

BIN
PC/InterFace.New/src/assets/custom-theme/fonts/element-icons.ttf

Binary file not shown.

BIN
PC/InterFace.New/src/assets/custom-theme/fonts/element-icons.woff

Binary file not shown.

1
PC/InterFace.New/src/assets/custom-theme/index.css

File diff suppressed because one or more lines are too long

2
PC/InterFace.New/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/InterFace.New/src/assets/img/drawerHeader.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
PC/InterFace.New/src/assets/img/menuLogo.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

46
PC/InterFace.New/src/components/AGTable/agGridBtn.vue

@ -0,0 +1,46 @@
<template>
<div>
<el-button
v-if="!item.hide"
v-for="(item,index) in buttons"
:key="index"
@click="clickHandle(item)"
:size="item.size"
:type="item.type"
:style="'color:'+item.color"
>{{item.label}}</el-button>
</div>
</template>
<script>
import AGTableBttons from "@/components/AGTable/btnControls.js"
export default {
data() {
return {
propsInit:null,//
buttons:[
AGTableBttons.tableEditBtn,
AGTableBttons.tableDeleteBtn,
],
cellValue:null
};
},
mounted(){
this.propsInit = this.params.colDef.cellRendererParams
console.log(33,this.propsInit.currency)
this.cellValue = this.params.data;
},
methods:{
clickHandle(data){
if(data.name == 'delete'){
AGTableBttons.deleteHandle(()=>{
console.log(33,this.cellValue)
})
}
// console.log(data,this.cellValue)
},
// getValueToDisplay(params) {
// return this.params.api.getRowNode(params.rowIndex).data
// },
}
}
</script>

42
PC/InterFace.New/src/components/AGTable/btnControls.js

@ -0,0 +1,42 @@
// 页面基础按钮样式
import i18n from "@/lang"
import { MessageBox } from 'element-ui';
// 编辑按钮
const tableEditBtn= {
type: "text",
icon: "el-icon-edit",
label: i18n.t('btns.edit'),
name: "edit",
size: "small",
color: "#ff9000",
}
// 删除按钮
const tableDeleteBtn= {
type: "text",
icon: "el-icon-delete",
label: i18n.t('btns.delete'),
name: "delete",
size: "small",
color: "red",
}
const deleteHandle = (callback) => {
MessageBox.confirm('您确定删除吗, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
// 确定操作
if(callback)callback()
}).catch(() => {
//取消操作
});
}
export default {
tableEditBtn,
tableDeleteBtn,
deleteHandle
}

115
PC/InterFace.New/src/components/AGTable/index.vue

@ -0,0 +1,115 @@
<template>
<div>
<ag-grid-vue
:style="'width:500px; height:'+uTableHeight + 'px'"
class="ag-theme-alpine"
:columnDefs="columnDefs"
:rowData="rowData"
:defaultColDef="defaultColDef"
>
</ag-grid-vue>
</div>
</template>
<script>
import "ag-grid-community/styles/ag-grid.css";
import "ag-grid-community/styles/ag-theme-alpine.css";
import { AgGridVue } from 'ag-grid-vue';
import agGridBtn from './agGridBtn.vue';
export default {
name: "agGridDemo",
components: {
AgGridVue,
agGridBtn
},
props:{
//
agGridBtnName:{
type: String,
default:'agGridBtn'
},
// app-main100%
setUTableHeight: {
type: Number,
default: () => {
return 280;
}
}
},
data() {
return {
uTableHeight:null,//
columnDefs: null,
rowData: null,
defaultColDef: {
// flex:1,
filter: true,
sortable: true,
floatingFilter: true,
resizable:true,
cellClass:"cell-wrap-text",
headerClass: 'ag-header-center',
autoHeight:true
},
};
},
watch: {
//
setUTableHeight(n,o){
this.setTableHeightHandle(n)
}
},
mounted() {
this.columnDefs = [
{
field:'操作',
lockPosition: 'left',
cellRenderer: this.agGridBtnName,
cellRendererParams: {
currency: 'EUREUREUREUREUREUR'
},
cellClass: 'locked-col',
width: 120,
suppressNavigable: true,
pinned:'right',
floatingFilter:false
},
{ field: "make" },
{ field: "model" },
{ field: "price" },
];
this.rowData = [
{ make: "Toyota", model: "Celica", price: 35000 },
{ make: "Ford", model: "Mondeo", price: 32000 },
{ make: "Porsche", model: "Boxster", price: 72000 },
{ make: "Porsche", model: "Boxster", price: 72000 },
{ make: "Porsche", model: "Boxster", price: 72000 },
{ make: "Porsche", model: "Boxster", price: 72000 },
{ make: "Porsche", model: "Boxster", price: 72000 },
{ make: "Porsche", model: "Boxster", price: 72000 },
{ make: "Porsche", model: "Boxster", price: 72000 },
{ make: "Porsche", model: "Boxster", price: 72000 },
{ make: "Porsche", model: "Boxster", price: 72000 },
{ make: "Porsche", model: "Boxster", price: 72000 },
{ make: "Porsche", model: "Boxster", price: 72000 },
{ make: "Porsche", model: "Boxster", price: 72000 },
];
this.setTableHeightHandle()
},
methods:{
//
setTableHeightHandle(height){
let _height = height || this.setUTableHeight
let _app_height = document.getElementsByClassName('app-main')[0].clientHeight
this.uTableHeight = Number(_app_height) - Number(_height)
console.log()
},
//
getTableHeight(){
return this.uTableHeight
},
}
}
</script>
<style lang="scss" scoped>
</style>

84
PC/InterFace.New/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/InterFace.New/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/InterFace.New/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/InterFace.New/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/InterFace.New/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/InterFace.New/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/InterFace.New/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/InterFace.New/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/InterFace.New/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/InterFace.New/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/InterFace.New/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/InterFace.New/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/InterFace.New/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/InterFace.New/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/InterFace.New/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/InterFace.New/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>

664
PC/InterFace.New/src/components/commonTabel-drawer/index.vue

@ -0,0 +1,664 @@
<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>
<!-- 主表信息 -->
<curren-descriptions
border
v-if="scope.value == 'masterInfo'"
:column="column"
:direction="direction"
:colon="false"
:tabsDesTions="masterColums"
:propsData="propsData.masterInfo"
>
</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 != 'masterInfo' &&
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";
import {
initApiColumnsForDto,
sliceStrEndDelete
} from '@/utils/index'
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.masterInfo){
this.initDropdownTabsData.push({
label: "主表信息",
name: 'masterInfo'
})
let _master_name = this.URLOption.masterRoute || sliceStrEndDelete(this.$route.name,'Detail')
this.masterColums = initApiColumnsForDto(this.propsData.masterInfo,_master_name,this)
}
// 使
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,
//
URLOption:allUrlOption[this.$route.name],
//-id
URLOption_masterId:allUrlOption[this.$route.name].masterId || allUrlOption.defalutMasterId || 'masterId',
//-
URLOption_detailList:allUrlOption[this.$route.name].detailListURL,
//
masterColums:null
}
},
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/InterFace.New/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/InterFace.New/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/InterFace.New/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/InterFace.New/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/InterFace.New/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>

184
PC/InterFace.New/src/components/currenDescriptions/index copy.vue

@ -0,0 +1,184 @@
<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
}
},
mounted(){
console.log(85,this.tabsDesTions)
},
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/InterFace.New/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/InterFace.New/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/InterFace.New/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/InterFace.New/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/InterFace.New/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/InterFace.New/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/InterFace.New/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/InterFace.New/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/InterFace.New/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/InterFace.New/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/InterFace.New/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>

335
PC/InterFace.New/src/components/filterForDetailPage/index.vue

@ -0,0 +1,335 @@
<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;">
<!-- 查看主表信息 如果配置中masterId的值为空则不显示-->
<el-button
v-if="item == 'showParent' && (scope.row[URLOption_masterId])"
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"
import { initApiColumnsForDto } from '@/utils/index'
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,
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 = initApiColumnsForDto(res.items[0],_parentName,this)
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/InterFace.New/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/InterFace.New/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/InterFace.New/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/InterFace.New/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/InterFace.New/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/InterFace.New/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/InterFace.New/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/InterFace.New/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/InterFace.New/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/InterFace.New/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/InterFace.New/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/InterFace.New/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/InterFace.New/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/InterFace.New/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/InterFace.New/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>

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

Loading…
Cancel
Save