提交 dc874fdc 编写于 作者: chenxiang@lab.ibiz5.com's avatar chenxiang@lab.ibiz5.com

1

上级 cbe60b63
*2020-3-7*
初始化
MIT License
Copyright (c) 2020 千反田丷
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
# VUE_R7
#### Description
{**When you're done, you can delete the content in this README and update the file with details for others getting started with your repository**}
#### Software Architecture
Software architecture description
#### Installation
1. xxxx
2. xxxx
3. xxxx
#### Instructions
1. xxxx
2. xxxx
3. xxxx
#### Contribution
1. Fork the repository
2. Create Feat_xxx branch
3. Commit your code
4. Create Pull Request
#### Gitee Feature
1. You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md
2. Gitee blog [blog.gitee.com](https://blog.gitee.com)
3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore)
4. The most valuable open source project [GVP](https://gitee.com/gvp)
5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help)
6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)
\ No newline at end of file
## 前言 # app
### 1. 简介 ## Project setup
该web应用是基于iBiz平台提供的一套PC端前端解决方案Vue_R7【**一套基于Vue全家桶(Vue + Vue-router + Vuex)的前端框架**】生产而成,Vue_R7不仅适用于管理后台或管理系统开发,且广泛适用于B/S架构的项目开发。本文档主要介绍项目如何快速上手,成果物代码结构做一阐述,旨在能够为开发人员提供一定开发指导支持。而今框架开源,希望能有更多志同道合的伙伴参与Vue_R7的迭代 ^_^
### 2. 开发环境要求
- Node.js
- Yarn
- Vue Cli
### 3. 开发技术要求
掌握`Vue``TypeScript``less``html`等技术。
### 4. 技术栈
- 前端MVVM框架:vue.js 2.6.10
- 路由:vue-router 3.1.3
- 状态管理:vue-router 3.1.3
- 国际化:vue-i18n 8.15.3
- 数据交互:axios 0.19.1
- UI框架:element-ui 2.13.0, view-design 4.1.0
- 工具库:qs, path-to-regexp, rxjs
- 图标库:font-awesome 4.7.0
- 引入组件: tinymce 4.8.5
- 代码风格检测:eslint
## 快速上手
### 1. 开发环境
> 在安装使用 `Yarn` 和 `Vue Cli (3.0)` 前,务必确认 [Node.js](https://nodejs.org) 已经升级到 v4.8.0 或以上,强烈建议升级至最新版本。
> 如果你想了解更多 `Yarn` 工具链的功能和命令,建议访问 [Yarn](https://yarnpkg.com) 了解更多。
> 如果你想了解更多 `Vue Cli (3.0)` 工具链的功能和命令,建议访问 [Vue Cli (3.0)](https://cli.vuejs.org/) 了解更多。
- 访问 [Node.js](https://nodejs.org) ,根据文档安装 `Node.js`
- 访问 [Yarn](https://yarnpkg.com) ,根据文档安装 `Yarn`
- 访问 [Vue Cli (3.0)](https://cli.vuejs.org/) ,根据文档安装 `Vue Cli (3.0)`
<blockquote style="border-color: red;"><p>在安装 Vue Cli (3.0) ,请使用 Yarn 模式全局安装。</p></blockquote>
```bash
$ yarn global add @vue/cli
``` ```
yarn install
以下为 Windows 环境开发正常配置
<br>
<br>
![开发环境信息](./imgs/getting-started/development.png)
### 2. 安装依赖
打开前端项目,进入工作空间下,执行安装依赖命令
```bash
$ yarn install
``` ```
### 3. 启动 ### Compiles and hot-reloads for development
在工作空间下,执行启动命令
```bash
$ yarn dev-serve
``` ```
yarn serve
启动后,通过 vue.config.js 开发服务 devServer 下配置的本地启动端口号访问开发项目。<br>
示例:
```bash
$ http://localhost:8111
``` ```
这儿需要注意一点,此时启动的项目访问的数据是我们前端的mock数据,如需与后台直接交互,请看第4点。
### 4. 远程代理 ### Compiles and minifies for production
在工作空间下,执行启动命令
```bash
$ yarn serve
``` ```
yarn build
修改远程代理文件 vue.config.js 代理地址
![远程代理地址](./imgs/getting-started/proxy.png)
### 5. 打包
在工作空间下,执行打包命令
```bash
$ yarn build
``` ```
打包完成,生成最终交付产物。 ### Run your unit tests
## 成果物结构
``` ```
|─ ─ app yarn test:unit
​ |─ ─ public public文件夹
​ |─ ─ assets 静态文件夹
|─ ─ favicon.ico 图标
​ |─ ─ src 工程文件夹
|─ ─ assets 静态资源
|─ ─ components 基础组件,主要包含编辑器组件和其他全局使用的组件
|─ ─ engine 引擎文件,主要封装了内置视图的内置逻辑
|─ ─ environments 环境文件
​ |─ ─ interface 接口文件
​ |─ ─ locale 多语言文件
|─ ─ mock 模拟数据
|─ ─ pages 视图文件夹
|─ ─ module 模块名称
​ |─ ─ XXX-view 视图文件夹
|─ ─ XXX-view-base.vue 视图基类
|─ ─ XXX-view.vue 自定义视图文件
|─ ─ XXX-view.less 自定义视图样式文件
​ |─ ─ main.ts 应用主函数入口
​ |─ ─ page-register.ts 全局视图注册
​ |─ ─ router.ts 路由配置文件
|─ ─ service 应用实体数据服务文件夹
|─ ─ XXX 应用实体名称
|─ ─ XXX-service-base.ts 应用实体数据服务文件
|─ ─ XXX-service.ts 自定义应用实体数据服务文件
|─ ─ YYY-logic-base.ts 应用实体数据处理逻辑文件
|─ ─ YYY-logic.ts 自定义应用实体数据处理逻辑文件
|─ ─ store 全局状态管理
|─ ─ styles 样式文件夹
|─ ─ default.less 默认样式
|─ ─ user.less 用户自定义样式
|─ ─ theme 主题文件夹
|─ ─ uiservice 界面服务文件
|─ ─ XXX 应用实体名称
|─ ─ XXX-ui-service-base.ts 应用实体界面服务文件
|─ ─ XXX-ui-service.ts 自定义应用实体界面服务文件
|─ ─ YYY-ui-logic-base.ts 应用实体界面处理逻辑文件
|─ ─ YYY-ui-logic.ts 自定义应用实体界面处理逻辑文件
|─ ─ utils 工具类文件
|─ ─ widgets 部件文件夹
|─ ─ appde 应用实体名称
​ |─ ─ XXX 部件名称
|─ ─ XXX-base.vue 视图基类
|─ ─ XXX.vue 自定义部件文件
|─ ─ XXX.less 部件样式文件
​ |─ ─ XXX.model.ts 部件model文件
​ |─ ─ XXX.service.ts 部件服务文件
|─ ─ app-register.ts 公共组件全局注册
​ |─ ─ App.vue 入口组件
​ |─ ─ user-register.ts 自定义组件全局注册
​|─ ─ package.json 依赖管理文件
​ |─ ─ vue.config.js vue cli 配置
``` ```
## 更新日志 ### Run your end-to-end tests
```
每个版本的详细更改都记录在[发行说明](CHANGELOG.md)中。 yarn test:e2e
```
## 如何贡献
如果你希望参与贡献,欢迎 [Pull Request](<http://demo.ibizlab.cn/ibiz_r7/vue_r7/issues/new>),或通过自助服务群给我们报告 Bug。
强烈推荐阅读 [《提问的智慧》](https://github.com/ryanhanwu/How-To-Ask-Questions-The-Smart-Way)(本指南不提供此项目的实际支持服务!)[《如何向开源社区提问题》](https://github.com/seajs/seajs/issues/545)[《如何有效地报告 Bug》](https://www.chiark.greenend.org.uk/~sgtatham/bugs-cn.html)[《如何向开源项目提交无法解答的问题》](https://zhuanlan.zhihu.com/p/25795393),更好的问题更容易获得帮助。
## 社区互助
1.[iBizLab论坛](https://bbs.ibizlab.cn/)
2.加入钉钉 Vue_R7自助服务群(中文) ### Lints and fixes files
```
yarn lint
```
<img src="./imgs/getting-started/vue-r7-group.png" height="400" width="400"> ### Customize configuration
\ No newline at end of file See [Configuration Reference](https://cli.vuejs.org/config/).
{
"name": "app",
"version": "0.1.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"adler-32": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/adler-32/-/adler-32-1.2.0.tgz",
"integrity": "sha1-aj5r8KY5ALoVZSgIyxXGgT0aXyU=",
"requires": {
"exit-on-epipe": "~1.0.1",
"printj": "~1.1.0"
}
},
"cfb": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/cfb/-/cfb-1.1.4.tgz",
"integrity": "sha512-rwFkl3aFO3f+ljR27YINwC0x8vPjyiEVbYbrTCKzspEf7Q++3THdfHVgJYNUbxNcupJECrLX+L40Mjm9hm/Bgw==",
"requires": {
"adler-32": "~1.2.0",
"commander": "^2.16.0",
"crc-32": "~1.2.0",
"printj": "~1.1.2"
}
},
"codepage": {
"version": "1.14.0",
"resolved": "https://registry.npmjs.org/codepage/-/codepage-1.14.0.tgz",
"integrity": "sha1-jL4lSBMjVZ19MHVxsP/5HnodL5k=",
"requires": {
"commander": "~2.14.1",
"exit-on-epipe": "~1.0.1"
},
"dependencies": {
"commander": {
"version": "2.14.1",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.14.1.tgz",
"integrity": "sha512-+YR16o3rK53SmWHU3rEM3tPAh2rwb1yPcQX5irVn7mb0gXbwuCCrnkbV5+PBfETdfg1vui07nM6PCG1zndcjQw=="
}
}
},
"commander": {
"version": "2.17.1",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz",
"integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg=="
},
"crc-32": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.0.tgz",
"integrity": "sha512-1uBwHxF+Y/4yF5G48fwnKq6QsIXheor3ZLPT80yGBV1oEUwpPojlEhQbWKVw1VwcTQyMGHK1/XMmTjmlsmTTGA==",
"requires": {
"exit-on-epipe": "~1.0.1",
"printj": "~1.1.0"
}
},
"exit-on-epipe": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/exit-on-epipe/-/exit-on-epipe-1.0.1.tgz",
"integrity": "sha512-h2z5mrROTxce56S+pnvAV890uu7ls7f1kEvVGJbw1OlFH3/mlJ5bkXu0KRyW94v37zzHPiUd55iLn3DA7TjWpw=="
},
"file-saver": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/file-saver/-/file-saver-2.0.2.tgz",
"integrity": "sha512-Wz3c3XQ5xroCxd1G8b7yL0Ehkf0TC9oYC6buPFkNnU9EnaPlifeAFCyCh+iewXTyFRcg0a6j3J7FmJsIhlhBdw=="
},
"frac": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/frac/-/frac-1.1.2.tgz",
"integrity": "sha512-w/XBfkibaTl3YDqASwfDUqkna4Z2p9cFSr1aHDt0WoMTECnRfBOv2WArlZILlqgWlmdIlALXGpM2AOhEk5W3IA=="
},
"printj": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/printj/-/printj-1.1.2.tgz",
"integrity": "sha512-zA2SmoLaxZyArQTOPj5LXecR+RagfPSU5Kw1qP+jkWeNlrq+eJZyY2oS68SU1Z/7/myXM4lo9716laOFAVStCQ=="
},
"raw-loader": {
"version": "0.5.1",
"resolved": "https://registry.npmjs.org/raw-loader/-/raw-loader-0.5.1.tgz",
"integrity": "sha1-DD0L6u2KAclm2Xh793goElKpeao=",
"dev": true
},
"script-loader": {
"version": "0.7.2",
"resolved": "https://registry.npmjs.org/script-loader/-/script-loader-0.7.2.tgz",
"integrity": "sha512-UMNLEvgOAQuzK8ji8qIscM3GIrRCWN6MmMXGD4SD5l6cSycgGsCo0tX5xRnfQcoghqct0tjHjcykgI1PyBE2aA==",
"dev": true,
"requires": {
"raw-loader": "~0.5.1"
}
},
"ssf": {
"version": "0.10.3",
"resolved": "https://registry.npmjs.org/ssf/-/ssf-0.10.3.tgz",
"integrity": "sha512-pRuUdW0WwyB2doSqqjWyzwCD6PkfxpHAHdZp39K3dp/Hq7f+xfMwNAWIi16DyrRg4gg9c/RvLYkJTSawTPTm1w==",
"requires": {
"frac": "~1.1.2"
}
},
"wmf": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wmf/-/wmf-1.0.2.tgz",
"integrity": "sha512-/p9K7bEh0Dj6WbXg4JG0xvLQmIadrner1bi45VMJTfnbVHsc7yIajZyoSoK60/dtVBs12Fm6WkUI5/3WAVsNMw=="
},
"xlsx": {
"version": "0.15.6",
"resolved": "https://registry.npmjs.org/xlsx/-/xlsx-0.15.6.tgz",
"integrity": "sha512-7vD9eutyLs65iDjNFimVN+gk/oDkfkCgpQUjdE82QgzJCrBHC4bGPH7fzKVyy0UPp3gyFVQTQEFJaWaAvZCShQ==",
"requires": {
"adler-32": "~1.2.0",
"cfb": "^1.1.4",
"codepage": "~1.14.0",
"commander": "~2.17.1",
"crc-32": "~1.2.0",
"exit-on-epipe": "~1.0.1",
"ssf": "~0.10.3",
"wmf": "~1.0.1"
}
}
}
}
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
"file-saver": "^2.0.2", "file-saver": "^2.0.2",
"font-awesome": "^4.7.0", "font-awesome": "^4.7.0",
"interactjs": "^1.9.4", "interactjs": "^1.9.4",
"moment": "^2.24.0",
"path-to-regexp": "^6.1.0", "path-to-regexp": "^6.1.0",
"qs": "^6.9.1", "qs": "^6.9.1",
"rxjs": "^6.5.4", "rxjs": "^6.5.4",
......
public/assets/img/logo.png

6.7 KB | W: | H:

public/assets/img/logo.png

2.0 KB | W: | H:

public/assets/img/logo.png
public/assets/img/logo.png
public/assets/img/logo.png
public/assets/img/logo.png
  • 2-up
  • Swipe
  • Onion skin
tinymce.addI18n('en_US',{
"Cut": "Cut",
"Heading 5": "Heading 5",
"Header 2": "Header 2",
"Your browser doesn't support direct access to the clipboard. Please use the Ctrl+X\/C\/V keyboard shortcuts instead.": "Your browser doesn't support direct access to the clipboard. Please use the Ctrl+X\/C\/V keyboard shortcuts instead.",
"Heading 4": "Heading 4",
"Div": "Div",
"Heading 2": "Heading 2",
"Paste": "Paste",
"Close": "Close",
"Font Family": "Font Family",
"Pre": "Pre",
"Align right": "Align right",
"New document": "New document",
"Blockquote": "Blockquote",
"Numbered list": "Numbered list",
"Heading 1": "Heading 1",
"Headings": "Headings",
"Increase indent": "Increase indent",
"Formats": "Formats",
"Headers": "Headers",
"Select all": "Select all",
"Header 3": "Header 3",
"Blocks": "Blocks",
"Undo": "Undo",
"Strikethrough": "Strike-through",
"Bullet list": "Bullet list",
"Header 1": "Header 1",
"Superscript": "Superscript",
"Clear formatting": "Clear formatting",
"Font Sizes": "Font Sizes",
"Subscript": "Subscript",
"Header 6": "Header 6",
"Redo": "Redo",
"Paragraph": "Paragraph",
"Ok": "Ok",
"Bold": "Bold",
"Code": "Code",
"Italic": "Italic",
"Align center": "Align centre",
"Header 5": "Header 5",
"Heading 6": "Heading 6",
"Heading 3": "Heading 3",
"Decrease indent": "Decrease indent",
"Header 4": "Header 4",
"Paste is now in plain text mode. Contents will now be pasted as plain text until you toggle this option off.": "Paste is now in plain text mode. Contents will now be pasted as plain text until you toggle this option off.",
"Underline": "Underline",
"Cancel": "Cancel",
"Justify": "Justify",
"Inline": "Inline",
"Copy": "Copy",
"Align left": "Align left",
"Visual aids": "Visual aids",
"Lower Greek": "Lower Greek",
"Square": "Square",
"Default": "Default",
"Lower Alpha": "Lower Alpha",
"Circle": "Circle",
"Disc": "Disc",
"Upper Alpha": "Upper Alpha",
"Upper Roman": "Upper Roman",
"Lower Roman": "Lower Roman",
"Id should start with a letter, followed only by letters, numbers, dashes, dots, colons or underscores.": "ID should start with a letter, followed only by letters, numbers, dashes, dots, colons or underscores.",
"Name": "Name",
"Anchor": "Anchor",
"Id": "ID",
"You have unsaved changes are you sure you want to navigate away?": "You have unsaved changes are you sure you want to navigate away?",
"Restore last draft": "Restore last draft",
"Special character": "Special character",
"Source code": "Source code",
"Language": "Language",
"Insert\/Edit code sample": "Insert\/Edit code sample",
"B": "B",
"R": "R",
"G": "G",
"Color": "Colour",
"Right to left": "Right to left",
"Left to right": "Left to right",
"Emoticons": "Emoticons",
"Robots": "Robots",
"Document properties": "Document properties",
"Title": "Title",
"Keywords": "Keywords",
"Encoding": "Encoding",
"Description": "Description",
"Author": "Author",
"Fullscreen": "Full-screen",
"Horizontal line": "Horizontal line",
"Horizontal space": "Horizontal space",
"Insert\/edit image": "Insert\/edit image",
"General": "General",
"Advanced": "Advanced",
"Source": "Source",
"Border": "Border",
"Constrain proportions": "Constrain proportions",
"Vertical space": "Vertical space",
"Image description": "Image description",
"Style": "Style",
"Dimensions": "Dimensions",
"Insert image": "Insert image",
"Image": "Image",
"Zoom in": "Zoom in",
"Contrast": "Contrast",
"Back": "Back",
"Gamma": "Gamma",
"Flip horizontally": "Flip horizontally",
"Resize": "Resize",
"Sharpen": "Sharpen",
"Zoom out": "Zoom out",
"Image options": "Image options",
"Apply": "Apply",
"Brightness": "Brightness",
"Rotate clockwise": "Rotate clockwise",
"Rotate counterclockwise": "Rotate counterclockwise",
"Edit image": "Edit image",
"Color levels": "Colour levels",
"Crop": "Crop",
"Orientation": "Orientation",
"Flip vertically": "Flip vertically",
"Invert": "Invert",
"Date\/time": "Date\/time",
"Insert date\/time": "Insert date\/time",
"Remove link": "Remove link",
"Url": "URL",
"Text to display": "Text to display",
"Anchors": "Anchors",
"Insert link": "Insert link",
"Link": "Link",
"New window": "New window",
"None": "None",
"The URL you entered seems to be an external link. Do you want to add the required http:\/\/ prefix?": "The URL you entered seems to be an external link. Do you want to add the required http:\/\/ prefix?",
"Paste or type a link": "Paste or type a link",
"Target": "Target",
"The URL you entered seems to be an email address. Do you want to add the required mailto: prefix?": "The URL you entered seems to be an email address. Do you want to add the required mailto: prefix?",
"Insert\/edit link": "Insert\/edit link",
"Insert\/edit video": "Insert\/edit video",
"Media": "Media",
"Alternative source": "Alternative source",
"Paste your embed code below:": "Paste your embed code below:",
"Insert video": "Insert video",
"Poster": "Poster",
"Insert\/edit media": "Insert\/edit media",
"Embed": "Embed",
"Nonbreaking space": "Non-breaking space",
"Page break": "Page break",
"Paste as text": "Paste as text",
"Preview": "Preview",
"Print": "Print",
"Save": "Save",
"Could not find the specified string.": "Could not find the specified string.",
"Replace": "Replace",
"Next": "Next",
"Whole words": "Whole words",
"Find and replace": "Find and replace",
"Replace with": "Replace with",
"Find": "Find",
"Replace all": "Replace all",
"Match case": "Match case",
"Prev": "Prev",
"Spellcheck": "Spell-check",
"Finish": "Finish",
"Ignore all": "Ignore all",
"Ignore": "Ignore",
"Add to Dictionary": "Add to Dictionary",
"Insert row before": "Insert row before",
"Rows": "Rows",
"Height": "Height",
"Paste row after": "Paste row after",
"Alignment": "Alignment",
"Border color": "Border colour",
"Column group": "Column group",
"Row": "Row",
"Insert column before": "Insert column before",
"Split cell": "Split cell",
"Cell padding": "Cell padding",
"Cell spacing": "Cell spacing",
"Row type": "Row type",
"Insert table": "Insert table",
"Body": "Body",
"Caption": "Caption",
"Footer": "Footer",
"Delete row": "Delete row",
"Paste row before": "Paste row before",
"Scope": "Scope",
"Delete table": "Delete table",
"H Align": "H Align",
"Top": "Top",
"Header cell": "Header cell",
"Column": "Column",
"Row group": "Row group",
"Cell": "Cell",
"Middle": "Middle",
"Cell type": "Cell type",
"Copy row": "Copy row",
"Row properties": "Row properties",
"Table properties": "Table properties",
"Bottom": "Bottom",
"V Align": "V Align",
"Header": "Header",
"Right": "Right",
"Insert column after": "Insert column after",
"Cols": "Cols",
"Insert row after": "Insert row after",
"Width": "Width",
"Cell properties": "Cell properties",
"Left": "Left",
"Cut row": "Cut row",
"Delete column": "Delete column",
"Center": "Centre",
"Merge cells": "Merge cells",
"Insert template": "Insert template",
"Templates": "Templates",
"Background color": "Background colour",
"Custom...": "Custom...",
"Custom color": "Custom colour",
"No color": "No colour",
"Text color": "Text colour",
"Table of Contents": "Table of Contents",
"Show blocks": "Show blocks",
"Show invisible characters": "Show invisible characters",
"Words: {0}": "Words: {0}",
"Insert": "Insert",
"File": "File",
"Edit": "Edit",
"Rich Text Area. Press ALT-F9 for menu. Press ALT-F10 for toolbar. Press ALT-0 for help": "Rich Text Area. Press ALT-F9 for menu. Press ALT-F10 for toolbar. Press ALT-0 for help",
"Tools": "Tools",
"View": "View",
"Table": "Table",
"Format": "Format"
});
\ No newline at end of file
window.Environment = {
// 是否为开发模式
devMode: true,
// 配置平台地址
StudioUrl: "http://neko.org.cn:3335/",
// 中心标识
SlnId: "AFFB70EF-A2CF-470A-B1AE-38156EAF4A50",
// 系统标识
SysId: "8A26FD38-06D7-495C-88B1-77238F3AB96D",
// 前端应用标识
AppId: "0df1f39e51db7152428a905a11c28a16"
}
\ No newline at end of file
public/favicon.ico

4.2 KB | W: | H:

public/favicon.ico

1.1 KB | W: | H:

public/favicon.ico
public/favicon.ico
public/favicon.ico
public/favicon.ico
  • 2-up
  • Swipe
  • Onion skin
<template> <template>
<div id='app'> <div id='app'>
<debug-actions/>
<router-view v-if="isRouterAlive"/> <router-view v-if="isRouterAlive"/>
</div> </div>
</template> </template>
......
...@@ -60,6 +60,14 @@ import AppActionBar from './components/app-actionbar/app-actionbar.vue' ...@@ -60,6 +60,14 @@ import AppActionBar from './components/app-actionbar/app-actionbar.vue'
import AppOrgSector from './components/app-orgsector/app-orgsector.vue' import AppOrgSector from './components/app-orgsector/app-orgsector.vue'
import AppBuild from './components/app-build/app-build.vue' import AppBuild from './components/app-build/app-build.vue'
import AppStudioAction from './components/app-studioaction/app-studioaction.vue' import AppStudioAction from './components/app-studioaction/app-studioaction.vue'
import AppDebugActions from './components/app-debug-actions/app-debug-actions.vue'
import AppHeaderMenus from './components/app-header-menus/app-header-menus.vue'
import AppColumnLink from './components/app-column-link/app-column-link.vue'
import AppDataUploadView from './components/app-data-upload/app-data-upload.vue'
import DropDownListDynamic from './components/dropdown-list-dynamic/dropdown-list-dynamic.vue'
import AppImagePreview from './components/app-image-preview/app-image-preview.vue'
import AppFormatData from './components/app-format-data/app-format-data.vue'
import AppUploadFileInfo from './components/app-upload-file-info/app-upload-file-info.vue'
// 全局挂载UI实体服务注册中心 // 全局挂载UI实体服务注册中心
window['uiServiceRegister'] = uiServiceRegister; window['uiServiceRegister'] = uiServiceRegister;
...@@ -129,5 +137,13 @@ export const AppComponents = { ...@@ -129,5 +137,13 @@ export const AppComponents = {
v.component('app-orgsector', AppOrgSector); v.component('app-orgsector', AppOrgSector);
v.component('app-build', AppBuild); v.component('app-build', AppBuild);
v.component('app-studioaction', AppStudioAction); v.component('app-studioaction', AppStudioAction);
v.component('app-debug-actions', AppDebugActions);
v.component('app-header-menus', AppHeaderMenus);
v.component('app-column-link', AppColumnLink);
v.component('app-data-upload', AppDataUploadView);
v.component('dropdown-list-dynamic', DropDownListDynamic);
v.component('app-image-preview', AppImagePreview);
v.component('app-format-data', AppFormatData);
v.component('app-upload-file-info', AppUploadFileInfo);
}, },
}; };
\ No newline at end of file
...@@ -5,7 +5,6 @@ html, body { ...@@ -5,7 +5,6 @@ html, body {
.app-error-view { .app-error-view {
height: 100%; height: 100%;
width: 100%; width: 100%;
position: relative;
.app-error-container { .app-error-container {
height: 380px; height: 380px;
width: 670px; width: 670px;
......
...@@ -3,8 +3,8 @@ ...@@ -3,8 +3,8 @@
<div class="app-error-container"> <div class="app-error-container">
<img src="/assets/img/404.png" /> <img src="/assets/img/404.png" />
<div class="error-text"> <div class="error-text">
<div class="error-text1">抱歉,您访问的页面不存在!</div> <div class="error-text1">{{$t('components.404.errorText1')}}</div>
<div class="error-text2">您要找的页面存在,请返回 <a on-click={this.gotoIndexView}>首页</a> 继续浏览</div> <div class="error-text2">{{$t('components.404.errorText2')}} <a @click="gotoIndexView">{{$t('components.404.indexPage')}}</a> {{$t('components.404.continue')}}</div>
</div> </div>
</div> </div>
</div> </div>
...@@ -13,7 +13,8 @@ ...@@ -13,7 +13,8 @@
<script lang="ts"> <script lang="ts">
import { Vue, Component } from 'vue-property-decorator'; import { Vue, Component } from 'vue-property-decorator';
@Component({}) @Component({
})
export default class Error404 extends Vue { export default class Error404 extends Vue {
/** /**
......
html, body { html, body {
height: 100%; height: 100%;
} }
.app-error-view { .app-error-view {
height: 100%; height: 100%;
width: 100%; width: 100%;
position: relative;
.app-error-container { .app-error-container {
height: 380px; height: 380px;
width: 670px; width: 670px;
......
...@@ -3,8 +3,8 @@ ...@@ -3,8 +3,8 @@
<div class="app-error-container"> <div class="app-error-container">
<img src="/assets/img/500.png" /> <img src="/assets/img/500.png" />
<div class="error-text"> <div class="error-text">
<div class="error-text1">抱歉,服务器出错了!</div> <div class="error-text1">{{$t('components.500.errorText1')}}</div>
<div class="error-text2">服务器出错了,请返回 <a on-click={this.gotoIndexView}>首页</a> 继续浏览</div> <div class="error-text2">{{$t('components.500.errorText2')}} <a @click="gotoIndexView">{{$t('components.500.indexPage')}}</a> {{$t('components.500.continue')}}</div>
</div> </div>
</div> </div>
</div> </div>
...@@ -13,7 +13,8 @@ ...@@ -13,7 +13,8 @@
<script lang="ts"> <script lang="ts">
import { Vue, Component } from 'vue-property-decorator'; import { Vue, Component } from 'vue-property-decorator';
@Component({}) @Component({
})
export default class Error404 extends Vue { export default class Error404 extends Vue {
/** /**
......
...@@ -23,7 +23,8 @@ import { Component, Vue, Prop, Model, Watch } from 'vue-property-decorator'; ...@@ -23,7 +23,8 @@ import { Component, Vue, Prop, Model, Watch } from 'vue-property-decorator';
import { Subject } from 'rxjs'; import { Subject } from 'rxjs';
import { debounceTime, distinctUntilChanged } from 'rxjs/operators'; import { debounceTime, distinctUntilChanged } from 'rxjs/operators';
@Component({}) @Component({
})
export default class AppAutocomplete extends Vue { export default class AppAutocomplete extends Vue {
/** /**
...@@ -195,16 +196,21 @@ export default class AppAutocomplete extends Vue { ...@@ -195,16 +196,21 @@ export default class AppAutocomplete extends Vue {
let _parentdata = this.$util.formatData(this.data,this.itemParam.parentdata); let _parentdata = this.$util.formatData(this.data,this.itemParam.parentdata);
Object.assign(param,_parentdata); Object.assign(param,_parentdata);
} }
// 错误信息国际化
let error: string = (this.$t('components.appAutocomplete.error') as any);
let miss: string = (this.$t('components.appAutocomplete.miss') as any);
let requestException: string = (this.$t('components.appAutocomplete.requestException') as any);
if(!this.service){ if(!this.service){
this.$Notice.error({ title: '错误', desc: '缺少参数service' }); this.$Notice.error({ title: error, desc: miss+'service' });
} else if(!this.acParams.serviceName) { } else if(!this.acParams.serviceName) {
this.$Notice.error({ title: '错误', desc: '缺少参数serviceName' }); this.$Notice.error({ title: error, desc: miss+'serviceName' });
} else if(!this.acParams.interfaceName) { } else if(!this.acParams.interfaceName) {
this.$Notice.error({ title: '错误', desc: '缺少参数interfaceName' }); this.$Notice.error({ title: error, desc: miss+'interfaceName' });
} else { } else {
this.service.getItems(this.acParams.serviceName,this.acParams.interfaceName, context, param).then((response: any) => { this.service.getItems(this.acParams.serviceName,this.acParams.interfaceName, context, param).then((response: any) => {
if (!response) { if (!response) {
this.$Notice.error({ title: '错误', desc: '请求异常' }); this.$Notice.error({ title: error, desc: requestException });
} else { } else {
this.items = [...response]; this.items = [...response];
} }
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
</i-button> </i-button>
</button-group> </button-group>
<button-group v-show="showTypeDir"> <button-group v-show="showTypeDir">
<el-tooltip content="定制"> <el-tooltip :content="$t('components.appBuild.custom')">
<i-button icon="md-build" type="primary" @click="handleClick"></i-button> <i-button icon="md-build" type="primary" @click="handleClick"></i-button>
</el-tooltip> </el-tooltip>
<i-button class="collapse-btn" type="primary" @click="clickCollapse('right')"> <i-button class="collapse-btn" type="primary" @click="clickCollapse('right')">
...@@ -21,8 +21,6 @@ import {Vue, Component, Prop, Watch} from 'vue-property-decorator'; ...@@ -21,8 +21,6 @@ import {Vue, Component, Prop, Watch} from 'vue-property-decorator';
@Component({ @Component({
components: {
}
}) })
export default class AppBuild extends Vue { export default class AppBuild extends Vue {
......
<template>
<FullCalendar ref="appCalendar" height="parent" :locales="locales" locale="zh-cn" :header="header" class="app-calendar" :events="items" defaultView="dayGridMonth" :plugins="calendarPlugins" @eventClick="onClick"/>
</template>
<script lang="ts">
import { Vue, Component, Prop, Watch } from "vue-property-decorator";
import FullCalendar from '@fullcalendar/vue';
import dayGridPlugin from '@fullcalendar/daygrid';
import allLocales from '@fullcalendar/core/locales-all';
import '@fullcalendar/core/main.css';
import '@fullcalendar/daygrid/main.css';
@Component({
components: {
FullCalendar
}
})
export default class AppCalendar extends Vue {
/**
* 数据集
*
* @type {string}
* @memberof AppCalendar
*/
@Prop() datas?: string;
/**
* 类型
*
* @type {string}
* @memberof aaa
*/
@Prop() type?: string;
/**
* 数据集对象
*
* @protected
* @type {any[]}
* @memberof AppCalendar
*/
protected items: any[] = [];
/**
* 头部设置
*
* @protected
* @memberof AppCalendar
*/
protected header: any = {
left: 'prev,next today',
center: 'title',
right: false
};
/**
* 语言资源
*
* @protected
* @memberof AppCalendar
*/
public locales = allLocales;
/**
* 日历插件
*
* @protected
* @type {any[]}
* @memberof aaa
*/
protected calendarPlugins: any[] = [dayGridPlugin];
/**
* 数据集监听
*
* @param {*} newVal
* @param {*} oldVal
* @memberof AppCalendar
*/
@Watch('datas')
onDatasChange(newVal: any, oldVal: any) {
if(newVal) {
this.items = this.prepareItems(JSON.parse(newVal));
}
}
/**
* 类型监听
*
* @param {*} newVal
* @param {*} oldVal
* @memberof AppCalendar
*/
@Watch('type')
onTypeChange(newVal: any, oldVal: any) {
if(Object.is(newVal, 'calendar')) {
let appCalendar: any = this.$refs.appCalendar;
let api = appCalendar.getApi();
api.updateSize()
}
}
/**
* 生命周期
*
* @memberof AppCalendar
*/
public mounted() {
if(this.datas) {
this.items = this.prepareItems(JSON.parse(this.datas));
}
}
/**
* 准备数据
*
* @param {*} datas
* @memberof AppCalendar
*/
public prepareItems(datas: any[]): any[] {
let items: any[] = [];
datas.forEach((data: any) => {
if(!data.hasOwnProperty('date')) {
data.date = data.create_date;
data.id = data.srfkey;
}
items.push(data);
})
return items;
}
/**
* 数据点击
*
* @param {*} datas
* @memberof AppCalendar
*/
public onClick($event: any) {
let item = this.items.find((item: any) => item.srfkey == $event.event.id);
if(item) {
this.$emit('click', item);
}
}
}
</script>
<style lang="less">
.app-calendar {
height: 100%;
width: 100%;
}
</style>
\ No newline at end of file
<template> <template>
<checkbox-group class="app-checkbox-list" v-model="selectArray"> <checkbox-group class="app-checkbox-list" v-model="selectArray">
<checkbox v-for="(item,index) in items" :key="index" :label="item.value" :disabled="isDisabled || item.disabled"> <checkbox v-for="(item,index) in items" :key="index" :label="item.value" :disabled="isDisabled || item.disabled">
<span>{{item.text}}</span> <span>{{Object.is(codelistType,'STATIC') ? $t('codelist.'+tag+'.'+item.value) : item.text}}</span>
</checkbox> </checkbox>
</checkbox-group > </checkbox-group >
</template> </template>
...@@ -10,7 +10,8 @@ ...@@ -10,7 +10,8 @@
import { Component, Vue, Prop, Model } from 'vue-property-decorator'; import { Component, Vue, Prop, Model } from 'vue-property-decorator';
import CodeListService from "@service/app/codelist-service"; import CodeListService from "@service/app/codelist-service";
@Component({}) @Component({
})
export default class AppCheckBox extends Vue { export default class AppCheckBox extends Vue {
/** /**
* 代码表服务对象 * 代码表服务对象
...@@ -36,6 +37,14 @@ export default class AppCheckBox extends Vue { ...@@ -36,6 +37,14 @@ export default class AppCheckBox extends Vue {
*/ */
@Prop() public codelistType?: string; @Prop() public codelistType?: string;
/**
* 代码表值分隔符
*
* @type {string}
* @memberof AppCheckBox
*/
@Prop({default:';'}) public valueSeparator?: string;
/** /**
* 是否禁用 * 是否禁用
* *
...@@ -136,7 +145,7 @@ export default class AppCheckBox extends Vue { ...@@ -136,7 +145,7 @@ export default class AppCheckBox extends Vue {
return selectsArray; return selectsArray;
} else if (Object.is(this.currentmode, 'str')) { } else if (Object.is(this.currentmode, 'str')) {
if (this.selects !== '') { if (this.selects !== '') {
return this.selects.split(this.currentseparator); return this.selects.split(this.valueSeparator);
} }
} }
} else { } else {
...@@ -166,7 +175,7 @@ export default class AppCheckBox extends Vue { ...@@ -166,7 +175,7 @@ export default class AppCheckBox extends Vue {
} }
_datas.push(item.value); _datas.push(item.value);
}); });
value = _datas.join(this.currentseparator); value = _datas.join(this.valueSeparator);
} }
this.$emit('change', value); this.$emit('change', value);
} }
...@@ -191,13 +200,13 @@ export default class AppCheckBox extends Vue { ...@@ -191,13 +200,13 @@ export default class AppCheckBox extends Vue {
if (codelist) { if (codelist) {
this.items = [...JSON.parse(JSON.stringify(codelist.items))]; this.items = [...JSON.parse(JSON.stringify(codelist.items))];
} else { } else {
console.log(`----${this.tag}----代码表不存在`); console.log(`----${this.tag}----$t('components.appCheckBox.notExist')`);
} }
} else if (Object.is(this.codelistType,"DYNAMIC")) { } else if (Object.is(this.codelistType,"DYNAMIC")) {
this.codeListService.getItems(this.tag).then((res:any) => { this.codeListService.getItems(this.tag).then((res:any) => {
this.items = res; this.items = res;
}).catch((error:any) => { }).catch((error:any) => {
console.log(`----${this.tag}----代码表不存在`); console.log(`----${this.tag}----$t('components.appCheckBox.notExist')`);
}); });
} }
} }
......
.app-column-link{
display: inline-block;
cursor:pointer;
}
\ No newline at end of file
<template>
<a class="app-column-link" @click="openLinkView($event)">
<slot></slot>
</a>
</template>
<script lang="ts">
import { Vue, Component,Prop } from 'vue-property-decorator';
import { Subject } from 'rxjs';
/**
* 表格列链接
*/
@Component({
})
export default class AppColumnLink extends Vue {
/**
* 表格行数据
*
* @type {*}
* @memberof AppColumnLink
*/
@Prop() public data!: any;
/**
* 数据链接视图
*
* @type {*}
* @memberof AppColumnLink
*/
@Prop() public linkview?: any;
/**
* 值项名称
*
* @type {string}
* @memberof AppColumnLink
*/
@Prop() public valueitem?: string;
/**
* 导航上下文
*
* @type {*}
* @memberof AppColumnLink
*/
@Prop({default:{}}) public context?:any;
/**
* 导航参数
*
* @type {*}
* @memberof AppColumnLink
*/
@Prop({default:{}}) public viewparams?:any;
/**
* 应用实体主键属性名称
*
* @type {string}
* @memberof AppColumnLink
*/
@Prop() public deKeyField!:string;
/**
* 打开链接视图
*
* @memberof AppColumnLink
*/
public openLinkView($event: any): void {
$event.stopPropagation();
if (!this.data || !this.valueitem || !this.data[this.valueitem]) {
this.$Notice.error({ title: (this.$t('components.appColumnLink.error') as string), desc: (this.$t('components.appColumnLink.valueItemException') as string) });
return;
}
// 公共参数处理
let data: any = {};
const bcancel: boolean = this.handlePublicParams(data);
if (!bcancel) {
return;
}
// 参数处理
let _context = data.context;
let _param = data.param;
Object.assign(_context, { [this.deKeyField]: this.data[this.valueitem] });
const view = JSON.parse(JSON.stringify(this.linkview));
const viewname2: string = this.$util.srfFilePath2(view.viewname);
view.viewname = viewname2;
if (view.isRedirectView) {
this.openRedirectView($event, view, data);
} else if (Object.is(view.placement, 'INDEXVIEWTAB') || Object.is(view.placement, '')) {
this.openIndexViewTab(view, _context, _param);
} else if (Object.is(view.placement, 'POPOVER')) {
this.openPopOver($event, view, _context, _param);
} else if (Object.is(view.placement, 'POPUPMODAL')) {
this.openPopupModal(view, _context, _param);
} else if (view.placement.startsWith('DRAWER')) {
this.openDrawer(view, _context, _param);
}
}
/**
* 路由模式打开视图
*
* @private
* @param {string} viewpath
* @param {*} data
* @memberof AppColumnLink
*/
private openIndexViewTab(view: any, context: any, param: any): void {
const routePath = this.$viewTool.buildUpRoutePath(this.$route, this.context, view.deResParameters, view.parameters, [context] , param);
this.$router.push(routePath);
}
/**
* 模态模式打开视图
*
* @private
* @param {*} view
* @param {*} data
* @memberof AppColumnLink
*/
private openPopupModal(view: any, context: any, param: any): void {
let container: Subject<any> = this.$appmodal.openModal(view, context, param);
container.subscribe((result: any) => {
if (!result || !Object.is(result.ret, 'OK')) {
return;
}
this.openViewClose(result);
});
}
/**
* 抽屉模式打开视图
*
* @private
* @param {*} view
* @param {*} data
* @memberof AppColumnLink
*/
private openDrawer(view: any, context: any, param: any): void {
let container: Subject<any> = this.$appdrawer.openDrawer(view, context, param);
container.subscribe((result: any) => {
if (!result || !Object.is(result.ret, 'OK')) {
return;
}
this.openViewClose(result);
});
}
/**
* 气泡卡片模式打开
*
* @private
* @param {*} $event
* @param {*} view
* @param {*} data
* @memberof AppColumnLink
*/
private openPopOver($event: any, view: any, context: any, param: any): void {
let container: Subject<any> = this.$apppopover.openPop($event, view, context, param);
container.subscribe((result: any) => {
if (!result || !Object.is(result.ret, 'OK')) {
return;
}
this.openViewClose(result);
});
}
/**
* 独立里面弹出
*
* @private
* @param {string} url
* @memberof AppColumnLink
*/
private openPopupApp(url: string): void {
window.open(url, '_blank');
}
/**
* 打开重定向视图
*
* @private
* @param {*} $event
* @param {*} view
* @param {*} data
* @memberof AppColumnLink
*/
private openRedirectView($event: any, view: any, data: any): void {
this.$http.get(view.url, data).then((response: any) => {
if (!response || response.status !== 200) {
this.$Notice.error({ title: '错误', desc: '请求异常' });
}
if (response.status === 401) {
return;
}
const { data: result } = response;
if (result.viewparams && !Object.is(result.viewparams.srfkey, '')) {
Object.assign(data, { srfkey: result.viewparams.srfkey });
}
if (Object.is(result.openmode, 'POPUPAPP') && result.url && !Object.is(result.url, '')) {
this.openPopupApp(result.url);
} else if (Object.is(result.openmode, 'INDEXVIEWTAB') || Object.is(result.openmode, '')) {
// 所有数据保持在同一级
if (data.srfparentdata) {
Object.assign(data, data.srfparentdata);
delete data.srfparentdata;
}
this.openIndexViewTab(view, null, data);
} else if (Object.is(result.openmode, 'POPUPMODAL')) {
const viewname = this.$util.srfFilePath2(result.viewname);
const view: any = {
viewname: viewname,
title: result.title,
width: result.width,
height: result.height,
}
this.openPopupModal(view, null,data);
} else if (result.openmode.startsWith('DRAWER')) {
const viewname = this.$util.srfFilePath2(result.viewname);
const view: any = {
viewname: viewname,
title: result.title,
width: result.width,
height: result.height,
placement: result.openmode,
}
this.openDrawer(view, null, data);
} else if (Object.is(result.openmode, 'POPOVER')) {
const viewname = this.$util.srfFilePath2(result.viewname);
const view: any = {
viewname: viewname,
title: result.title,
width: result.width,
height: result.height,
placement: result.openmode,
}
this.openPopOver($event, view, null, data);
}
}).catch((response: any) => {
if (!response || !response.status || !response.data) {
this.$Notice.error({ title: '错误', desc: '系统异常!' });
return;
}
if (response.status === 401) {
return;
}
});
}
/**
* 打开页面关闭
*
* @param {*} result
* @memberof AppColumnLink
*/
public openViewClose(result: any) {
let item: any = {};
if (result.datas && Array.isArray(result.datas)) {
Object.assign(item, result.datas[0]);
}
console.log(item);
}
/**
* 公共参数处理
*
* @param {*} arg
* @returns
* @memberof AppColumnLink
*/
public handlePublicParams(arg: any): boolean {
if (!this.data) {
this.$Notice.error({ title: (this.$t('components.appColumnLink.error') as string), desc: (this.$t('components.appColumnLink.rowDataException') as string) });
return false;
}
// 合并表单参数
arg.param = JSON.parse(JSON.stringify(this.viewparams));
arg.context = JSON.parse(JSON.stringify(this.context));
return true;
}
}
</script>
<style lang='less'>
@import './app-column-link.less';
</style>
\ No newline at end of file
...@@ -5,12 +5,12 @@ ...@@ -5,12 +5,12 @@
<input-box :disabled="disabled" v-model="editorvalue" @change="($event)=>{onEditorValueChange($event)}"></input-box> <input-box :disabled="disabled" v-model="editorvalue" @change="($event)=>{onEditorValueChange($event)}"></input-box>
</template> </template>
<template v-else-if="Object.is(type,'dropdown')"> <template v-else-if="Object.is(type,'dropdown')">
<i-select v-model="editorvalue" :disabled="disabled" :clearable="true" placeholder='请选择...' > <i-select v-model="editorvalue" :disabled="disabled" :clearable="true" :placeholder="$t('components.appColumnRender.select')" >
<i-option v-for="(item, index) in codelist" :key="index" :value="item.value">{{item.text}}</i-option> <i-option v-for="(item, index) in codelist" :key="index" :value="item.value">{{item.text}}</i-option>
</i-select> </i-select>
</template> </template>
<template v-else> <template v-else>
<span>{{type}}不支持</span> <span>{{type}}{{$t('components.appColumnRender.unsupported')}}</span>
</template> </template>
</div> </div>
</template> </template>
...@@ -20,7 +20,8 @@ import { Vue, Component, Prop, Model, Emit, Watch } from "vue-property-decorator ...@@ -20,7 +20,8 @@ import { Vue, Component, Prop, Model, Emit, Watch } from "vue-property-decorator
import { Subject } from "rxjs"; import { Subject } from "rxjs";
import { debounceTime, distinctUntilChanged } from "rxjs/operators"; import { debounceTime, distinctUntilChanged } from "rxjs/operators";
@Component({}) @Component({
})
export default class AppColumnRender extends Vue { export default class AppColumnRender extends Vue {
/** /**
* 值 * 值
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
<el-menu v-show="!filterVal" :unique-opened="true"> <el-menu v-show="!filterVal" :unique-opened="true">
<template v-for="(item, index) of list"> <template v-for="(item, index) of list">
<el-submenu :key="item.type + index" :index="item.type + index"> <el-submenu :key="item.type + index" :index="item.type + index">
<div slot="title">{{item.name}}</div> <div slot="title">{{Object.is(item.type, 'app') ? $t('components.appDashboardDesign.global') : item.name}}</div>
<template v-for="(item2, index2) of item.children"> <template v-for="(item2, index2) of item.children">
<el-submenu :key="item2.type + index2" :index="item2.type + index2"> <el-submenu :key="item2.type + index2" :index="item2.type + index2">
<div slot="title">{{item2.name}}</div> <div slot="title">{{item2.name}}</div>
...@@ -225,9 +225,9 @@ export default class AppDashboardDesign extends Vue { ...@@ -225,9 +225,9 @@ export default class AppDashboardDesign extends Vue {
* @memberof AppDashboardDesign * @memberof AppDashboardDesign
*/ */
public created() { public created() {
this.loadList(); this.loadList();
this.load(); this.load();
if (this.viewState) { if (this.viewState) {
this.viewStateEvent = this.viewState.subscribe(({ tag, action, data }) => { this.viewStateEvent = this.viewState.subscribe(({ tag, action, data }) => {
if (Object.is('save', action)) { if (Object.is('save', action)) {
this.save(); this.save();
......
.app-data-upload-view{
width: 100%;
height: 100%;
padding: 16px;
.import-temp{
text-align: right;
vertical-align: middle;
color: #409EFF;
}
.data-info-content{
height: 100%;
width: 100%;
overflow: auto;
}
.font-class{
margin: 0px;
padding: 0px;
font-family: '微软雅黑','黑体','宋体';
font-size: 16px;
}
}
\ No newline at end of file
<template>
<div class="app-data-upload-view">
<el-row :gutter="20">
<el-col :span="4">
<el-button type="primary" @click="handleUpLoad">{{$t('components.appDataUploadView.selectfile')}}</el-button>
<input ref="inputUpLoad" type="file" style="display: none" accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" @change="importFile"/>
</el-col>
<el-col :span="4">
<el-button type="primary" @click="uploadServer">{{$t('components.appDataUploadView.uploadserver')}}</el-button>
</el-col>
<el-col :span="16">
<div class="import-temp"><span style="cursor: pointer;" @click="downloadTemp">{{$t('components.appDataUploadView.datatemplate')}}</span></div>
</el-col>
</el-row>
<el-divider></el-divider>
<el-row style="height:calc(100% - 128px);padding: 0px 12px;">
<div class="data-info-content" >
<template v-if="importDataArray.length >0 && isUploading === false">
<ul>
<li v-for="(item,index) in importDataArray" :key="index" class="font-class">
{{$t('components.appDataUploadView.dataid')+item[importUniqueItem]+$t('components.appDataUploadView.read')+'......'}}
</li>
</ul>
</template>
<template v-if="hasImported === true && importDataArray.length === 0">
<span class="font-class">{{isUploading === true?$t('components.appDataUploadView.importing')+"......":promptInfo}}</span>
</template>
</div>
</el-row>
<el-row>
<!-- <el-col :span="4">
<div class="import-temp">
<div style="cursor: pointer;display: inline-block;" @click="downloadSuccessData">{{importSuccessData.length >0?"下载导入成功数据":""}}</div>
</div>
</el-col>
<el-col :span="4">
<div class="import-temp">
<span style="cursor: pointer;display: inline-block;" @click="downloadErrorData">{{importErrorData.length >0?"下载导入失败数据":""}}</span>
</div>
</el-col> -->
<el-col :span="2" :offset="22">
<el-button type="primary" @click="handleOK">{{$t('components.appDataUploadView.confirm')}}</el-button>
</el-col>
</el-row>
</div>
</template>
<script lang="ts">
import XLSX from 'xlsx';
import CodeListService from "@service/app/codelist-service";
import EntityService from '@/service/entity-service';
import { Vue, Component, Prop, Provide, Emit, Watch } from 'vue-property-decorator';
@Component({
})
export default class AppDataUploadView extends Vue {
/**
* 传入视图上下文
*
* @type {string}
* @memberof AppDataUploadView
*/
@Prop() protected viewdata!: string;
/**
* 传入视图参数
*
* @type {string}
* @memberof AppDataUploadView
*/
@Prop() protected viewparam!: string;
/**
* 代码表服务对象
*
* @type {CodeListService}
* @memberof AppDataUploadView
*/
public codeListService:CodeListService = new CodeListService({ $store: this.$store });
/**
* 实体服务对象
*
* @protected
* @type {EntityService}
* @memberof AppDataUploadView
*/
protected entityService: EntityService = new EntityService();
/**
* 视图参数
*
* @type {*}
* @memberof AppDataUploadView
*/
protected viewparams:any = {};
/**
* 导入数据模型
*
* @type {Array<*>}
* @memberof AppDataUploadView
*/
protected importDataModel:Array<any> = [];
/**
* 导入数据集合
*
* @type {Array<*>}
* @memberof AppDataUploadView
*/
protected importDataArray:Array<any> = [];
/**
* 导入标识
*
* @type {string}
* @memberof AppDataUploadView
*/
protected importId:string = "";
/**
* 是否已有导入数据
*
* @type {boolean}
* @memberof AppDataUploadView
*/
protected hasImported:boolean = false;
/**
* 导入数据识别项属性
*
* @type {string}
* @memberof AppDataUploadView
*/
protected importUniqueItem:string ="";
/**
* 提示信息
*
* @type {string}
* @memberof AppDataUploadView
*/
protected promptInfo:string ="";
/**
* 导入状态
*
* @type {boolean}
* @memberof AppDataUploadView
*/
protected isUploading:boolean = false;
/**
* 导入成功数据
*
* @type {string}
* @memberof AppDataUploadView
*/
protected importSuccessData:Array<any> = [];
/**
* 导入失败数据
*
* @type {string}
* @memberof AppDataUploadView
*/
protected importErrorData:Array<any> = [];
/**
* 读取完成的数据
*
* @type {*}
* @memberof AppDataUploadView
*/
public workBookData:any;
/**
* 所有的代码表
*
* @type {*}
* @memberof AppDataUploadView
*/
public allCodeList:any;
/**
* 属性Map(用作属性转化)
*
* @type {*}
* @memberof AppDataUploadView
*/
public allFieldMap:Map<string,any> = new Map();
/**
* 视图参数变化
*
* @param {*} newVal
* @param {*} oldVal
* @memberof AppDataUploadView
*/
@Watch('viewparam',{immediate: true, deep: true})
onParamData(newVal: any, oldVal: any) {
if(newVal){
Object.assign(this.viewparams, JSON.parse(this.viewparam));
this.initBasic();
}
}
/**
* 初始化基础数据
*
* @memberof AppDataUploadView
*/
public async initBasic(){
if(this.viewparams.importId){
this.importId = this.viewparams.importId;
}
if(this.viewparams.importData){
this.importDataModel = Object.values(this.viewparams.importData);
this.BubbleSort(this.importDataModel,this.importDataModel.length);
}
this.importDataModel.forEach((item:any) =>{
if(item.isuniqueitem){
this.importUniqueItem = item.headername;
}
this.allFieldMap.set(item.headername,item);
});
//获取代码表值
this.allCodeList = await this.getChartAllCodeList();
}
/**
* 冒泡排序
*
* @param {*} newVal
* @param {*} oldVal
* @memberof AppDataUploadView
*/
public BubbleSort(array:Array<any>,length:number){
for (let i = 0; i < length; i++){
for (let j = 0; j < length - i - 1; j++){
if (array[j].order > array[j + 1].order){
let temp:any;
temp = array[j + 1];
array[j + 1] = array[j];
array[j] = temp;
}
}
}
}
/**
* 下载导入数据模板
*
* @memberof AppDataUploadView
*/
public downloadTemp(){
this.importExcel(this.viewparams.appDeLogicName+this.$t('components.appDataUploadView.datatemp'),[]);
}
/**
* 选择文件
*
* @memberof AppDataUploadView
*/
public handleUpLoad(){
this.importSuccessData = [];
(this.$refs.inputUpLoad as any).click();
}
/**
* 上传服务器
*
* @memberof AppDataUploadView
*/
public uploadServer(){
if(this.importDataArray.length == 0){
return;
}
let tempDataArray:Array<any> = [];
this.transformData(this.importDataArray,tempDataArray);
this.hasImported = true;
this.isUploading = true;
this.importDataArray = [];
try{
this.entityService.getService(this.viewparams.serviceName).then((service:any) =>{
service.ImportData(this.viewdata,{name:this.importId,data:tempDataArray}).then((res:any) =>{
const result:any = res.data;
if(result && result.rst !== 0){
this.promptInfo = (this.$t('components.appDataUploadView.importfailed') as string);
this.isUploading = false;
return;
}
this.importSuccessData = result.data;
this.promptInfo = (this.$t('components.appDataUploadView.completed') as string);
this.isUploading = false;
})
}).catch((error:any) =>{
this.isUploading = false;
this.promptInfo = (this.$t('components.appDataUploadView.importfailed') as string);
console.error(error);
})
}catch(error){
this.isUploading = false;
this.promptInfo = (this.$t('components.appDataUploadView.importfailed') as string);
console.error(error);
};
}
/**
* 导出excel
*
* @memberof AppDataUploadView
*/
public async importExcel (filename:string,_data:any){
const tHeader: Array<any> = [];
this.importDataModel.forEach((item: any) => {
tHeader.push(item.headername);
});
//const data = await this.formatExcelData(filterVal, _data);
const data = _data?_data:[];
this.$export.exportExcel().then((excel:any)=>{
excel.export_json_to_excel({
header: tHeader, //表头 必填
data:data, //具体数据 必填
filename: filename, //非必填
autoWidth: true, //非必填
bookType: "xlsx" //非必填
});
});
};
/**
* 确认
*
* @memberof AppDataUploadView
*/
public handleOK(){
this.$emit('close',this.importSuccessData);
}
/**
* 导入Excel
*
* @memberof AppDataUploadView
*/
public importFile($event:any) {
let obj = $event.target || $event.srcElement;
if (!obj.files) {
return;
}
let f = obj.files[0];
let reader = new FileReader();
reader.onload = (e:any) => {
let data = e.target.result;
this.workBookData = XLSX.read(data, {type: 'binary'});
let xlsxData = XLSX.utils.sheet_to_json(this.workBookData.Sheets[this.workBookData.SheetNames[0]]);
let list1 = this.getFirstRow(this.workBookData);
xlsxData = this.AddXlsxData(xlsxData, list1);
this.importDataArray = JSON.parse(JSON.stringify(xlsxData));
(this.$refs.inputUpLoad as any).value = '';
};
reader.readAsBinaryString(f);
}
/**
* 获取excel第一行的内容
*
* @memberof AppDataUploadView
*/
public getFirstRow(wb:any) {
//// 读取的excel单元格内容
let wbData = wb.Sheets[wb.SheetNames[0]];
// 匹配excel第一行的内容
let re = /^[A-Z]1$/;
let temparr = [];
// excel第一行内容赋值给数组
for (let key in wbData) {
if (wbData.hasOwnProperty(key)) {
if (re.test(key)) {
temparr.push(wbData[key].h);
}
}
}
return temparr;
}
/**
* 增加对应字段空白内容
*
* @memberof AppDataUploadView
*/
public AddXlsxData(xlsxData:any, list1:any) {
// 空白字段替换值
let addData = null;
for (let i = 0; i < xlsxData.length; i++) {
// 要被JSON的数组
for (let j = 0; j < list1.length; j++) {
// excel第一行内容
if (!xlsxData[i][list1[j]]) {
xlsxData[i][list1[j]] = addData;
}
}
}
return xlsxData;
}
/**
* 获取图表所需代码表
*
* @memberof AppDataUploadView
*/
public async getChartAllCodeList(){
let codeListMap:Map<string,any> = new Map();
if(Object.values(this.importDataModel).length >0){
await Object.values(this.importDataModel).forEach(async (singleDataModel:any) =>{
if(singleDataModel.codelist){
let tempCodeListMap:Map<any,any> = new Map();
let res:any = await this.getCodeList(singleDataModel.codelist);
if(res && res.length >0){
res.forEach((codeListItem:any) =>{
tempCodeListMap.set(codeListItem.value,codeListItem.text);
})
}
codeListMap.set(singleDataModel.codelist.tag,tempCodeListMap);
}
})
}
return codeListMap;
}
/**
* 获取代码表
*
* @returns {Promise<any>}
* @memberof AppDataUploadView
*/
public getCodeList(codeListObject:any):Promise<any>{
return new Promise((resolve:any,reject:any) =>{
if(codeListObject.tag && Object.is(codeListObject.type,"STATIC")){
const codelist = this.$store.getters.getCodeList(codeListObject.tag);
if (codelist) {
resolve([...JSON.parse(JSON.stringify(codelist.items))]);
} else {
console.log(`----${codeListObject.tag}----代码表不存在`);
}
}else if(codeListObject.tag && Object.is(codeListObject.type,"DYNAMIC")){
this.codeListService.getItems(codeListObject.tag).then((res:any) => {
resolve(res);
}).catch((error:any) => {
console.log(`----${codeListObject.tag}----代码表不存在`);
});
}
})
}
/**
* 转化数据
*
* @memberof AppDataUploadView
*/
public transformData(data:Array<any>,result:Array<any>){
data.forEach((item:any) =>{
let curObject:any = {};
Object.keys(item).forEach((ele:any) => {
if(this.allFieldMap.get(ele).codelist){
let codelistTag:string = this.allFieldMap.get(ele).codelist.tag;
let codelistIsNumber:boolean = this.allFieldMap.get(ele).codelist.isnumber;
let curCodeList:any = this.transCodeList(codelistTag,codelistIsNumber,true);
Object.defineProperty(curObject, this.allFieldMap.get(ele).name, {
value: curCodeList.get(item[ele]),
writable : true,
enumerable : true,
configurable : true
});
}else{
Object.defineProperty(curObject, this.allFieldMap.get(ele).name, {
value: item[ele],
writable : true,
enumerable : true,
configurable : true
});
}
});
result.push(curObject);
})
}
/**
* 翻译代码表
*
* @memberof AppDataUploadView
*/
public transCodeList(codeListTag:string,codelistIsNumber:boolean,isTransform:boolean){
let curCodeList:any = this.allCodeList.get(codeListTag);
if(isTransform){
let tempCodelist:Map<string,string> = new Map();
curCodeList.forEach((item:string,key:string) =>{
let value:any = codelistIsNumber?Number(key):key;
tempCodelist.set(item,value);
})
curCodeList = tempCodelist;
}
return curCodeList;
}
}
</script>
<style lang='less'>
@import './app-data-upload.less';
</style>
\ No newline at end of file
.app-debug-actions {
position: absolute;
top: 0px;
left: 50%;
z-index: 10000;
text-align: center;
transition: all 0.3s;
margin-top: -32px;
>.actions {
.ivu-btn {
width: 100%;
}
}
>.show-buttons {
width: 100%;
height: 18px;
border-width: 0px 1px 1px 1px;
border-style: solid;
border-color: #8893a7;
text-align: center;
color: #8893a7;
cursor: pointer;
>.button {
margin-top: -5px;
}
}
}
.app-debug-actions:hover {
margin-top: 0px;
}
\ No newline at end of file
<template>
<div class="app-debug-actions">
<div class="actions">
<button-group vertical>
<i-button :title="$t('components.appDebugActions.button')" :type="sdc.isShowTool ? 'warning' : 'info'" ghost @click="() => sdc.showToolChange()" :icon="sdc.isShowTool ? 'ios-bug' : 'ios-bug-outline'" ></i-button>
</button-group>
</div>
<div class="show-buttons">
<div class="button"><i class="ivu-icon ivu-icon-ios-arrow-down" /></div>
</div>
</div>
</template>
<script lang = 'ts'>
import { Vue, Component } from 'vue-property-decorator';
import { StudioActionUtil } from '@/utils';
import { Environment } from '@/environments/environment';
/**
* 开发模式控制行为组
*
* @export
* @class AppDebugActions
* @extends {Vue}
*/
@Component({
})
export default class AppDebugActions extends Vue {
/**
* 配置平台操作控制器
*
* @type {StudioActionController}
* @memberof AppDebugActions
*/
public sdc: StudioActionUtil = StudioActionUtil.getInstance();
}
</script>
<style lang = "less">
@import "./app-debug-actions.less";
</style>
\ No newline at end of file
...@@ -11,8 +11,8 @@ ...@@ -11,8 +11,8 @@
</component> </component>
</div> </div>
<template v-if="placeholder"> <template v-if="placeholder">
<div v-if="value" class="app-embed-value">{this.value}</div> <div v-if="value" class="app-embed-value">{{value}}</div>
<div v-else class="app-embed-placeholder">{this.placeholder}</div> <div v-else class="app-embed-placeholder">{{placeholder}}</div>
</template> </template>
</div> </div>
<div v-else>{{emptyText}}</div> <div v-else>{{emptyText}}</div>
......
...@@ -2,17 +2,17 @@ ...@@ -2,17 +2,17 @@
<dropdown v-if="itemLevel === 0" :transfer="true" trigger='click'> <dropdown v-if="itemLevel === 0" :transfer="true" trigger='click'>
<i-button :disabled="item.disabled"> <i-button :disabled="item.disabled">
<i class='fa fa-file-excel-o'></i> <i class='fa fa-file-excel-o'></i>
<span class='caption'>{{item.caption}}</span> <span class='caption'>{{caption}}</span>
</i-button> </i-button>
<dropdown-menu slot='list'> <dropdown-menu slot='list'>
<dropdown-item> <dropdown-item>
<p @click="exportExcel($event, 'maxRowCount')"> <p @click="exportExcel($event, 'maxRowCount')">
{{item.caption}}全部(最大{{item.caption}}{{item.MaxRowCount}}) {{caption}}{{$t('components.appExportExcel.total')}}({{$t('components.appExportExcel.max')}}{{caption}}{{item.MaxRowCount}}{{$t('components.appExportExcel.row')}})
</p> </p>
</dropdown-item> </dropdown-item>
<dropdown-item> <dropdown-item>
<p @click="exportExcel($event, 'activatedPage')"> <p @click="exportExcel($event, 'activatedPage')">
{{this.item.caption}}当前页 {{caption}}{{$t('components.appExportExcel.currentPage')}}
</p> </p>
</dropdown-item> </dropdown-item>
</dropdown-menu> </dropdown-menu>
...@@ -29,7 +29,8 @@ import { Vue, Component, Prop, Watch } from 'vue-property-decorator'; ...@@ -29,7 +29,8 @@ import { Vue, Component, Prop, Watch } from 'vue-property-decorator';
* @class AppExportExcel * @class AppExportExcel
* @extends {Vue} * @extends {Vue}
*/ */
@Component({}) @Component({
})
export default class AppExportExcel extends Vue { export default class AppExportExcel extends Vue {
/** /**
...@@ -40,6 +41,14 @@ export default class AppExportExcel extends Vue { ...@@ -40,6 +41,14 @@ export default class AppExportExcel extends Vue {
*/ */
@Prop() public item?: any; @Prop() public item?: any;
/**
* 工具栏项
*
* @type {*}
* @memberof AppExportExcel
*/
@Prop() public caption?: any;
/** /**
* 工具栏项层级 * 工具栏项层级
* *
...@@ -128,4 +137,4 @@ export default class AppExportExcel extends Vue { ...@@ -128,4 +137,4 @@ export default class AppExportExcel extends Vue {
<style lang='less'> <style lang='less'>
@import './app-export-excel.less'; @import './app-export-excel.less';
</style> </style>
\ No newline at end of file
.app-file-upload{
.upload-col{
text-align: center;
.button-preview{
padding: 8px 15px 8.5px 15px;
.ivu-badge{
margin-left: 2px;
.ivu-badge-count{
height: auto;
min-width: auto;
line-height: unset;
padding: 0 4px;
}
}
}
}
}
.upload-preview-modal{
.ivu-modal{
height: 86%;
.ivu-modal-content{
height: 100%;
overflow-y: scroll;
.preview-file-list-item{
margin: 0 8px 8px 0;
display: inline-block;
position: relative;
}
.preview-file-list-img{
display: inline-block;
position: relative;
}
.file-name{
text-align: center;
}
.preview-file-list-actions{
position: absolute;
width: 100%;
height: 100%;
left: 0;
top: 0;
font-size: 20px;
text-align: center;
color: #fff;
opacity: 0;
transition: opacity .3s;
}
.preview-file-list-actions:hover{
position: absolute;
width: 100%;
height: 100%;
left: 0;
top: 0;
font-size: 20px;
text-align: center;
color: #fff;
opacity: 1;
background-color: rgba(0,0,0,.5);
}
.preview-file-list-actions::after{
display: inline-block;
content: "";
height: 100%;
vertical-align: middle;
}
.action-delete{
margin-left:15px;
}
}
}
}
\ No newline at end of file
<template> <template>
<el-upload <div class="app-file-upload">
:disabled="disabled" <el-row>
:file-list="files" <el-col v-if="rowPreview && files.length > 0" :span="12" class="upload-col">
:action="uploadUrl" <el-button size='small' class="button-preview" icon='el-icon-view' :disabled="disabled" @click="()=>{this.dialogVisible = true;}">{{$t('components.appFileUpload.preview')}}<Badge :count="files.length" type="info"></Badge></el-button>
:headers="{}" </el-col>
:before-upload="beforeUpload" <el-col :span="(rowPreview && files.length > 0) ? 12 : 24" class="upload-col">
:before-remove="onRemove" <el-upload
:on-success="onSuccess" :disabled="disabled"
:on-error="onError" :file-list="files"
:on-preview="onDownload" :action="uploadUrl"
:drag="isdrag" :headers="{}"
> :before-upload="beforeUpload"
<el-button v-if="!isdrag" size='small' icon='el-icon-upload' :disabled="disabled">{{this.$t('app.fileUpload.caption')}}</el-button> :before-remove="onRemove"
<i v-if="isdrag" class="el-icon-upload"></i> :on-success="onSuccess"
<div v-if="isdrag" class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div> :on-error="onError"
</el-upload> :on-preview="onDownload"
:drag="isdrag"
:show-file-list="!rowPreview"
>
<el-button v-if="!isdrag" size='small' icon='el-icon-upload' :disabled="disabled">{{this.$t('app.fileUpload.caption')}}</el-button>
<i v-if="isdrag" class="el-icon-upload"></i>
<div v-if="isdrag" class="el-upload__text" v-html="$t('components.appFileUpload.uploadText')"></div>
</el-upload>
</el-col>
</el-row>
<modal width="80%" v-model="dialogVisible" footer-hide class-name='upload-preview-modal'>
<ul class="">
<li v-for="(file,index) in files" :key="index" class="preview-file-list-item">
<div class='preview-file-list-img'>
<el-image :src="file.url" class='' style=''>
<div slot='error' class='image-slot'>
<img src="/assets/img/picture.png" style='width:100%;height:100%;'>
</div>
</el-image>
<div class='preview-file-list-actions' @mouseenter="()=>{showActions = true;}" @mouseleave="()=>{showActions = false;}">
<span v-show="showActions" class='action-download'>
<i class='el-icon-download' @click="onDownload(file)"></i>
</span>
<span v-show="showActions" :style="{ 'display': disabled? 'none' : 'inline-block' }" class='action-delete'>
<i class='el-icon-delete' @click="onRemove(file, files)"></i>
</span>
</div>
</div>
<div class="file-name">{{file.name}}</div>
</li>
</ul>
</modal>
</div>
</template> </template>
<script lang="ts"> <script lang="ts">
...@@ -23,7 +55,8 @@ import { Environment } from '@/environments/environment'; ...@@ -23,7 +55,8 @@ import { Environment } from '@/environments/environment';
import { CreateElement } from 'vue'; import { CreateElement } from 'vue';
import { Subject, Unsubscribable } from 'rxjs'; import { Subject, Unsubscribable } from 'rxjs';
@Component({}) @Component({
})
export default class AppFileUpload extends Vue { export default class AppFileUpload extends Vue {
/** /**
...@@ -87,12 +120,8 @@ export default class AppFileUpload extends Vue { ...@@ -87,12 +120,8 @@ export default class AppFileUpload extends Vue {
if (this.ignorefieldvaluechange) { if (this.ignorefieldvaluechange) {
return; return;
} }
if (newval) { this.setFiles(newval)
this.files = JSON.parse(newval); this.dataProcess();
this.dataProcess();
} else {
this.files = [];
}
} }
/** /**
...@@ -188,6 +217,21 @@ export default class AppFileUpload extends Vue { ...@@ -188,6 +217,21 @@ export default class AppFileUpload extends Vue {
*/ */
public appData: any; public appData: any;
/**
* 设置files
*
* @private
* @memberof AppFileUpload
*/
private setFiles(value:any): void {
let _files = JSON.parse(value);
if (value && Object.prototype.toString.call(_files)=='[object Array]') {
this.files = _files;
} else {
this.files = [];
}
}
/** /**
* 数据处理 * 数据处理
* *
...@@ -230,9 +274,7 @@ export default class AppFileUpload extends Vue { ...@@ -230,9 +274,7 @@ export default class AppFileUpload extends Vue {
this.formStateEvent = this.formState.subscribe(($event: any) => { this.formStateEvent = this.formState.subscribe(($event: any) => {
// 表单加载完成 // 表单加载完成
if (Object.is($event.type, 'load')) { if (Object.is($event.type, 'load')) {
if (this.value) { this.setFiles(this.value);
this.files = JSON.parse(this.value);
}
this.dataProcess(); this.dataProcess();
} }
}); });
...@@ -271,12 +313,7 @@ export default class AppFileUpload extends Vue { ...@@ -271,12 +313,7 @@ export default class AppFileUpload extends Vue {
this.export_keys = export_keys; this.export_keys = export_keys;
this.custom_arr = custom_arr; this.custom_arr = custom_arr;
if (this.value) { this.setFiles(this.value);
let _files = JSON.parse(this.value);
if(typeof _files === "object" ){
this.files = _files;
}
}
this.dataProcess(); this.dataProcess();
} }
...@@ -298,7 +335,14 @@ export default class AppFileUpload extends Vue { ...@@ -298,7 +335,14 @@ export default class AppFileUpload extends Vue {
* @memberof AppFileUpload * @memberof AppFileUpload
*/ */
public beforeUpload(file: any) { public beforeUpload(file: any) {
// console.log('上传之前'); if(this.imageOnly){
const imageTypes = ["image/jpeg" , "image/gif" , "image/png" , "image/bmp"];
const isImage = imageTypes.some((type: any)=> Object.is(type, file.type));
if (!isImage) {
this.$Notice.error({ title: (this.$t('components.appFileUpload.fileTypeErrorTitle') as any) ,desc: (this.$t('components.appFileUpload.fileTypeErrorInfo') as any)});
}
return isImage;
}
} }
/** /**
...@@ -333,7 +377,7 @@ export default class AppFileUpload extends Vue { ...@@ -333,7 +377,7 @@ export default class AppFileUpload extends Vue {
* @memberof AppFileUpload * @memberof AppFileUpload
*/ */
public onError(error: any, file: any, fileList: any) { public onError(error: any, file: any, fileList: any) {
this.$Notice.error({ title: '上传失败' }); this.$Notice.error({ title: (this.$t('components.appFileUpload.uploadError') as any) });
} }
/** /**
...@@ -351,6 +395,9 @@ export default class AppFileUpload extends Vue { ...@@ -351,6 +395,9 @@ export default class AppFileUpload extends Vue {
} }
}); });
let value: any = arr.length > 0 ? JSON.stringify(arr) : null; let value: any = arr.length > 0 ? JSON.stringify(arr) : null;
if(arr.length == 0){
this.dialogVisible = false;
}
this.$emit('formitemvaluechange', { name: this.name, value: value }); this.$emit('formitemvaluechange', { name: this.name, value: value });
} }
...@@ -364,6 +411,38 @@ export default class AppFileUpload extends Vue { ...@@ -364,6 +411,38 @@ export default class AppFileUpload extends Vue {
window.open(file.url); window.open(file.url);
} }
/**
* 是否只支持图片上传
*
* @type {boolean}
* @memberof AppFileUpload
*/
@Prop({default: false}) public imageOnly!: boolean;
/**
* 是否开启行内预览
*
* @type {boolean}
* @memberof AppFileUpload
*/
@Prop({default: false}) public rowPreview!: boolean;
/**
* 是否开启行内预览
*
* @type {boolean}
* @memberof AppFileUpload
*/
public dialogVisible: boolean = false;
/**
* 是否开启行内预览
*
* @type {boolean}
* @memberof AppFileUpload
*/
public showActions: boolean = false;
} }
</script> </script>
......
...@@ -13,13 +13,14 @@ ...@@ -13,13 +13,14 @@
@viewdataschange="viewdataschange" @viewdataschange="viewdataschange"
@viewload="viewload"> @viewload="viewload">
</component> </component>
<spin v-if="blockUI" class='app-druipart-spin' fix >{{ blockUITipInfo }}</spin> <spin v-if="blockUI" class='app-druipart-spin' fix >{{ $t('components.appFormDRUIPart.blockUITipInfo') }}</spin>
</div> </div>
</template> </template>
<script lang = 'ts'> <script lang = 'ts'>
import { Vue, Component, Prop, Watch } from 'vue-property-decorator'; import { Vue, Component, Prop, Watch } from 'vue-property-decorator';
import { Subject, Unsubscribable } from 'rxjs'; import { Subject, Unsubscribable } from 'rxjs';
@Component({}) @Component({
})
export default class AppFormDRUIPart extends Vue { export default class AppFormDRUIPart extends Vue {
/** /**
...@@ -183,14 +184,6 @@ export default class AppFormDRUIPart extends Vue { ...@@ -183,14 +184,6 @@ export default class AppFormDRUIPart extends Vue {
*/ */
public blockUI: boolean = false; public blockUI: boolean = false;
/**
* 遮罩提示信息
*
* @type {string}
* @memberof AppFormDRUIPart
*/
public blockUITipInfo: string = '请先保存主数据';
/** /**
* 是否刷新关系数据 * 是否刷新关系数据
* *
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
> .el-tabs { > .el-tabs {
height: 100%; height: 100%;
> .el-tabs__content { > .el-tabs__content {
height: calc(100% - 51px); height: calc(100% - 62px);
> .el-tab-pane { > .el-tab-pane {
height: 100%; height: 100%;
overflow: auto; overflow: auto;
......
.app-format-data{
display: inline-block;
}
\ No newline at end of file
<template>
<span class="app-format-data">
{{getcurValue()}}
</span>
</template>
<script lang = 'ts'>
import { Component, Vue, Prop } from 'vue-property-decorator';
import moment from "moment";
@Component({})
export default class AppFormatData extends Vue {
/**
* 格式化正则
*
* @type {string}
* @memberof AppFormatData
*/
@Prop({default:'YYYY-MM-DD HH:mm:ss'}) public format?:string;
/**
* 传入数据
*
* @type {*}
* @memberof AppFormatData
*/
@Prop() public data!:any;
/**
* 显示值
*
* @memberof AppFormatData
*/
getcurValue(){
if(this.data){
if(this.format){
if(this.format.indexOf('%1$t') !== -1){
return moment(this.data).format("YYYY-MM-DD HH:mm:ss");
}else{
return moment(this.data).format(this.format);
}
}else{
return this.data;
}
}else{
return "";
}
}
}
</script>
<style lang="less">
@import './app-format-data.less';
</style>
\ No newline at end of file
.app-header-menus {
display: flex;
align-items: center;
height: 100%;
line-height: 20px;
>.app-header-menu-item{
height: 24px;
display: flex;
align-items: center;
margin-right: 16px;
color: #8893a7;
border: 1px solid rgba(0, 0, 0, 0);
cursor: pointer;
}
>.app-header-menu-item.icon {
>.app-header-menu-item-icon {
font-size: 20px;
}
>.app-header-menu-item-img {
height: 20px;
width: 20px;
>img {
height: 100%;
width: 100%;
}
}
}
>.app-header-menu-item.icon:hover{
color: #68758e;
text-decoration: none;
}
>.app-header-menu-item.text {
border-radius: 4px;
border: 1px solid #8893a7;
text-align: center;
font-size: 12px;
padding: 2px 4px;
>.app-header-menu-item-icon {
width: 20px;
height: 20px;
overflow: hidden;
font-size: 16px;
margin-right: 3px;
margin-top: -3px;
}
>.app-header-menu-item-img {
height: 16px;
width: 16px;
margin-right: 3px;
>img {
height: 100%;
width: 100%;
}
}
}
>.app-header-menu-item.text:hover {
color: #107fff;
border: 1px solid #107fff;
}
}
.app-header-menus:hover {
background: none !important;
}
\ No newline at end of file
<template>
<div class="app-header-menus">
<div v-for="(menu,index) in menus" :key="index" class="app-header-menu-item text" @click="openWindow(menu)">
<div class="app-header-menu-item-icon">
<i :class="menu.iconcls" :aria-hidden="true" />
</div>
<div class="app-header-menu-item-text">{{$t(menu.title)}}</div>
</div>
</div>
</template>
<script lang="ts">
import { Vue, Component, Prop, Model, Emit } from "vue-property-decorator";
import { Subject } from "rxjs";
import { Environment } from '@/environments/environment';
@Component({
})
export default class AppHeaderMenus extends Vue {
/**
* 菜单数据
*
* @type {any}
* @memberof AppHeaderMenus
*/
public menus:any = [
{
name: "ibizlab",
title: "components.appHeaderMenus.ibizlab.title",
url: Environment.ibizlabtUrl,
iconcls: 'fa fa-home',
},
{
name: "publishProject",
title: "components.appHeaderMenus.publishProject.title",
url: Environment.PublishProjectUrl,
iconcls: 'fa fa-folder-open-o',
},
{
name: "ibizstudio",
title: "components.appHeaderMenus.ibizstudio.title",
url: `${Environment.StudioUrl}?#/common_slnindex/srfkeys=${Environment.SlnId}/sysdesign_psdevslnsysmodeltreeexpview`,
iconcls: 'fa fa-wrench',
},
{
name: "ibizbbs",
title: "components.appHeaderMenus.ibizbbs.title",
url: Environment.ibizbbstUrl,
iconcls: 'fa fa-comments-o',
},
];
/**
* 触发界面行为
*
* @memberof AppHeaderMenus
*/
public openWindow(menu:any){
window.open(menu.url, '_blank');
}
}
</script>
<style lang='less'>
@import "./app-header-menus.less";
</style>
\ No newline at end of file
/*** BEGIN:图片上传 ***/
.app-picture-preview {
.preview-file-list-item{
margin: 0 8px 8px 0;
display: inline-block;
position: relative;
}
.preview-file-list-img{
display: inline-block;
position: relative;
width: 148px;
height: 148px;
.el-image{
width: 100%;
height: 100%;
.image-slot{
width: 100%;
height: 100%;
}
}
}
.preview-file-list-actions{
position: absolute;
width: 100%;
height: 100%;
left: 0;
top: 0;
font-size: 20px;
text-align: center;
color: #fff;
opacity: 0;
transition: opacity .3s;
.action-download{
margin-left: 15px;
}
}
.preview-file-list-actions:hover{
position: absolute;
width: 100%;
height: 100%;
left: 0;
top: 0;
font-size: 20px;
text-align: center;
color: #fff;
opacity: 1;
background-color: rgba(0,0,0,.5);
}
.preview-file-list-actions::after{
display: inline-block;
content: "";
height: 100%;
vertical-align: middle;
}
>div{
display: inline;
}
}
.app-image-preview-model {
width: 100%;
height: 100%;
text-align: center;
.ivu-modal{
top: 50%;
transform: translateY(-50%);
display: inline-block;
.ivu-modal-content{
display: inline-block;
.ivu-modal-close{
display: none;
}
.ivu-modal-body{
display: inline-block;
line-height: 0;
.el-image {
width: auto;
height: auto;
line-height: 0;
.image-slot {
width: auto;
height: auto;
line-height: 0;
img{
max-width: 1200px;
max-height: 1600px;
}
}
}
}
}
}
}
/*** END:图片上传 ***/
\ No newline at end of file
<template>
<div class='app-picture-preview'>
<ul class="">
<li v-for="(file,index) in files" :key="index" class="preview-file-list-item">
<div class='preview-file-list-img'>
<el-image :src="file.url" class='' style=''>
<div slot='error' class='image-slot'>
<img src="/assets/img/picture.png" style='width:100%;height:100%;'>
</div>
</el-image>
<div class='preview-file-list-actions'>
<span class='action-preview'>
<i class='el-icon-zoom-in' @click="onPreview(file)"></i>
</span>
<span class='action-download'>
<i class='el-icon-download' @click="onDownload(file)"></i>
</span>
</div>
</div>
</li>
</ul>
<!-- 预览 -->
<modal v-model="dialogVisible" footer-hide width="auto" class-name='app-image-preview-model'>
<el-image src="dialogImageUrl">
<div slot='error' class='image-slot'>
<img src="/assets/img/picture.png">
</div>
</el-image>
</modal>
</div>
</template>
<script lang = 'ts'>
import { Vue, Component, Prop, Watch, Provide } from 'vue-property-decorator';
import { Environment } from '@/environments/environment';
import { Subject, Unsubscribable } from 'rxjs';
@Component({})
export default class AppImagePreview extends Vue {
/**
* 表单状态
*
* @type {Subject<any>}
* @memberof AppImagePreview
*/
@Prop() public formState?: Subject<any>
/**
* 表单状态事件
*
* @private
* @type {(Unsubscribable | undefined)}
* @memberof AppImagePreview
*/
private formStateEvent: Unsubscribable | undefined;
/**
* 初始化值
*
* @type {*}
* @memberof AppImagePreview
*/
@Prop() public value?: any;
/**
* 数据值变化
*
* @param {*} newval
* @param {*} val
* @returns
* @memberof AppImagePreview
*/
@Watch('value')
onValueChange(newval: any, val: any) {
this.setFiles(newval)
}
/**
* 所属表单项名称
*
* @type {string}
* @memberof AppImagePreview
*/
@Prop() public name!: string;
/**
* 上传文件路径
*
* @memberof AppImagePreview
*/
public uploadUrl = Environment.BaseUrl + Environment.UploadFile;
/**
* 下载文件路径
*
* @memberof AppImagePreview
*/
public downloadUrl = Environment.BaseUrl + Environment.ExportFile;
/**
* 文件列表
*
* @memberof AppImagePreview
*/
@Provide() public files = [];
/**
* 设置files
*
* @private
* @memberof AppImagePreview
*/
private setFiles(value:any): void {
let _files = JSON.parse(value);
if (value && Object.prototype.toString.call(_files)=='[object Array]') {
this.files = _files;
this.files.forEach((file: any) => {
let url = `${this.downloadUrl}/${file.id}`;
file.url = url;
});
} else {
this.files = [];
}
}
/**
* vue 生命周期
*
* @memberof AppImagePreview
*/
public created() {
if (this.formState) {
this.formStateEvent = this.formState.subscribe(($event: any) => {
// 表单加载完成
if (Object.is($event.type, 'load')) {
this.setFiles(this.value);
}
});
}
}
/**
* vue 生命周期
*
* @memberof AppImagePreview
*/
public mounted() {
this.setFiles(this.value);
}
/**
* 组件销毁
*
* @memberof AppImagePreview
*/
public destroyed(): void {
if (this.formStateEvent) {
this.formStateEvent.unsubscribe();
}
}
/**
* 下载文件
*
* @param {*} file
* @memberof AppImagePreview
*/
public onDownload(file: any) {
window.open(file.url);
}
/**
* 预览图片地址
*
* @type {string}
* @memberof AppImagePreview
*/
public dialogImageUrl: string = '';
/**
* 是否显示预览界面
*
* @type {boolean}
* @memberof AppImagePreview
*/
public dialogVisible: boolean = false;
/**
* 预览
*
* @param {*} file
* @memberof AppImagePreview
*/
public onPreview(file: any) {
this.dialogImageUrl = file.url;
this.dialogVisible = true;
}
}
</script>
<style lang = "less">
@import './app-image-preview.less';
</style>
\ No newline at end of file
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
<ul class='el-upload-list el-upload-list--picture-card'> <ul class='el-upload-list el-upload-list--picture-card'>
<!-- 绘制缩略图 Start --> <!-- 绘制缩略图 Start -->
<li v-for="(file,index) in files" :key="index" class='el-upload-list__item is-success'> <li v-for="(file,index) in files" :key="index" class='el-upload-list__item is-success'>
<el-image src={file.url} class='el-upload-list__item-thumbnail' style='min-height:100px;min-width:100px;'> <el-image :src="file.url" class='el-upload-list__item-thumbnail' style='min-height:100px;min-width:100px;'>
<div slot='error' class='image-slot'> <div slot='error' class='image-slot'>
<i class='el-icon-picture-outline'></i> <i class='el-icon-picture-outline'></i>
</div> </div>
...@@ -119,12 +119,8 @@ export default class AppImageUpload extends Vue { ...@@ -119,12 +119,8 @@ export default class AppImageUpload extends Vue {
if (this.ignorefieldvaluechange) { if (this.ignorefieldvaluechange) {
return; return;
} }
if (newval) { this.setFiles(newval)
this.files = JSON.parse(newval); this.dataProcess();
this.dataProcess();
} else {
this.files = [];
}
} }
/** /**
...@@ -220,6 +216,21 @@ export default class AppImageUpload extends Vue { ...@@ -220,6 +216,21 @@ export default class AppImageUpload extends Vue {
*/ */
public appData: any=""; public appData: any="";
/**
* 设置files
*
* @private
* @memberof AppImageUpload
*/
private setFiles(value:any): void {
let _files = JSON.parse(value);
if (value && Object.prototype.toString.call(_files)=='[object Array]') {
this.files = _files;
} else {
this.files = [];
}
}
/** /**
* 数据处理 * 数据处理
* *
...@@ -262,10 +273,7 @@ export default class AppImageUpload extends Vue { ...@@ -262,10 +273,7 @@ export default class AppImageUpload extends Vue {
this.formStateEvent = this.formState.subscribe(($event: any) => { this.formStateEvent = this.formState.subscribe(($event: any) => {
// 表单加载完成 // 表单加载完成
if (Object.is($event.type, 'load')) { if (Object.is($event.type, 'load')) {
if (this.value) { this.setFiles(this.value);
// console.log(this.value);
this.files = JSON.parse(this.value);
}
this.dataProcess(); this.dataProcess();
} }
}); });
...@@ -303,12 +311,7 @@ export default class AppImageUpload extends Vue { ...@@ -303,12 +311,7 @@ export default class AppImageUpload extends Vue {
this.export_keys = export_keys; this.export_keys = export_keys;
this.custom_arr = custom_arr; this.custom_arr = custom_arr;
if (this.value) { this.setFiles(this.value);
let _files = JSON.parse(this.value);
if(typeof _files === "object" ){
this.files = _files;
}
}
this.dataProcess(); this.dataProcess();
} }
......
<template> <template>
<dropdown trigger='click' on-click="selectLang"> <dropdown trigger='click' @on-click="selectLang">
<span> <span>
{{title}} {{title}}
<icon size='18' type='md-arrow-dropdown'></icon> <icon size='18' type='md-arrow-dropdown'></icon>
......
...@@ -15,7 +15,8 @@ import { Component, Vue, Prop, Watch } from 'vue-property-decorator'; ...@@ -15,7 +15,8 @@ import { Component, Vue, Prop, Watch } from 'vue-property-decorator';
import { Subject } from 'rxjs'; import { Subject } from 'rxjs';
import { AppModal } from '@/utils'; import { AppModal } from '@/utils';
@Component({}) @Component({
})
export default class AppMpicker extends Vue { export default class AppMpicker extends Vue {
/** /**
...@@ -150,16 +151,20 @@ export default class AppMpicker extends Vue { ...@@ -150,16 +151,20 @@ export default class AppMpicker extends Vue {
if (this.activeData) { if (this.activeData) {
Object.assign(param, { srfreferdata: this.activeData }); Object.assign(param, { srfreferdata: this.activeData });
} }
// 错误信息国际化
let error: string = (this.$t('components.appMpicker.error') as any);
let miss: string = (this.$t('components.appMpicker.miss') as any);
let requestException: string = (this.$t('components.appMpicker.requestException') as any);
if(!this.service){ if(!this.service){
this.$Notice.error({ title: '错误', desc: '缺少参数service' }); this.$Notice.error({ title: error, desc: miss+'service' });
} else if(!this.acParams.serviceName) { } else if(!this.acParams.serviceName) {
this.$Notice.error({ title: '错误', desc: '缺少参数serviceName' }); this.$Notice.error({ title: error, desc: miss+'serviceName' });
} else if(!this.acParams.interfaceName) { } else if(!this.acParams.interfaceName) {
this.$Notice.error({ title: '错误', desc: '缺少参数interfaceName' }); this.$Notice.error({ title: error, desc: miss+'interfaceName' });
} else { } else {
this.service.getItems(this.acParams.serviceName,this.acParams.interfaceName, param).then((response: any) => { this.service.getItems(this.acParams.serviceName,this.acParams.interfaceName, param).then((response: any) => {
if (!response) { if (!response) {
this.$Notice.error({ title: '错误', desc: '请求异常' }); this.$Notice.error({ title: error, desc: requestException });
} else { } else {
this.items = [...response]; this.items = [...response];
} }
...@@ -232,7 +237,8 @@ export default class AppMpicker extends Vue { ...@@ -232,7 +237,8 @@ export default class AppMpicker extends Vue {
_selectItems[index].srfkey = item[this.deKeyField]; _selectItems[index].srfkey = item[this.deKeyField];
}); });
} }
_context = Object.assign(_context, { srfparentdata: { srfparentkey: this.activeData[this.deKeyField] }, selectedData: [..._selectItems], }); _context = Object.assign(_context, { srfparentdata: { srfparentkey: this.activeData[this.deKeyField] }, });
_viewparams = Object.assign(_viewparams,{ selectedData: [..._selectItems]});
let formdata = this.activeData; let formdata = this.activeData;
const modal: Subject<any> = this.$appmodal.openModal(view, _context, _viewparams) const modal: Subject<any> = this.$appmodal.openModal(view, _context, _viewparams)
modal.subscribe((result: any) => { modal.subscribe((result: any) => {
......
...@@ -26,6 +26,8 @@ ...@@ -26,6 +26,8 @@
overflow:inherit; overflow:inherit;
} }
} }
} }
}
.select-no-dropdown.el-select-dropdown{
display: none;
} }
\ No newline at end of file
<template> <template>
<div class="app-picker-select-view"> <div class="app-picker-select-view">
<Dropdown :visible="visible" trigger="custom" style="left:0px;width: 100%" @on-clickoutside="() => {triggerMenu(false);}" > <Dropdown :visible="visible" trigger="custom" style="left:0px;width: 100%" @on-clickoutside="() => {triggerMenu(false);}" >
<Input v-model="inputValue" class="tree-input" type="text" :placeholder="placeholder" :disabled="disabled" @on-change="OnInputChange" @on-focus="()=>{triggerMenu(true);}" > <Input v-if="isSingleSelect" v-model="queryValue" class="tree-input" type="text" :placeholder="placeholder ? placeholder : $t('components.appPickerSelectView.placeholder')" :disabled="disabled" @on-change="OnInputChange" @on-focus="()=>{triggerMenu(true);}" >
<template v-slot:suffix> <template v-slot:suffix>
<i v-if="inputValue && !disabled" class='el-icon-circle-close' @click="onClear"></i> <i v-if="queryValue && !disabled" class='el-icon-circle-close' @click="onClear"></i>
<Icon :type="visible ? 'ios-arrow-up' : 'ios-arrow-down'" class="icon-arrow" @click="() => {triggerMenu();}"></Icon> <Icon :type="visible ? 'ios-arrow-up' : 'ios-arrow-down'" class="icon-arrow" @click="() => {triggerMenu();}"></Icon>
<icon v-if="linkview" type="ios-open-outline" @click="openLinkView"/> <icon v-if="linkview" type="ios-open-outline" @click="openLinkView"/>
</template> </template>
</Input> </Input>
<el-select v-if="!isSingleSelect" popper-class="select-no-dropdown" :value="keySet" multiple filterable remote :remote-method="($event) => {this.queryValue = $event;}" size="small" style="width:100%;" @change="onSelectChange" @focus="() => {triggerMenu(true);}" :disabled="disabled">
<el-option v-for="(item, index) in items" :key="index" :label="item.srfmajortext" :value="item[deKeyField]"></el-option>
</el-select>
<DropdownMenu slot="list"> <DropdownMenu slot="list">
<component <component
:is="pickupView.viewname" :is="pickupView.viewname"
:viewdata="viewdata" :viewdata="viewdata"
:viewparam="viewparam" :viewparam="viewparam"
:ifShowButtons="false" :isShowButton="false"
:viewDefaultUsage="false" :viewDefaultUsage="false"
@viewdataschange="setValue" @viewdataschange="onViewdatasChange"
style="height:100%;"> style="height:100%;">
</component> </component>
</DropdownMenu> </DropdownMenu>
...@@ -29,7 +32,8 @@ import { CreateElement } from 'vue'; ...@@ -29,7 +32,8 @@ import { CreateElement } from 'vue';
import { Subject, Subscription } from 'rxjs'; import { Subject, Subscription } from 'rxjs';
import { ViewTool } from '@/utils/view-tool/view-tool'; import { ViewTool } from '@/utils/view-tool/view-tool';
@Component({}) @Component({
})
export default class AppPickerSelectView extends Vue { export default class AppPickerSelectView extends Vue {
/** /**
* 视图上下文 * 视图上下文
...@@ -46,6 +50,38 @@ export default class AppPickerSelectView extends Vue { ...@@ -46,6 +50,38 @@ export default class AppPickerSelectView extends Vue {
* @memberof AppFormDRUIPart * @memberof AppFormDRUIPart
*/ */
@Prop() public viewparams!: any; @Prop() public viewparams!: any;
/**
* 是否单选
*
* @type {*}
* @memberof AppFormDRUIPart
*/
@Prop({default: 'true'}) public isSingleSelect!: any;
/**
* 当前多选框选中值的key集合
*
* @type {string}
* @memberof AppTreePicker
*/
public keySet: any = [];
/**
* 当前多选框选中项对象集合
*
* @type {string}
* @memberof AppTreePicker
*/
public selectItems: Array<any> = [];
/**
* 所有操作过的下拉选项对象集合
*
* @type {string}
* @memberof AppTreePicker
*/
public items: Array<any> = [];
/** /**
* 视图参数 * 视图参数
...@@ -53,7 +89,7 @@ export default class AppPickerSelectView extends Vue { ...@@ -53,7 +89,7 @@ export default class AppPickerSelectView extends Vue {
* @type {string} * @type {string}
* @memberof AppTreePicker * @memberof AppTreePicker
*/ */
public viewparam: any = JSON.stringify(this.viewparams);; public viewparam: any = JSON.stringify(this.viewparams);
/** /**
* 视图上下文 * 视图上下文
...@@ -104,12 +140,12 @@ export default class AppPickerSelectView extends Vue { ...@@ -104,12 +140,12 @@ export default class AppPickerSelectView extends Vue {
@Prop({default: 'srfkey'}) public deKeyField!: string; @Prop({default: 'srfkey'}) public deKeyField!: string;
/** /**
* 输入框值 * 输入框值(搜索值)
* *
* @type {string} * @type {string}
* @memberof AppTreePicker * @memberof AppTreePicker
*/ */
public inputValue: any = ''; public queryValue: any = '';
/** /**
* 值项名称 * 值项名称
...@@ -117,7 +153,7 @@ export default class AppPickerSelectView extends Vue { ...@@ -117,7 +153,7 @@ export default class AppPickerSelectView extends Vue {
* @type {string} * @type {string}
* @memberof AppPicker * @memberof AppPicker
*/ */
@Prop() public valueitem?: string; @Prop() public valueitem!: string;
/** /**
* 关联视图名称 * 关联视图名称
...@@ -141,7 +177,7 @@ export default class AppPickerSelectView extends Vue { ...@@ -141,7 +177,7 @@ export default class AppPickerSelectView extends Vue {
* @type {string} * @type {string}
* @memberof AppTreePicker * @memberof AppTreePicker
*/ */
@Prop({default:"请选择..."}) public placeholder!: string; @Prop() public placeholder!: string;
/** /**
* 属性项名称 * 属性项名称
...@@ -182,7 +218,7 @@ export default class AppPickerSelectView extends Vue { ...@@ -182,7 +218,7 @@ export default class AppPickerSelectView extends Vue {
* @memberof AppTreePicker * @memberof AppTreePicker
*/ */
public OnInputChange($event: any){ public OnInputChange($event: any){
let _viewdata = Object.assign({ query: this.inputValue }, JSON.parse(this.viewdata)) ; let _viewdata = Object.assign({ query: this.queryValue }, JSON.parse(this.viewdata)) ;
this.viewdata = JSON.stringify(_viewdata); this.viewdata = JSON.stringify(_viewdata);
} }
...@@ -215,7 +251,7 @@ export default class AppPickerSelectView extends Vue { ...@@ -215,7 +251,7 @@ export default class AppPickerSelectView extends Vue {
return true; return true;
} }
if (!this.data) { if (!this.data) {
this.$Notice.error({ title: '错误', desc: '表单数据异常' }); this.$Notice.error({ title: (this.$t('components.appPickerSelectView.error') as any), desc: (this.$t('components.appPickerSelectView.formdataException') as any) });
return false; return false;
} }
// 合并表单参数 // 合并表单参数
...@@ -264,9 +300,35 @@ export default class AppPickerSelectView extends Vue { ...@@ -264,9 +300,35 @@ export default class AppPickerSelectView extends Vue {
* @param {*} oldVal * @param {*} oldVal
* @memberof AppPicker * @memberof AppPicker
*/ */
@Watch('value') @Watch('value', { deep: true })
public onValueChange(newVal: any, oldVal: any) { public onValueChange(newVal: any, oldVal: any) {
this.inputValue = newVal; if(this.isSingleSelect){
this.queryValue = newVal;
if (!this.data || !this.valueitem || !this.data[this.valueitem]) {
this.$Notice.error({ title: (this.$t('components.appPickerSelectView.error') as any), desc: (this.$t('components.appPickerSelectView.editor') as any)+this.name+(this.$t('components.appPickerSelectView.valueitemException') as any) });
}else{
let _viewparam = JSON.parse(this.viewparam);
_viewparam.selectedData = [{srfkey: this.data[this.valueitem], srfmajortext: this.value }];
this.viewparam = JSON.stringify(_viewparam);
}
}else{
this.keySet = [];
this.selectItems = [];
if (newVal) {
this.selectItems = JSON.parse(newVal);
this.selectItems.forEach((item: any) => {
this.keySet.push(item.srfkey);
let index = this.items.findIndex((i) => Object.is(i.srfkey, item.srfkey));
if (index < 0) {
this.items.push({ srfmajortext : item.srfmajortext, srfkey: item.srfkey });
}
});
let _viewparam = JSON.parse(this.viewparam);
_viewparam.selectedData = this.selectItems;
this.viewparam = JSON.stringify(_viewparam);
}
}
this.$forceUpdate();
} }
/** /**
...@@ -301,19 +363,36 @@ export default class AppPickerSelectView extends Vue { ...@@ -301,19 +363,36 @@ export default class AppPickerSelectView extends Vue {
* @param {*} item * @param {*} item
* @memberof AppTreePicker * @memberof AppTreePicker
*/ */
public setValue(item: any) { public onViewdatasChange($event: any) {
this.visible = false; if($event.length == 0){
if(item.length == 0){
this.onClear(null); this.onClear(null);
return; return;
} }
if (this.valueitem) { if(this.isSingleSelect){
let tempvalue = item[0][this.deMajorField] ? item[0][this.deKeyField] : item[0].srfkey; this.visible = false;
this.$emit('formitemvaluechange', { name: this.valueitem, value: item[0][this.deKeyField] }); if (this.valueitem) {
} let tempvalue = $event[0][this.deKeyField] ? $event[0][this.deKeyField] : $event[0].srfkey;
if (this.name) { this.$emit('formitemvaluechange', { name: this.valueitem, value: tempvalue });
let tempvalue = item[0][this.deMajorField] ? item[0][this.deMajorField] : item[0].srfmajortext; }
this.$emit('formitemvaluechange', { name: this.name, value: tempvalue }); if (this.name) {
let tempvalue = $event[0][this.deMajorField] ? $event[0][this.deMajorField] : $event[0].srfmajortext;
this.$emit('formitemvaluechange', { name: this.name, value: tempvalue });
}
}else{
let selects: Array<any> = [];
if ($event && Array.isArray($event)) {
$event.forEach((select: any) => {
selects.push({ srfkey: select.srfkey, srfmajortext: select.srfmajortext });
let index = this.items.findIndex((item) => Object.is(item.srfkey, select.srfkey));
if (index < 0) {
this.items.push({ srfmajortext : select.srfmajortext, srfkey: select.srfkey });
}
});
}
if (this.name) {
let value = selects.length > 0 ? JSON.stringify(selects) : '';
this.$emit('formitemvaluechange', { name: this.name, value: value });
}
} }
} }
...@@ -337,11 +416,8 @@ export default class AppPickerSelectView extends Vue { ...@@ -337,11 +416,8 @@ export default class AppPickerSelectView extends Vue {
* @memberof AppPicker * @memberof AppPicker
*/ */
public openLinkView($event: any): void { public openLinkView($event: any): void {
if (this.disabled) {
return;
}
if (!this.data || !this.valueitem || !this.data[this.valueitem]) { if (!this.data || !this.valueitem || !this.data[this.valueitem]) {
this.$Notice.error({ title: '错误', desc: '值项异常!' }); console.error({ title: (this.$t('components.appPickerSelectView.error') as any), desc: (this.$t('components.appPickerSelectView.editor') as any)+this.name+(this.$t('components.appPickerSelectView.valueitemException') as any) });
return; return;
} }
// 公共参数处理 // 公共参数处理
...@@ -459,6 +535,26 @@ export default class AppPickerSelectView extends Vue { ...@@ -459,6 +535,26 @@ export default class AppPickerSelectView extends Vue {
} }
} }
} }
/**
* 下拉选中回调
*
* @param {*} selects 当前选中的key值集合
* @memberof AppMpicker
*/
public onSelectChange(selects: any) {
let val: Array<any> = [];
if (selects.length > 0) {
selects.forEach((select: any) => {
let index = this.items.findIndex((item) => Object.is(item[this.deKeyField], select));
if (index >= 0) {
val.push(this.items[index]);
}
});
}
let value = val.length > 0 ? JSON.stringify(val) : '';
this.$emit('formitemvaluechange', { name: this.name, value: value });
}
} }
</script> </script>
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
@input="onInput" @blur="onBlur" style='width:100%;'> @input="onInput" @blur="onBlur" style='width:100%;'>
<template v-slot:default="{item}"> <template v-slot:default="{item}">
<template v-if="item.isNew"> <template v-if="item.isNew">
<div v-if="linkview" @click="newAndEdit">创建并编辑...</div> <div v-if="linkview" @click="newAndEdit">{{$t('components.appPicker.newAndEdit')}}</div>
</template> </template>
<slot v-else name="default" :item="item"></slot> <slot v-else name="default" :item="item"></slot>
</template> </template>
...@@ -52,7 +52,8 @@ import { Component, Vue, Prop, Model, Watch } from 'vue-property-decorator'; ...@@ -52,7 +52,8 @@ import { Component, Vue, Prop, Model, Watch } from 'vue-property-decorator';
import { Subject } from 'rxjs'; import { Subject } from 'rxjs';
import { AppModal } from '@/utils'; import { AppModal } from '@/utils';
@Component({}) @Component({
})
export default class AppPicker extends Vue { export default class AppPicker extends Vue {
/** /**
...@@ -165,7 +166,7 @@ export default class AppPicker extends Vue { ...@@ -165,7 +166,7 @@ export default class AppPicker extends Vue {
* @type {string} * @type {string}
* @memberof AppPicker * @memberof AppPicker
*/ */
@Prop() public valueitem?: string; @Prop() public valueitem!: string;
/** /**
* 值 * 值
...@@ -309,16 +310,20 @@ export default class AppPicker extends Vue { ...@@ -309,16 +310,20 @@ export default class AppPicker extends Vue {
} }
this.inputState = false; this.inputState = false;
Object.assign(_param, { query: query }); Object.assign(_param, { query: query });
// 错误信息国际化
let error: string = (this.$t('components.appPicker.error') as any);
let miss: string = (this.$t('components.appPicker.miss') as any);
let requestException: string = (this.$t('components.appPicker.requestException') as any);
if(!this.service){ if(!this.service){
this.$Notice.error({ title: '错误', desc: '缺少参数service' }); this.$Notice.error({ title: error, desc: miss+'service' });
} else if(!this.acParams.serviceName) { } else if(!this.acParams.serviceName) {
this.$Notice.error({ title: '错误', desc: '缺少参数serviceName' }); this.$Notice.error({ title: error, desc: miss+'serviceName' });
} else if(!this.acParams.interfaceName) { } else if(!this.acParams.interfaceName) {
this.$Notice.error({ title: '错误', desc: '缺少参数interfaceName' }); this.$Notice.error({ title: error, desc: miss+'interfaceName' });
} else { } else {
this.service.getItems(this.acParams.serviceName,this.acParams.interfaceName, _context, _param).then((response: any) => { this.service.getItems(this.acParams.serviceName,this.acParams.interfaceName, _context, _param).then((response: any) => {
if (!response) { if (!response) {
this.$Notice.error({ title: '错误', desc: '请求异常' }); this.$Notice.error({ title: error, desc: requestException });
} else { } else {
this.items = [...response]; this.items = [...response];
} }
...@@ -401,6 +406,7 @@ export default class AppPicker extends Vue { ...@@ -401,6 +406,7 @@ export default class AppPicker extends Vue {
const view = { ...this.pickupView }; const view = { ...this.pickupView };
let _context = data.context; let _context = data.context;
let _param = data.param; let _param = data.param;
_param.selectedData = [{srfkey: this.data[this.valueitem], srfmajortext: this.curvalue }];
// 判断打开方式 // 判断打开方式
if (view.placement && !Object.is(view.placement, '')) { if (view.placement && !Object.is(view.placement, '')) {
if (Object.is(view.placement, 'POPOVER')) { if (Object.is(view.placement, 'POPOVER')) {
...@@ -505,7 +511,7 @@ export default class AppPicker extends Vue { ...@@ -505,7 +511,7 @@ export default class AppPicker extends Vue {
private openRedirectView($event: any, view: any, data: any): void { private openRedirectView($event: any, view: any, data: any): void {
this.$http.get(view.url, data).then((response: any) => { this.$http.get(view.url, data).then((response: any) => {
if (!response || response.status !== 200) { if (!response || response.status !== 200) {
this.$Notice.error({ title: '错误', desc: '请求异常' }); this.$Notice.error({ title: (this.$t('components.appPicker.error') as any), desc: (this.$t('components.appPicker.requestException') as any) });
} }
if (response.status === 401) { if (response.status === 401) {
return; return;
...@@ -557,7 +563,7 @@ export default class AppPicker extends Vue { ...@@ -557,7 +563,7 @@ export default class AppPicker extends Vue {
} }
}).catch((response: any) => { }).catch((response: any) => {
if (!response || !response.status || !response.data) { if (!response || !response.status || !response.data) {
this.$Notice.error({ title: '错误', desc: '系统异常!' }); this.$Notice.error({ title: (this.$t('components.appPicker.error') as any), desc: (this.$t('components.appPicker.systemException') as any) });
return; return;
} }
if (response.status === 401) { if (response.status === 401) {
...@@ -572,11 +578,8 @@ export default class AppPicker extends Vue { ...@@ -572,11 +578,8 @@ export default class AppPicker extends Vue {
* @memberof AppPicker * @memberof AppPicker
*/ */
public openLinkView($event: any): void { public openLinkView($event: any): void {
if (this.disabled) {
return;
}
if (!this.data || !this.valueitem || !this.data[this.valueitem]) { if (!this.data || !this.valueitem || !this.data[this.valueitem]) {
this.$Notice.error({ title: '错误', desc: '值项异常!' }); console.error({ title: (this.$t('components.appPicker.error') as any), desc: (this.$t('components.appPicker.valueitemException') as any) });
return; return;
} }
// 公共参数处理 // 公共参数处理
...@@ -640,7 +643,7 @@ export default class AppPicker extends Vue { ...@@ -640,7 +643,7 @@ export default class AppPicker extends Vue {
return true; return true;
} }
if (!this.data) { if (!this.data) {
this.$Notice.error({ title: '错误', desc: '表单数据异常' }); this.$Notice.error({ title: (this.$t('components.appPicker.error') as any), desc: (this.$t('components.appPicker.formdataException') as any) });
return false; return false;
} }
// 合并表单参数 // 合并表单参数
......
<template> <template>
<card class="app-portal-design" :dis-hover="true" :padding="0" :bordered="false"> <card class="app-portal-design" :dis-hover="true" :padding="0" :bordered="false">
<p slot="title"> <p slot="title">
自定义门户 {{$t('components.appPortalDesign.customPortal')}}
</p> </p>
<div class="design-toolbar" slot="extra"> <div class="design-toolbar" slot="extra">
<i-button @click="click">保存</i-button> <i-button @click="click">{{$t('components.appPortalDesign.save')}}</i-button>
</div> </div>
<div class="design-container"> <div class="design-container">
<app-dashboard-design :viewState="viewState" :context="context" :viewparams="viewparams" :utilServiceName="utilServiceName" @save="onSaved"></app-dashboard-design> <app-dashboard-design :viewState="viewState" :context="context" :viewparams="viewparams" :utilServiceName="utilServiceName" @save="onSaved"></app-dashboard-design>
......
<template> <template>
<radio-group class="app-radio-group" v-model="value" > <radio-group class="app-radio-group" v-model="value" >
<radio v-for="(_item,index) in items" :key = "index" :label="_item.value" :disabled="isDisabled || _item.disabled"> <radio v-for="(_item,index) in items" :key = "index" :label="_item.value" :disabled="isDisabled || _item.disabled">
<span>{{_item.text}}</span> <span>{{Object.is(codelistType,'STATIC') ? $t('codelist.'+tag+'.'+_item.value) : _item.text}}</span>
</radio> </radio>
</radio-group> </radio-group>
</template> </template>
......
<template> <template>
<div class="app-range-date"> <div class="app-range-date">
<span class="editor-span"></span> <span class="editor-span">{{$t('components.appRangDate.from')}}</span>
<template v-for="(item, index) in refFormItem"> <template v-for="(item, index) in refFormItem">
<span v-if="index > 0" class="editor-space" :key="index">日 0 时 起 至</span> <span v-if="index > 0" class="editor-space" :key="index">{{$t('components.appRangDate.daystart')}}</span>
<date-picker <date-picker
:key="index + '-onlydate'" :key="index + '-onlydate'"
v-if="Object.is(editorType, 'DATEPICKEREX') || Object.is(editorType, 'DATEPICKEREX_NOTIME') && index == 0" v-if="Object.is(editorType, 'DATEPICKEREX') || Object.is(editorType, 'DATEPICKEREX_NOTIME') && index == 0"
type="date" type="date"
:transfer="true" :transfer="true"
:format="valFormat" :format="valFormat"
placeholder="请选择时间..." :placeholder="$t('components.appRangDate.placeholder')"
:value="activeData[item]" :value="activeData[item]"
:disabled="disabled" :disabled="disabled"
@on-change="startOnValueChange" @on-change="startOnValueChange"
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
type="datetime" type="datetime"
:transfer="true" :transfer="true"
:format="valFormat" :format="valFormat"
placeholder="请选择时间..." :placeholder="$t('components.appRangDate.placeholder')"
:value="activeData[item]" :value="activeData[item]"
:disabled="disabled" :disabled="disabled"
@on-change="startOnValueChange" @on-change="startOnValueChange"
...@@ -33,7 +33,7 @@ ...@@ -33,7 +33,7 @@
type="date" type="date"
:transfer="true" :transfer="true"
:format="valFormat" :format="valFormat"
placeholder="请选择时间..." :placeholder="$t('components.appRangDate.placeholder')"
:value="activeData[item]" :value="activeData[item]"
:disabled="disabled" :disabled="disabled"
@on-change="endOnValueChange" @on-change="endOnValueChange"
...@@ -45,12 +45,12 @@ ...@@ -45,12 +45,12 @@
type="datetime" type="datetime"
:transfer="true" :transfer="true"
:format="valFormat" :format="valFormat"
placeholder="请选择时间..." :placeholder="$t('components.appRangDate.placeholder')"
:value="activeData[item]" :value="activeData[item]"
:disabled="disabled" :disabled="disabled"
@on-change="endOnValueChange" @on-change="endOnValueChange"
></date-picker> ></date-picker>
<span v-if="index > 0" :key="index + '-only'" class="editor-space">日 24 时 止</span> <span v-if="index > 0" :key="index + '-only'" class="editor-space">{{$t('components.appRangDate.dayend')}}</span>
</template> </template>
</div> </div>
</template> </template>
...@@ -60,7 +60,8 @@ import { Component, Vue, Prop, Model, Watch } from "vue-property-decorator"; ...@@ -60,7 +60,8 @@ import { Component, Vue, Prop, Model, Watch } from "vue-property-decorator";
import { Subject } from "rxjs"; import { Subject } from "rxjs";
import { debounceTime, distinctUntilChanged } from "rxjs/operators"; import { debounceTime, distinctUntilChanged } from "rxjs/operators";
@Component({}) @Component({
})
export default class AppRangDate extends Vue { export default class AppRangDate extends Vue {
/** /**
* 编辑项名称 * 编辑项名称
......
<template> <template>
<div class="app-range-editor"> <div class="app-range-editor">
<template v-for="(item, index) in refFormItem"> <template v-for="(item, index) in refFormItem">
<span v-if="index > 0" class="editor-space" :key="index">~</span> <span v-if="index > 0" class="editor-space" :key="index+10">~</span>
<date-picker <date-picker
:key="index" :key="index"
v-if="Object.is(editorType, 'DATEPICKEREX') || Object.is(editorType, 'DATEPICKEREX_NOTIME')" v-if="Object.is(editorType, 'DATEPICKEREX') || Object.is(editorType, 'DATEPICKEREX_NOTIME')"
type="date" type="date"
:transfer="true" :transfer="true"
:format="valFormat" :format="valFormat"
placeholder="请选择时间..." :placeholder="$t('components.appRangeEditor.placeholder')"
:value="activeData[item]" :value="activeData[item]"
:disabled="disabled" :disabled="disabled"
@on-change="onValueChange"> @on-change="(value,type)=>{onValueChange(item,value)}">
</date-picker> </date-picker>
<time-picker <time-picker
:key="index" :key="index"
v-else-if="editorType.startsWith('DATEPICKEREX')" v-else-if="editorType.startsWith('DATEPICKEREX')"
:transfer="true" :transfer="true"
:format="valFormat" :format="valFormat"
placeholder="请选择时间..." :placeholder="$t('components.appRangeEditor.placeholder')"
:value="activeData[item]" :value="activeData[item]"
:disabled="disabled" :disabled="disabled"
@on-change="onValueChange"> @on-change="(value)=>{onValueChange(item,value)}">
</time-picker> </time-picker>
<i-input <InputNumber
:key="index"
v-else-if="Object.is(editorType, 'NUMBER')"
:value="activeData[item]"
:disabled="disabled"
:placeholder="$t('components.appRangeEditor.input')"
@on-change="(value)=>{onValueChange(item,value)}">
</InputNumber>
<app-span
:key="index"
v-else-if="Object.is(editorType, 'SPAN')"
:value="activeData[item]"
:disabled="disabled">
</app-span>
<el-input
:key="index" :key="index"
v-else v-else
type="number"
:value="getValue(item)" :value="getValue(item)"
:disabled="disabled" :disabled="disabled"
placeholder="请输入" :placeholder="$t('components.appRangeEditor.input')"
@on-change="setValue"> @input="(value)=>{onValueChange(item,value)}">
</i-input> </el-input>
</template> </template>
</div> </div>
</template> </template>
...@@ -41,14 +54,15 @@ import { Component, Vue, Prop, Model, Watch } from 'vue-property-decorator'; ...@@ -41,14 +54,15 @@ import { Component, Vue, Prop, Model, Watch } from 'vue-property-decorator';
import { Subject } from 'rxjs'; import { Subject } from 'rxjs';
import { debounceTime, distinctUntilChanged } from 'rxjs/operators'; import { debounceTime, distinctUntilChanged } from 'rxjs/operators';
@Component({}) @Component({
export default class AppPicker extends Vue { })
export default class AppRangeEditor extends Vue {
/** /**
* 编辑项名称 * 编辑项名称
* *
* @type {string} * @type {string}
* @memberof AppPicker * @memberof AppRangeEditor
*/ */
@Prop() public name!: string; @Prop() public name!: string;
...@@ -56,7 +70,7 @@ export default class AppPicker extends Vue { ...@@ -56,7 +70,7 @@ export default class AppPicker extends Vue {
* 是否禁用 * 是否禁用
* *
* @type {boolean} * @type {boolean}
* @memberof AppPicker * @memberof AppRangeEditor
*/ */
@Prop() public disabled!: boolean; @Prop() public disabled!: boolean;
...@@ -64,7 +78,7 @@ export default class AppPicker extends Vue { ...@@ -64,7 +78,7 @@ export default class AppPicker extends Vue {
* 表单数据对象 * 表单数据对象
* *
* @type {*} * @type {*}
* @memberof AppPicker * @memberof AppRangeEditor
*/ */
@Prop() public activeData: any; @Prop() public activeData: any;
...@@ -72,7 +86,7 @@ export default class AppPicker extends Vue { ...@@ -72,7 +86,7 @@ export default class AppPicker extends Vue {
* 值格式 * 值格式
* *
* @type {string} * @type {string}
* @memberof AppPicker * @memberof AppRangeEditor
*/ */
@Prop() public format!: string; @Prop() public format!: string;
...@@ -80,7 +94,7 @@ export default class AppPicker extends Vue { ...@@ -80,7 +94,7 @@ export default class AppPicker extends Vue {
* 编辑器类型 * 编辑器类型
* *
* @type {string} * @type {string}
* @memberof AppPicker * @memberof AppRangeEditor
*/ */
@Prop() public editorType!: string; @Prop() public editorType!: string;
...@@ -88,7 +102,7 @@ export default class AppPicker extends Vue { ...@@ -88,7 +102,7 @@ export default class AppPicker extends Vue {
* 关系表单项集合 * 关系表单项集合
* *
* @type {string[]} * @type {string[]}
* @memberof AppPicker * @memberof AppRangeEditor
*/ */
@Prop() public refFormItem!: string[]; @Prop() public refFormItem!: string[];
...@@ -105,7 +119,7 @@ export default class AppPicker extends Vue { ...@@ -105,7 +119,7 @@ export default class AppPicker extends Vue {
* 处理值格式 * 处理值格式
* *
* @readonly * @readonly
* @memberof AppPicker * @memberof AppRangeEditor
*/ */
get valFormat() { get valFormat() {
return this.format.replace('YYYY', 'yyyy').replace('DD', 'dd'); return this.format.replace('YYYY', 'yyyy').replace('DD', 'dd');
...@@ -116,7 +130,7 @@ export default class AppPicker extends Vue { ...@@ -116,7 +130,7 @@ export default class AppPicker extends Vue {
* *
* @param {string} name * @param {string} name
* @returns * @returns
* @memberof AppPicker * @memberof AppRangeEditor
*/ */
public getValue(name: string) { public getValue(name: string) {
return this.activeData[name]; return this.activeData[name];
...@@ -127,7 +141,7 @@ export default class AppPicker extends Vue { ...@@ -127,7 +141,7 @@ export default class AppPicker extends Vue {
* *
* @param {string} name * @param {string} name
* @param {*} val * @param {*} val
* @memberof AppPicker * @memberof AppRangeEditor
*/ */
public setValue(name: string, val: any) { public setValue(name: string, val: any) {
this.inputDataChang.next({ name: name, value: val }); this.inputDataChang.next({ name: name, value: val });
...@@ -153,7 +167,7 @@ export default class AppPicker extends Vue { ...@@ -153,7 +167,7 @@ export default class AppPicker extends Vue {
* *
* @param {string} name * @param {string} name
* @param {*} value * @param {*} value
* @memberof AppPicker * @memberof AppRangeEditor
*/ */
public onValueChange(name: string, value: any) { public onValueChange(name: string, value: any) {
this.$emit('formitemvaluechange', { name: name, value: value }); this.$emit('formitemvaluechange', { name: name, value: value });
......
...@@ -44,6 +44,7 @@ export default class AppRichTextEditor extends Vue { ...@@ -44,6 +44,7 @@ export default class AppRichTextEditor extends Vue {
this.init(newval); this.init(newval);
} }
} }
/** /**
* 输入name * 输入name
...@@ -63,17 +64,38 @@ export default class AppRichTextEditor extends Vue { ...@@ -63,17 +64,38 @@ export default class AppRichTextEditor extends Vue {
/** /**
* 当前语言,默认中文 * 当前语言,默认中文
*/ */
@Prop() langu?: string; public langu: any = localStorage.getItem('local') ? localStorage.getItem('local') : 'zh_CN' ;
/**
* 监听语言变化
*/
@Watch('$i18n.locale')
onLocaleChange(newval: any, val: any) {
console.log("语言变更"+newval)
this.langu = newval;
if(this.editor){
tinymceCode.remove('#' + this.id);
}
this.init('');
}
/**
* 语言映射文件
*/
public languMap:any = {
'zh-CN': 'zh_CN',
'en-US': 'en_US',
};
/** /**
* 上传文件路径 * 上传文件路径
*/ */
public uploadUrl = '/' + Environment.BaseUrl + Environment.UploadFile; public uploadUrl = Environment.BaseUrl + Environment.UploadFile;
/** /**
* 下载路径 * 下载路径
*/ */
public downloadUrl = '/' + Environment.BaseUrl + Environment.ExportFile; public downloadUrl = Environment.BaseUrl + Environment.ExportFile;
/** /**
* 当前富文本 * 当前富文本
...@@ -154,7 +176,8 @@ export default class AppRichTextEditor extends Vue { ...@@ -154,7 +176,8 @@ export default class AppRichTextEditor extends Vue {
paste_data_images: true, paste_data_images: true,
codesample_content_css: 'assets/tinymce/prism.css', codesample_content_css: 'assets/tinymce/prism.css',
skin_url: './assets/tinymce/skins/lightgray', skin_url: './assets/tinymce/skins/lightgray',
language_url: './assets/tinymce/langs/' + (this.langu ? this.langu : 'zh_CN') + '.js', language_url: './assets/tinymce/langs/' + this.languMap[this.langu] + '.js',
language:this.languMap[this.langu],
setup: (editor: any) => { setup: (editor: any) => {
this.editor = editor; this.editor = editor;
editor.on('blur', () => { editor.on('blur', () => {
...@@ -166,14 +189,15 @@ export default class AppRichTextEditor extends Vue { ...@@ -166,14 +189,15 @@ export default class AppRichTextEditor extends Vue {
const formData = new FormData(); const formData = new FormData();
formData.append('file', bolbinfo.blob(), bolbinfo.filename()); formData.append('file', bolbinfo.blob(), bolbinfo.filename());
const _url = richtexteditor.uploadUrl; const _url = richtexteditor.uploadUrl;
richtexteditor.uploadFile(_url, formData).subscribe((response: any) => { richtexteditor.uploadFile(_url, formData).subscribe((file: any) => {
if (response.ret === 0 && response.files.length > 0) { if (file.filename) {
const id: string = response.files[0].id; const id: string = file.fileid;
const url: string = `${richtexteditor.downloadUrl}?fileid=${id}` const url: string = `${richtexteditor.downloadUrl}/${id}`
success(url); success(url);
} }
}, (error: any) => { }, (error: any) => {
console.log(error); console.log(error);
failure('HTTP Error: ' + error.status);
}); });
}, },
init_instance_callback: (editor: any) => { init_instance_callback: (editor: any) => {
......
.app-span{
white-space: nowrap;
text-overflow: ellipsis;
word-break: break-all;
overflow: hidden;
}
<template> <template>
<span>{{text}}</span> <codelist v-if="tag" :tag="tag" :value="value" :codelistType="codelistType" :renderMode="renderMode" :valueSeparator="valueSeparator" :textSeparator="textSeparator"></codelist>
<span class="app-span" v-else >{{text}}</span>
</template> </template>
<script lang="ts"> <script lang="ts">
import { Vue, Component, Prop,Watch,Model } from 'vue-property-decorator'; import { Vue, Component, Prop, Watch, Model } from 'vue-property-decorator';
import CodeListService from "@service/app/codelist-service"; import CodeListService from "@service/app/codelist-service";
@Component({}) @Component({})
export default class DropDownList extends Vue { export default class DropDownList extends Vue {
/**
* 代码表服务对象
*
* @type {CodeListService}
* @memberof AppSpan
*/
public codeListService:CodeListService = new CodeListService({ $store: this.$store });
/** /**
* 当前值 * 当前值
...@@ -22,15 +16,51 @@ export default class DropDownList extends Vue { ...@@ -22,15 +16,51 @@ export default class DropDownList extends Vue {
* @type {*} * @type {*}
* @memberof AppSpan * @memberof AppSpan
*/ */
@Prop() public data?: any; @Prop() public value?: any;
/**
* 代码表标识
*
* @type {string}
* @memberof AppSpan
*/
@Prop() public tag?: string;
/**
* 代码表类型
*
* @type {string}
* @memberof AppSpan
*/
@Prop() public codelistType?: string;
/**
* 获取或模式
* @type {boolean}
* @memberof SelectPicker
*/
@Prop({default:"STR"}) public renderMode?: string;
/**
* 文本分隔符
* @type {boolean}
* @memberof SelectPicker
*/
@Prop({default:"、"}) public textSeparator?: string;
/**
* 值分隔符
* @type {boolean}
* @memberof SelectPicker
*/
@Prop({default:";"}) public valueSeparator?: string;
/** /**
* 监控表单属性 data 值 * 监控表单属性 data 值
* *
* @memberof AppSpan * @memberof AppSpan
*/ */
@Watch('data') @Watch('value')
onDataChange(newVal: any, oldVal: any) { onDataChange(newVal: any, oldVal: any) {
if(newVal !== oldVal){ if(newVal !== oldVal){
this.load(); this.load();
...@@ -45,28 +75,12 @@ export default class DropDownList extends Vue { ...@@ -45,28 +75,12 @@ export default class DropDownList extends Vue {
public text:any = ''; public text:any = '';
/** /**
* 代码表标识 * 编辑器类型
* *
* @type {string} * @type {string}
* @memberof AppSpan * @memberof AppSpan
*/ */
@Prop() public tag?: string; @Prop() public editorType?: string;
/**
* 代码表类型
*
* @type {string}
* @memberof AppSpan
*/
@Prop() public codelistType?: string;
/**
* 代码表
*
* @type {any[]}
* @memberof AppSpan
*/
public items: any[] = [];
/** /**
* vue 生命周期 * vue 生命周期
...@@ -78,47 +92,26 @@ export default class DropDownList extends Vue { ...@@ -78,47 +92,26 @@ export default class DropDownList extends Vue {
} }
/** /**
* 加载代码表 * 处理数据
* *
* @memberof AppSpan * @memberof AppSpan
*/ */
public load(){ public load(){
if(this.tag && Object.is(this.codelistType,"STATIC")){ if(!this.value || this.tag){
const codelist = this.$store.getters.getCodeList(this.tag); return; //代码表走codelist组件
if (codelist) { } else if(Object.is(this.editorType,'PICTURE') || Object.is(this.editorType,'PICTURE_ONE') || Object.is(this.editorType,'FILEUPLOADER')){
this.items = [...JSON.parse(JSON.stringify(codelist.items))]; let files: any[] = JSON.parse(this.value);
this.setText(); let names: any[] = [];
} else { if(files.length && files.length > 0){
console.log(`----${this.tag}----代码表不存在`); files.forEach((item:any) => {
names.push(item.name);
});
this.text = names.join(',');
} }
}else if(this.tag && Object.is(this.codelistType,"DYNAMIC")){
this.codeListService.getItems(this.tag).then((res:any) => {
this.items = res;
this.setText();
}).catch((error:any) => {
console.log(`----${this.tag}----代码表不存在`);
});
}else{ }else{
this.setText(); this.text = this.value;
} }
} }
/**
* 设置显示值
* @memberof AppSpan
*/
public setText(){
if(this.items.length>0){
let currentItem:any = this.items.find((item:any)=>{
return item.value == this.data;
});
if(currentItem){
this.text = currentItem.label;
}
}else{
this.text = this.data;
}
}
} }
</script> </script>
......
<template> <template>
<div class="app-stepper"> <div class="app-stepper">
<el-input-number :value="currentVal" :disabled="disabled" @change="onChange" :min="min" :max="max" :step="step" label="描述文字"></el-input-number> <el-input-number :value="currentVal" :disabled="disabled" @change="onChange" :min="min" :max="max" :step="step"></el-input-number>
</div> </div>
</template> </template>
......
...@@ -5,11 +5,11 @@ ...@@ -5,11 +5,11 @@
{{viewTitle}} {{viewTitle}}
</div> </div>
<div class="actions"> <div class="actions">
<div class="action-item" title="进入当前视图配置界面"> <div class="action-item" :title="$t('components.appStudioAction.configTitle')">
<i-button type="text" ghost @click="configView()">配置</i-button> <i-button type="text" ghost @click="configView()">{{$t('components.appStudioAction.configButton')}}</i-button>
</div> </div>
<div class="action-item" title="建立当前界面的issues"> <div class="action-item" :title="$t('components.appStudioAction.issueTitle')">
<i-button type="text" ghost @click="createIssues()">新建issues</i-button> <i-button type="text" ghost @click="createIssues()">{{$t('components.appStudioAction.issueButton')}}</i-button>
</div> </div>
</div> </div>
</div> </div>
...@@ -20,7 +20,8 @@ import { Vue, Component, Inject, Prop } from "vue-property-decorator"; ...@@ -20,7 +20,8 @@ import { Vue, Component, Inject, Prop } from "vue-property-decorator";
import { Environment } from '@/environments/environment'; import { Environment } from '@/environments/environment';
import { StudioActionUtil } from '@/utils'; import { StudioActionUtil } from '@/utils';
@Component({}) @Component({
})
export default class AppStudioAction extends Vue { export default class AppStudioAction extends Vue {
/** /**
......
<template> <template>
<div class='app-theme'> <div class='app-theme'>
<poptip <poptip
:title="$t('caption.theme')" :title="$t('components.appTheme.caption.theme')"
popper-class='app-app-theme' popper-class='app-app-theme'
placement='bottom-end' placement='bottom-end'
:width="Object.is($i18n.locale, 'zh-CN') ? 180 : 240"> :width="Object.is($i18n.locale, 'zh-CN') ? 180 : 250">
<a> <a>
<icon class='app-theme-icon' type='md-settings' :size="22" /> <icon class='app-theme-icon' type='md-settings' :size="22" />
</a> </a>
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
</div> </div>
<div> <div>
<i-form label-position='left'> <i-form label-position='left'>
<form-item :label="$t('caption.font')"> <form-item :label="$t('components.appTheme.caption.font')">
<i-select <i-select
:value="selectFont" :value="selectFont"
size='small' size='small'
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
<i-option <i-option
:value="font.value" :value="font.value"
:key="font.value"> :key="font.value">
{{$t(`fontFamilys.${font.label}`)}} {{$t(`components.appTheme.fontFamilys.${font.label}`)}}
</i-option> </i-option>
</template> </template>
</i-select> </i-select>
...@@ -50,32 +50,6 @@ ...@@ -50,32 +50,6 @@
import { Component, Vue } from 'vue-property-decorator'; import { Component, Vue } from 'vue-property-decorator';
@Component({ @Component({
i18n: {
messages: {
'zh-CN': {
caption: {
theme: '主题',
font: '字体',
},
fontFamilys: {
MicrosoftYaHei: '微软雅黑',
SimHei: '黑体',
YouYuan: '幼圆',
},
},
'en-US': {
caption: {
theme: 'Theme',
font: 'Font family',
},
fontFamilys: {
MicrosoftYaHei: 'Microsoft YaHei',
SimHei: 'SimHei',
YouYuan: 'YouYuan',
},
}
}
}
}) })
export default class AppTheme extends Vue { export default class AppTheme extends Vue {
......
<template>
<el-timeline class="app-timeline">
<template v-for="(item, index) of items">
<el-timeline-item :key="index" :timestamp="item.name" placement="top">
<template v-for="data of item.items">
<div :key="data.srfkey" class="app-timeline-item-title" @click="onClick(data)">
<card>
<div>{{data.name}}</div>
<div>{{data.actor || data.create_uid_text}}</div>
<div>{{data.time || data.create_date}}</div>
</card>
</div>
</template>
</el-timeline-item>
</template>
</el-timeline>
</template>
<script lang="ts">
import { Vue, Component, Prop, Watch } from "vue-property-decorator";
@Component({})
export default class AppTimeline extends Vue {
/**
* 数据集
*
* @type {string}
* @memberof AppTimeline
*/
@Prop() datas?: string;
/**
* 数据集对象
*
* @protected
* @type {any[]}
* @memberof AppTimeline
*/
protected items: any[] = [];
/**
* 数据集监听
*
* @param {*} newVal
* @param {*} oldVal
* @memberof AppTimeline
*/
@Watch('datas')
onDatasChange(newVal: any, oldVal: any) {
if(newVal) {
this.prepareData(JSON.parse(newVal))
}
}
/**
* 生命周期
*
* @memberof AppTimeline
*/
public mounted() {
if(this.datas) {
this.prepareData(JSON.parse(this.datas))
}
}
/**
* 准备数据
*
* @param {*} datas
* @memberof AppTimeline
*/
public prepareData(datas: any[] = []) {
let format: any = this.getFormat();
datas.forEach((data: any) => {
let time = data.time || data.create_date;
if(format.test(time)) {
time.replace(format, (str: string) => {
let item: any = this.items.find((item: any) => Object.is(item.name, str));
if(!item) {
item = {name: str, items: [data]};
this.items.push(item);
} else {
item.items.push(data);
}
});
}
})
}
/**
* 获取时间格式
*
* @memberof AppTimeline
*/
public getFormat() {
return /^(\d{1,4})(-|\/)(\d{1,2})\2(\d{1,2})/;
}
/**
* 选中
*
* @param {*} item
* @memberof AppTimeline
*/
public onClick(item: any) {
this.$emit('click', item);
}
}
</script>
<style lang="less">
.app-timeline {
margin-left: 50px;
.el-timeline-item__timestamp {
color: initial;
font-weight: bold;
}
.app-timeline-item-title {
cursor: pointer;
width: 350px;
margin-bottom: 5px;
}
.app-timeline-item-title:hover {
color: #108cee;
}
}
</style>
\ No newline at end of file
<template> <template>
<div v-if="refviewname" class="app-tree-picker"> <div v-if="refviewname" class="app-tree-picker">
<Dropdown :visible="visible" trigger="custom" style="left:0px;width: 100%" @on-clickoutside="() => {triggerMenu(false);}" > <Dropdown :visible="visible" trigger="custom" style="left:0px;width: 100%" @on-clickoutside="() => {triggerMenu(false);}" >
<Input v-model="inputValue" class="tree-input" type="text" :placeholder="placeholder" :disabled="disabled" @on-change="OnInputChange" @on-focus="()=>{triggerMenu();}" > <Input v-model="inputValue" class="tree-input" type="text" :placeholder="placeholder ? placeholder : $t('components.appTreePicker.placeholder')" :disabled="disabled" @on-change="OnInputChange" @on-focus="()=>{triggerMenu();}" >
<template v-slot:suffix> <template v-slot:suffix>
<i v-if="inputValue && !disabled" class='el-icon-circle-close' @click="onClear"></i> <i v-if="inputValue && !disabled" class='el-icon-circle-close' @click="onClear"></i>
<Icon :type="visible ? 'ios-arrow-up' : 'ios-arrow-down'" class="icon-arrow" @click="() => {triggerMenu();}"></Icon> <Icon :type="visible ? 'ios-arrow-up' : 'ios-arrow-down'" class="icon-arrow" @click="() => {triggerMenu();}"></Icon>
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
:is="refviewname" :is="refviewname"
:viewdata="viewdata" :viewdata="viewdata"
:viewparam="viewparam" :viewparam="viewparam"
:ifShowButtons="false" :isShowButton="false"
:viewDefaultUsage="false" :viewDefaultUsage="false"
@viewdataschange="setValue" @viewdataschange="setValue"
style="height:100%;"> style="height:100%;">
...@@ -28,7 +28,8 @@ import { Vue, Component, Prop, Watch } from 'vue-property-decorator'; ...@@ -28,7 +28,8 @@ import { Vue, Component, Prop, Watch } from 'vue-property-decorator';
import { CreateElement } from 'vue'; import { CreateElement } from 'vue';
import { Subject, Subscription } from 'rxjs'; import { Subject, Subscription } from 'rxjs';
@Component({}) @Component({
})
export default class AppTreePicker extends Vue { export default class AppTreePicker extends Vue {
/** /**
...@@ -118,7 +119,7 @@ export default class AppTreePicker extends Vue { ...@@ -118,7 +119,7 @@ export default class AppTreePicker extends Vue {
* @type {string} * @type {string}
* @memberof AppTreePicker * @memberof AppTreePicker
*/ */
@Prop({default:"请选择..."}) public placeholder!: string; @Prop() public placeholder?: string;
/** /**
* 属性项名称 * 属性项名称
......
.app-upload-file-info{
white-space: nowrap;
text-overflow: ellipsis;
word-break: break-all;
overflow: hidden;
text-align: left;
.file-item{
color: #606266;
display: inline-block;
padding-left: 4px;
text-overflow: ellipsis;
-webkit-transition: color .3s;
transition: color .3s;
white-space: nowrap;
}
.file-item:hover{
color: #409EFF;
cursor: pointer;
}
i{
margin-right: 7px;
}
}
\ No newline at end of file
<template>
<div class="app-upload-file-info">
<a class="file-item" v-for="file in files" @click="() => onDownload(file)"><i class="el-icon-document"></i>{{file.name}}</a>
</div>
</template>
<script lang="ts">
import { Component, Vue, Prop, Watch } from 'vue-property-decorator';
import { Environment } from '@/environments/environment';
import { CreateElement } from 'vue';
import { Subject, Unsubscribable } from 'rxjs';
@Component({
})
export default class AppUploadFileInfo extends Vue {
/**
* 初始化值
*
* @type {*}
* @memberof AppUploadFileInfo
*/
@Prop() public value?: any;
/**
* 数据值变化
*
* @param {*} newval
* @param {*} val
* @memberof AppUploadFileInfo
*/
@Watch('value')
onValueChange(newval: any, val: any) {
this.dataProcess();
}
/**
* 所属表单项名称
*
* @type {string}
* @memberof AppUploadFileInfo
*/
@Prop() public name!: string;
/**
* 上传文件路径
*
* @memberof AppUploadFileInfo
*/
public uploadUrl = Environment.BaseUrl + Environment.UploadFile;
/**
* 下载文件路径
*
* @memberof AppUploadFileInfo
*/
public downloadUrl = Environment.BaseUrl + Environment.ExportFile;
/**
* 文件列表
*
* @memberof AppUploadFileInfo
*/
public files = [];
/**
* 数据处理
*
* @private
* @memberof AppUploadFileInfo
*/
private dataProcess(): void {
if(this.value){
let files = JSON.parse(this.value);
if(files.length){
files.forEach((file: any) => {
let url = `${this.downloadUrl}/${file.id}`;
file.url = url;
});
}else{
files = []
}
this.files =files;
}
}
/**
* vue 生命周期
*
* @memberof AppUploadFileInfo
*/
public created() {
this.dataProcess();
}
/**
* 下载文件
*
* @param {*} file
* @memberof AppUploadFileInfo
*/
public onDownload(file: any) {
window.open(file.url);
}
}
</script>
<style lang='less'>
@import './app-upload-file-info.less';
</style>
\ No newline at end of file
...@@ -2,13 +2,13 @@ ...@@ -2,13 +2,13 @@
<div class='app-header-user'> <div class='app-header-user'>
<dropdown @on-click="userSelect" :transfer="true"> <dropdown @on-click="userSelect" :transfer="true">
<div class='user'> <div class='user'>
<span>{{user.name}}</span> <span>{{user.name ? user.name : $t('components.appUser.name')}}</span>
&nbsp;&nbsp;<avatar :src="user.avatar" /> &nbsp;&nbsp;<avatar :src="user.avatar" />
</div> </div>
<dropdown-menu class='menu' slot='list' style='font-size: 15px !important;'> <dropdown-menu class='menu' slot='list' style='font-size: 15px !important;'>
<dropdown-item name='logout' style='font-size: 15px !important;'> <dropdown-item name='logout' style='font-size: 15px !important;'>
<span><i aria-hidden='true' class='fa fa-cogs' style='margin-right: 8px;'></i></span> <span><i aria-hidden='true' class='fa fa-cogs' style='margin-right: 8px;'></i></span>
<span>{{$t('user.logout')}}</span> <span>{{$t('components.appUser.logout')}}</span>
</dropdown-item> </dropdown-item>
</dropdown-menu> </dropdown-menu>
</dropdown> </dropdown>
...@@ -18,24 +18,6 @@ ...@@ -18,24 +18,6 @@
import { Vue, Component } from 'vue-property-decorator'; import { Vue, Component } from 'vue-property-decorator';
@Component({ @Component({
i18n: {
messages: {
'zh-CN': {
user: {
name: '匿名访问',
logout: '退出登陆',
surelogout: '确认要退出登陆?',
}
},
'en-US': {
user: {
name: 'Anonymous access',
logout: 'Logout',
surelogout: 'Are you sure logout?',
}
}
}
}
}) })
export default class AppUser extends Vue { export default class AppUser extends Vue {
...@@ -45,7 +27,7 @@ export default class AppUser extends Vue { ...@@ -45,7 +27,7 @@ export default class AppUser extends Vue {
* @memberof AppUser * @memberof AppUser
*/ */
public user = { public user = {
name: 'user.name', name: '',
avatar: './assets/img/avatar.png', avatar: './assets/img/avatar.png',
} }
...@@ -57,7 +39,7 @@ export default class AppUser extends Vue { ...@@ -57,7 +39,7 @@ export default class AppUser extends Vue {
*/ */
public userSelect(data: any) { public userSelect(data: any) {
if (Object.is(data, 'logout')) { if (Object.is(data, 'logout')) {
const title: any = this.$t('user.surelogout'); const title: any = this.$t('components.appUser.surelogout');
this.$Modal.confirm({ this.$Modal.confirm({
title: title, title: title,
onOk: () => { onOk: () => {
......
<template> <template>
<div class="codelist"> <div class="codelist">
<span v-if="ifEmpty">{{emptytext}}</span> <span v-if="ifEmpty">{{$t('codelist.'+tag+'.empty')}}</span>
<template v-if="!ifEmpty"> <template v-if="!ifEmpty">
<template v-if="renderMode == 'string'"> <template v-for="(item, index) in items">
<template v-for="(val, index) in items"> <span>{{ index != 0 ? textSeparator : ''}}</span>
{{ index != 0 ? textSeparator : ''}} <i v-if="item.iconCls" :class="item.iconCls"></i>
<template v-for="(item, index) in val"> <span :class="item.textCls" :style="{color:item.color}">{{isUseLangres ? $t(item.text) : item.text}}</span>
{{ index != 0 ? "、" : ''}} </template>
<i v-if="item.iconCls" :class="item.iconCls"></i>
<span :class="item.textCls" :style="{color:item.color}">{{item.text}}</span>
</template>
</template>
</template>
<template v-else>
<template v-for="(item, index) in items">
{{ index != 0 ? textSeparator : ''}}
<i v-if="item.iconCls" :class="item.iconCls"></i>
<span :class="item.textCls" :style="{color:item.color}">{{item.text}}</span>
</template>
</template>
</template> </template>
</div> </div>
</template> </template>
...@@ -43,7 +31,7 @@ export default class CodeList extends Vue { ...@@ -43,7 +31,7 @@ export default class CodeList extends Vue {
* @type {string} * @type {string}
* @memberof CodeList * @memberof CodeList
*/ */
@Prop() public srfkey!: string; @Prop() public tag!: string;
/** /**
* 代码表类型 * 代码表类型
...@@ -62,18 +50,11 @@ export default class CodeList extends Vue { ...@@ -62,18 +50,11 @@ export default class CodeList extends Vue {
@Prop() public value?: string; @Prop() public value?: string;
/** /**
* 空值显示文本 * 获取或模式
* @type {boolean} * @type {boolean}
* @memberof SelectPicker * @memberof SelectPicker
*/ */
@Prop() public emptytext?: string; @Prop({default:"STR"}) public renderMode?: string;
/**
* 绘制模式
* @type {boolean}
* @memberof SelectPicker
*/
@Prop() public renderMode?: string;
/** /**
* 文本分隔符 * 文本分隔符
...@@ -90,14 +71,14 @@ export default class CodeList extends Vue { ...@@ -90,14 +71,14 @@ export default class CodeList extends Vue {
@Prop({default:";"}) public valueSeparator?: string; @Prop({default:";"}) public valueSeparator?: string;
/** /**
* 是否 * 是否为空
* *
* @memberof CodeList * @memberof CodeList
*/ */
public ifEmpty:boolean = false; public ifEmpty:boolean = false;
/** /**
* 显示数据 * 显示数据集合
* *
* @type {any[]} * @type {any[]}
* @memberof CodeList * @memberof CodeList
...@@ -113,6 +94,13 @@ export default class CodeList extends Vue { ...@@ -113,6 +94,13 @@ export default class CodeList extends Vue {
this.dataHandle(); this.dataHandle();
} }
/**
* 是否使用多语言资源
* @type {boolean}
* @memberof CodeList
*/
public isUseLangres:boolean = false;
/** /**
* 数据值变化 * 数据值变化
* *
...@@ -133,6 +121,7 @@ export default class CodeList extends Vue { ...@@ -133,6 +121,7 @@ export default class CodeList extends Vue {
* @memberof CodeList * @memberof CodeList
*/ */
private dataHandle(){ private dataHandle(){
this.isUseLangres = false;
let _this = this; let _this = this;
// 空值判断 // 空值判断
if(Object.is(this.$util.typeOf(this.value), 'undefined') || Object.is(this.$util.typeOf(this.value), 'null')){ if(Object.is(this.$util.typeOf(this.value), 'undefined') || Object.is(this.$util.typeOf(this.value), 'null')){
...@@ -142,15 +131,16 @@ export default class CodeList extends Vue { ...@@ -142,15 +131,16 @@ export default class CodeList extends Vue {
this.ifEmpty = false; this.ifEmpty = false;
// 动态代码表处理 // 动态代码表处理
if (Object.is(this.codelistType, "DYNAMIC")) { if (Object.is(this.codelistType, "DYNAMIC")) {
this.codeListService.getItems(this.srfkey).then((res: any) => { this.codeListService.getItems(this.tag).then((res: any) => {
let items = res; let items = res;
_this.setItems(items, _this); _this.setItems(items, _this);
}).catch((error: any) => { }).catch((error: any) => {
console.log(`----${_this.srfkey}----代码表不存在`); console.log(`----${_this.tag}----代码表不存在`);
}); });
// 静态处理 // 静态处理
} else if(Object.is(this.codelistType, "STATIC")){ } else if(Object.is(this.codelistType, "STATIC")){
let items = this.$store.getters.getCodeListItems(this.srfkey); this.isUseLangres = true;
let items = this.$store.getters.getCodeListItems(this.tag);
_this.setItems(items, _this); _this.setItems(items, _this);
} }
} }
...@@ -167,7 +157,8 @@ export default class CodeList extends Vue { ...@@ -167,7 +157,8 @@ export default class CodeList extends Vue {
private setItems(items: any[], _this: any){ private setItems(items: any[], _this: any){
if (items) { if (items) {
let result:any = []; let result:any = [];
if(Object.is(this.renderMode,"number")){ if(Object.is(_this.renderMode,"NUM")){
_this.isUseLangres = false;
items.map((_item: any, index: number)=>{ items.map((_item: any, index: number)=>{
const nValue = parseInt((_this.value as any), 10); const nValue = parseInt((_this.value as any), 10);
const codevalue = _item.value; const codevalue = _item.value;
...@@ -175,22 +166,10 @@ export default class CodeList extends Vue { ...@@ -175,22 +166,10 @@ export default class CodeList extends Vue {
result.push(_item); result.push(_item);
} }
}); });
} else if(Object.is(this.renderMode,"string")){
const arrayValue: Array<any> = (_this.value as any).split(_this.valueSeparator);
arrayValue.map((value: any, index: number) => {
result.push([]);
let values: any[] = Object.is(this.$util.typeOf(value), 'number') ? [value] : [...(value as any).split(this.valueSeparator)];
values.map((val:any ,num: number)=>{
const item = this.getItem(items, val);
if(item){
result[index].push(item);
}
});
});
} else { } else {
let values: any[] = Object.is(this.$util.typeOf(this.value), 'number') ? [this.value] : [...(this.value as any).split(this.valueSeparator)]; let values: any[] = Object.is(_this.$util.typeOf(_this.value), 'NUM') ? [_this.value] : [...(_this.value as any).split(_this.valueSeparator)];
values.map((value:any ,index: number)=>{ values.map((value:any ,index: number)=>{
const item = this.getItem(items, value); const item = _this.getItem(items, value);
if(item){ if(item){
result.push(item); result.push(item);
} }
...@@ -198,9 +177,9 @@ export default class CodeList extends Vue { ...@@ -198,9 +177,9 @@ export default class CodeList extends Vue {
} }
// 设置items // 设置items
if(result.length != 0){ if(result.length != 0){
_this.items = result; _this.items = result;
}else{ }else{
_this.items = [{text:"不匹配"}]; _this.items = [{text:_this.value}];
} }
} }
} }
...@@ -221,13 +200,23 @@ export default class CodeList extends Vue { ...@@ -221,13 +200,23 @@ export default class CodeList extends Vue {
return undefined; return undefined;
} }
result = { ...arr[0] }; result = { ...arr[0] };
return result; if(Object.is(this.codelistType,'STATIC')){
let value = JSON.parse(JSON.stringify(result));
value.text = 'codelist.'+this.tag+'.'+value.value;
return value;
}else{
return result;
}
} }
} }
</script> </script>
<style lang='less'> <style lang='less'>
.codelist {
white-space: nowrap;
text-overflow: ellipsis;
word-break: break-all;
overflow: hidden;
}
</style> </style>
\ No newline at end of file
.data-reveal-type {
height: 100%;
width: 100%;
position: relative;
.show-type {
text-align: right;
padding-right: 16px;
position: absolute;
z-index: 1;
right: 0;
top: 2px;
.ivu-btn-group {
.collapse-btn {
padding: 0;
}
}
}
.data-reveal-content {
height: 100%;
overflow: auto;
}
}
\ No newline at end of file
<template>
<div class="data-reveal-type">
<div class='show-type'>
<button-group v-show="!showTypeDir">
<i-button class="collapse-btn" type="primary" @click="clickCollapse('left')">
<icon type="ios-arrow-back"/>
</i-button>
<i-button v-show="showTypeDir"></i-button>
</button-group>
<button-group v-show="showTypeDir">
<el-tooltip content="默认">
<i-button :type="activeType == 'default' ? 'primary' : 'default'" @click="onClickChange('default')">
<i class="fa fa-table" aria-hidden="true"></i>
</i-button>
</el-tooltip>
<el-tooltip content="日历">
<i-button :type="activeType == 'calendar' ? 'primary' : 'default'" @click="onClickChange('calendar')">
<i class="fa fa-calendar" aria-hidden="true"></i>
</i-button>
</el-tooltip>
<el-tooltip content="时间轴">
<i-button :type="activeType == 'timeline' ? 'primary' : 'default'" @click="onClickChange('timeline')">
<i class="fa fa-list-alt" aria-hidden="true"></i>
</i-button>
</el-tooltip>
<i-button class="collapse-btn" type="primary" @click="clickCollapse('right')">
<icon type="ios-arrow-forward"/>
</i-button>
</button-group>
</div>
<div class="data-reveal-content" v-show="Object.is(activeType, 'default')">
<slot></slot>
</div>
<div class="data-reveal-content" v-show="Object.is(activeType, 'calendar')">
<app-calendar :type="activeType" :datas="datas" @click="onClick"></app-calendar>
</div>
<div class="data-reveal-content" v-show="Object.is(activeType, 'timeline')">
<app-timeline :datas="datas" @click="onClick"></app-timeline>
</div>
</div>
</template>
<script lang="ts">
import {Vue, Component, Prop, Watch} from 'vue-property-decorator';
import AppTimeline from '@components/app-timeline/app-timeline.vue';
import AppCalendar from '@components/app-calendar/app-calendar.vue';
@Component({
components: {
AppTimeline,
AppCalendar
}
})
export default class DataRevealType extends Vue {
/**
* 数据集
*
* @type {string}
* @memberof DataRevealType
*/
@Prop() datas?: string;
/**
* 激活类型
*
* @protected
* @type {string}
* @memberof DataRevealType
*/
protected activeType: string = 'default';
/**
* 工具栏伸缩
*
* @protected
* @type {boolean}
* @memberof DataRevealType
*/
public showTypeDir: boolean = false;
/**
* 切换展现类型
*
* @param {string} type
* @memberof DataRevealType
*/
public onClickChange(type: string) {
this.activeType = type;
}
/**
* 选中
*
* @param {*} item
* @memberof DataRevealType
*/
public onClick(item: any) {
this.$emit('click', item);
}
/**
* 点击伸缩
*
* @param {*} type
* @memberof DataRevealType
*/
public clickCollapse(type: string) {
this.showTypeDir = Object.is(type, 'left') ? true : false;
}
}
</script>
<style lang="less">
@import './data-reveal-type.less';
</style>
\ No newline at end of file
<template> <template>
<div class="ibiz-date-picker"> <div class="ibiz-date-picker">
<div class="date-picker-text">保险期限 : 自</div> <div class="date-picker-text">{{$t('components.dateRange.startText')}}</div>
<el-date-picker <el-date-picker
v-model="value" v-model="value"
type="daterange" type="daterange"
:range-separator="rangeSeparatorr" :range-separator="rangeSeparatorr ? rangeSeparatorr : $t('components.dateRange.rangeSeparatorr')"
:start-placeholder="startPlaceholder" :start-placeholder="startPlaceholder ? startPlaceholder : $t('components.dateRange.startPlaceholder')"
:end-placeholder="endPlaceholder" :end-placeholder="endPlaceholder ? endPlaceholder : $t('components.dateRange.endPlaceholder')"
:disabled="disabled" :disabled="disabled"
value-format="yyyy-MM-dd" value-format="yyyy-MM-dd"
@change="change" @change="change"
:format="format" :format="format"
></el-date-picker> ></el-date-picker>
<div class="date-picker-text">日 24 时 止</div> <div class="date-picker-text">{{$t('components.dateRange.endText')}}</div>
</div> </div>
</template> </template>
<script lang = 'ts'> <script lang = 'ts'>
import { Component, Vue, Model, Prop } from "vue-property-decorator"; import { Component, Vue, Model, Prop } from "vue-property-decorator";
@Component({}) @Component({
})
export default class DateRange extends Vue { export default class DateRange extends Vue {
/** /**
* 日期格式 * 日期格式
* @type {any} * @type {any}
...@@ -48,7 +43,7 @@ export default class DateRange extends Vue { ...@@ -48,7 +43,7 @@ export default class DateRange extends Vue {
* @type {*} * @type {*}
* @memberof DateRange * @memberof DateRange
*/ */
@Prop({ default: "结束日期" }) public endPlaceholder?: string; @Prop() public endPlaceholder?: string;
/** /**
* 中间Placeholder * 中间Placeholder
...@@ -56,7 +51,7 @@ export default class DateRange extends Vue { ...@@ -56,7 +51,7 @@ export default class DateRange extends Vue {
* @type {*} * @type {*}
* @memberof DateRange * @memberof DateRange
*/ */
@Prop({ default: "日 0 时起 至" }) public rangeSeparatorr?: string; @Prop() public rangeSeparatorr?: string;
/** /**
* 开始日期Placeholder * 开始日期Placeholder
...@@ -64,7 +59,7 @@ export default class DateRange extends Vue { ...@@ -64,7 +59,7 @@ export default class DateRange extends Vue {
* @type {*} * @type {*}
* @memberof DateRange * @memberof DateRange
*/ */
@Prop({ default: "开始日期" }) public startPlaceholder?: string; @Prop() public startPlaceholder?: string;
/** /**
* 双向绑定值 * 双向绑定值
......
.dropdown-list-dynamic{
display: inline-block;
}
<template>
<i-select
class='dropdown-list-dynamic'
:transfer="true"
v-model="currentVal"
:disabled="disabled === true ? true : false"
:clearable="true"
:filterable="filterable === true ? true : false"
@on-open-change="onClick"
:placeholder="$t('components.dropDownListDynamic.placeholder')">
<i-option v-for="(item, index) in items" :key="index" :value="item.value">{{($t('userCustom.'+tag+'.'+item.value)!== ('userCustom.'+tag+'.'+item.value))?$t('userCustom.'+tag+'.'+item.value) : item.text}}</i-option>
</i-select>
</template>
<script lang="ts">
import { Vue, Component, Watch, Prop, Model } from 'vue-property-decorator';
import CodeListService from "@service/app/codelist-service";
@Component({
})
export default class DropDownListDynamic extends Vue {
/**
* 代码表服务对象
*
* @type {CodeListService}
* @memberof DropDownListDynamic
*/
public codeListService:CodeListService = new CodeListService({ $store: this.$store });
/**
* 额外参数
*
* @type {*}
* @memberof DropDownListDynamic
*/
public otherParam:any;
/**
* 查询参数
* @type {*}
* @memberof DropDownListDynamic
*/
public queryParam:any;
/**
* 当前选中值
* @type {any}
* @memberof DropDownListDynamic
*/
@Model('change') readonly itemValue!: any;
/**
* 代码表标识
*
* @type {string}
* @memberof DropDownListDynamic
*/
@Prop() public tag?: string;
/**
* 代码表类型
*
* @type {string}
* @memberof DropDownListDynamic
*/
@Prop() public codelistType?: string;
/**
* 传入表单数据
*
* @type {*}
* @memberof DropDownListDynamic
*/
@Prop() public data?: any;
/**
* 监听表单数据
*
* @memberof DropDownListDynamic
*/
@Watch('data',{ deep: true })
onDataChange(newVal: any, val: any){
if(newVal){
this.handleOtherParam();
}
}
/**
* 传入额外参数
*
* @type {*}
* @memberof DropDownListDynamic
*/
@Prop() public itemParam?: any;
/**
* 是否禁用
* @type {any}
* @memberof DropDownListDynamic
*
*/
@Prop() public disabled?: any;
/**
* 是否支持过滤
* @type {boolean}
* @memberof DropDownListDynamic
*/
@Prop() public filterable?: boolean;
/**
* 下拉选提示内容
* @type {string}
* @memberof DropDownListDynamic
*/
@Prop() public placeholder?: string;
/**
* 计算属性(当前值)
* @type {any}
* @memberof DropDownListDynamic
*/
set currentVal(val: any) {
const type: string = this.$util.typeOf(val);
val = Object.is(type, 'null') || Object.is(type, 'undefined') ? undefined : val;
this.$emit('change', val);
}
/**
* 获取值对象
*
* @memberof DropDownListDynamic
*/
get currentVal() {
return this.itemValue;
}
/**
* 代码表
*
* @type {any[]}
* @memberof DropDownListDynamic
*/
public items: any[] = [];
/**
* 处理额外参数
*/
public handleOtherParam(){
if(this.itemParam){
this.queryParam = {};
this.otherParam = this.itemParam.parentdata;
if(this.otherParam && Object.keys(this.otherParam).length >0){
Object.keys(this.otherParam).forEach((item:any) =>{
let value: string | null = this.otherParam[item];
if (value && value.startsWith('%') && value.endsWith('%')) {
const key = value.substring(1, value.length - 1);
if (this.data && this.data.hasOwnProperty(key)) {
value = (this.data[key] !== null && this.data[key] !== undefined) ? this.data[key] : null;
} else {
value = null;
}
}
Object.assign(this.queryParam,{[item]:value});
})
}
}
}
/**
* vue 生命周期
*
* @memberof DropDownListDynamic
*/
public created() {
if(this.tag && Object.is(this.codelistType,"STATIC")){
const codelist = this.$store.getters.getCodeList(this.tag);
if (codelist) {
this.items = [...JSON.parse(JSON.stringify(codelist.items))];
} else {
console.log(`----${this.tag}----代码表不存在`);
}
}else if(this.tag && Object.is(this.codelistType,"DYNAMIC")){
this.codeListService.getItems(this.tag,{},this.queryParam).then((res:any) => {
this.items = res;
}).catch((error:any) => {
console.log(`----${this.tag}----代码表不存在`);
});
}
}
/**
* 下拉点击事件
*
* @param {*} $event
* @memberof DropDownListDynamic
*/
public onClick($event:any){
if($event){
if(this.tag && Object.is(this.codelistType,"DYNAMIC")){
this.codeListService.getItems(this.tag,{},this.queryParam).then((res:any) => {
this.items = res;
}).catch((error:any) => {
console.log(`----${this.tag}----代码表不存在`);
});
}
}
}
}
</script>
<style lang='less'>
@import './dropdown-list-dynamic.less';
</style>
\ No newline at end of file
...@@ -8,10 +8,10 @@ ...@@ -8,10 +8,10 @@
:clearable="true" :clearable="true"
:filterable="filterable === true ? true : false" :filterable="filterable === true ? true : false"
@on-open-change="onClick" @on-open-change="onClick"
:placeholder="placeholder ? this.placeholder : '请选择'"> :placeholder="$t('components.dropDownListMpicker.placeholder')">
<i-option v-for="(item, index) in items" :key="index" :value="item.value" :label="item.text"> <i-option v-for="(item, index) in items" :key="index" :value="item.value" :label="item.text">
<Checkbox :value = "(currentVal.indexOf(item.value))==-1?false:true"> <Checkbox :value = "(currentVal.indexOf(item.value))==-1?false:true">
{{item.text}} {{Object.is(codelistType,'STATIC') ? $t('codelist.'+tag+'.'+item.value) : item.text}}
</Checkbox> </Checkbox>
</i-option> </i-option>
</i-select> </i-select>
...@@ -20,8 +20,9 @@ ...@@ -20,8 +20,9 @@
<script lang="ts"> <script lang="ts">
import { Vue, Component, Prop, Model } from 'vue-property-decorator'; import { Vue, Component, Prop, Model } from 'vue-property-decorator';
import CodeListService from "@service/app/codelist-service"; import CodeListService from "@service/app/codelist-service";
@Component({}) @Component({
export default class DropDownList extends Vue { })
export default class DropDownListMpicker extends Vue {
/** /**
* 代码表服务对象 * 代码表服务对象
* *
...@@ -53,6 +54,14 @@ export default class DropDownList extends Vue { ...@@ -53,6 +54,14 @@ export default class DropDownList extends Vue {
*/ */
@Prop() public codelistType?: string; @Prop() public codelistType?: string;
/**
* 代码表值分隔符
*
* @type {string}
* @memberof DropDownListMpicker
*/
@Prop({default:';'}) public valueSeparator?: string;
/** /**
* 是否禁用 * 是否禁用
* @type {any} * @type {any}
...@@ -83,7 +92,7 @@ export default class DropDownList extends Vue { ...@@ -83,7 +92,7 @@ export default class DropDownList extends Vue {
set currentVal(val: any) { set currentVal(val: any) {
const type: string = this.$util.typeOf(val); const type: string = this.$util.typeOf(val);
val = Object.is(type, 'null') || Object.is(type, 'undefined') ? [] : val; val = Object.is(type, 'null') || Object.is(type, 'undefined') ? [] : val;
let value = val.length > 0 ? val.join(',') : ''; let value = val.length > 0 ? val.join(this.valueSeparator) : '';
this.$emit('change', value); this.$emit('change', value);
} }
...@@ -93,7 +102,7 @@ export default class DropDownList extends Vue { ...@@ -93,7 +102,7 @@ export default class DropDownList extends Vue {
* @memberof DropDownListMpicker * @memberof DropDownListMpicker
*/ */
get currentVal() { get currentVal() {
return this.itemValue? this.itemValue.split(','):[]; return this.itemValue? this.itemValue.split(this.valueSeparator):[];
} }
/** /**
...@@ -110,7 +119,6 @@ export default class DropDownList extends Vue { ...@@ -110,7 +119,6 @@ export default class DropDownList extends Vue {
* @memberof DropDownListMpicker * @memberof DropDownListMpicker
*/ */
public created() { public created() {
this.currentVal = [];
if(this.tag && Object.is(this.codelistType,"STATIC")){ if(this.tag && Object.is(this.codelistType,"STATIC")){
const codelist = this.$store.getters.getCodeList(this.tag); const codelist = this.$store.getters.getCodeList(this.tag);
if (codelist) { if (codelist) {
......
.dropdown-list{ .dropdown-list{
display: inline-block;
} }
...@@ -7,16 +7,17 @@ ...@@ -7,16 +7,17 @@
:clearable="true" :clearable="true"
:filterable="filterable === true ? true : false" :filterable="filterable === true ? true : false"
@on-open-change="onClick" @on-open-change="onClick"
:placeholder="placeholder ? this.placeholder : '请选择'"> :placeholder="$t('components.dropDownList.placeholder')">
<i-option v-for="(item, index) in items" :key="index" :value="item.value">{{item.text}}</i-option> <i-option v-for="(item, index) in items" :key="index" :value="item.value">{{($t('codelist.'+tag+'.'+item.value)!== ('codelist.'+tag+'.'+item.value))?$t('codelist.'+tag+'.'+item.value) : item.text}}</i-option>
</i-select> </i-select>
</template> </template>
<script lang="ts"> <script lang="ts">
import { Vue, Component, Prop, Model } from 'vue-property-decorator'; import { Vue, Component, Watch, Prop, Model } from 'vue-property-decorator';
import CodeListService from "@service/app/codelist-service"; import CodeListService from "@service/app/codelist-service";
@Component({}) @Component({
})
export default class DropDownList extends Vue { export default class DropDownList extends Vue {
/** /**
* 代码表服务对象 * 代码表服务对象
...@@ -26,6 +27,21 @@ export default class DropDownList extends Vue { ...@@ -26,6 +27,21 @@ export default class DropDownList extends Vue {
*/ */
public codeListService:CodeListService = new CodeListService({ $store: this.$store }); public codeListService:CodeListService = new CodeListService({ $store: this.$store });
/**
* 额外参数
*
* @type {*}
* @memberof DropDownList
*/
public otherParam:any;
/**
* 查询参数
* @type {*}
* @memberof DropDownList
*/
public queryParam:any;
/** /**
* 当前选中值 * 当前选中值
* @type {any} * @type {any}
...@@ -45,14 +61,42 @@ export default class DropDownList extends Vue { ...@@ -45,14 +61,42 @@ export default class DropDownList extends Vue {
* 代码表类型 * 代码表类型
* *
* @type {string} * @type {string}
* @memberof AppCheckBox * @memberof DropDownList
*/ */
@Prop() public codelistType?: string; @Prop() public codelistType?: string;
/**
* 传入表单数据
*
* @type {*}
* @memberof DropDownList
*/
@Prop() public data?: any;
/**
* 监听表单数据
*
* @memberof DropDownList
*/
@Watch('data',{ deep: true })
onDataChange(newVal: any, val: any){
if(newVal){
this.handleOtherParam();
}
}
/**
* 传入额外参数
*
* @type {*}
* @memberof DropDownList
*/
@Prop() public itemParam?: any;
/** /**
* 是否禁用 * 是否禁用
* @type {any} * @type {any}
* @memberof SelectPicker * @memberof DropDownList
* *
*/ */
@Prop() public disabled?: any; @Prop() public disabled?: any;
...@@ -60,21 +104,22 @@ export default class DropDownList extends Vue { ...@@ -60,21 +104,22 @@ export default class DropDownList extends Vue {
/** /**
* 是否支持过滤 * 是否支持过滤
* @type {boolean} * @type {boolean}
* @memberof SelectPicker * @memberof DropDownList
*/ */
@Prop() public filterable?: boolean; @Prop() public filterable?: boolean;
/** /**
* 下拉选提示内容 * 下拉选提示内容
* @type {string} * @type {string}
* @memberof SelectPicker * @memberof DropDownList
*/ */
@Prop() public placeholder?: string; @Prop() public placeholder?: string;
/** /**
* 计算属性(当前值) * 计算属性(当前值)
* @type {any} * @type {any}
* @memberof SelectPicker * @memberof DropDownList
*/ */
set currentVal(val: any) { set currentVal(val: any) {
const type: string = this.$util.typeOf(val); const type: string = this.$util.typeOf(val);
...@@ -99,6 +144,30 @@ export default class DropDownList extends Vue { ...@@ -99,6 +144,30 @@ export default class DropDownList extends Vue {
*/ */
public items: any[] = []; public items: any[] = [];
/**
* 处理额外参数
*/
public handleOtherParam(){
if(this.itemParam){
this.queryParam = {};
this.otherParam = this.itemParam.parentdata;
if(this.otherParam && Object.keys(this.otherParam).length >0){
Object.keys(this.otherParam).forEach((item:any) =>{
let value: string | null = this.otherParam[item];
if (value && value.startsWith('%') && value.endsWith('%')) {
const key = value.substring(1, value.length - 1);
if (this.data && this.data.hasOwnProperty(key)) {
value = (this.data[key] !== null && this.data[key] !== undefined) ? this.data[key] : null;
} else {
value = null;
}
}
Object.assign(this.queryParam,{[item]:value});
})
}
}
}
/** /**
* vue 生命周期 * vue 生命周期
* *
...@@ -113,7 +182,7 @@ export default class DropDownList extends Vue { ...@@ -113,7 +182,7 @@ export default class DropDownList extends Vue {
console.log(`----${this.tag}----代码表不存在`); console.log(`----${this.tag}----代码表不存在`);
} }
}else if(this.tag && Object.is(this.codelistType,"DYNAMIC")){ }else if(this.tag && Object.is(this.codelistType,"DYNAMIC")){
this.codeListService.getItems(this.tag).then((res:any) => { this.codeListService.getItems(this.tag,{},this.queryParam).then((res:any) => {
this.items = res; this.items = res;
}).catch((error:any) => { }).catch((error:any) => {
console.log(`----${this.tag}----代码表不存在`); console.log(`----${this.tag}----代码表不存在`);
...@@ -128,12 +197,14 @@ export default class DropDownList extends Vue { ...@@ -128,12 +197,14 @@ export default class DropDownList extends Vue {
* @memberof DropDownList * @memberof DropDownList
*/ */
public onClick($event:any){ public onClick($event:any){
if(this.tag && Object.is(this.codelistType,"DYNAMIC")){ if($event){
this.codeListService.getItems(this.tag).then((res:any) => { if(this.tag && Object.is(this.codelistType,"DYNAMIC")){
this.items = res; this.codeListService.getItems(this.tag,{},this.queryParam).then((res:any) => {
}).catch((error:any) => { this.items = res;
console.log(`----${this.tag}----代码表不存在`); }).catch((error:any) => {
}); console.log(`----${this.tag}----代码表不存在`);
});
}
} }
} }
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
<card :bordered="false"> <card :bordered="false">
<p slot='title'> <p slot='title'>
<icon type='ios-log-in'></icon> <icon type='ios-log-in'></icon>
&nbsp;&nbsp;{{this.$t('login.caption')}} &nbsp;&nbsp;{{this.$t('components.login.caption')}}
</p> </p>
<div class='form-con'> <div class='form-con'>
<i-form ref='loginForm' :rules="rules" :model="form"> <i-form ref='loginForm' :rules="rules" :model="form">
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
<i-input <i-input
prefix='ios-contact' prefix='ios-contact'
v-model="form.loginname" v-model="form.loginname"
:placeholder="this.$t('login.loginname.placeholder')"> :placeholder="this.$t('components.login.loginname.placeholder')">
</i-input> </i-input>
</form-item> </form-item>
<form-item prop='password'> <form-item prop='password'>
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
prefix='ios-key' prefix='ios-key'
v-model="form.password" v-model="form.password"
type='password' type='password'
:placeholder="this.$t('login.password.placeholder')"> :placeholder="this.$t('components.login.password.placeholder')">
</i-input> </i-input>
</form-item> </form-item>
<form-item> <form-item>
...@@ -28,12 +28,12 @@ ...@@ -28,12 +28,12 @@
@click="handleSubmit" @click="handleSubmit"
type='primary' type='primary'
long> long>
{{this.$t('login.name')}} {{this.$t('components.login.name')}}
</i-button> </i-button>
</form-item> </form-item>
</i-form> </i-form>
<p class='login-tip'> <p class='login-tip'>
{{this.$t('login.tip')}} {{this.$t('components.login.tip')}}
</p> </p>
</div> </div>
</card> </card>
...@@ -42,46 +42,10 @@ ...@@ -42,46 +42,10 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import { Vue, Component } from 'vue-property-decorator'; import { Vue, Component, Watch } from 'vue-property-decorator';
import { Environment } from '@/environments/environment'; import { Environment } from '@/environments/environment';
@Component({ @Component({
i18n: {
messages: {
'zh-CN': {
login: {
caption: '欢迎登录',
name: '登录',
tip: '输入用户名和密码',
loginname: {
placeholder: '请输入用户名',
message: '用户名不能为空',
},
password: {
placeholder: '请输入密码',
message: '密码不能为空',
},
loginfailed: '登陆失败',
},
},
'en-US': {
login: {
caption: 'Welcome to login',
name: 'Login',
tip: 'Enter username and password',
loginname: {
placeholder: 'Username',
message: 'The username cannot be empty',
},
password: {
placeholder: 'Password',
message: 'The password cannot be empty',
},
loginfailed: 'Login failed'
},
}
}
}
}) })
export default class Login extends Vue { export default class Login extends Vue {
...@@ -99,15 +63,43 @@ export default class Login extends Vue { ...@@ -99,15 +63,43 @@ export default class Login extends Vue {
* @type {*} * @type {*}
* @memberof Login * @memberof Login
*/ */
public rules: any = { public rules = {};
loginname: [
{ required: true, message: '用户名不能为空', trigger: 'change' }, /**
], * 设置值规则
password: [ *
{ required: true, message: '密码不能为空', trigger: 'change' }, * @memberof Login
], */
public setRules(){
this.rules = {
loginname: [
{ required: true, message: this.$t('components.login.loginname.message'), trigger: 'change' },
],
password: [
{ required: true, message: this.$t('components.login.password.message'), trigger: 'change' },
],
}
}; };
/**
* 生命周期Create
*
* @memberof Login
*/
public created(){
this.setRules();
}
/**
* 监听语言变化
*
* @memberof Login
*/
@Watch('$i18n.locale')
onLocaleChange(newval: any, val: any) {
this.setRules();
}
/** /**
* 登陆处理 * 登陆处理
* *
...@@ -132,8 +124,8 @@ export default class Login extends Vue { ...@@ -132,8 +124,8 @@ export default class Login extends Vue {
this.$router.push({ path: url }); this.$router.push({ path: url });
} }
}).catch((error: any) => { }).catch((error: any) => {
const loginfailed: any = this.$t('login.loginfailed'); const loginfailed: any = this.$t('components.login.loginfailed');
this.$Notice.error({ title: '错误', desc: loginfailed }); this.$Notice.error({ title: (this.$t('components.login.error') as any), desc: loginfailed });
}); });
} }
......
.app-header-menus {
display: flex;
align-items: center;
height: 100%;
>.app-view-quick-search {
>.ivu-input-wrapper.ivu-input-wrapper-default.ivu-input-type-text {
width: 300px;
>.ivu-input.ivu-input-default.ivu-input-with-suffix {
border-radius: 20px;
}
}
}
>.app-view-quick-search.default {
font-size: 20px;
margin-right: 16px;
}
>.app-view-quick-search.view {
margin-right: 10px;
}
>.app-header-menu-item,
>.app-view-quick-search {
height: 24px;
display: flex;
align-items: center;
margin-right: 16px;
color: #8893a7;
border: 1px solid rgba(0, 0, 0, 0);
cursor: pointer;
}
>.app-header-menu-item.icon {
>.app-header-menu-item-icon {
font-size: 20px;
}
>.app-header-menu-item-img {
height: 20px;
width: 20px;
>img {
height: 100%;
width: 100%;
}
}
}
>.app-header-menu-item.icon:hover, >.app-view-quick-search:hover {
color: #68758e;
text-decoration: none;
}
>.app-header-menu-item.text {
border-radius: 4px;
border: 1px solid #8893a7;
text-align: center;
font-size: 12px;
padding: 2px 4px;
>.app-header-menu-item-icon {
width: 20px;
height: 20px;
overflow: hidden;
font-size: 16px;
margin-right: 3px;
margin-top: -3px;
}
>.app-header-menu-item-img {
height: 16px;
width: 16px;
margin-right: 3px;
>img {
height: 100%;
width: 100%;
}
}
}
>.app-header-menu-item.text:hover {
color: #107fff;
border: 1px solid #107fff;
}
>.app-header-view-menu-item {
margin-right: 10px;
>span {
display: flex;
>.app-header-menu-item-icon {
margin-right: 6px;
font-size: 14px;
}
>.app-header-menu-item-img {
height: 14px;
width: 14px;
margin-right: 6px;
>img {
height: 100%;
width: 100%;
margin-top: 3px;
}
}
}
}
}
\ No newline at end of file
import { Vue, Component, Prop, Emit, Watch, Model } from 'vue-property-decorator';
import './app-header-menus.less';
/**
* 绘制应用头部菜单
*
* @export
* @class AppHeaderMenus
* @extends {Vue}
*/
@Component({})
export class AppHeaderMenus extends Vue {
/**
* 所有菜单项
*
* @type {any[]}
* @memberof AppHeaderMenus
*/
@Prop({ default: () => [] })
public menus!: any[];
@Watch('menus', { deep: true, immediate: true })
public watchMenus(menus: any[]): void {
if (menus && menus.length > 0) {
this.items = this.menus;
this.$forceUpdate();
}
}
/**
* 展示菜单项
*
* @protected
* @type {any[]}
* @memberof AppHeaderMenus
*/
protected items: any[] = [];
/**
* 工具栏模型
*
* @protected
* @type {*}
* @memberof AppHeaderMenus
*/
@Prop()
protected toolbarModel?: any;
/**
* 工具栏展示模式
*
* @protected
* @type {('default' | 'view' | 'view2')}
* @memberof AppHeaderMenus
*/
@Prop({ default: 'default' })
protected mode!: 'default' | 'view' | 'view2';
/**
* 视图呈现模式
*
* @type {string}
* @memberof AppLayout
*/
@Prop({ default: 'DEFAULT' })
public openMode!: string;
/**
* 是否启用快捷搜索
*
* @protected
* @type {boolean}
* @memberof AppHeaderMenus
*/
@Prop({ default: false })
protected isEnableQuickSearch!: boolean;
/**
* 搜索框值
*
* @protected
* @type {string}
* @memberof AppHeaderMenus
*/
@Model('change', { default: '' })
protected searchValue!: string;
/**
* 搜索框提示内容
*
* @protected
* @type {string}
* @memberof AppHeaderMenus
*/
@Prop({ default: '' })
protected searchPlaceholder!: string;
/**
* 是否激活搜索框
*
* @protected
* @type {boolean}
* @memberof AppHeaderMenus
*/
protected isActiveSearch: boolean = false;
/**
* 监控工具栏模型
*
* @param {*} val
* @param {*} oldVal
* @memberof AppHeaderMenus
*/
@Watch('toolbarModel', { deep: true, immediate: true })
public watchToolbarModel(val: any, oldVal: any): void {
if (val && Object.keys(val).length > 0) {
this.items = [];
const keys: string[] = Object.keys(val);
keys.forEach((key: string) => {
const value: any = val[key];
if (Object.is(value.type, 'DEUIACTION')) {
this.items.push(val[key]);
}
});
}
}
/**
* 是否为模式1呈现
*
* @protected
* @returns {boolean}
* @memberof AppHeaderMenus
*/
protected isModeOne(): boolean {
return (Object.is(this.mode, 'view') && !Object.is(this.openMode, 'MODAL'));
}
/**
* 组件挂载完毕
*
* @memberof AppHeaderMenus
*/
public mounted(): void {
this.isActiveSearch = this.isModeOne();
}
/**
* 工具栏
*
* @protected
* @param {*} item
* @returns {*}
* @memberof AppHeaderMenus
*/
@Emit('menu-click')
protected menuClick(item: any): any {
if (!item.tag) {
item.tag = item.name
}
return item;
}
/**
* 绘制项图标
*
* @protected
* @param {*} item
* @returns {*}
* @memberof AppHeaderMenus
*/
protected renderIcon(item: any): any {
if (item) {
if (item.icon && !Object.is(item.icon, '')) {
return <div class="app-header-menu-item-img">
<img src={item.icon} />
</div>;
} else if (item.iconcls && !Object.is(item.iconcls, '')) {
return <div class="app-header-menu-item-icon">
<i class={item.iconcls} aria-hidden="true" />
</div>;
}
}
}
/**
* 绘制菜单项
*
* @protected
* @param {*} item
* @returns {*}
* @memberof AppHeaderMenus
*/
protected renderMenuItem(item: any): any {
if (Object.is(this.mode, 'default')) {
if (item.caption && !Object.is(item.caption, '')) {
return <div class="app-header-menu-item text" disabled={item.disabled} on-click={() => this.menuClick(item)}>
{this.renderIcon(item)}
<div class="app-header-menu-item-text">{item.caption}</div>
</div>;
} else {
return <div class="app-header-menu-item icon" disabled={item.disabled} on-click={() => this.menuClick(item)}>
<el-tooltip class="item" effect="dark" content={item.tooltip} placement="bottom" open-delay={300}>
{this.renderIcon(item)}
</el-tooltip>
</div>;
}
} else if (Object.is(this.mode, 'view') || Object.is(this.mode, 'view2')) {
const button: any = <i-button class="app-header-view-menu-item" type={this.isModeOne() ? 'text' : 'default'} disabled={item.disabled} on-click={() => this.menuClick(item)}>
{this.renderIcon(item)}
{item.caption}
</i-button>;
if (item.tooltip && !Object.is(item.tooltip, '')) {
return <el-tooltip class="app-header-view-menu-item-tooltip" effect="dark" content={item.tooltip} placement="bottom" open-delay={300}>{button}</el-tooltip>;
}
return button;
}
}
/**
* 激活搜索
*
* @protected
* @memberof AppHeaderMenus
*/
protected activeSearch(): void {
this.isActiveSearch = true;
this.$nextTick(() => {
const search: any = this.$refs.search;
if (search) {
search.focus();
}
});
}
/**
* 搜索框失去焦点
*
* @protected
* @memberof AppHeaderMenus
*/
protected searchBlur(): void {
if (this.isModeOne()) {
return;
}
this.isActiveSearch = false;
}
/**
* 搜索事件
*
* @protected
* @param {string} val
* @memberof AppHeaderMenus
*/
@Emit('search')
protected search(val: string): void { }
/**
* 搜索值发生变化
*
* @protected
* @param {*} val
* @memberof AppHeaderMenus
*/
protected searchValChange(val: any): void {
if (val) {
this.$emit('change', this.searchValue + val);
} else {
this.$emit('change', '');
}
}
/**
* 绘制搜索按钮
*
* @protected
* @returns {*}
* @memberof AppHeaderMenus
*/
protected renderSearchMenu(): any {
if (!this.isEnableQuickSearch) {
return;
}
let searchMenu: any;
if (Object.is(this.mode, 'default')) {
searchMenu = <i class="ivu-icon ivu-icon-ios-search" on-click={() => this.activeSearch()} />
} else if (Object.is(this.mode, 'view') || Object.is(this.mode, 'view2')) {
searchMenu = <i-button type={this.isModeOne() ? 'text' : 'default'} shape="circle" icon="ios-search" on-click={() => this.activeSearch()} />
}
return <div class={"app-view-quick-search " + this.mode}>
<i-input v-show={this.isActiveSearch} ref="search" value={this.searchValue} autofocus autocomplete="on" search placeholder={this.searchPlaceholder} on-on-change={(e: any) => this.searchValChange(e.data)} on-on-blur={() => this.searchBlur()} on-on-search={(val: string) => this.search(val)} />
{!this.isActiveSearch ? searchMenu : null}
</div>
}
/**
* 绘制头部菜单内容
*
* @returns {*}
* @memberof AppHeaderMenus
*/
public render(): any {
return <div class="app-header-menus">
{this.renderSearchMenu()}
{this.items.map((item: any) => {
if (!item.visabled) {
return;
}
return this.renderMenuItem(item);
})}
</div>;
}
}
\ No newline at end of file
html,
body {
overflow: hidden;
}
.crm-app-layout {
width: 100vw;
height: 100vh;
overflow: hidden;
background-color: #f3f5f8;
position: relative;
>.crm-app-header-container {
width: 100vw;
height: 53px;
z-index: 1;
overflow: hidden;
display: flex;
position: relative;
border-bottom: 1px solid #e0e3e9;
border-bottom-width: 1px;
border-bottom-style: solid;
border-bottom-color: rgb(224, 227, 233);
padding: 6px;
>.crm-app-header-background {
top: 0px;
left: 0px;
right: 0px;
bottom: 0px;
position: absolute;
z-index: -10;
background: #fff;
background-image: url(../../../assets/img/header-bg.png);
background-size: contain;
background-position: 50%;
}
>.crm-app-header-background::before {
content: " ";
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: -webkit-gradient(linear, left top, left bottom, from(#f9fafd), to(#e7eef8));
background: -o-linear-gradient(top, #f9fafd 0, #e7eef8 100%);
background: linear-gradient(180deg, #f9fafd, #e7eef8);
opacity: .9;
z-index: -1;
}
>.crm-app-header {
display: flex;
flex-grow: 1;
justify-content: space-between;
height: 100%;
}
>.crm-user-info-container {
flex-shrink: 0;
width: 45px;
height: 100%;
>.crm-app-header-left-container {
height: 100%;
}
>.crm-app-header-right-container {
height: 100%;
}
}
>.crm-modal-close {
width: 40px;
font-size: 28px;
text-align: center;
margin-top: -2px;
cursor: pointer;
}
}
>.crm-app-content-container {
width: 100vw;
height: calc(100vh - 53px);
overflow-x: hidden;
overflow-y: auto;
}
}
.crm-app-view {
width: 100%;
height: 100%;
background-color: white;
padding-top: 12px;
padding-left: 6px;
position: relative;
>.crm-app-view-header-wrapper {
width: 100%;
height: 40px;
padding: 0 10px 10px 10px;
>.crm-app-view-header-left-wrapper {
float: left;
height: 100%;
>.view-header-left {
>.view-caption {
font-size: 16px;
font-weight: 600;
}
}
}
>.crm-app-view-header-right-wrapper {
float: right;
height: 100%;
}
}
>.crm-app-view-content-wrapper {
width: 100%;
height: calc(100% - 40px);
padding: 0 10px 0 10px;
overflow-x: auto;
.el-table {
thead {
color: #304265;
}
}
}
}
.crm-app-view.no-caption-bar {
padding: 0px;
>.crm-app-view-content-wrapper {
height: 100%;
padding: 0px;
overflow-x: auto;
}
}
\ No newline at end of file
import { Vue, Component, Emit, Prop } from 'vue-property-decorator';
import { ViewConfigActions } from '../view-config-actions/view-config-actions';
import './app-layout.less';
/**
* 应用基础布局
*
* @export
* @class AppLayout
* @extends {Vue}
*/
@Component({
components: {
'view-config-actions': ViewConfigActions
}
})
export class AppLayout extends Vue {
/**
* 视图名称
*
* @type {string}
* @memberof AppLayout
*/
@Prop({ default: () => { } })
public viewName!: string;
/**
* 视图标题
*
* @type {string}
* @memberof AppLayout
*/
@Prop({ default: '' })
public viewTitle!: string;
/**
* 额外样式名称
*
* @type {{[key: string]: boolean}}
* @memberof AppLayout
*/
@Prop({ default: () => { } })
public className!: { [key: string]: boolean };
/**
* 布局呈现模式
*
* @type {string}
* @memberof AppLayout
*/
@Prop({ default: 'DEFAULT' })
public layoutMode!: string;
/**
* 是否展示用户信息
*
* @type {boolean}
* @memberof AppLayout
*/
@Prop({ default: true })
public isShowUserInfo!: boolean;
/**
* 视图呈现模式
*
* @type {string}
* @memberof AppLayout
*/
@Prop({ default: 'DEFAULT' })
public openMode!: string;
/**
* 是否显示标题栏
*
* @type {boolean}
* @memberof AppLayout
*/
@Prop({ default: true })
public isShowCaptionBar!: boolean;
/**
* 是否显示工具栏区域
*
* @type {boolean}
* @memberof AppLayout
*/
@Prop({ default: true })
public isShowToolbar!: boolean;
/**
* 组件挂载完毕
*
* @memberof AppLayout
*/
@Emit('mounted')
public mounted(): void { }
/**
* 视图关闭
*
* @memberof AppLayout
*/
@Emit('close-view')
public closeView(): any {
return [];
}
/**
* 绘制布局内容
*
* @returns {*}
* @memberof AppLayout
*/
public render(): any {
if (Object.is(this.layoutMode, 'VIEW') && Object.is(this.openMode, 'DEFAULT')) {
Object.assign(this.className, { 'crm-app-view': true, 'no-caption-bar': (!this.isShowCaptionBar && !this.isShowToolbar) });
return <div class={this.className}>
{(!this.isShowCaptionBar && !this.isShowToolbar) ? null : <div class="crm-app-view-header-wrapper">
{this.isShowCaptionBar ? <div class="crm-app-view-header-left-wrapper">
{this.$slots.headerLeft}
</div> : null}
{this.isShowToolbar ? <div class="crm-app-view-header-right-wrapper">
{this.$slots.headerRight}
</div> : null}
</div>}
<div class="crm-app-view-content-wrapper">
<view-config-actions viewName={this.viewName} viewTitle={this.viewTitle}/>
{this.$slots.content}
</div>
</div>;
}
Object.assign(this.className, { 'crm-app-layout': true, 'no-caption-bar': !this.isShowCaptionBar });
return <div class={this.className}>
<div class="crm-app-header-container">
<div class="crm-app-header-background"></div>
<div class="crm-app-header">
<div class="crm-app-header-left-container">{this.$slots.headerLeft}</div>
<div class="crm-app-header-right-container">{this.$slots.headerRight}</div>
</div>
{this.isShowUserInfo ? <div class="crm-user-info-container">
<app-user-info />
</div> : null}
{Object.is(this.openMode, 'MODAL') ? <div class="crm-modal-close" on-click={() => this.closeView()}>
<i class="ivu-icon ivu-icon-md-close" />
</div> : null}
</div>
<div class="crm-app-content-container">
<view-config-actions viewName={this.viewName} viewTitle={this.viewTitle}/>
{this.$slots.content}
</div>
</div>;
}
}
\ No newline at end of file
.app-menus {
width: 100%;
margin-bottom: 24px;
color: #304265;
box-shadow: inset 0 0 10px 0 #dee4f1;
>.app-menus-content {
padding: 0 120px;
padding-top: 8px;
padding-bottom: 8px;
border-bottom: 1px solid #f3f5f8;
>.app-menu-list {
position: relative;
display: flex;
width: 100%;
height: 40px;
user-select: none;
list-style-type: none;
>.app-menu-item {
display: flex;
align-items: center;
padding: 8px;
cursor: pointer;
border-radius: 5px;
>.app-menu-item-img {
width: 24px;
height: 24px;
>img {
width: 100%;
height: 100%;
}
}
>.app-menu-item-icon {
font-size: 24px;
}
>.app-menu-item-text {
display: block;
margin: 0 2px 0 10px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
font-size: 14px;
}
}
>.app-menu-item:hover {
background: #f7fafc;
}
}
}
}
.app-menus-vertical-wrapper {
width: 100%;
height: 100%;
box-shadow: inset 0 0 10px 0 #dee4f1;
>.el-menu.app-menus-vertical {
height: 100%;
background-color: #f7fafc;
>.el-submenu {
.el-menu {
background-color: #f7fafc;
}
>.el-submenu__title {
font-size: 14px;
>.app-menu-item-icon {
float: left;
margin-right: 10px;
}
>.app-menu-item-img {
float: left;
width: 18px;
height: 18px;
margin-right: 10px;
>img {
height: 100%;
width: 100%;
}
}
}
>.el-submenu__title:hover {
background: #ecf1f7;
color: #107fff;
}
}
>.el-menu-item {
font-size: 14px;
>.app-menu-item-icon {
float: left;
margin-right: 10px;
}
>.app-menu-item-img {
float: left;
width: 18px;
height: 18px;
margin-right: 10px;
>img {
height: 100%;
width: 100%;
}
}
}
}
.el-menu-item.is-active,
.el-menu-item:hover {
background: #ecf1f7;
color: #107fff;
}
}
\ No newline at end of file
import { Vue, Component, Prop, Emit, Watch } from 'vue-property-decorator';
import './app-menus.less';
/**
* 首页应用菜单
*
* @export
* @class AppMenu
* @extends {Vue}
*/
@Component({})
export class AppMenus extends Vue {
/**
* 当前激活菜单的Index
*
* @protected
* @type {string}
* @memberof AppMenus
*/
protected defaultActive: string = '';
/**
* 默认展开的菜单项
*
* @protected
* @type {string[]}
* @memberof AppMenus
*/
protected defaultOpeneds: string[] = [];
/**
* 菜单数据
*
* @type {any[]}
* @memberof AppMenus
*/
@Prop({
default: () => []
})
public menus!: any[];
/**
* 监控菜单数据变化
*
* @param {any[]} val
* @param {any[]} oldVal
* @memberof AppMenus
*/
@Watch('menus')
public watchMenus(val: any[], oldVal: any[]): void {
if (val && val.length > 0) {
this.defaultCalculation();
}
}
/**
* 菜单对齐方向
*
* @type {CrmIndexService}
* @memberof CrmIndex
*/
@Prop({ default: '' })
protected menuAlign!: string;
/**
* 菜单项点击
*
* @protected
* @param {*} item
* @returns {*}
* @memberof AppMenus
*/
@Emit('menu-click')
protected menuClick(item: any): any { }
/**
* 菜单项激活
*
* @protected
* @param {*} item
* @memberof AppMenus
*/
protected menuActive(item: any): void {
this.defaultActive = item.id;
this.menuClick(item);
}
/**
* 计算菜单默认选中值
*
* @protected
* @memberof AppMenus
*/
protected defaultCalculation(): void {
if (this.$route && this.$route.matched.length <= 1) {
this.calcDefaultActive(this.menus);
this.defaultOpeneds = this.defaultOpeneds.reverse();
}
}
/**
* 递归计算默认选中
*
* @protected
* @param {any[]} menus
* @memberof AppMenus
*/
protected calcDefaultActive(menus: any[]): boolean {
return menus.find((item: any) => {
if (item.items) {
if (this.calcDefaultActive(item.items)) {
this.defaultOpeneds.push(item.id);
return true;
}
}
if (item.opendefault) {
this.defaultActive = item.id;
this.menuActive(item);
return true;
}
});
}
/**
* 绘制项图标
*
* @protected
* @param {*} item
* @returns {*}
* @memberof AppHeaderMenus
*/
protected renderIcon(item: any): any {
if (item) {
if (item.icon && !Object.is(item.icon, '')) {
return <div class="app-menu-item-img">
<img src={item.icon} />
</div>;
} else if (item.iconcls && !Object.is(item.iconcls, '')) {
return <div class="app-menu-item-icon">
<i class={item.iconcls} aria-hidden="true" />
</div>;
}
}
}
/**
* 绘制左侧模式菜单项
*
* @protected
* @param {*} item
* @returns {*}
* @memberof AppMenus
*/
protected renderMenuItem(item: any): any {
return <el-menu-item index={item.id} on-click={() => this.menuActive(item)}>
{this.renderIcon(item)}
<span slot="title">{item.text}</span>
</el-menu-item>
}
/**
* 绘制左侧模式子菜单
*
* @protected
* @param {*} item
* @returns {*}
* @memberof AppMenus
*/
protected renderSubMenu(item: any): any {
return <el-submenu index={item.id}>
<template slot="title">
{this.renderIcon(item)}
<span>{item.text}</span>
</template>
{item.items.map((item: any) => {
return this.renderMenuItem(item);
})}
</el-submenu>;
}
/**
* 绘制Left模式菜单
*
* @protected
* @returns {*}
* @memberof AppMenus
*/
protected renderLeftModeMenu(): any {
return <div class="app-menus-vertical-wrapper">
<el-menu class="app-menus-vertical" default-active={this.defaultActive}>
{this.menus.map((item: any) => {
if (item.hidden) {
return;
}
if (item.items && item.items.length > 0) {
return this.renderSubMenu(item);
}
return this.renderMenuItem(item);
})}
</el-menu>
</div>;
}
/**
* 绘制菜单内容
*
* @returns {*}
* @memberof AppMenu
*/
public render(): any {
if (Object.is(this.menuAlign, 'LEFT')) {
return this.renderLeftModeMenu();
}
return <div class="app-menus">
<div class="app-menus-content">
<ul class="app-menu-list">
{this.menus.map((item: any) => {
return <li class="app-menu-item" on-click={() => this.menuClick(item)}>
{this.renderIcon(item)}
<div class="app-menu-item-text">{item.text}</div>
</li>;
})}
</ul>
</div>
</div>;
}
}
\ No newline at end of file
.crm-app-user-info {
width: 100%;
height: 100%;
display: flex;
align-items: center;
cursor: pointer;
>.user-head-sculpture {
width: 32px;
height: 32px;
border-radius: 50%;
border: 1px solid #8893a7;
font-size: 18px;
font-weight: 900;
text-align: center;
}
>span {
display: inline-block;
margin-left: 3px;
margin-top: 3px;
}
}
\ No newline at end of file
import { Vue, Component } from 'vue-property-decorator';
import './app-user-info.less';
/**
* 用户信息展示
*
* @export
* @class AppUserInfo
* @extends {Vue}
*/
@Component({})
export class AppUserInfo extends Vue {
/**
* 绘制用户信息内容
*
* @returns {*}
* @memberof AppUserInfo
*/
public render(): any {
return <div class="crm-app-user-info">
<div class="user-head-sculpture">
</div>
<span>
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAAUCAYAAACqJ5zlAAAAN0lEQVQoU2PsmLzCk5Hh/0wGBgaG/wyM6Yydk5c/+s/AIAsSYGRgeIwpgKEFpBQZMJIhMIzcAQAhOjo7JEcKTQAAAABJRU5ErkJggg=="></img>
</span>
</div>;
}
}
\ No newline at end of file
.debug-actions {
position: absolute;
top: 0px;
left: 50%;
z-index: 10000;
text-align: center;
transition: all 0.3s;
margin-top: -32px;
>.actions {
.ivu-btn {
width: 100%;
}
}
>.show-buttons {
width: 100%;
height: 18px;
border-width: 0px 1px 1px 1px;
border-style: solid;
border-color: #8893a7;
text-align: center;
color: #8893a7;
cursor: pointer;
>.button {
margin-top: -5px;
}
}
}
.debug-actions:hover {
margin-top: 0px;
}
\ No newline at end of file
import { Vue, Component } from 'vue-property-decorator';
import { StudioActionController } from '@/crm-core/core/base/StudioActionController';
import { Environment } from '@/environments/environment';
import './debug-actions.less';
/**
* 开发模式控制行为组
*
* @export
* @class DebugActions
* @extends {Vue}
*/
@Component({})
export class DebugActions extends Vue {
/**
* 配置平台操作控制器
*
* @type {StudioActionController}
* @memberof DebugActions
*/
public sdc: StudioActionController = StudioActionController.getInstance();
/**
* 绘制内容
*
* @memberof DebugActions
*/
public render(): any {
return Environment.devMode ? <div class="debug-actions">
<div class="actions">
<button-group vertical>
<i-button title="开启配置模式" type={this.sdc.isShowTool ? 'warning' : 'info'} ghost on-click={() => this.sdc.showToolChange()} icon={this.sdc.isShowTool ? 'ios-bug' : 'ios-bug-outline'} ></i-button>
</button-group>
</div>
<div class="show-buttons">
<div class="button"><i class="ivu-icon ivu-icon-ios-arrow-down" /></div>
</div>
</div> : null;
}
}
\ No newline at end of file
.view-go-back {
width: 50px;
height: 52px;
font-size: 26px;
text-align: center;
color: #304265;
cursor: pointer;
border-right: 1px solid rgba(224, 227, 233, 0.7);
margin-right: 10px;
margin-top: -6px;
margin-left: -6px;
margin-bottom: -6px;
>i {
margin-top: 12px;
}
}
.view-go-back:hover {
background: rgba(204,214,229,.22);
}
\ No newline at end of file
import { Vue, Component } from 'vue-property-decorator';
import './go-back-button.less';
/**
* 通用级工具栏返回
*
* @export
* @class GoBackButton
* @extends {Vue}
*/
@Component({})
export class GoBackButton extends Vue {
/**
* 路由返回
*
* @protected
* @memberof GoBackButton
*/
protected back(): void {
this.$router.back();
}
/**
* 绘制返回按钮
*
* @returns {*}
* @memberof GoBackButton
*/
public render(): any {
return <div class="view-go-back" on-click={() => this.back()}>
<i class="el-icon-back"/>
</div>;
}
}
\ No newline at end of file
import { Subject, Observable } from 'rxjs';
/**
* 模态面包屑导航服务
*
* @export
* @class ModalBreadcrumbService
*/
export class ModalBreadcrumbService {
/**
* 数据变更订阅
*
* @protected
* @type {Subject<any>}
* @memberof ModalBreadcrumbService
*/
protected subject: Subject<any> = new Subject();
/**
* 当前模态打开视图列表
*
* @protected
* @type {any[]}
* @memberof ModalBreadcrumbService
*/
protected viewList: any[] = [];
/**
* 项激活事件
*
* @protected
* @type {Subject<any>}
* @memberof ModalBreadcrumbService
*/
protected breadcrumbActiveSubject: Subject<any> = new Subject();
/**
* 设置激活项
*
* @param {number} index
* @memberof ModalBreadcrumbService
*/
public breadcrumbActive(index: number): void {
this.breadcrumbActiveSubject.next(index);
}
/**
* 订阅激活事件
*
* @returns {Observable<any>}
* @memberof ModalBreadcrumbService
*/
public subBreadcrumbActive(): Observable<any> {
return this.breadcrumbActiveSubject.asObservable();
}
/**
* 打开视图列表变更
*
* @returns {Observable<any>}
* @memberof ModalBreadcrumbService
*/
public change(): Observable<any> {
return this.subject.asObservable();
}
/**
* 设置视图列表
*
* @param {any[]} list
* @memberof ModalBreadcrumbService
*/
public setViewList(list: any[]): void {
this.viewList = list;
}
/**
* 获取视图列表
*
* @returns {any[]}
* @memberof ModalBreadcrumbService
*/
public getViewList(): any[] {
return this.viewList;
}
}
// 模态面包屑导航实例
export const modalBreadcrumbService: ModalBreadcrumbService = new ModalBreadcrumbService();
\ No newline at end of file
.modal-breadcrumb {
display: flex;
>.modal-breadcrumb-item {
font-size: 18px;
color: #304265;
>.name {
float: left;
>span:hover {
color: #107fff;
text-decoration: underline;
cursor: pointer;
}
}
>.breadcrumb {
float: left;
padding: 0px 6px;
font-weight: 900;
}
}
>.modal-breadcrumb-item.last {
>.name {
font-weight: 700 !important;
}
}
}
\ No newline at end of file
import { Vue, Component } from 'vue-property-decorator';
import { Util } from '@/utils';
import { modalBreadcrumbService } from './modal-breadcrumb-service';
import './modal-breadcrumb.less';
/**
* 模态视图面包屑导航
*
* @export
* @class ModalBreadcrumb
* @extends {Vue}
*/
@Component({})
export class ModalBreadcrumb extends Vue {
/**
* 导航数据服务实例
*
* @protected
* @type {*}
* @memberof ModalBreadcrumb
*/
protected viewList: any[] = [];
/**
* 组件创建完毕
*
* @protected
* @memberof ModalBreadcrumb
*/
protected created(): void {
this.viewList = Util.deepCopy(modalBreadcrumbService.getViewList());
}
/**
* 激活项
*
* @protected
* @param {number} i
* @memberof ModalBreadcrumb
*/
protected active(i: number): void {
modalBreadcrumbService.breadcrumbActive(i);
}
/**
* 绘制面包屑导航
*
* @returns {*}
* @memberof ModalBreadcrumb
*/
public render(): any {
return <div class="modal-breadcrumb">
{this.viewList.map((view: any, i: number) => {
const isLast: boolean = (this.viewList.length - 1) === i;
return <div class={{ 'modal-breadcrumb-item': true, 'last': isLast }} on-click={() => this.active(i)}>
<div class="name">{isLast ? view.title : <span>{view.title}</span>}</div>
{isLast ? null : <div class="breadcrumb">/</div>}
</div>;
})}
</div>;
}
}
\ No newline at end of file
.studio-config-container {
position: absolute;
top: 10px;
right: 30px;
z-index: 1;
background: rgba(22, 22, 22, 0.6);
border-radius: 5px;
display: flex;
>.title {
color: white;
border-right: 1px solid #333;
padding: 5px;
text-align: center;
>.ivu-tooltip {
cursor: help;
margin-right: 3px;
}
}
>.actions {
.ivu-btn {
padding: 0px 8px;
}
}
}
\ No newline at end of file
import { Component, Vue, Prop } from 'vue-property-decorator';
import { StudioActionController } from '@/crm-core/core/base/StudioActionController';
import { Environment } from '@/environments/environment';
import './view-config-actions.less';
/**
* 视图快捷配置
*
* @export
* @class ViewConfigActions
* @extends {Vue}
*/
@Component({})
export class ViewConfigActions extends Vue {
/**
* 视图名称
*
* @type {string}
* @memberof ViewConfigActions
*/
@Prop({ default: () => { } })
public viewName!: string;
/**
* 视图标题
*
* @type {string}
* @memberof ViewConfigActions
*/
@Prop({ default: '' })
public viewTitle!: string;
/**
* 视图配置信息
*
* @protected
* @type {*}
* @memberof ViewConfigActions
*/
protected config: any = {};
/**
* 配置平台操作控制器
*
* @type {StudioActionController}
* @memberof ViewConfigActions
*/
public sdc: StudioActionController = StudioActionController.getInstance();
/**
* 触发配置
*
* @protected
* @memberof AppLayout
*/
protected configView(): void {
this.sdc.openStudioConfigView(this.viewName);
}
/**
* 新建issues
*
* @protected
* @memberof AppLayout
*/
protected createIssues(): void {
this.sdc.createdIssues(this.viewName);
}
/**
* 组件创建完毕
*
* @protected
* @returns {Promise<void>}
* @memberof ViewConfigActions
*/
protected async created(): Promise<void> {
if (Environment.devMode) {
this.config = await this.sdc.getConfig(this.viewName);
}
}
/**
* 绘制内容
*
* @returns {*}
* @memberof ViewConfigActions
*/
public render(): any {
return Environment.devMode ? <div v-show={this.sdc.isShowTool} class="studio-config-container">
<div class="title">
<tooltip content={this.config.memo || '无备注'} placement="bottom-end">
<icon type="ios-bulb-outline" />
</tooltip>
{this.viewTitle}
</div>
<div class="actions">
<button-group>
<i-button title="进入当前视图配置界面" type="text" icon="ios-hammer" ghost on-click={() => this.configView()}>配置</i-button>
<i-button title="建立当前界面的issues" type="text" icon="ios-browsers" ghost on-click={() => this.createIssues()}>新建issues</i-button>
</button-group>
</div>
</div> : null;
}
}
\ No newline at end of file
import Vue from 'vue';
import { Http } from '@/utils';
import { Environment } from '@/environments/environment';
import { on } from '@/utils/dom/dom';
/**
* Studio Debug控制器
*
* @export
* @class StudioActionController
*/
export class StudioActionController {
/**
* 唯一实例
*
* @private
* @static
* @type {StudioActionController}
* @memberof StudioActionController
*/
private static readonly instance: StudioActionController = new StudioActionController();
/**
* 是否启用
*
* @protected
* @type {boolean}
* @memberof StudioActionController
*/
protected isEnable: boolean = Environment.devMode;
/**
* 请求对象
*
* @protected
* @type {Http}
* @memberof StudioActionController
*/
protected http: Http = Http.getInstance();
/**
* 配置信息
*
* @protected
* @type {*}
* @memberof StudioActionController
*/
protected config: any = null;
/**
* 配置平台界面
*
* @protected
* @type {Window}
* @memberof StudioActionController
*/
protected studioWin: Window | null = null;
/**
* 是否显示开发配置工具栏
*
* @type {boolean}
* @memberof StudioActionController
*/
public isShowTool: boolean = false;
/**
* Creates an instance of StudioActionController.
* @memberof StudioActionController
*/
constructor() {
if (StudioActionController.instance) {
return StudioActionController.instance;
}
if (Environment.devMode) {
on(window, 'keydown', (e: KeyboardEvent) => {
if ((e.ctrlKey || e.metaKey) && e.keyCode === 123) {
this.showToolChange();
}
});
}
}
/**
* 为当前视图建立issues
*
* @param {string} viewName
* @returns {Promise<void>}
* @memberof StudioActionController
*/
public async createdIssues(viewName: string): Promise<void> {
const config: any = await this.getConfig(viewName);
if (config) {
const context: string = `视图模块:${config.viewmodule}\n视图抬头: ${config.title}\n视图标题: ${config.caption}\n视图标识:${config.viewname}\n视图类型:${config.viewtype}\n`;
window.open(`${Environment.ProjectUrl}/issues/new?issue[title]=${encodeURIComponent('问题')}&issue[description]=${encodeURIComponent(context)}`, '_blank');
}
}
/**
* 打开Studio配置界面
*
* @param {string} viewName
* @returns {Promise<void>}
* @memberof StudioActionController
*/
public async openStudioConfigView(viewName: string): Promise<void> {
const config: any = await this.getConfig(viewName);
if (config) {
const params: any = {
"appType": "APPSTUDIO",
"appKey": Environment.AppId,
"dataType": "AppDesign_PSAppViewDesignRedirectView",
"srfkey": config.viewtag
};
if (this.studioWin && this.studioWin.closed === false) {
this.studioWin.postMessage({
type: 'OpenView',
params
}, '*');
Vue.prototype.$message.warning('请在已打开的配置平台查看!');
} else {
this.studioWin = window.open(`${Environment.StudioUrl}?ov=${encodeURIComponent(JSON.stringify(params))}#/common_slnindex/srfkeys=${Environment.SlnId}/sysdesign_psdevslnsysmodeltreeexpview/srfkey=${Environment.SysId}`, '_blank');
}
}
}
/**
* 获取视图配置参数
*
* @param {string} viewName
* @returns {Promise<any>}
* @memberof StudioActionController
*/
public async getConfig(viewName: string): Promise<any> {
if (!this.config) {
await this.loadConfig();
}
return this.config[viewName];
}
/**
* 加载配置信息
*
* @protected
* @returns {Promise<void>}
* @memberof StudioActionController
*/
protected async loadConfig(): Promise<void> {
const response: any = await this.http.get('./view-config/view-config.json');
if (response && response.status === 200 && response.data) {
this.config = response.data;
} else {
console.warn('Studio操作控制器,视图参数信息加载失败!');
}
}
/**
* 展示配置工具栏状态变更
*
* @memberof StudioActionController
*/
public showToolChange(): void {
this.isShowTool = !this.isShowTool;
}
/**
* 获取实例
*
* @static
* @returns {StudioActionController}
* @memberof StudioActionController
*/
public static getInstance(): StudioActionController {
return this.instance;
}
}
\ No newline at end of file
/**
* Vue多层继承生命周期处理
*
* @export
* @param {*} constructor
* @returns {*}
*/
export function VueLifeCycleProcessing(constructor: any): any {
// 原型
const p = constructor.prototype;
// 方法名数组
const methodNames: string[] = ['beforeCreate', 'created', 'beforeMount', 'mounted', 'beforeUpdate', 'updated', 'activated', 'deactivated', 'beforeDestroy', 'destroyed', 'errorCaptured'];
methodNames.forEach((name: string) => {
if (!p.hasOwnProperty(name) && p[name]) {
p[name] = function () {
if (this[name]) {
this[name]();
}
}
}
});
if (!p.hasOwnProperty('render') && p.render) {
p.render = function (h: any) {
if (this.render) {
return this.render(h);
}
}
}
}
\ No newline at end of file
.crm-modal {
position: absolute;
top: 0px;
left: 0px;
height: 100vh;
z-index: 100;
transition: all 0.5s;
// 滚动条宽度
::-webkit-scrollbar {
width: 6px;
height: 6px;
background: transparent;
}
// 滚动槽
::-webkit-scrollbar-track {
border-radius: 0;
box-shadow: none;
border: 0;
}
// 滚动条滑块
::-webkit-scrollbar-thumb {
border-radius: 0;
box-shadow: none;
border: 0;
background-color: var(--app-scroll-bar-color);
}
>.crm-modal-item {
position: absolute;
height: 100vh;
width: 100vw;
top: 0px;
left: 0px;
right: 0px;
z-index: 1;
}
.view-content-wrapper {
padding: 0px 10px;
}
}
.crm-modal {
>.crm-modal-item {
.crm-app-view-header-wrapper {
border-bottom: 1px solid #EBEEF5;
}
>.view-container {
>.crm-app-content-container {
>.view-content-wrapper {
>.tabviewpanel {
>.tabexppanel.ivu-tabs {
>.ivu-tabs-bar {
display: flex;
justify-content: center;
border-bottom: none;
}
}
}
}
}
}
}
}
\ No newline at end of file
import { Vue, Component } from 'vue-property-decorator';
import { CreateElement } from 'vue/types/umd';
import { Subject, Observable } from 'rxjs';
import { Util } from '@/utils';
import { on } from '@/utils/dom/dom';
import store from '@/store';
import i18n from '@/locale';
import { ModalBreadcrumbService, modalBreadcrumbService } from '@/crm-core/components/modal-breadcrumb/modal-breadcrumb-service';
import './crm-drawer.less';
/**
* 模态承载组件
*
* @export
* @class CrmModal
* @extends {Vue}
*/
@Component({})
export class CrmModal extends Vue {
/**
* 导航数据服务实例
*
* @protected
* @type {ModalBreadcrumbService}
* @memberof ModalBreadcrumb
*/
protected mbs: ModalBreadcrumbService = modalBreadcrumbService;
/**
* 已呈现视图列表
*
* @protected
* @type {any[]}
* @memberof CrmModal
*/
protected viewList: any[] = [];
/**
* 关闭模态数据传递
*
* @protected
* @type {*}
* @memberof CrmModal
*/
protected closeModalData: any;
/**
* 待关闭视图
*
* @protected
* @type {any[]}
* @memberof CrmModal
*/
protected toBeClosedViews: any[] = [];
/**
* 是否展示模态
*
* @protected
* @type {boolean}
* @memberof CrmModal
*/
protected isShow: boolean = false;
/**
* 视图层级
*
* @protected
* @type {number}
* @memberof CrmModal
*/
protected zIndex: number = 100;
/**
* 组件创建完毕
*
* @protected
* @memberof CrmModal
*/
protected created(): void {
this.mbs.subBreadcrumbActive().subscribe((i: number) => {
this.toBeClosedViews = [];
for (let index = i + 1; index < this.viewList.length - 1; index++) {
this.toBeClosedViews.push({
viewname: this.viewList[index].viewname,
index: index
});
}
this.refCloseView(this.viewList[this.viewList.length - 1], this.viewList.length - 1);
});
on(document, 'keydown', ($event: KeyboardEvent) => {
if ($event && $event.keyCode === 27 && this.viewList.length > 0) {
this.refCloseView(this.viewList[this.viewList.length - 1], this.viewList.length - 1);
}
});
}
/**
* 使用实例方法关闭视图
*
* @protected
* @param {*} view
* @param {number} i
* @returns {*}
* @memberof CrmModal
*/
protected refCloseView(view: any, i: number): any {
const ref: any = this.$refs[view.viewname + i];
if (ref && ref.closeView) {
ref.closeView();
}
}
/**
* 打开模态视图
*
* @param {*} [param={}]
* @returns {Promise<any>}
* @memberof CrmModal
*/
public openModal(param: any = {}): Promise<any> {
return new Promise((resolve: (res: any) => void) => {
if (!this.isShow) {
const zIndex: number = this.$store.getters.getZIndex();
if (zIndex) {
this.zIndex = zIndex + 100;
this.$store.commit('updateZIndex', this.zIndex);
}
setTimeout(() => this.isShow = true, 50);
}
this.viewList.push(Object.assign(Util.deepCopy(param), { resolve }));
this.mbs.setViewList(this.viewList);
});
}
/**
* 关闭模态视图
*
* @memberof CrmModal
*/
public closeView(item: any): void {
if (this.closeModalData) {
item.resolve({ ret: 'OK', datas: this.closeModalData});
} else {
item.resolve({ ret: '', datas: this.closeModalData});
}
this.viewList.pop();
if (this.toBeClosedViews.length > 0) {
const view: any = this.toBeClosedViews[this.toBeClosedViews.length - 1];
const viewname: string = view.viewname;
const i: number = view.index;
this.toBeClosedViews.pop();
this.refCloseView({ viewname }, i);
}
}
/**
* 绘制模态内容
*
* @returns {*}
* @memberof CrmModal
*/
public render(h: CreateElement): any {
return <div class="crm-modal" key="crm-modal" style={{ 'z-index': this.zIndex, 'margin-top': this.isShow ? '0px' : '-100vh' }}>
{
this.viewList.map((view: any, i: number) => {
const props: any = { openMode: 'MODAL', viewDefaultUsage: false, viewdata: JSON.stringify(view.viewdata), viewparams: view.viewparams };
const style: any = { 'z-index': i + 1 };
return <div class="crm-modal-item">
{h(view.viewname, {
key: view.viewname + i,
ref: view.viewname + i,
style,
props,
on: {
viewdataschange: (data: any) => this.closeModalData = data,
close: () => {
if (this.viewList.length === 1) {
this.isShow = false;
setTimeout(() => this.closeView(view), 500);
} else {
this.closeView(view);
}
}
}
})}
</div>;
})
}
</div>;
}
}
/**
* 模态
*
* @export
* @class CrmDrawerController
*/
export class CrmDrawerController {
/**
* 唯一实例
*
* @protected
* @static
* @type {CrmDrawerController}
* @memberof CrmDrawerController
*/
protected static readonly instance: CrmDrawerController = new CrmDrawerController();
/**
* 模态承载容器
*
* @protected
* @type {HTMLDivElement}
* @memberof CrmDrawerController
*/
protected modalContainer: HTMLDivElement;
/**
* Vue实例
*
* @protected
* @type {*}
* @memberof CrmDrawerController
*/
protected vueInstance!: any;
/**
* Creates an instance of CrmDrawerController.
* @memberof CrmDrawerController
*/
constructor() {
this.modalContainer = document.createElement('div');
document.body.appendChild(this.modalContainer);
}
/**
* 初始化
*
* @protected
* @memberof CrmDrawerController
*/
protected init(): void {
this.vueInstance = new Vue({
i18n,
store,
render: (h: any) => h(CrmModal, { ref: 'crmModal' })
}).$mount(this.modalContainer);
}
/**
* 顶部抽屉模式打开视图
*
* @param {{ viewname: string, title: string, width?: number, height?: number }} view 视图
* @param {*} [viewParam={}] 视图参数
* @param {any[]} deResParameters 关系实体参数对象
* @param {any[]} parameters 当前应用视图参数对象
* @param {any[]} args 多项数据
* @param {*} [data={}] 行为参数
* @returns {Observable<any>}
* @memberof CrmDrawerController
*/
public openDrawer(view: { viewname: string, title: string, width?: number, height?: number, placement?: string }, context: any, data: any = {}): Observable<any> {
const subject: Subject<any> = new Subject();
this.getVueInstance().$refs.crmModal.openModal({ ...view, viewdata: Util.deepCopy(context), viewparams: data }).then((data: any) => {
subject.next(data);
subject.complete();
subject.unsubscribe();
});
return subject.asObservable();
}
/**
* 获取Vue容器实例
*
* @protected
* @returns {*}
* @memberof CrmDrawerController
*/
protected getVueInstance(): any {
if (!this.vueInstance) {
this.init();
}
return this.vueInstance;
}
}
// 模态服务控制器实例
export const crmDrawerController: CrmDrawerController = new CrmDrawerController();
\ No newline at end of file
import { CalendarViewBase } from './CalendarViewBase';
/**
* 日历导航视图基类
*
* @export
* @class CalendarExpViewBase
* @extends {ViewBase}
*/
export class CalendarExpViewBase extends CalendarViewBase {
}
\ No newline at end of file
import { CalendarViewBase } from './CalendarViewBase';
/**
* 日历部件视图基类
*
* @export
* @class CalendarView9Base
* @extends {CalendarViewBase}
*/
export class CalendarView9Base extends CalendarViewBase {
}
\ No newline at end of file
import { MDViewBase } from './MDViewBase';
/**
* 日历视图基类
*
* @export
* @class CalendarViewBase
* @extends {MDViewBase}
*/
export class CalendarViewBase extends MDViewBase {
}
\ No newline at end of file
import { ChartViewBase } from './ChartViewBase';
/**
* 图表视图基类
*
* @export
* @class ChartView9Base
* @extends {ChartViewBase}
*/
export class ChartView9Base extends ChartViewBase {
}
\ No newline at end of file
import { MDViewBase } from './MDViewBase';
/**
* 图表视图基类
*
* @export
* @class ChartViewBase
* @extends {MDViewBase}
*/
export class ChartViewBase extends MDViewBase {
}
\ No newline at end of file
import { DashboardViewBase } from './DashboardViewBase';
/**
* 看板视图部件视图基类
*
* @export
* @class DashboardView9Base
* @extends {DashboardViewBase}
*/
export class DashboardView9Base extends DashboardViewBase {
}
\ No newline at end of file
import { ViewBase } from './ViewBase';
/**
* 看板视图基类
*
* @export
* @class DashboardViewBase
* @extends {ViewBase}
*/
export class DashboardViewBase extends ViewBase {
}
\ No newline at end of file
import { MDViewBase } from './MDViewBase';
/**
* 数据部件视图基类
*
* @export
* @class DataView9Base
* @extends {MDViewBase}
*/
export class DataView9Base extends MDViewBase {
}
\ No newline at end of file
import { MDViewBase } from './MDViewBase';
/**
* 数据视图基类
*
* @export
* @class DataViewBase
* @extends {MDViewBase}
*/
export class DataViewBase extends MDViewBase {
}
\ No newline at end of file
import { DataViewBase } from './DataViewBase';
/**
* 数据视图基类
*
* @export
* @class DataViewExpViewBase
* @extends {MDViewBase}
*/
export class DataViewExpViewBase extends DataViewBase {
}
\ No newline at end of file
import { EditViewBase } from './EditViewBase';
/**
* 编辑视图(左右关系)基类
*
* @export
* @class EditView2Base
* @extends {EditViewBase}
*/
export class EditView2Base extends EditViewBase {
}
\ No newline at end of file
import { EditViewBase } from './EditViewBase';
/**
* 编辑视图(分页关系)基类
*
* @export
* @class EditView3Base
* @extends {EditViewBase}
*/
export class EditView3Base extends EditViewBase {
}
\ No newline at end of file
import { EditViewBase } from './EditViewBase';
/**
* 编辑视图(上下关系)基类
*
* @export
* @class EditView4Base
* @extends {EditViewBase}
*/
export class EditView4Base extends EditViewBase {
}
\ No newline at end of file
import { EditViewBase } from './EditViewBase';
/**
* 编辑部件视图基类
*
* @export
* @class EditView9Base
* @extends {EditViewBase}
*/
export class EditView9Base extends EditViewBase {
}
\ No newline at end of file
import { ViewBase } from './ViewBase';
/**
* 编辑视图基类
*
* @export
* @class EditViewBase
* @extends {ViewBase}
*/
export class EditViewBase extends ViewBase {
}
\ No newline at end of file
import { ViewBase } from './ViewBase';
/**
* 实体表单选择数据视图(部件视图)基类
*
* @export
* @class FormPickupDataViewBase
* @extends {ViewBase}
*/
export class FormPickupDataViewBase extends ViewBase {
}
\ No newline at end of file
import { ViewBase } from './ViewBase';
/**
* 实体表格导航视图基类
*
* @export
* @class GridExpViewBase
* @extends {ViewBase}
*/
export class GridExpViewBase extends ViewBase {
}
\ No newline at end of file
import { GridViewBase } from './GridViewBase';
/**
* 表格部件视图基类
*
* @export
* @class GridView9Base
* @extends {GridViewBase}
*/
export class GridView9Base extends GridViewBase {
}
\ No newline at end of file
import { MDViewBase } from './MDViewBase';
/**
* 表格视图基类
*
* @export
* @class GridViewBase
* @extends {MDViewBase}
*/
export class GridViewBase extends MDViewBase {
}
\ No newline at end of file
import { MDViewBase } from './MDViewBase';
/**
* 实体索引关系选择数据视图(部件视图)基类
*
* @export
* @class IndexPickupDataViewBase
* @extends {MDViewBase}
*/
export class IndexPickupDataViewBase extends MDViewBase {
}
\ No newline at end of file
import { ViewBase } from './ViewBase';
import { Emit } from 'vue-property-decorator';
/**
* 首页视图基类
*
* @export
* @class IndexViewBase
* @extends {ViewBase}
*/
export class IndexViewBase extends ViewBase {
/**
* 数据变化
*
* @param {*} val
* @returns {*}
* @memberof ${srfclassname('${view.name}')}Base
*/
@Emit()
public viewDatasChange(val: any):any {
return val;
}
/**
* 父数据对象
*
* @protected
* @type {*}
* @memberof IndexViewBase
*/
protected srfparentdata: any = {};
/**
* 顶部菜单项
*
* @protected
* @type {any[]}
* @memberof IndexViewBase
*/
protected topMenus: any[] = [];
/**
* Vue声明周期(组件初始化完毕)
*
* @memberof IndexViewBase
*/
public mounted() {
super.mounted();
this.viewState.next({ tag: "appmenu", action: "load", data: {} });
this.$viewTool.setIndexParameters([
{ pathName: "index", parameterName: "index" }
]);
}
/**
* 应用菜单项变更
*
* @protected
* @param {any[]} menus
* @memberof IndexViewBase
*/
protected appMenusChange(menus: any[]): void {
if (menus) {
const item: any = menus.find((item: any) => Object.is(item.name, 'HomeTopMenus'));
if (item && item.items) {
this.topMenus = item.items;
this.topMenus.forEach((item: any) => {
item.caption = item.text;
item.disabled = false;
item.visabled = true;
});
}
}
}
/**
* 顶部菜单项点击
*
* @protected
* @param {*} menu
* @memberof IndexViewBase
*/
protected topMenuClick(menu: any): void {
if (menu && this.$refs.appmenu) {
(this.$refs.appmenu as any).click(menu);
}
}
}
\ No newline at end of file
import { ListViewBase } from './ListViewBase';
/**
* 列表导航视图基类
*
* @export
* @class ListExpViewBase
* @extends {ListViewBase}
*/
export class ListExpViewBase extends ListViewBase {
}
\ No newline at end of file
import { ListViewBase } from './ListViewBase';
/**
* 列表部件视图基类
*
* @export
* @class ListView9Base
* @extends {ListViewBase}
*/
export class ListView9Base extends ListViewBase {
}
\ No newline at end of file
import { MDViewBase } from './MDViewBase';
/**
* 列表视图基类
*
* @export
* @class ListViewBase
* @extends {MDViewBase}
*/
export class ListViewBase extends MDViewBase {
}
\ No newline at end of file
import { ViewBase } from './ViewBase';
/**
* 多数据视图基类
*
* @export
* @class MDViewBase
* @extends {ViewBase}
*/
export class MDViewBase extends ViewBase {
}
\ No newline at end of file
import { ViewBase } from './ViewBase';
/**
* 实体多表单编辑视图基类
*
* @export
* @class MEditView9Base
* @extends {ViewBase}
*/
export class MEditView9Base extends ViewBase {
}
\ No newline at end of file
import { ViewBase } from './ViewBase';
/**
* 多项数据选择视图基类
*
* @export
* @class MPickupViewBase
* @extends {ViewBase}
*/
export class MPickupViewBase extends ViewBase {
}
\ No newline at end of file
import { ViewBase } from './ViewBase';
/**
* 列表视图基类
*
* @export
* @class OptionViewBase
* @extends {MDViewBase}
*/
export class OptionViewBase extends ViewBase {
}
\ No newline at end of file
import { ViewBase } from './ViewBase';
/**
* 选择表格视图基类
*
* @export
* @class PickupGridViewBase
* @extends {ViewBase}
*/
export class PickupGridViewBase extends ViewBase {
}
\ No newline at end of file
import { MDViewBase } from './MDViewBase';
/**
* 实体选择树视图(部件视图)基类
*
* @export
* @class PickupTreeViewBase
* @extends {MDViewBase}
*/
export class PickupTreeViewBase extends MDViewBase {
}
\ No newline at end of file
import { MDViewBase } from './MDViewBase';
/**
* 数据选择视图(分页关系)基类
*
* @export
* @class PickupView3Base
* @extends {MDViewBase}
*/
export class PickupView3Base extends MDViewBase {
}
\ No newline at end of file
import { ViewBase } from './ViewBase';
/**
* 数据选择视图基类
*
* @export
* @class PickupViewBase
* @extends {ViewBase}
*/
export class PickupViewBase extends ViewBase {
}
\ No newline at end of file
import { ViewBase } from './ViewBase';
/**
* 门户视图基类
*
* @export
* @class PortalViewBase
* @extends {ViewBase}
*/
export class PortalViewBase extends ViewBase {
/**
* 组件挂载完毕
*
* @memberof PortalViewBase
*/
public mounted(): void {
super.mounted();
this.viewState.next({ tag: 'dashboard', action: 'load', data: {} });
}
}
\ No newline at end of file
import { ViewBase } from './ViewBase';
/**
* 分页导航视图基类
*
* @export
* @class TabExpViewBase
* @extends {ViewBase}
*/
export class TabExpViewBase extends ViewBase {
}
\ No newline at end of file
import { ViewBase } from './ViewBase';
/**
* 实体分页表单(嵌入)视图基类
*
* @export
* @class TabFormView9Base
* @extends {ViewBase}
*/
export class TabFormView9Base extends ViewBase {
}
\ No newline at end of file
import { MDViewBase } from './MDViewBase';
/**
* 树导航视图基类
*
* @export
* @class TreeExpViewBase
* @extends {MDViewBase}
*/
export class TreeExpViewBase extends MDViewBase {
}
\ No newline at end of file
import { MDViewBase } from './MDViewBase';
/**
* 树部件视图基类
*
* @export
* @class TreeView9Base
* @extends {MDViewBase}
*/
export class TreeView9Base extends MDViewBase {
}
\ No newline at end of file
import { MDViewBase } from './MDViewBase';
/**
* 树视图基类
*
* @export
* @class TreeViewBase
* @extends {MDViewBase}
*/
export class TreeViewBase extends MDViewBase {
}
\ No newline at end of file
import { Vue, Prop, Watch } from 'vue-property-decorator';
import { Subject } from 'rxjs';
/**
* 视图基类
*
* @export
* @class ViewBase
* @extends {Vue}
*/
export class ViewBase extends Vue {
/**
* 视图状态订阅对象
*
* @private
* @type {Subject<{action: string, data: any}>}
* @memberof ViewBase
*/
protected viewState: Subject<ViewState> = new Subject();
/**
* 视图标识
*
* @type {string}
* @memberof ViewBase
*/
protected viewtag: string = '';
/**
* 当前视图上下文
*
* @type {*}
* @memberof ViewBase
*/
protected context: any = {};
/**
* 视图参数
*
* @type {*}
* @memberof ViewBase
*/
protected viewparams: any = {};
/**
* 视图默认引擎
*
* @protected
* @type {*}
* @memberof ViewBase
*/
protected engine: any;
/**
* 视图打开模式
*
* @protected
* @type {('DEFAULT' | 'MODAL')}
* @memberof ViewBase
*/
@Prop({ default: 'DEFAULT' })
protected openMode!: 'DEFAULT' | 'MODAL';
/**
* 视图默认使用
*
* @type {boolean}
* @memberof ViewBase
*/
@Prop({ default: true })
protected viewDefaultUsage!: boolean;
/**
* 数据视图
*
* @type {string}
* @memberof ViewBase
*/
@Prop()
protected viewdata!: string;
/**
* 处理值变化
*
* @param {*} newVal
* @param {*} oldVal
* @memberof ViewBase
*/
@Watch("viewdata")
protected onViewData(newVal: any, oldVal: any): void {
if (!Object.is(newVal, oldVal) && this.engine) {
this.parseViewParam();
this.engine.load();
}
}
/**
* 传入视图参数
*
* @protected
* @type {*}
* @memberof ViewBase
*/
@Prop()
protected viewparam: any;
/**
* 视图参数变化
*
* @param {*} newVal
* @param {*} oldVal
* @memberof ViewBase
*/
@Watch('viewparam', { immediate: true, deep: true })
protected onParamData(newVal: any, oldVal: any): void {
if (newVal) {
for(let key in this.viewparams){
delete this.viewparams[key];
}
Object.assign(this.viewparams, JSON.parse(this.viewparam));
this.viewParamChange(newVal, oldVal);
}
}
/**
* 自定义视图导航上下文集合
*
* @type {*}
* @memberof ViewBase
*/
protected customViewNavContexts: any = {};
/**
* 自定义视图导航参数集合
*
* @type {*}
* @memberof ViewBase
*/
protected customViewParams: any = {};
/**
* 视图参数变更
*
* @protected
* @param {*} newVal
* @param {*} oldVal
* @memberof ViewBase
*/
protected viewParamChange(newVal: any, oldVal: any): void { }
/**
* Vue声明周期
*
* @memberof ViewBase
*/
public created() {
const secondtag = this.$util.createUUID();
this.$store.commit("viewaction/createdView", {
viewtag: this.viewtag,
secondtag: secondtag
});
this.viewtag = secondtag;
this.parseViewParam();
}
/**
* Vue声明周期(组件初始化完毕)
*
* @memberof ViewBase
*/
public mounted() {
this.engineInit();
this.loadModel();
this.$viewTool.setIndexViewParam(this.context);
this.viewMounted();
}
/**
* 视图组件挂载完毕
*
* @protected
* @memberof ViewBase
*/
protected viewMounted(): void { }
/**
* 销毁之前
*
* @memberof ViewBase
*/
public beforeDestroy() {
this.$store.commit("viewaction/removeView", this.viewtag);
}
/**
* 是否为默认类型视图
*
* @protected
* @returns {boolean}
* @memberof ViewBase
*/
protected isDefaultView(): boolean {
return Object.is(this.openMode, 'DEFAULT');
}
/**
* 是否为模态类型视图
*
* @protected
* @returns {boolean}
* @memberof ViewBase
*/
protected isModalView(): boolean {
return Object.is(this.openMode, 'MODAL');
}
/**
* 引擎初始化
*
* @protected
* @memberof ViewBase
*/
protected engineInit(): void { }
/**
* 加载模型
*
* @protected
* @returns {Promise<any>}
* @memberof ViewBase
*/
protected async loadModel(): Promise<any> { }
/**
* 解析视图参数
*
* @protected
* @memberof ViewBase
*/
protected parseViewParam(): void {
for(let key in this.context){
delete this.context[key];
}
if (this.viewDefaultUsage) {
//初始化视图唯一标识
Object.assign(this.context, { srfsessionid: this.$util.createUUID() });
}
if (
!this.viewDefaultUsage &&
this.viewdata &&
!Object.is(this.viewdata, "")
) {
Object.assign(this.context, JSON.parse(this.viewdata));
if (this.context && this.context.srfparentdename) {
Object.assign(this.viewparams, { srfparentdename: this.context.srfparentdename });
}
if (this.context && this.context.srfparentkey) {
Object.assign(this.viewparams, { srfparentkey: this.context.srfparentkey });
}
this.$forceUpdate()
this.handleCustomViewData();
return;
}
const path = this.$route.matched[this.$route.matched.length - 1].path;
const keys: Array<any> = [];
const curReg = this.$pathToRegExp.pathToRegexp(path, keys);
const matchArray = curReg.exec(this.$route.path);
let tempValue: Object = {};
keys.forEach((item: any, index: number) => {
Object.defineProperty(tempValue, item.name, {
enumerable: true,
value: matchArray[index + 1]
});
});
this.$viewTool.formatRouteParams(tempValue, this.$route, this.context, this.viewparams);
if (this.$store.getters.getAppData() && this.$store.getters.getAppData().context) {
Object.assign(this.context, this.$store.getters.getAppData().context);
}
}
/**
* 处理自定义视图数据
*
* @protected
* @memberof ViewBase
*/
protected handleCustomViewData(): void {
this.handleViewRes();
if (Object.keys(this.customViewNavContexts).length > 0) {
Object.keys(this.customViewNavContexts).forEach((item: any) => {
let tempContext: any = {};
let curNavContext: any = this.customViewNavContexts[item];
this.handleCustomDataLogic(curNavContext, tempContext, item);
Object.assign(this.context, tempContext);
})
}
if (Object.keys(this.customViewParams).length > 0) {
Object.keys(this.customViewParams).forEach((item: any) => {
let tempParam: any = {};
let curNavParam: any = this.customViewParams[item];
this.handleCustomDataLogic(curNavParam, tempParam, item);
Object.assign(this.viewparams, tempParam);
})
}
}
/**
* 处理指定视图控制关系将父键转为父实体上下文
*
* @protected
* @memberof ViewBase
*/
protected handleViewRes(): void { }
/**
* 处理自定义视图数据逻辑
*
* @protected
* @param {*} curNavData
* @param {*} tempData
* @param {string} item
* @memberof ViewBase
*/
protected handleCustomDataLogic(curNavData: any, tempData: any, item: string): void {
// 直接值直接赋值
if (curNavData.isRawValue) {
if (Object.is(curNavData.value, "null") || Object.is(curNavData.value, "")) {
Object.defineProperty(tempData, item, {
value: null,
writable: true,
enumerable: true,
configurable: true
});
} else {
Object.defineProperty(tempData, item, {
value: curNavData.value,
writable: true,
enumerable: true,
configurable: true
});
}
} else {
// 先从导航上下文取数,没有再从导航参数(URL)取数,如果导航上下文和导航参数都没有则为null
if (this.context[curNavData.value]) {
Object.defineProperty(tempData, item, {
value: this.context[curNavData.value],
writable: true,
enumerable: true,
configurable: true
});
} else {
if (this.viewparams[curNavData.value]) {
Object.defineProperty(tempData, item, {
value: this.viewparams[curNavData.value],
writable: true,
enumerable: true,
configurable: true
});
} else {
Object.defineProperty(tempData, item, {
value: null,
writable: true,
enumerable: true,
configurable: true
});
}
}
}
}
/**
* 关闭视图
*
* @param {any[]} args
* @memberof IndexBase
*/
public closeView(args: any[]): void {
if (!this.viewDefaultUsage) {
this.$emit("viewdataschange", args);
this.$emit("close");
} else {
this.$router.back();
}
}
}
\ No newline at end of file
import { MDViewBase } from './MDViewBase';
/**
* 向导视图基类
*
* @export
* @class WizardViewBase
* @extends {MDViewBase}
*/
export class WizardViewBase extends MDViewBase {
}
\ No newline at end of file
import { CtrlBase } from './CtrlBase';
import { Emit } from 'vue-property-decorator';
/**
* 应用菜单基类
*
* @export
* @class AppMenusCtrlBase
* @extends {CtrlBase}
*/
export class AppMenusCtrlBase extends CtrlBase {
/**
* 菜单数据
*
* @protected
* @type {any[]}
* @memberof AppMenusCtrlBase
*/
protected menus: any[] = [];
/**
* 计数器数据
*
* @protected
* @type {*}
* @memberof AppMenusCtrlBase
*/
protected counterdata: any = {};
/**
* 菜单模型
*
* @protected
* @type {IndexMode}
* @memberof Index
*/
protected menuModel?: any;
/**
* 获取部件类型
*
* @returns {string}
* @memberof AppMenusCtrlBase
*/
public getControlType(): string {
return "APPMENU";
}
/**
* vue 生命周期
*
* @memberof AppMenusCtrlBase
*/
public created() {
if (this.viewState) {
this.viewStateEvent = this.viewState.subscribe(
({ tag, action, data }: any) => {
if (!Object.is(tag, this.name)) {
return;
}
this.load(data);
}
);
}
}
/**
* vue 生命周期
*
* @memberof AppMenusCtrlBase
*/
public destroyed() {
if (this.viewStateEvent) {
this.viewStateEvent.unsubscribe();
}
}
/**
* 获取菜单项数据
*
* @protected
* @param {any[]} items
* @param {string} name
* @returns
* @memberof AppMenusCtrlBase
*/
protected compute(items: any[], name: string) {
const item: any = {};
items.some((_item: any) => {
if (name && Object.is(_item.name, name)) {
Object.assign(item, _item);
return true;
}
if (_item.items && Array.isArray(_item.items)) {
const subItem = this.compute(_item.items, name);
if (Object.keys(subItem).length > 0) {
Object.assign(item, subItem);
return true;
}
}
return false;
});
return item;
}
/**
* 菜单项选中处理
*
* @param {*} index
* @param {any[]} indexs
* @returns
* @memberof AppMenusCtrlBase
*/
public select(index: any, indexs: any[]) {
let item = this.compute(this.menus, index);
if (Object.keys(item).length === 0) {
return;
}
this.click(item);
}
/**
* 菜单点击
*
* @protected
* @param {*} item 菜单数据
* @memberof AppMenusCtrlBase
*/
protected click(item: any) { }
/**
* 数据加载
*
* @param {*} data
* @memberof Index
*/
public load(data: any) {
this.menus = this.menuModel.getAppMenuItems();
this.menusChange();
}
/**
* 菜单变更
*
* @returns {*}
* @memberof AppMenusCtrlBase
*/
@Emit('menus-change')
public menusChange(): any {
return this.menus;
}
}
\ No newline at end of file
import { Vue, Prop } from 'vue-property-decorator';
import { Subject, Subscription } from 'rxjs';
/**
* 部件基类
*
* @export
* @class CtrlBase
* @extends {Vue}
*/
export class CtrlBase extends Vue {
/**
* 名称
*
* @type {string}
* @memberof CtrlBase
*/
@Prop()
public name?: string;
/**
* 视图通讯对象
*
* @type {Subject<ViewState>}
* @memberof CtrlBase
*/
@Prop()
public viewState!: Subject<ViewState>;
/**
* 应用上下文
*
* @type {*}
* @memberof CtrlBase
*/
@Prop()
public context: any;
/**
* 视图参数
*
* @type {*}
* @memberof CtrlBase
*/
@Prop()
public viewparams: any;
/**
* 是否显示处理提示
*
* @type {boolean}
* @memberof CtrlBase
*/
@Prop({ default: true })
public showBusyIndicator?: boolean;
/**
* 视图状态事件
*
* @protected
* @type {(Subscription | undefined)}
* @memberof CtrlBase
*/
protected viewStateEvent: Subscription | undefined;
/**
* 获取部件类型
*
* @returns {string}
* @memberof CtrlBase
*/
public getControlType(): string {
throw new Error('getControlType方法需重写');
}
/**
* 关闭视图
*
* @param {any[]} args
* @memberof CtrlBase
*/
public closeView(args: any[]): void {
this.$emit("closeview", args);
}
/**
* 获取多项数据
*
* @returns {any[]}
* @memberof CtrlBase
*/
public getDatas(): any[] {
return [];
}
/**
* 获取单项树
*
* @returns {*}
* @memberof CtrlBase
*/
public getData(): any {
return null;
}
}
\ No newline at end of file
// 视图基类
export { IndexViewBase } from './core/view/IndexViewBase';
export { GridViewBase } from './core/view/GridViewBase';
export { GridView9Base } from './core/view/GridView9Base';
export { EditViewBase } from './core/view/EditViewBase';
export { EditView9Base } from './core/view/EditView9Base';
export { DashboardViewBase } from './core/view/DashboardViewBase';
export { DashboardView9Base } from './core/view/DashboardView9Base';
export { TabExpViewBase } from './core/view/TabExpViewBase';
export { PickupViewBase } from './core/view/PickupViewBase';
export { PickupGridViewBase } from './core/view/PickupGridViewBase';
export { MPickupViewBase } from './core/view/MPickupViewBase';
export { ListViewBase } from './core/view/ListViewBase';
export { ListView9Base } from './core/view/ListView9Base';
export { CalendarViewBase } from './core/view/CalendarViewBase';
export { CalendarView9Base } from './core/view/CalendarView9Base';
export { PortalViewBase } from './core/view/PortalViewBase';
export { ChartView9Base } from './core/view/ChartView9Base';
export { ChartViewBase } from './core/view/ChartViewBase';
export { FormPickupDataViewBase } from './core/view/FormPickupDataViewBase';
export { GridExpViewBase } from './core/view/GridExpViewBase';
export { MEditView9Base } from './core/view/MEditView9Base';
export { EditView2Base } from './core/view/EditView2Base';
export { EditView3Base } from './core/view/EditView3Base';
export { EditView4Base } from './core/view/EditView4Base';
export { TabFormView9Base } from './core/view/TabFormView9Base';
export { DataView9Base } from './core/view/DataView9Base';
export { DataViewBase } from './core/view/DataViewBase';
export { PickupView3Base } from './core/view/PickupView3Base';
export { TreeExpViewBase } from './core/view/TreeExpViewBase';
export { TreeView9Base } from './core/view/TreeView9Base';
export { TreeViewBase } from './core/view/TreeViewBase';
export { PickupTreeViewBase } from './core/view/PickupTreeViewBase';
export { WizardViewBase } from './core/view/WizardViewBase';
export { CalendarExpViewBase } from './core/view/CalendarExpViewBase';
export { DataViewExpViewBase } from './core/view/DataViewExpViewBase';
export { ListExpViewBase } from './core/view/ListExpViewBase';
export { IndexPickupDataViewBase } from './core/view/IndexPickupDataViewBase';
export { OptionViewBase } from './core/view/OptionViewBase';
// 部件基类
export { AppMenusCtrlBase } from './core/widgets/AppMenusCtrlBase';
// 组件
export { AppHeaderMenus } from './components/app-header-menus/app-header-menus';
export { AppLayout } from './components/app-layout/app-layout';
export { AppMenus } from './components/app-menus/app-menus';
export { AppUserInfo } from './components/app-user-info/app-user-info';
export { GoBackButton } from './components/go-back-button/go-back-button';
export { ModalBreadcrumb } from './components/modal-breadcrumb/modal-breadcrumb';
export { DebugActions } from './components/debug-actions/debug-actions';
// 装饰器
export { VueLifeCycleProcessing } from './core/decorators/VueLifeCycleProcessing';
\ No newline at end of file
...@@ -95,6 +95,9 @@ export default class MPickupViewEngine extends ViewEngine { ...@@ -95,6 +95,9 @@ export default class MPickupViewEngine extends ViewEngine {
}); });
const _disbaled: boolean = this.view.containerModel[`view_${ctrlName}`].selections.length > 0 ? true : false; const _disbaled: boolean = this.view.containerModel[`view_${ctrlName}`].selections.length > 0 ? true : false;
this.view.containerModel.view_rightbtn = _disbaled; this.view.containerModel.view_rightbtn = _disbaled;
if(!this.view.isShowButton){
this.view.$emit('viewdataschange', [...args]);
}
} }
/** /**
......
...@@ -82,7 +82,7 @@ export default class PickupViewEngine extends ViewEngine { ...@@ -82,7 +82,7 @@ export default class PickupViewEngine extends ViewEngine {
this.view.viewSelections = [...args] this.view.viewSelections = [...args]
const _disabled: boolean = this.view.viewSelections.length > 0 ? false : true; const _disabled: boolean = this.view.viewSelections.length > 0 ? false : true;
this.view.containerModel.view_okbtn.disabled = _disabled; this.view.containerModel.view_okbtn.disabled = _disabled;
if(!this.view.ifShowButtons){ if(!this.view.isShowButton){
this.view.$emit('viewdataschange', [...args]); this.view.$emit('viewdataschange', [...args]);
} }
} }
......
export default {
"404": {
errorText1: 'sorry,the page you visited is not exist!',
errorText2: 'The page you visited is not exist,please return to',
indexPage: 'home page',
continue: 'to continue browsing',
},
"500": {
errorText1: "sorry,there's something wrong with the server!",
errorText2: "There's something wrong with the server,please return to",
indexPage: 'home page',
continue: 'to continue browsing',
},
appAutocomplete: {
error: 'Error',
miss: 'Missing parameter ',
requestException: 'Request Exception!',
},
appBuild: {
custom: 'Customize',
},
appCheckBox: {
notExist: 'codelist is not existed',
},
appColumnLink: {
error: 'error',
valueItemException:"value item exception",
rowDataException:"table row data exception",
},
appColumnRender: {
select: 'please select...',
unsupported: 'unsupported',
},
appDashboardDesign: {
global: 'Global',
},
appDataUploadView: {
"viewtitle":"AppDataUploadView",
"selectfile":"Select File",
"uploadserver":"Upload Server",
"datatemplate":"Download Import Data Template",
"dataid":"Data ID is ",
"read":" read Successful",
"importing":"Importing",
"completed":"Import Completed",
"confirm":"OK",
"datatemp":"Data Template",
"importfailed":"Import Failed"
},
appDebugActions: {
button: 'Open Configuration Mode',
},
appExportExcel: {
total: 'All',
max: 'At Most',
row: 'Lines',
currentPage: 'Current Page',
},
appFileUpload: {
preview: 'preview',
uploadText: 'Drag files here,or <em>Click</em> to upload',
fileTypeErrorTitle: 'File type incorrect',
fileTypeErrorInfo: 'Please select files with picture types,such as JPEG,GIF,PNG,BMP',
},
appFormDRUIPart: {
blockUITipInfo: 'Please save the major data first',
},
appHeaderMenus: {
ibizlab:{
title: 'iBizLab',
},
publishProject:{
title: 'Publish Project',
},
ibizstudio:{
title: 'Model Design Tools',
},
ibizbbs:{
title: 'iBizBBS',
},
},
appMpicker: {
error: 'Error',
miss: 'Missing parameter ',
requestException: 'Request Exception!',
},
appPicker: {
error: 'Error',
miss: 'Missing parameter ',
requestException: 'Request Exception!',
newAndEdit: 'Create And Edit...',
systemException: 'System Error!',
valueitemException: 'valueitem Error!',
formdataException: 'formdata Error!',
},
appPickerSelectView: {
error: 'Error',
valueitemException: 'valueitem Error!',
formdataException: 'formdata Error!',
placeholder: 'Please select...',
},
appPortalDesign: {
customPortal: 'Custom portal',
save: 'Save',
},
appRangDate: {
placeholder: 'Please select time...',
from: 'from',
daystart: '00:00:00 to',
dayend: '24:00:00',
},
appRangeEditor: {
placeholder: 'Please select time...',
input: 'Please input...',
},
appStudioAction: {
configTitle: 'Enter the configuration of current view',
configButton: 'Configuration',
issueTitle: 'Create issues of current view',
issueButton: 'Create issues',
},
appTreePicker: {
placeholder: 'please select...',
},
dateRange: {
startText: 'Insurance period : From',
endText: '24:00:00',
startPlaceholder: 'Begin Date',
rangeSeparatorr: ' 00:00:00 To',
endPlaceholder: 'End Dat4e',
},
dropDownList: {
placeholder: 'please select...'
},
dropDownListDynamic: {
placeholder: 'please select...'
},
dropDownListMpicker: {
placeholder: 'please select...'
},
login: {
error: 'Error',
caption: 'Welcome to login',
name: 'Login',
tip: 'Enter username and password',
loginname: {
placeholder: 'Username',
message: 'The username cannot be empty',
},
password: {
placeholder: 'Password',
message: 'The password cannot be empty',
},
loginfailed: 'Login failed',
},
appUser: {
name: 'System',
logout: 'Logout',
surelogout: 'Are you sure logout?',
},
appTheme: {
caption: {
theme: 'Theme',
font: 'Font family',
},
fontFamilys: {
MicrosoftYaHei: 'Microsoft YaHei',
SimHei: 'SimHei',
YouYuan: 'YouYuan',
},
},
};
\ No newline at end of file
export default {
"404": {
errorText1: '抱歉,您访问的页面不存在!',
errorText2: '您要找的页面不存在,请返回',
indexPage: '首页',
continue: '继续浏览',
},
"500": {
errorText1: '抱歉,服务器出错了!',
errorText2: '服务器出错了,请返回 ',
indexPage: '首页',
continue: '继续浏览',
},
appAutocomplete: {
error: '错误',
miss: '缺少参数',
requestException: '请求异常!',
},
appBuild: {
custom: '定制',
},
appCheckBox: {
notExist: '代码表不存在',
},
appColumnLink: {
error: '错误',
valueItemException:"值项异常",
rowDataException:"表格行数据异常"
},
appColumnRender: {
select: '请选择...',
unsupported: '不支持',
},
appDashboardDesign: {
global: '全局',
},
appDataUploadView: {
"viewtitle":"应用数据导入视图",
"selectfile":"选取文件",
"uploadserver":"上传服务器",
"datatemplate":"下载导入数据模板",
"dataid":"数据标识为",
"read":"读取成功",
"importing":"导入中",
"completed":"导入完成",
"confirm":"确认",
"datatemp":"导入数据模板",
"importfailed":"导入失败"
},
appDebugActions:{
button: '开启配置模式',
},
appExportExcel: {
total: '全部',
max: '最大',
row: '行',
currentPage: '当前页',
},
appFileUpload: {
preview: '查看',
uploadText: '将文件拖到此处,或<em>点击上传</em>',
uploadError: '上传失败',
fileTypeErrorTitle: '文件类型错误',
fileTypeErrorInfo: '请选择图片类型的文件,如JPEG,GIF,PNG,BMP',
},
appFormDRUIPart: {
blockUITipInfo: '请先保存主数据',
},
appHeaderMenus: {
ibizlab:{
title: 'iBiz开放平台',
},
publishProject:{
title: '项目文件',
},
ibizstudio:{
title: '模型设计工具',
},
ibizbbs:{
title: 'iBiz论坛',
},
},
appMpicker: {
error: '错误',
miss: '缺少参数',
requestException: '请求异常!',
},
appPicker: {
error: '错误',
miss: '缺少参数',
requestException: '请求异常!',
newAndEdit: '创建并编辑...',
systemException: '系统异常!',
valueitemException: '值项异常!',
formdataException: '表单数据异常!',
},
appPickerSelectView: {
error: '错误',
valueitemException: '值项异常!',
formdataException: '表单数据异常!',
placeholder: '请选择...',
},
appPortalDesign: {
customPortal: '自定义门户',
save: '保存',
},
appRangDate: {
placeholder: '请选择时间...',
from: '自',
daystart: '日 0 时 起 至',
dayend: '日 24 时 止',
},
appRangeEditor: {
placeholder: '请选择时间...',
input: '请输入...',
},
appStudioAction: {
configTitle: '进入当前视图配置界面',
configButton: '配置',
issueTitle: '建立当前界面的issues',
issueButton: '新建issues',
},
appTreePicker: {
placeholder: '请选择...',
},
dateRange: {
startText: '保险期限 : 自',
endText: '日 24 时 止',
startPlaceholder: '开始日期',
rangeSeparatorr: ' 0 时起 至',
endPlaceholder: '结束日期',
},
dropDownList: {
placeholder: '请选择...'
},
dropDownListDynamic: {
placeholder: '请选择...'
},
dropDownListMpicker: {
placeholder: '请选择...'
},
login: {
error: '错误',
caption: '欢迎登录',
name: '登录',
tip: '输入用户名和密码',
loginname: {
placeholder: '请输入用户名',
message: '用户名不能为空',
},
password: {
placeholder: '请输入密码',
message: '密码不能为空',
},
loginfailed: '登陆失败',
},
appUser: {
name: '系统管理员',
logout: '退出登陆',
surelogout: '确认要退出登陆?',
},
appTheme: {
caption: {
theme: '主题',
font: '字体',
},
fontFamilys: {
MicrosoftYaHei: '微软雅黑',
SimHei: '黑体',
YouYuan: '幼圆',
},
},
};
\ No newline at end of file
// 用户自定义语言资源 英文
export default {
};
\ No newline at end of file
// 用户自定义语言资源 中文
export default {
};
\ No newline at end of file
import Mock from 'mockjs' import Mock from 'mockjs'
import { MockAdapter } from '@/mock/mock-adapter';
const mock = MockAdapter.getInstance();
const Random = Mock.Random; const Random = Mock.Random;
// 上传 // ajax上传
Mock.mock(RegExp(new RegExp(/^\.\.\/ibizutil\/upload.*$/)),"post",(ops:any) => { // 拦截ajax请求,调用函数 Mock.mock(RegExp(new RegExp(/^\.\.\/ibizutil\/upload.*$/)),"post",(ops:any) => { // 拦截ajax请求,调用函数
console.log(ops) // 先看一下这个ops是什么 console.log(ops) // 先看一下这个ops是什么
console.log(ops.body) console.log(ops.body)
return { return {
"name": "xxx.png", "filename": "xxx.png",
"id": Random.string(128) "fileid": Random.string("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789",32)
}; };
});
// axios上传
mock.onPost(new RegExp(/^\.\.\/ibizutil\/upload.*$/)).reply((config: any) => {
return [200, {
"filename": "xxx.png",
"fileid": Random.string("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789",32)
}];
}); });
\ No newline at end of file
import { ChartSeries } from './chart-series';
/**
* 柱状图序列模型
*
* @export
* @class ChartBarSeries
*/
export class ChartBarSeries extends ChartSeries{
/**
* 分类属性
*
* @type {string}
* @memberof ChartBarSeries
*/
public categorField: string = '';
/**
* 值属性
*
* @type {string}
* @memberof ChartBarSeries
*/
public valueField: string = '';
/**
* 分类代码表
*
* @type {string}
* @memberof ChartBarSeries
*/
public categorCodeList: any = null;
/**
* 维度定义
*
* @type {string}
* @memberof ChartBarSeries
*/
public dimensions:Array<string> = [];
/**
* 维度编码
*
* @type {*}
* @memberof ChartBarSeries
*/
public encode:any = null;
/**
* 序列模板
*
* @type {*}
* @memberof ChartBarSeries
*/
public seriesTemp:any = null;
/**
* Creates an instance of ChartBarSeries.
* ChartBarSeries 实例
*
* @param {*} [opts={}]
* @memberof ChartBarSeries
*/
constructor(opts: any = {}) {
super(opts);
this.categorField = !Object.is(opts.categorField, '') ? opts.categorField : '';
this.categorCodeList = opts.categorCodeList ? opts.categorCodeList : null;
this.valueField = !Object.is(opts.valueField, '') ? opts.valueField : '';
this.dimensions = opts.dimensions ? opts.dimensions :'';
this.encode = opts.encode ? opts.encode : null;
this.seriesTemp = opts.seriesTemp ? opts.seriesTemp:null;
}
/**
* 设置分类属性
*
* @param {string} state
* @memberof ChartBarSeries
*/
public setCategorField(state: string): void {
this.categorField = state;
}
/**
* 设置序列名称
*
* @param {string} state
* @memberof ChartBarSeries
*/
public setValueField(state: string): void {
this.valueField = state;
}
/**
* 分类代码表
*
* @param {*} state
* @memberof ChartBarSeries
*/
public setCategorCodeList(state: any): void {
this.categorCodeList = state;
}
/**
* 维度定义
*
* @param {*} state
* @memberof ChartBarSeries
*/
public setDimensions(state: any): void {
this.dimensions = state;
}
/**
* 设置编码
*
* @param {*} state
* @memberof ChartBarSeries
*/
public setEncode(state: any): void {
this.encode = state;
}
/**
* 设置序列模板
*
* @param {*} state
* @memberof ChartBarSeries
*/
public setSeriesTemp(state: any): void {
this.seriesTemp = state;
}
}
\ No newline at end of file
/**
* 图表数据集属性模型
*
* @export
* @class ChartDataSetField
*/
export class ChartDataSetField {
/**
* 图表属性名称
*
* @type {string}
* @memberof ChartDataSetField
*/
public name: string = '';
/**
* 图表属性代码表
*
* @type {*}
* @memberof ChartDataSetField
*/
public codelist: any = null;
/**
* 是否分组属性
*
* @type {boolean}
* @memberof ChartDataSetField
*/
public isGroupField: boolean = false;
/**
* 分组模式
*
* @type {string}
* @memberof ChartDataSetField
*/
public groupMode:string ="";
/**
* Creates an instance of ChartDataSetField.
* ChartDataSetField 实例
*
* @param {*} [opts={}]
* @memberof ChartDataSetField
*/
constructor(opts: any = {}) {
this.name = !Object.is(opts.name, '') ? opts.name : '';
this.codelist = opts.codelist?opts.codelist:null;
this.isGroupField = opts.isGroupField?opts.isGroupField:false;
this.groupMode = !Object.is(opts.groupMode, '') ? opts.groupMode : '';
}
/**
* 设置图表属性名称
*
* @param {string} state
* @memberof ChartDataSetField
*/
public setName(state: string): void {
this.name = state;
}
/**
* 设置图表属性代码表
*
* @param {*} state
* @memberof ChartDataSetField
*/
public setCodeList(state: any): void {
this.codelist = state;
}
/**
* 设置分组属性
*
* @param {boolean} state
* @memberof ChartDataSetField
*/
public setisGroupField(state: boolean): void {
this.isGroupField = state;
}
/**
* 设置属性分组模式
*
* @param {string} state
* @memberof ChartDataSetField
*/
public setGroupMode(state: string): void {
this.groupMode = state;
}
}
\ No newline at end of file
import { ChartSeries } from './chart-series';
/**
* 漏斗图序列模型
*
* @export
* @class ChartFunnelSeries
*/
export class ChartFunnelSeries extends ChartSeries{
/**
* 分类属性
*
* @type {string}
* @memberof ChartFunnelSeries
*/
public categorField: string = '';
/**
* 值属性
*
* @type {string}
* @memberof ChartFunnelSeries
*/
public valueField: string = '';
/**
* 分类代码表
*
* @type {string}
* @memberof ChartFunnelSeries
*/
public categorCodeList: any = null;
/**
* 维度定义
*
* @type {string}
* @memberof ChartFunnelSeries
*/
public dimensions:Array<string> = [];
/**
* 维度编码
*
* @type {*}
* @memberof ChartFunnelSeries
*/
public encode:any = null;
/**
* Creates an instance of ChartFunnelSeries.
* ChartFunnelSeries 实例
*
* @param {*} [opts={}]
* @memberof ChartFunnelSeries
*/
constructor(opts: any = {}) {
super(opts);
this.categorField = !Object.is(opts.categorField, '') ? opts.categorField : '';
this.categorCodeList = opts.categorCodeList ? opts.categorCodeList : null;
this.valueField = !Object.is(opts.valueField, '') ? opts.valueField : '';
this.dimensions = opts.dimensions ? opts.dimensions :'';
this.encode = opts.encode ? opts.encode : null;
}
/**
* 设置分类属性
*
* @param {string} state
* @memberof ChartFunnelSeries
*/
public setCategorField(state: string): void {
this.categorField = state;
}
/**
* 设置序列名称
*
* @param {string} state
* @memberof ChartFunnelSeries
*/
public setValueField(state: string): void {
this.valueField = state;
}
/**
* 分类代码表
*
* @param {*} state
* @memberof ChartFunnelSeries
*/
public setCategorCodeList(state: any): void {
this.categorCodeList = state;
}
/**
* 维度定义
*
* @param {*} state
* @memberof ChartFunnelSeries
*/
public setDimensions(state: any): void {
this.dimensions = state;
}
/**
* 设置编码
*
* @param {*} state
* @memberof ChartFunnelSeries
*/
public setEncode(state: any): void {
this.encode = state;
}
}
\ No newline at end of file
import { ChartSeries } from './chart-series';
/**
* 折线图序列模型
*
* @export
* @class ChartLineSeries
*/
export class ChartLineSeries extends ChartSeries{
/**
* 分类属性
*
* @type {string}
* @memberof ChartLineSeries
*/
public categorField: string = '';
/**
* 值属性
*
* @type {string}
* @memberof ChartLineSeries
*/
public valueField: string = '';
/**
* 分类代码表
*
* @type {string}
* @memberof ChartLineSeries
*/
public categorCodeList: any = null;
/**
* 维度定义
*
* @type {string}
* @memberof ChartLineSeries
*/
public dimensions:Array<string> = [];
/**
* 维度编码
*
* @type {*}
* @memberof ChartLineSeries
*/
public encode:any = null;
/**
* 序列模板
*
* @type {*}
* @memberof ChartLineSeries
*/
public seriesTemp:any = null;
/**
* Creates an instance of ChartLineSeries.
* ChartLineSeries 实例
*
* @param {*} [opts={}]
* @memberof ChartLineSeries
*/
constructor(opts: any = {}) {
super(opts);
this.categorField = !Object.is(opts.categorField, '') ? opts.categorField : '';
this.categorCodeList = opts.categorCodeList ? opts.categorCodeList : null;
this.valueField = !Object.is(opts.valueField, '') ? opts.valueField : '';
this.dimensions = opts.dimensions ? opts.dimensions :'';
this.encode = opts.encode ? opts.encode : null;
this.seriesTemp = opts.seriesTemp ? opts.seriesTemp:null;
}
/**
* 设置分类属性
*
* @param {string} state
* @memberof ChartLineSeries
*/
public setCategorField(state: string): void {
this.categorField = state;
}
/**
* 设置序列名称
*
* @param {string} state
* @memberof ChartLineSeries
*/
public setValueField(state: string): void {
this.valueField = state;
}
/**
* 分类代码表
*
* @param {*} state
* @memberof ChartLineSeries
*/
public setCategorCodeList(state: any): void {
this.categorCodeList = state;
}
/**
* 维度定义
*
* @param {*} state
* @memberof ChartLineSeries
*/
public setDimensions(state: any): void {
this.dimensions = state;
}
/**
* 设置编码
*
* @param {*} state
* @memberof ChartLineSeries
*/
public setEncode(state: any): void {
this.encode = state;
}
/**
* 设置序列模板
*
* @param {*} state
* @memberof ChartLineSeries
*/
public setSeriesTemp(state: any): void {
this.seriesTemp = state;
}
}
\ No newline at end of file
import { ChartSeries } from './chart-series';
/**
* 饼图序列模型
*
* @export
* @class ChartPieSeries
*/
export class ChartPieSeries extends ChartSeries{
/**
* 分类属性
*
* @type {string}
* @memberof ChartPieSeries
*/
public categorField: string = '';
/**
* 值属性
*
* @type {string}
* @memberof ChartPieSeries
*/
public valueField: string = '';
/**
* 分类代码表
*
* @type {string}
* @memberof ChartPieSeries
*/
public categorCodeList: any = null;
/**
* 维度定义
*
* @type {string}
* @memberof ChartPieSeries
*/
public dimensions:Array<string> = [];
/**
* 维度编码
*
* @type {*}
* @memberof ChartPieSeries
*/
public encode:any = null;
/**
* Creates an instance of ChartPieSeries.
* ChartPieSeries 实例
*
* @param {*} [opts={}]
* @memberof ChartPieSeries
*/
constructor(opts: any = {}) {
super(opts);
this.categorField = !Object.is(opts.categorField, '') ? opts.categorField : '';
this.categorCodeList = opts.categorCodeList ? opts.categorCodeList : null;
this.valueField = !Object.is(opts.valueField, '') ? opts.valueField : '';
this.dimensions = opts.dimensions ? opts.dimensions :'';
this.encode = opts.encode ? opts.encode : null;
}
/**
* 设置分类属性
*
* @param {string} state
* @memberof ChartPieSeries
*/
public setCategorField(state: string): void {
this.categorField = state;
}
/**
* 设置序列名称
*
* @param {string} state
* @memberof ChartPieSeries
*/
public setValueField(state: string): void {
this.valueField = state;
}
/**
* 分类代码表
*
* @param {*} state
* @memberof ChartPieSeries
*/
public setCategorCodeList(state: any): void {
this.categorCodeList = state;
}
/**
* 维度定义
*
* @param {*} state
* @memberof ChartPieSeries
*/
public setDimensions(state: any): void {
this.dimensions = state;
}
/**
* 设置编码
*
* @param {*} state
* @memberof ChartPieSeries
*/
public setEncode(state: any): void {
this.encode = state;
}
}
\ No newline at end of file
import { ChartDataSetField } from './chart-dataset-field';
/**
* 图表序列模型
*
* @export
* @class ChartSeries
*/
export class ChartSeries {
/**
* 序列类型
*
* @type {string}
* @memberof ChartSeries
*/
public type: string = '';
/**
* 图表对象
*
* @type {*}
* @memberof ChartSeries
*/
public chart: any = null;
/**
* 序列名称
*
* @type {string}
* @memberof ChartSeries
*/
public name: string = '';
/**
* 序列标题
*
* @type {string}
* @memberof ChartSeries
*/
public caption: string = '';
/**
* 序列标识属性
*
* @type {string}
* @memberof ChartSeries
*/
public seriesIdField: string = '';
/**
* 序列名称属性
*
* @type {string}
* @memberof ChartSeries
*/
public seriesNameField: string = '';
/**
* 序列标识名称键值对
*
* @type {any}
* @memberof ChartSeries
*/
public seriesMap:any = null;
/**
* 对象索引
*
* @type {number}
* @memberof ChartSeries
*/
public index: number = 0;
/**
* 序列映射数据
*
* @type {*}
* @memberof ChartSeries
*/
public dataSet: any = [];
/**
* 预置配置
*
* @type {number}
* @memberof ChartSeries
*/
public ecxObject:any;
/**
* 用户自定义配置
*
* @type {number}
* @memberof ChartSeries
*/
public ecObject:any;
/**
* 序列索引
*
* @type {number}
* @memberof ChartSeries
*/
public seriesIndex:number = 0;
/**
* 数据集属性集合
*
* @type {Array<ChartDataSetField>}
* @memberof ChartSeries
*/
public dataSetFields:Array<ChartDataSetField> = [];
/**
* 取值方式
* 'column':默认,dataset 的列对应于系列,从而 dataset 中每一列是一个维度(dimension)
* 'row':dataset 的行对应于系列,从而 dataset 中每一行是一个维度(dimension
*
* @type {string}
* @memberof ChartSeries
*/
public seriesLayoutBy:string = "column";
/**
* Creates an instance of ChartSeries.
* ChartSeries 实例
*
* @param {*} [opts={}]
* @memberof ChartSeries
*/
constructor(opts: any = {}) {
this.type = !Object.is(opts.type, '') ? opts.type : '';
this.name = !Object.is(opts.name, '') ? opts.name : '';
this.caption = !Object.is(opts.caption, '') ? opts.caption : '';
this.seriesIdField = !Object.is(opts.seriesIdField, '') ? opts.seriesIdField : '';
this.seriesNameField = !Object.is(opts.seriesNameField, '') ? opts.seriesNameField : '';
this.index = this.index ? this.index : 0;
this.chart = opts.chart ? opts.chart : null;
this.dataSet = opts.dataSet ? opts.dataSet : [];
this.ecxObject = opts.ecxObject ? opts.ecxObject : null;
this.ecObject = opts.ecObject ? opts.ecObject : null;
this.seriesLayoutBy = opts.seriesLayoutBy ? opts.seriesLayoutBy:"column";
this.dataSetFields = opts.dataSetFields ? opts.dataSetFields:[];
this.seriesMap = opts.seriesMap ? opts.seriesMap:null;
this.seriesIndex = opts.seriesIndex? opts.seriesIndex:0;
}
/**
* 设置序列类型
*
* @param {string} state
* @memberof ChartSeries
*/
public setType(state: string): void {
this.type = state;
}
/**
* 设置序列名称
*
* @param {string} state
* @memberof ChartSeries
*/
public setCaption(state: string): void {
this.caption = state;
}
/**
* 设置序列标题
*
* @param {string} state
* @memberof ChartSeries
*/
public setName(state: string): void {
this.name = state;
}
/**
* 设置数据集
*
* @param {*} state
* @memberof ChartSeries
*/
public setDataSet(state: any): void {
this.dataSet = state;
}
/**
* 设置序列标识名称键值对
*
* @param {*} state
* @memberof ChartSeries
*/
public setSeriesMap(state: any): void {
this.seriesMap = state;
}
/**
* 设置序列映射的图表
*
* @param {*} state
* @memberof ChartSeries
*/
public setChart(state: any): void {
this.chart = state;
}
/**
* 设置序列标识属性
*
* @param {*} state
* @memberof ChartSeries
*/
public setSeriesIdField(state: any): void {
this.seriesIdField = state;
}
/**
* 设置序列名称属性
*
* @param {*} state
* @memberof ChartSeries
*/
public setSeriesNameField(state: any): void {
this.seriesNameField = state;
}
/**
* 设置对象索引
*
* @param {number} state
* @memberof ChartSeries
*/
public setIndex(state: number): void {
this.index = state;
}
/**
* 设置预置配置
*
* @param {*} state
* @memberof ChartSeries
*/
public setECXObject(state: any): void {
this.ecxObject = state;
}
/**
* 设置用户自定义参数
*
* @param {*} state
* @memberof ChartSeries
*/
public setECObject(state: any): void {
this.ecObject = state;
}
/**
* 设置取值方式
*
* @param {string} state
* @memberof ChartSeries
*/
public setSeriesLayoutBy(state: string): void {
this.seriesLayoutBy = state;
}
/**
* 设置数据集属性集合
*
* @param {Array<ChartDataSetField>} state
* @memberof ChartSeries
*/
public setDataSetFields(state: Array<ChartDataSetField>): void {
this.dataSetFields = state;
}
/**
* 设置序列索引
*
* @param {number} state
* @memberof ChartSeries
*/
public setSeriesIndex(state: number): void {
this.seriesIndex = state;
}
}
\ No newline at end of file
export { ChartDataSetField } from './chart-dataset-field';
export { ChartLineSeries } from './chart-line-series';
export { ChartFunnelSeries } from './chart-funnel-series';
export { ChartPieSeries } from './chart-pie-series';
export { ChartBarSeries } from './chart-bar-series';
\ No newline at end of file
...@@ -116,7 +116,7 @@ export default class EntityService { ...@@ -116,7 +116,7 @@ export default class EntityService {
* @memberof EntityService * @memberof EntityService
*/ */
public async Select(context: any = {},data: any = {}, isloading?: boolean): Promise<any> { public async Select(context: any = {},data: any = {}, isloading?: boolean): Promise<any> {
return { status: 500, data: { title: '失败', message: '预置实体行为 Select 未实现' }}; return this.SelectTemp(context,data,isloading);
} }
/** /**
...@@ -155,7 +155,7 @@ export default class EntityService { ...@@ -155,7 +155,7 @@ export default class EntityService {
public async CreateTemp(context: any = {},data: any = {}, isloading?: boolean): Promise<any> { public async CreateTemp(context: any = {},data: any = {}, isloading?: boolean): Promise<any> {
if(context.srfsessionkey && !Object.is(this.tempStorage.getItem(context.srfsessionkey+'_'+this.APPDENAME),'undefined')){ if(context.srfsessionkey && !Object.is(this.tempStorage.getItem(context.srfsessionkey+'_'+this.APPDENAME),'undefined')){
let tempData:any = JSON.parse(this.tempStorage.getItem(context.srfsessionkey+'_'+this.APPDENAME) as any); let tempData:any = JSON.parse(this.tempStorage.getItem(context.srfsessionkey+'_'+this.APPDENAME) as any);
data[this.APPDEKEY] = null; data.srffrontuf = "0";
tempData.push(data); tempData.push(data);
this.tempStorage.setItem(context.srfsessionkey+'_'+this.APPDENAME,JSON.stringify(tempData)); this.tempStorage.setItem(context.srfsessionkey+'_'+this.APPDENAME,JSON.stringify(tempData));
return {"status":200,"data":data}; return {"status":200,"data":data};
...@@ -198,7 +198,7 @@ export default class EntityService { ...@@ -198,7 +198,7 @@ export default class EntityService {
* @memberof EntityService * @memberof EntityService
*/ */
public async Update(context: any = {},data: any = {}, isloading?: boolean): Promise<any> { public async Update(context: any = {},data: any = {}, isloading?: boolean): Promise<any> {
return { status: 500, data: { title: '失败', message: '预置实体行为 Update 未实现' }}; return this.UpdateTemp(context,data,isloading);
} }
/** /**
...@@ -322,7 +322,7 @@ export default class EntityService { ...@@ -322,7 +322,7 @@ export default class EntityService {
* @memberof EntityService * @memberof EntityService
*/ */
public async GetDraft(context: any = {},data: any = {}, isloading?: boolean): Promise<any> { public async GetDraft(context: any = {},data: any = {}, isloading?: boolean): Promise<any> {
return { status: 500, data: { title: '失败', message: '预置实体行为 GetDraft 未实现' }}; return this.GetDraftTemp(context,data,isloading);
} }
/** /**
...@@ -335,7 +335,7 @@ export default class EntityService { ...@@ -335,7 +335,7 @@ export default class EntityService {
* @memberof EntityService * @memberof EntityService
*/ */
public async Remove(context: any = {},data: any = {}, isloading?: boolean): Promise<any> { public async Remove(context: any = {},data: any = {}, isloading?: boolean): Promise<any> {
return { status: 500, data: { title: '失败', message: '预置实体行为 Remove 未实现' }}; return this.RemoveTemp(context,data,isloading);
} }
/** /**
...@@ -374,7 +374,7 @@ export default class EntityService { ...@@ -374,7 +374,7 @@ export default class EntityService {
* @memberof EntityService * @memberof EntityService
*/ */
public async Get(context: any = {},data: any = {}, isloading?: boolean): Promise<any> { public async Get(context: any = {},data: any = {}, isloading?: boolean): Promise<any> {
return { status: 500, data: { title: '失败', message: '预置实体行为 Get 未实现' }}; return this.GetTemp(context,data,isloading);
} }
/** /**
...@@ -400,7 +400,7 @@ export default class EntityService { ...@@ -400,7 +400,7 @@ export default class EntityService {
* @memberof EntityService * @memberof EntityService
*/ */
public async Create(context: any = {},data: any = {}, isloading?: boolean): Promise<any> { public async Create(context: any = {},data: any = {}, isloading?: boolean): Promise<any> {
return { status: 500, data: { title: '失败', message: '预置实体行为 Create 未实现' }}; return this.CreateTemp(context,data,isloading);
} }
/** /**
...@@ -552,6 +552,19 @@ export default class EntityService { ...@@ -552,6 +552,19 @@ export default class EntityService {
return this.FetchDefault(context,data,isloading); return this.FetchDefault(context,data,isloading);
} }
/**
* ImportData接口方法
*
* @param {*} [context={}]
* @param {*} [data={}]
* @param {boolean} [isloading]
* @returns {Promise<any>}
* @memberof EntityService
*/
public async ImportData(context: any = {},data: any = {}, isloading?: boolean): Promise<any> {
return Http.getInstance().post(`/${this.APPDENAME}/import`,data,isloading);
}
/** /**
* WFStart接口方法 * WFStart接口方法
* *
......
...@@ -7,5 +7,6 @@ declare module '@fullcalendar/vue'; ...@@ -7,5 +7,6 @@ declare module '@fullcalendar/vue';
declare module '@fullcalendar/timegrid'; declare module '@fullcalendar/timegrid';
declare module '@fullcalendar/list'; declare module '@fullcalendar/list';
declare module '@fullcalendar/interaction'; declare module '@fullcalendar/interaction';
declare module '@fullcalendar/core/locales-all';
declare module 'vue-grid-layout'; declare module 'vue-grid-layout';
declare module 'vue-print-nb'; declare module 'vue-print-nb';
\ No newline at end of file
...@@ -4,63 +4,77 @@ ...@@ -4,63 +4,77 @@
@import '../theme/default.theme.less'; @import '../theme/default.theme.less';
@import './var.css'; @import './var.css';
.view-container { .view-container {
height: calc(100% - 38px);
// height: 100%; .view-header-left {
// display: flex;
padding: 0 15px;
// flex-direction: column;
> .view-card {
height: 100%; height: 100%;
// display: flex; display: flex;
// flex-direction: column; align-items: center;
> .ivu-card-body {
// height: 50%; >.view-caption {
// flex-grow: 1; font-size: 18px;
height: calc(100% - 51px); font-weight: 900;
padding: 0px; color: black;
> .content-container { height: 32px;
height: 100%; line-height: 32px;
display: flex; white-space: nowrap;
margin: 0; font-family: AlibabaPuHuiTiB, "Alibaba PuHuiTi";
flex-direction: column;
}
} }
>.ivu-card-head{ }
border:0;
.view-header-right {
height: 100%;
>.app-header-menus {
>.ivu-btn {
padding: 0px 6px;
}
} }
} }
> .view-card.view-no-caption.view-no-toolbar {
> .ivu-card-body { .view-content-wrapper {
height: 100%; height: 100%;
width: 100%;
overflow-y: auto;
overflow-x: hidden;
display: flex;
flex-direction: column;
align-items: center;
padding-top: 32px;
background-color: white;
>* {
width: 60%;
}
>.pickupviewpanel {
height: calc(100% - 64px);
} }
} }
} }
.viewcontainer2 {
height: 100%; .ivu-spin-fullscreen.ivu-spin-fullscreen-wrapper {
width: 100%;
} >.ivu-spin.ivu-spin-large.ivu-spin-fix.ivu-spin-fullscreen {
.viewcontainer3 { background-color: rgba(255,255,255,0.3);
height: 100%; }
width: 100%;
padding: 0px;
} }
.view-container.default-mode-view {
/*** BRGIN:加载遮罩 ***/ .view-content-wrapper {
.el-loading-mask { padding-top: 0px;
background-color: initial;
.el-loading-spinner { >* {
.path { width: 100%;
stroke-width: 3px;
} }
} }
} }
/*** END:加载遮罩 ***/
.grid-row-select { .grid-row-select {
background-color: #ecf5ff !important; background-color: #ecf5ff !important;
td { td {
background-color: #ecf5ff !important; background-color: #ecf5ff !important;
} }
...@@ -69,73 +83,133 @@ ...@@ -69,73 +83,133 @@
/*** BRGIN:表单错误信息2 ***/ /*** BRGIN:表单错误信息2 ***/
.app-form-item-error-info { .app-form-item-error-info {
display: flex; display: flex;
.icon { .icon {
width: 30px; width: 30px;
flex-shrink: 0; flex-shrink: 0;
} }
.contant{
.contant {
flex-grow: 1; flex-grow: 1;
} }
} }
/*** END:表单错误信息2 ***/ /*** END:表单错误信息2 ***/
/*** BRGIN:多数据视图属性布局 ***/ /*** BRGIN:多数据视图属性布局 ***/
.property-layout-left, .property-layout-right { .property-layout-left,
.property-layout-right {
display: flex; display: flex;
height: 100%; height: 100%;
> div {
>div {
height: 100%; height: 100%;
} }
> div:nth-child(1) {
>div:nth-child(1) {
flex-grow: 1; flex-grow: 1;
padding-left: 0; padding-left: 0;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
} }
> div:nth-child(2) {
>div:nth-child(2) {
flex-shrink: 0; flex-shrink: 0;
} }
} }
.property-layout-top, .property-layout-bottom {
.property-layout-top,
.property-layout-bottom {
display: flex; display: flex;
height: 100%; height: 100%;
> div:nth-child(1) {
>div:nth-child(1) {
flex-grow: 1; flex-grow: 1;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
} }
> div:nth-child(2) {
>div:nth-child(2) {
flex-shrink: 0; flex-shrink: 0;
} }
} }
.property-layout-left { .property-layout-left {
flex-direction: row-reverse; flex-direction: row-reverse;
> div:nth-child(1) {
>div:nth-child(1) {
border-left: 1px solid #ddd; border-left: 1px solid #ddd;
padding-left: 16px; padding-left: 16px;
} }
} }
.property-layout-right { .property-layout-right {
flex-direction: row; flex-direction: row;
> div:nth-child(1) {
>div:nth-child(1) {
border-right: 1px solid #ddd; border-right: 1px solid #ddd;
padding-right: 16px; padding-right: 16px;
} }
} }
.property-layout-top { .property-layout-top {
flex-direction: column-reverse; flex-direction: column-reverse;
> div:nth-child(1) {
>div:nth-child(1) {
border-top: 1px solid #ddd; border-top: 1px solid #ddd;
padding-top: 16px; padding-top: 16px;
} }
} }
.property-layout-bottom { .property-layout-bottom {
flex-direction: column; flex-direction: column;
> div:nth-child(1) {
>div:nth-child(1) {
border-bottom: 1px solid #ddd; border-bottom: 1px solid #ddd;
padding-bottom: 16px; padding-bottom: 16px;
} }
} }
// 表单分组
.app-form-group {
.ivu-card-head {
>p {
color: #304265;
font-weight: 600;
}
}
.ivu-form-item,
app-form-item {
.ivu-form-item-label {
color: #304265;
font-size: 12px;
font-weight: 600;
}
}
.ivu-card-body {
padding: 8px;
}
.ivu-card-head {
padding: 7px 0px;
}
}
// 信息表单分组
.app-form-group.app-info-group-mode {
.ivu-form-item.app-form-item {
margin-bottom: 0px;
}
}
/*** END:多数据视图属性布局 ***/ /*** END:多数据视图属性布局 ***/
@import './user.less'; @import './user.less';
\ No newline at end of file
...@@ -15,5 +15,6 @@ ...@@ -15,5 +15,6 @@
<!-- <link rel="stylesheet" href="<%= BASE_URL %>assets/styles/loader.css"> <!-- <link rel="stylesheet" href="<%= BASE_URL %>assets/styles/loader.css">
<div class="loader" id="app-loader"></div> --> <div class="loader" id="app-loader"></div> -->
<!-- built files will be auto injected --> <!-- built files will be auto injected -->
<script src="./environments/environment.js"></script>
</body> </body>
</html> </html>
/*** BRGIN:默认蓝色主题 ***/ /*** BRGIN:默认蓝色主题 ***/
.app_theme_blue { .app_theme_blue {
> header { > header {
background-color: #2d5f8b; background-color: #2d5f8b;
color: #6ba1d1; color: #6ba1d1;
.app-theme-icon { .app-theme-icon {
color: #6ba1d1; color: #6ba1d1;
} }
.page-logo { .page-logo {
color: #ffffff; color: #fff;
} }
.header-right { .header-right {
.app-header-user { > div:hover {
background: #28547c; background: #3774aa;
} }
> div:hover { }
background: #3774aa; .el-menu.el-menu--horizontal {
} > .el-menu-item, > .el-submenu > .el-submenu__title {
} background: #2d5f8b;
.el-menu.el-menu--horizontal { color: #6ba1d1;
> .el-menu-item, > .el-submenu > .el-submenu__title { i {
background: #2d5f8b; color: #6ba1d1;
color: #6ba1d1; }
i { }
color: #6ba1d1; > .el-menu-item.is-active, > .el-submenu.is-active > .el-submenu__title {
} background-color: #4276a4;
} color: #f1f1f1;
> .el-menu-item.is-active, > .el-submenu.is-active > .el-submenu__title { i {
background-color: #4276a4; color: #f1f1f1;
color: #f1f1f1; }
i { }
color: #f1f1f1; > .el-menu-item:hover, > .el-submenu:hover > .el-submenu__title {
} background-color: #3c6c95;
} color: #f1f1f1 !important;
> .el-menu-item:hover, > .el-submenu:hover > .el-submenu__title { i {
background-color: #3c6c95; color: #f1f1f1;
color: #f1f1f1 !important; }
i { }
color: #f1f1f1; }
} }
} > .ivu-layout {
} > .ivu-layout-sider {
} background-color: #4276a4;
> .ivu-layout { .sider-top {
> .ivu-layout-sider { .ivu-icon {
background-color: #4276a4; background: #2d5f8b;
.sider-top { color: #6ba1d1;
.ivu-icon { }
background: #2d5f8b; }
color: #6ba1d1; .app-menu {
} > .el-menu-item.is-active, > .el-submenu.is-active > .el-submenu__title {
} border-left: 4px solid #d64635;
.app-menu { }
> .el-menu-item.is-active, > .el-submenu.is-active > .el-submenu__title { }
border-left: 4px solid #d64635; }
} }
} > .el-menu , > .ivu-layout > .ivu-layout-sider .app-app-menu > .app-menu {
} background: #4276a4;
} .el-menu-item:hover, .el-menu-item.is-active {
> .el-menu , > .ivu-layout > .ivu-layout-sider .app-app-menu > .app-menu { background: #3c6c95 !important;
background: #4276a4; color: #f1f1f1 !important;
.el-menu-item:hover, .el-menu-item.is-active { i {
background: #3c6c95 !important; color: #f1f1f1;
color: #f1f1f1 !important; }
i { }
color: #f1f1f1; .el-submenu.is-opened, .el-submenu:hover, .el-submenu.is-active {
} > .el-submenu__title {
} background: #3c6c95 !important;
.el-submenu.is-opened, .el-submenu:hover, .el-submenu.is-active { color: #f1f1f1 !important;
> .el-submenu__title { i {
background: #3c6c95 !important; color: #f1f1f1;
color: #f1f1f1 !important; }
i { }
color: #f1f1f1; }
} .el-submenu__title, .el-menu-item {
} color: #c9dff5;
} i {
.el-submenu__title, .el-menu-item { color: #c9dff5;
color: #c9dff5; }
i { }
color: #c9dff5; .el-menu-item {
} border-top: 1px solid #4276a4;
} background: #4276a4;
.el-menu-item { }
border-top: 1px solid #4276a4; .el-submenu {
background: #4276a4; border-top: 1px solid #4276a4;
} background: #4276a4;
.el-submenu { > .el-menu {
border-top: 1px solid #4276a4; border-top: 1px solid #4276a4;
background: #4276a4; background: #4276a4;
> .el-menu { }
border-top: 1px solid #4276a4; }
background: #4276a4; }
} .ivu-menu-light{
} background: #4276a4;
} }
.ivu-menu-light{ .ivu-menu-submenu-title{
background: #4276a4; color: #f5f5f5;
} }
.ivu-menu-submenu-title{
color: #f5f5f5;
}
} }
/*** END:默认蓝色主题 ***/ /*** END:默认蓝色主题 ***/
\ No newline at end of file
/*** BRGIN:默认Dark Blue主题 ***/ /*** BRGIN:默认Dark Blue主题 ***/
.app_theme_darkblue { .app_theme_darkblue {
> header { > header {
background-color: #2b3643; background-color: #2b3643;
color: #606d80; color: #606d80;
.app-theme-icon { .app-theme-icon {
color: #606d80; color: #606d80;
} }
.page-logo { .page-logo {
color: #ffffff; color: #fff;
} }
.header-right { .header-right {
.app-header-user { > div:hover {
background: #232c37; background: #3b4a5c;
} }
> div:hover { }
background: #3b4a5c; .el-menu.el-menu--horizontal {
} > .el-menu-item, > .el-submenu > .el-submenu__title {
} background: #2b3643;
.el-menu.el-menu--horizontal { color: #606d80;
> .el-menu-item, > .el-submenu > .el-submenu__title { i {
background: #2b3643; color: #606d80;
color: #606d80; }
i { }
color: #606d80; > .el-menu-item.is-active, > .el-submenu.is-active > .el-submenu__title {
} background-color: #364150;
} color: #f1f1f1;
> .el-menu-item.is-active, > .el-submenu.is-active > .el-submenu__title { i {
background-color: #364150; color: #f1f1f1;
color: #f1f1f1; }
i { }
color: #f1f1f1; > .el-menu-item:hover, > .el-submenu:hover > .el-submenu__title {
} background-color: #3e4b5c;
} color: #f1f1f1 !important;
> .el-menu-item:hover, > .el-submenu:hover > .el-submenu__title { i {
background-color: #3e4b5c; color: #f1f1f1;
color: #f1f1f1 !important; }
i { }
color: #f1f1f1; }
} }
} > .ivu-layout {
} > .ivu-layout-sider {
} background-color: #364150;
> .ivu-layout { .sider-top {
> .ivu-layout-sider { .ivu-icon {
background-color: #364150; background: #2b3643;
.sider-top { color: #606d80;
.ivu-icon { }
background: #2b3643; }
color: #606d80; .app-menu {
} > .el-menu-item.is-active, > .el-submenu.is-active > .el-submenu__title {
} border-left: 4px solid #1caf9a;
.app-menu { }
> .el-menu-item.is-active, > .el-submenu.is-active > .el-submenu__title { }
border-left: 4px solid #1caf9a; }
} }
} > .el-menu , > .ivu-layout > .ivu-layout-sider .app-app-menu > .app-menu {
} background: #364150;
} .el-menu-item:hover, .el-menu-item.is-active {
> .el-menu , > .ivu-layout > .ivu-layout-sider .app-app-menu > .app-menu { background: #3e4b5c !important;
background: #364150; color: #f1f1f1 !important;
.el-menu-item:hover, .el-menu-item.is-active { i {
background: #3e4b5c !important; color: #f1f1f1;
color: #f1f1f1 !important; }
i { }
color: #f1f1f1; .el-submenu.is-opened, .el-submenu:hover, .el-submenu.is-active {
} > .el-submenu__title {
} background: #3e4b5c !important;
.el-submenu.is-opened, .el-submenu:hover, .el-submenu.is-active { color: #f1f1f1 !important;
> .el-submenu__title { i {
background: #3e4b5c !important; color: #f1f1f1;
color: #f1f1f1 !important; }
i { }
color: #f1f1f1; }
} .el-submenu__title, .el-menu-item {
} color: #b4bcc8;
} i {
.el-submenu__title, .el-menu-item { color: #b4bcc8;
color: #b4bcc8; }
i { }
color: #b4bcc8; .el-menu-item {
} border-top: 1px solid #364150;
} background: #364150;
.el-menu-item { }
border-top: 1px solid #364150; .el-submenu {
background: #364150; border-top: 1px solid #364150;
} background: #364150;
.el-submenu { > .el-menu {
border-top: 1px solid #364150; border-top: 1px solid #364150;
background: #364150; background: #364150;
> .el-menu { }
border-top: 1px solid #364150; }
background: #364150; }
} .ivu-menu-light{
} background: #364150;
} }
.ivu-menu-light{ .ivu-menu-submenu-title{
background: #364150; color: #fff;
} }
.ivu-menu-submenu-title{
color: #fff;
}
} }
/*** END:默认Dark Blue主题 ***/ /*** END:默认Dark Blue主题 ***/
\ No newline at end of file
/*** BRGIN:默认亮色主题 ***/ /*** BRGIN:默认亮色主题 ***/
.app-default-theme { .app-default-theme {
> header { > header {
background-color: #e1e1e1; background-color: #e8eaec;
color: #aaaaaa; color: #aaaaaa;
.app-theme-icon { .app-theme-icon {
color: #aaaaaa; color: #aaaaaa;
} }
.page-logo { .page-logo {
color: #535c70; color: #535c70;
} }
.header-right { .header-right {
.app-header-user { > div:hover {
background: #d9d9d9; background: #d4d4d4;
} }
> div:hover { }
background: #d4d4d4; .el-menu.el-menu--horizontal {
} > .el-menu-item, > .el-submenu > .el-submenu__title {
} background: #e1e1e1;
.el-menu.el-menu--horizontal { color: #aaaaaa;
> .el-menu-item, > .el-submenu > .el-submenu__title { i {
background: #e1e1e1; color: #aaaaaa;
color: #aaaaaa; }
i { }
color: #aaaaaa; > .el-menu-item.is-active, > .el-submenu.is-active > .el-submenu__title {
} background-color: #f6f6f6;
} color: #666666;
> .el-menu-item.is-active, > .el-submenu.is-active > .el-submenu__title { i {
background-color: #f6f6f6; color: #666666;
color: #666666; }
i { }
color: #666666; > .el-menu-item:hover, > .el-submenu:hover > .el-submenu__title {
} background-color: #e9e9e9;
} color: #666666 !important;
> .el-menu-item:hover, > .el-submenu:hover > .el-submenu__title { i {
background-color: #e9e9e9; color: #666666;
color: #666666 !important; }
i { }
color: #666666; }
} }
} > .ivu-layout {
} > .ivu-layout-sider {
} background-color: #f6f6f6;
> .ivu-layout { .sider-top {
> .ivu-layout-sider { .ivu-icon {
background-color: #f6f6f6; background: #f6f6f6;
.sider-top { color: #aaaaaa;
.ivu-icon { }
background: #ccd3dd; }
color: #fff; .app-menu {
} > .el-menu-item.is-active, > .el-submenu.is-active > .el-submenu__title {
} border-left: 4px solid #1890ff;
.app-menu { }
> .el-menu-item.is-active, > .el-submenu.is-active > .el-submenu__title { }
border-left: 4px solid #3fd5c0; }
} }
} > .el-menu , > .ivu-layout > .ivu-layout-sider .app-app-menu > .app-menu {
} background: #f6f6f6;
} .el-menu-item:hover, .el-menu-item.is-active {
> .el-menu , > .ivu-layout > .ivu-layout-sider .app-app-menu > .app-menu { background: #fff !important;
background: #f6f6f6; color: #1890ff !important;
.el-menu-item:hover, .el-menu-item.is-active { i {
background: #e9e9e9 !important; color: #1890ff;
color: #666666 !important; }
i { }
color: #666666; .el-submenu.is-opened, .el-submenu:hover, .el-submenu.is-active {
} > .el-submenu__title {
} background: #fff !important;
.el-submenu.is-opened, .el-submenu:hover, .el-submenu.is-active { color: #1890ff !important;
> .el-submenu__title { i {
background: #e9e9e9 !important; color: #1890ff;
color: #666666 !important; }
i { }
color: #666666; }
} .el-submenu__title, .el-menu-item {
} color: #666666;
} i {
.el-submenu__title, .el-menu-item { color: #666666;
color: #666666; }
i { }
color: #666666; .el-menu-item {
} border-top: 1px solid #f6f6f6;
} background: #f6f6f6;
.el-menu-item { }
border-top: 1px solid #f6f6f6; .el-submenu {
background: #f6f6f6; border-top: 1px solid #f6f6f6;
} background: #f6f6f6;
.el-submenu { > .el-menu {
border-top: 1px solid #f6f6f6; border-top: 1px solid #f6f6f6;
background: #f6f6f6; background: #f6f6f6;
> .el-menu { }
border-top: 1px solid #f6f6f6; }
background: #f6f6f6; }
} .ivu-menu-light{
} background: #f6f6f6;
} }
.ivu-menu-light{ .ivu-menu-submenu-title{
background: #f6f6f6; color: #000;
} }
.ivu-menu-submenu-title{
color: #000;
}
} }
/*** END:默认亮色主题 ***/ /*** END:默认亮色主题 ***/
\ No newline at end of file
import { AppLayout, AppMenus, AppUserInfo, AppHeaderMenus, GoBackButton, ModalBreadcrumb, DebugActions } from '@/crm-core';
import DataRevealType from './components/data-reveal-type/data-reveal-type.vue'
/**
* 注册组件
*/
export const UserDefaultComponent = {
install(v: any, opt: any) {
v.component('app-layout', AppLayout);
v.component('app-menus', AppMenus);
v.component('app-user-info', AppUserInfo);
v.component('app-header-menus', AppHeaderMenus);
v.component('go-back-button', GoBackButton);
v.component('modal-breadcrumb', ModalBreadcrumb);
v.component('data-reveal-type', DataRevealType);
v.component('debug-actions', DebugActions);
}
};
\ No newline at end of file
import { UserDefaultComponent } from './user-default-register';
export const UserComponent = { export const UserComponent = {
install(v: any, opt: any) { install(v: any, opt: any) {
UserDefaultComponent.install(v, opt);
} }
}; };
\ No newline at end of file
import Vue from 'vue'; import Vue from 'vue';
import { Subject } from 'rxjs'; import { Subject, Observable } from 'rxjs';
import { ViewTool } from '../view-tool/view-tool'; import { ViewTool } from '../view-tool/view-tool';
import store from '../../store'; import store from '../../store';
import i18n from '@/locale'; import i18n from '@/locale';
import AppDrawerCompponent from "./app-drawer.vue"; import AppDrawerCompponent from "./app-drawer.vue";
import { crmDrawerController } from '@/crm-core/core/utils/crm-drawer/crm-drawer';
export class AppDrawer { export class AppDrawer {
...@@ -91,7 +92,10 @@ export class AppDrawer { ...@@ -91,7 +92,10 @@ export class AppDrawer {
* @returns {Subject<any>} * @returns {Subject<any>}
* @memberof AppDrawer * @memberof AppDrawer
*/ */
public openDrawer(view: { viewname: string, title: string, width?: number, height?: number, placement?: 'DRAWER_LEFT' | 'DRAWER_RIGHT' }, context: any = {}, data: any = {}): Subject<any> { public openDrawer(view: { viewname: string, title: string, width?: number, height?: number, placement?: 'DRAWER_LEFT' | 'DRAWER_RIGHT' | 'DRAWER_TOP' | 'DRAWER_BOTTOM' }, context: any = {}, data: any = {}): Observable<any> {
if (Object.is(view.placement, 'DRAWER_TOP')) {
return crmDrawerController.openDrawer(view, context, data);
}
try { try {
let viewdata: any = {}; let viewdata: any = {};
Object.assign(viewdata, JSON.parse(JSON.stringify(context))); Object.assign(viewdata, JSON.parse(JSON.stringify(context)));
...@@ -99,7 +103,6 @@ export class AppDrawer { ...@@ -99,7 +103,6 @@ export class AppDrawer {
const subject = this.createVueExample(view, viewdata,data,uuid); const subject = this.createVueExample(view, viewdata,data,uuid);
return subject; return subject;
} catch (error) { } catch (error) {
console.log(error);
return new Subject<any>(); return new Subject<any>();
} }
} }
......
import axios from 'axios'; import axios from 'axios';
import { Loading } from 'element-ui';
import { ElLoadingComponent } from 'element-ui/types/loading'; import { ElLoadingComponent } from 'element-ui/types/loading';
import qs from 'qs'; import qs from 'qs';
import Vue from 'vue';
/** /**
* Http net 对象 * Http net 对象
* 调用 getInstance() 获取实例 * 调用 getInstance() 获取实例
...@@ -106,29 +106,29 @@ export class Http { ...@@ -106,29 +106,29 @@ export class Http {
* @returns {Promise<any>} * @returns {Promise<any>}
* @memberof Http * @memberof Http
*/ */
public get(url: string,params: any = {}, isloading?: boolean, serialnumber?: number): Promise<any> { public get(url: string, params: any = {}, isloading?: boolean, serialnumber?: number): Promise<any> {
params = this.handleRequestData(params); params = this.handleRequestData(params);
if(params.srfparentdata){ if (params.srfparentdata) {
Object.assign(params,params.srfparentdata); Object.assign(params, params.srfparentdata);
delete params.srfparentdata; delete params.srfparentdata;
} }
if((Object.keys(params)).length>0){ if ((Object.keys(params)).length > 0) {
let tempParam:any = {}; let tempParam: any = {};
let sort:any = null; let sort: any = null;
Object.keys(params).forEach((item:any) =>{ Object.keys(params).forEach((item: any) => {
if( params[item] || Object.is(params[item],0) ){ if (params[item] || Object.is(params[item], 0)) {
if (Object.is(item,'sort')){ if (Object.is(item, 'sort')) {
sort = params[item]; sort = params[item];
}else{ } else {
tempParam[item] = params[item]; tempParam[item] = params[item];
} }
} }
}) })
url += `?${qs.stringify(tempParam)}`; url += `?${qs.stringify(tempParam)}`;
if(sort){ if (sort) {
url += '&sort='+sort; url += '&sort=' + sort;
} }
} }
if (isloading) { if (isloading) {
this.beginLoading(); this.beginLoading();
} }
...@@ -215,10 +215,7 @@ export class Http { ...@@ -215,10 +215,7 @@ export class Http {
*/ */
private beginLoading(): void { private beginLoading(): void {
if (this.loadingCount === 0) { if (this.loadingCount === 0) {
this.elLoadingComponent = Loading.service({ Vue.prototype.$Spin.show();
body: true,
fullscreen: true,
});
} }
this.loadingCount++; this.loadingCount++;
} }
...@@ -235,7 +232,7 @@ export class Http { ...@@ -235,7 +232,7 @@ export class Http {
} }
setTimeout(() => { setTimeout(() => {
if (this.loadingCount === 0) { if (this.loadingCount === 0) {
this.elLoadingComponent.close(); Vue.prototype.$Spin.hide();
} }
}, 500); }, 500);
} }
...@@ -247,11 +244,11 @@ export class Http { ...@@ -247,11 +244,11 @@ export class Http {
* @param data * @param data
* @memberof Http * @memberof Http
*/ */
private handleRequestData(data:any){ private handleRequestData(data: any) {
if(data.srfsessionkey){ if (data.srfsessionkey) {
delete data.srfsessionkey; delete data.srfsessionkey;
} }
if(data.srfsessionid){ if (data.srfsessionid) {
delete data.srfsessionid; delete data.srfsessionid;
} }
return data; return data;
......
// 打印类属性、方法定义
/* eslint-disable */
const Print = function (dom, options) {
if (!(this instanceof Print)) return new Print(dom, options);
this.options = this.extend({
'noPrint': '.no-print'
}, options);
if ((typeof dom) === "string") {
this.dom = document.querySelector(dom);
} else {
this.isDOM(dom)
this.dom = this.isDOM(dom) ? dom : dom.$el;
}
this.init();
};
Print.prototype = {
init: function () {
var content = this.getStyle() + this.getHtml();
this.writeIframe(content);
},
extend: function (obj, obj2) {
for (var k in obj2) {
obj[k] = obj2[k];
}
return obj;
},
getStyle: function () {
var str = "",
styles = document.querySelectorAll('style,link');
for (var i = 0; i < styles.length; i++) {
str += styles[i].outerHTML;
}
str += "<style>" + (this.options.noPrint ? this.options.noPrint : '.no-print') + "{display:none;}</style>";
return str;
},
getHtml: function () {
var inputs = document.querySelectorAll('input');
var textareas = document.querySelectorAll('textarea');
var selects = document.querySelectorAll('select');
for (var k = 0; k < inputs.length; k++) {
if (inputs[k].type == "checkbox" || inputs[k].type == "radio") {
if (inputs[k].checked == true) {
inputs[k].setAttribute('checked', "checked")
} else {
inputs[k].removeAttribute('checked')
}
} else if (inputs[k].type == "text") {
inputs[k].setAttribute('value', inputs[k].value)
} else {
inputs[k].setAttribute('value', inputs[k].value)
}
}
for (var k2 = 0; k2 < textareas.length; k2++) {
if (textareas[k2].type == 'textarea') {
textareas[k2].innerHTML = textareas[k2].value
}
}
for (var k3 = 0; k3 < selects.length; k3++) {
if (selects[k3].type == 'select-one') {
var child = selects[k3].children;
for (var i in child) {
if (child[i].tagName == 'OPTION') {
if (child[i].selected == true) {
child[i].setAttribute('selected', "selected")
} else {
child[i].removeAttribute('selected')
}
}
}
}
}
// 包裹要打印的元素
// fix: https://github.com/xyl66/vuePlugs_printjs/issues/36
return this.wrapperRefDom(this.dom).outerHTML;
},
// 向父级元素循环,包裹当前需要打印的元素
// 防止根级别开头的 css 选择器不生效
wrapperRefDom: function (refDom) {
let prevDom = null
let currDom = refDom
while (currDom && currDom.tagName.toLowerCase() !== 'body') {
if (prevDom) {
let element = currDom.cloneNode(false)
element.appendChild(prevDom)
prevDom = element
} else {
prevDom = currDom.cloneNode(true)
}
currDom = currDom.parentElement
}
return currDom.tagName.toLowerCase() === 'body' ? currDom : prevDom
},
writeIframe: function (content) {
var w, doc, iframe = document.createElement('iframe'),
f = document.body.appendChild(iframe);
iframe.id = "myIframe";
//iframe.style = "position:absolute;width:0;height:0;top:-10px;left:-10px;";
iframe.setAttribute('style', 'position:absolute;width:0;height:0;top:-10px;left:-10px;');
w = f.contentWindow || f.contentDocument;
doc = f.contentDocument || f.contentWindow.document;
doc.open();
doc.write(content);
doc.close();
var _this = this
iframe.onload = function(){
_this.toPrint(w);
setTimeout(function () {
document.body.removeChild(iframe)
}, 100)
}
},
toPrint: function (frameWindow) {
try {
setTimeout(function () {
frameWindow.focus();
try {
if (!frameWindow.document.execCommand('print', false, null)) {
frameWindow.print();
}
} catch (e) {
frameWindow.print();
}
frameWindow.close();
}, 10);
} catch (err) {
console.log('err', err);
}
},
isDOM: (typeof HTMLElement === 'object') ?
function (obj) {
return obj instanceof HTMLElement;
} :
function (obj) {
return obj && typeof obj === 'object' && obj.nodeType === 1 && typeof obj.nodeName === 'string';
}
};
const MyPlugin = {}
MyPlugin.install = function (Vue, options) {
// 4. 添加实例方法
Vue.prototype.$print = Print
}
export default MyPlugin
...@@ -75,7 +75,7 @@ export class StudioActionUtil { ...@@ -75,7 +75,7 @@ export class StudioActionUtil {
if (Environment.devMode) { if (Environment.devMode) {
on(window, 'keydown', (e: KeyboardEvent) => { on(window, 'keydown', (e: KeyboardEvent) => {
if ((e.ctrlKey || e.metaKey) && e.keyCode === 123) { if ((e.ctrlKey || e.metaKey) && e.keyCode === 123) {
this.isShowTool = !this.isShowTool; this.showToolChange();
} }
}); });
} }
...@@ -119,8 +119,7 @@ export class StudioActionUtil { ...@@ -119,8 +119,7 @@ export class StudioActionUtil {
}, '*'); }, '*');
Vue.prototype.$message.warning('请在已打开的配置平台查看!'); Vue.prototype.$message.warning('请在已打开的配置平台查看!');
} else { } else {
console.log(`${Environment.StudioUrl}?ov=${JSON.stringify(params)}#/common_slnindex/srfkeys=${Environment.DCId}/sysdesign_psdevslnsysmodeltreeexpview/srfkey=${Environment.SysId}`); this.studioWin = window.open(`${Environment.StudioUrl}?ov=${encodeURIComponent(JSON.stringify(params))}#/common_slnindex/srfkeys=${Environment.SlnId}/sysdesign_psdevslnsysmodeltreeexpview/srfkey=${Environment.SysId}`, '_blank');
this.studioWin = window.open(`${Environment.StudioUrl}?ov=${encodeURIComponent(JSON.stringify(params))}#/common_slnindex/srfkeys=${Environment.DCId}/sysdesign_psdevslnsysmodeltreeexpview/srfkey=${Environment.SysId}`, '_blank');
} }
} }
} }
...@@ -156,6 +155,15 @@ export class StudioActionUtil { ...@@ -156,6 +155,15 @@ export class StudioActionUtil {
} }
} }
/**
* 展示配置工具栏状态变更
*
* @memberof StudioActionController
*/
public showToolChange(): void {
this.isShowTool = !this.isShowTool;
}
/** /**
* 获取实例 * 获取实例
* *
......
...@@ -345,4 +345,21 @@ export class Util { ...@@ -345,4 +345,21 @@ export class Util {
return fmt; return fmt;
} }
/**
* 深度合并对象
*
* @param FirstOBJ 目标对象
* @param SecondOBJ 原对象
* @returns {Object}
* @memberof Util
*/
public static deepObjectMerge(FirstOBJ:any, SecondOBJ:any) {
for (var key in SecondOBJ) {
FirstOBJ[key] = FirstOBJ[key] && FirstOBJ[key].toString() === "[object Object]" ?
this.deepObjectMerge(FirstOBJ[key], SecondOBJ[key]) : FirstOBJ[key] = SecondOBJ[key];
}
return FirstOBJ;
}
} }
\ No newline at end of file
...@@ -172,19 +172,7 @@ export default class ControlService { ...@@ -172,19 +172,7 @@ export default class ControlService {
// } // }
item[dataitem.name] = val; item[dataitem.name] = val;
}); });
if (isCreate) { item.srfuf = data.srfuf ? data.srfuf : (isCreate ? "0" : "1");
if(!item.srfuf){
Object.assign(item, {
srfuf: '0'
});
}
} else {
if(!item.srfuf){
Object.assign(item, {
srfuf: '1'
});
}
}
return item; return item;
} }
......
...@@ -794,6 +794,41 @@ ...@@ -794,6 +794,41 @@
debug "^3.1.0" debug "^3.1.0"
lodash.once "^4.1.1" lodash.once "^4.1.1"
"@fullcalendar/core@^4.4.0", "@fullcalendar/core@~4.4.0":
version "4.4.0"
resolved "https://registry.yarnpkg.com/@fullcalendar/core/-/core-4.4.0.tgz#79dbc0cca836ce628a07e739a456da11ff141373"
integrity sha512-PC4mmXHJHAlXmUEmZVnePyA8yYCOBdxBNq8yjJqedEtT1X0x36yTFz/Y0Ux6bniICZDqYtk0xoxe6jaxi++e0g==
"@fullcalendar/daygrid@^4.4.0", "@fullcalendar/daygrid@~4.4.0":
version "4.4.0"
resolved "https://registry.yarnpkg.com/@fullcalendar/daygrid/-/daygrid-4.4.0.tgz#25fcae7226b62688b4e086a611582e72253b5229"
integrity sha512-pDfvL0XZxKHTZ4VFOmwaYe3LmuABEIZsEopeqQ8y5O6BDen9KCbJqgHeCI8FpASSBd6bNlUx7il7EHdSoHhgIw==
"@fullcalendar/interaction@^4.4.0":
version "4.4.0"
resolved "https://registry.yarnpkg.com/@fullcalendar/interaction/-/interaction-4.4.0.tgz#fc8f8baaf5cb3533d6ce0a684d6f9952a4430685"
integrity sha512-nGu0ZzYYlNpIhqfyv3JupteWKFETs3W1MzbRJcEZkuPncn4BooEi4A2blgHfacHAmmpaNkT84tAmhzi734MFBA==
"@fullcalendar/list@^4.4.0":
version "4.4.0"
resolved "https://registry.yarnpkg.com/@fullcalendar/list/-/list-4.4.0.tgz#8edab49d06903b7de0ca68eefc1d44d0a58860a9"
integrity sha512-uUDSPS71czNTK5Z3x3HzeE3KIvqkCfvhY+mGFdaAL6+7VpCwEIfB6s3GIJOjzu9TONmczMk4jdq0b1WUFLY5PQ==
"@fullcalendar/timegrid@^4.4.0":
version "4.4.0"
resolved "https://registry.yarnpkg.com/@fullcalendar/timegrid/-/timegrid-4.4.0.tgz#c5837cfd676afff0d95535ac4cc054ed65965976"
integrity sha512-QwJ9oM87/ZTbXaE8PMIVp20GPtVCFmroaeR1GydJ6BKYtbxG/nsaSv7RhqvDa2jLjHaTWC2NjHo9hRfjQjtCZA==
dependencies:
"@fullcalendar/daygrid" "~4.4.0"
"@fullcalendar/vue@^4.4.0":
version "4.4.0"
resolved "https://registry.yarnpkg.com/@fullcalendar/vue/-/vue-4.4.0.tgz#d7c7025217d09407939d6bad687629d217501b27"
integrity sha512-9lvlUhQRvqBMstLqfsnwZ8EBHV0PMETgWnlCvpMZfA9zBfB9tb0f6mSFRScKbYDiT4wPpigBjJXMFaoRlqHleA==
dependencies:
"@fullcalendar/core" "~4.4.0"
fast-deep-equal "^2.0.1"
"@hapi/address@2.x.x": "@hapi/address@2.x.x":
version "2.1.4" version "2.1.4"
resolved "https://registry.yarnpkg.com/@hapi/address/-/address-2.1.4.tgz#5d67ed43f3fd41a69d4b9ff7b56e7c0d1d0a81e5" resolved "https://registry.yarnpkg.com/@hapi/address/-/address-2.1.4.tgz#5d67ed43f3fd41a69d4b9ff7b56e7c0d1d0a81e5"
...@@ -826,6 +861,121 @@ ...@@ -826,6 +861,121 @@
dependencies: dependencies:
"@hapi/hoek" "^8.3.0" "@hapi/hoek" "^8.3.0"
"@interactjs/actions@1.9.4":
version "1.9.4"
resolved "https://registry.yarnpkg.com/@interactjs/actions/-/actions-1.9.4.tgz#8249dd1771e0d9b3260cbb7e20579e4051ee85cd"
integrity sha512-mEru1f/t0bbbBsu6pGjqKSs/ZOmW6nJ5kVKNcgqeIRw1J09EUmQnjtI1C0kgyuoaCQiUjGIstpeyiDz2oOedDA==
optionalDependencies:
"@interactjs/interact" "1.9.4"
"@interactjs/auto-scroll@1.9.4":
version "1.9.4"
resolved "https://registry.yarnpkg.com/@interactjs/auto-scroll/-/auto-scroll-1.9.4.tgz#6ec104f47b6397755a61d9c4e78eb7daf5a08826"
integrity sha512-3xIKw473slijgU/QDVYgTfZkIBox+Ke/zEvG3h2GZsZ+Y2LMyHs2AW4lHMB7X38GKg+oCcb+23aGnrWd8TiNCw==
optionalDependencies:
"@interactjs/interact" "1.9.4"
"@interactjs/auto-start@1.9.4":
version "1.9.4"
resolved "https://registry.yarnpkg.com/@interactjs/auto-start/-/auto-start-1.9.4.tgz#a585e88fcc98761f928e3009f65e9f7a8a528664"
integrity sha512-zYnNRi+te7mQo8ssQUSAdX7tzJT7hSeWbyz8Sl7qlv7Ms7pIfckV+BWSxWtXiPfduZDYK8JFfS83diMbAs5qAA==
optionalDependencies:
"@interactjs/interact" "1.9.4"
"@interactjs/core@1.9.4":
version "1.9.4"
resolved "https://registry.yarnpkg.com/@interactjs/core/-/core-1.9.4.tgz#480fcb1b167765fea3609087b1da81be4a6ebed3"
integrity sha512-+ln6A5gcWi8H49qUKrlZijzLt3qtRU74DY4GbiXQrZc5gxu8xKy3uriUBHupAU21g35tySrA1UZPLV4vOclzMg==
"@interactjs/dev-tools@1.9.4":
version "1.9.4"
resolved "https://registry.yarnpkg.com/@interactjs/dev-tools/-/dev-tools-1.9.4.tgz#046b47171c67e0e9f28b5bd0b36befb3304f6910"
integrity sha512-UOFWiuqTkKnK5nN7gGgkZdh96Y2+PzP2SS+OGVaWPXu0xXM9g0UeqeEwCc+NAJFHYhcTqF6u74maQqop6wHWXg==
dependencies:
"@interactjs/utils" "1.9.4"
optionalDependencies:
"@interactjs/interact" "1.9.4"
"@interactjs/inertia@1.9.4":
version "1.9.4"
resolved "https://registry.yarnpkg.com/@interactjs/inertia/-/inertia-1.9.4.tgz#75d2a8989db0d784900c9b4143ff694a10195a8c"
integrity sha512-DtxEeJACySMjsNejELqXNgA7JoOR2SIOryb752PTcwYXaj01WvQOvtUnOtf3lbyos5JciDqU42tHQtAPDYbiJA==
optionalDependencies:
"@interactjs/interact" "1.9.4"
"@interactjs/interact@1.9.4":
version "1.9.4"
resolved "https://registry.yarnpkg.com/@interactjs/interact/-/interact-1.9.4.tgz#02385a62402ff14e83f18aaa442a81a1a0544cfe"
integrity sha512-mil5jzYEEwM3YJ+Uz/fYZlXVgpljDCF0u2xcDfu5x21NRd3A1UW/ZaTQgsBLt21Wz4l7waHJ2eLANvQJ+XqWhw==
"@interactjs/interactjs@1.9.4":
version "1.9.4"
resolved "https://registry.yarnpkg.com/@interactjs/interactjs/-/interactjs-1.9.4.tgz#2598b782142123acb381b43e6311ae351a98a537"
integrity sha512-9kIXh07lQ6qGJwvWqpixIKsjrozuemtMr33X2hSqBjdj1gHc76Dlanog2OmLhxp8JcynutMrQ6VLaxrel9fg6Q==
dependencies:
"@interactjs/actions" "1.9.4"
"@interactjs/auto-scroll" "1.9.4"
"@interactjs/auto-start" "1.9.4"
"@interactjs/dev-tools" "1.9.4"
"@interactjs/inertia" "1.9.4"
"@interactjs/interact" "1.9.4"
"@interactjs/modifiers" "1.9.4"
"@interactjs/offset" "1.9.4"
"@interactjs/pointer-events" "1.9.4"
"@interactjs/reflow" "1.9.4"
"@interactjs/types" "1.9.4"
"@interactjs/utils" "1.9.4"
"@interactjs/modifiers@1.9.4":
version "1.9.4"
resolved "https://registry.yarnpkg.com/@interactjs/modifiers/-/modifiers-1.9.4.tgz#c8f30d1c197d9dfdcb2513af1633ed13790ec01b"
integrity sha512-AAz3vlcfB81n0euk1eUsrsqpF1T5O5aFIidO+qI+ArPZ/aOSa7nUB3qnH6JyjR27jV9UNL03cpkGFBXhuHfhbw==
optionalDependencies:
"@interactjs/interact" "1.9.4"
"@interactjs/offset@1.9.4":
version "1.9.4"
resolved "https://registry.yarnpkg.com/@interactjs/offset/-/offset-1.9.4.tgz#c7aeee4e6837ed91df20148cfaa592d03da77e07"
integrity sha512-0FQCSFz4EzvW9oZbfCU85wl4wZLjie7bJ3ZRKdM+cAe4XQ5pNPWdrdld3z1omnQujIUW8kDFA3j2g/8agsBrXg==
optionalDependencies:
"@interactjs/interact" "1.9.4"
"@interactjs/pointer-events@1.9.4":
version "1.9.4"
resolved "https://registry.yarnpkg.com/@interactjs/pointer-events/-/pointer-events-1.9.4.tgz#e89e607443af20d984a1db72cb2cbf9779bb6761"
integrity sha512-94fa18INZO/UUfyEydyyQPeTu9ISMIwX1VCMYzIha6yMQ+6n5yaAFLl0nP9qFbR8wTCBqGjrdEm4Db3IxVlCVg==
optionalDependencies:
"@interactjs/interact" "1.9.4"
"@interactjs/reflow@1.9.4":
version "1.9.4"
resolved "https://registry.yarnpkg.com/@interactjs/reflow/-/reflow-1.9.4.tgz#c0d9f443e14f4457b8f84b950cdbb8011048c619"
integrity sha512-GC4S/zXxQ7zGs5Xa4hrKlGxUc41uuyV1eBuSx/GnzukmDoyyrdqXf0BwcMSeg4MZeva7p4gWdEsiNVaF2kPOSQ==
optionalDependencies:
"@interactjs/interact" "1.9.4"
"@interactjs/types@1.9.4":
version "1.9.4"
resolved "https://registry.yarnpkg.com/@interactjs/types/-/types-1.9.4.tgz#b6bcb480258169b88dfcea24490629f7a7d4a744"
integrity sha512-+5do2EnrHcL4pm0FPDcb5u1/Oo0zyujmPeKSLtoDyHZvAmD4kak1WAm7f0lMIW3y4iwkKPa/xKKk1MaKL9rsFQ==
dependencies:
"@interactjs/actions" "1.9.4"
"@interactjs/auto-scroll" "1.9.4"
"@interactjs/auto-start" "1.9.4"
"@interactjs/core" "1.9.4"
"@interactjs/dev-tools" "1.9.4"
"@interactjs/inertia" "1.9.4"
"@interactjs/interact" "1.9.4"
"@interactjs/modifiers" "1.9.4"
"@interactjs/pointer-events" "1.9.4"
"@interactjs/reflow" "1.9.4"
"@interactjs/utils" "1.9.4"
"@interactjs/utils@1.9.4":
version "1.9.4"
resolved "https://registry.yarnpkg.com/@interactjs/utils/-/utils-1.9.4.tgz#e8051de35bb0fd136cc6ff833db054b428492ec0"
integrity sha512-HLcH6Ygg6mejamlzNkqT1w+h7+gvfz09yIKDVkqitXB4ScGRwDcxTZiVZSjvW/R5Onp9WJ6msoZB0JhPtaOylw==
"@intervolga/optimize-cssnano-plugin@^1.0.5": "@intervolga/optimize-cssnano-plugin@^1.0.5":
version "1.0.6" version "1.0.6"
resolved "https://registry.yarnpkg.com/@intervolga/optimize-cssnano-plugin/-/optimize-cssnano-plugin-1.0.6.tgz#be7c7846128b88f6a9b1d1261a0ad06eb5c0fdf8" resolved "https://registry.yarnpkg.com/@intervolga/optimize-cssnano-plugin/-/optimize-cssnano-plugin-1.0.6.tgz#be7c7846128b88f6a9b1d1261a0ad06eb5c0fdf8"
...@@ -1043,6 +1193,13 @@ ...@@ -1043,6 +1193,13 @@
resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0" resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0"
integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ== integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==
"@types/echarts@^4.4.3":
version "4.4.3"
resolved "https://registry.yarnpkg.com/@types/echarts/-/echarts-4.4.3.tgz#9a04003c3a70cc6feb38de5220cc1d079f19f2cb"
integrity sha512-HmDmg9hDJQC5KOpNOeVgcaBM+emDiduNyCCHVInDrVVfLDVPuK4fSSISy39kn1HqPa1hYDQ96FIGEhjRNGHhPA==
dependencies:
"@types/zrender" "*"
"@types/events@*": "@types/events@*":
version "3.0.0" version "3.0.0"
resolved "https://registry.yarnpkg.com/@types/events/-/events-3.0.0.tgz#2862f3f58a9a7f7c3e78d79f130dd4d71c25c2a7" resolved "https://registry.yarnpkg.com/@types/events/-/events-3.0.0.tgz#2862f3f58a9a7f7c3e78d79f130dd4d71c25c2a7"
...@@ -1151,6 +1308,11 @@ ...@@ -1151,6 +1308,11 @@
dependencies: dependencies:
"@types/yargs-parser" "*" "@types/yargs-parser" "*"
"@types/zrender@*":
version "4.0.0"
resolved "https://registry.yarnpkg.com/@types/zrender/-/zrender-4.0.0.tgz#a6806f12ec4eccaaebd9b0d816f049aca6188fbd"
integrity sha512-s89GOIeKFiod2KSqHkfd2rzx+T2DVu7ihZCBEBnhFrzvQPUmzvDSBot9Fi1DfMQm9Odg+rTqoMGC38RvrwJK2w==
"@vue/babel-helper-vue-jsx-merge-props@^1.0.0": "@vue/babel-helper-vue-jsx-merge-props@^1.0.0":
version "1.0.0" version "1.0.0"
resolved "https://registry.yarnpkg.com/@vue/babel-helper-vue-jsx-merge-props/-/babel-helper-vue-jsx-merge-props-1.0.0.tgz#048fe579958da408fb7a8b2a3ec050b50a661040" resolved "https://registry.yarnpkg.com/@vue/babel-helper-vue-jsx-merge-props/-/babel-helper-vue-jsx-merge-props-1.0.0.tgz#048fe579958da408fb7a8b2a3ec050b50a661040"
...@@ -1626,6 +1788,14 @@ address@^1.1.2: ...@@ -1626,6 +1788,14 @@ address@^1.1.2:
resolved "https://registry.yarnpkg.com/address/-/address-1.1.2.tgz#bf1116c9c758c51b7a933d296b72c221ed9428b6" resolved "https://registry.yarnpkg.com/address/-/address-1.1.2.tgz#bf1116c9c758c51b7a933d296b72c221ed9428b6"
integrity sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA== integrity sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA==
adler-32@~1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/adler-32/-/adler-32-1.2.0.tgz#6a3e6bf0a63900ba15652808cb15c6813d1a5f25"
integrity sha1-aj5r8KY5ALoVZSgIyxXGgT0aXyU=
dependencies:
exit-on-epipe "~1.0.1"
printj "~1.1.0"
aggregate-error@^3.0.0: aggregate-error@^3.0.0:
version "3.0.1" version "3.0.1"
resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.0.1.tgz#db2fe7246e536f40d9b5442a39e117d7dd6a24e0" resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.0.1.tgz#db2fe7246e536f40d9b5442a39e117d7dd6a24e0"
...@@ -2540,6 +2710,16 @@ caseless@~0.12.0: ...@@ -2540,6 +2710,16 @@ caseless@~0.12.0:
resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=
cfb@^1.1.4:
version "1.1.4"
resolved "https://registry.yarnpkg.com/cfb/-/cfb-1.1.4.tgz#81fd35ede4c919d8f0962a94582e1dfaf7051e2a"
integrity sha512-rwFkl3aFO3f+ljR27YINwC0x8vPjyiEVbYbrTCKzspEf7Q++3THdfHVgJYNUbxNcupJECrLX+L40Mjm9hm/Bgw==
dependencies:
adler-32 "~1.2.0"
commander "^2.16.0"
crc-32 "~1.2.0"
printj "~1.1.2"
chalk@2.4.2, chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.0, chalk@^2.4.1, chalk@^2.4.2: chalk@2.4.2, chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.0, chalk@^2.4.1, chalk@^2.4.2:
version "2.4.2" version "2.4.2"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
...@@ -2757,6 +2937,14 @@ code-point-at@^1.0.0: ...@@ -2757,6 +2937,14 @@ code-point-at@^1.0.0:
resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77"
integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=
codepage@~1.14.0:
version "1.14.0"
resolved "https://registry.yarnpkg.com/codepage/-/codepage-1.14.0.tgz#8cbe25481323559d7d307571b0fff91e7a1d2f99"
integrity sha1-jL4lSBMjVZ19MHVxsP/5HnodL5k=
dependencies:
commander "~2.14.1"
exit-on-epipe "~1.0.1"
collection-visit@^1.0.0: collection-visit@^1.0.0:
version "1.0.0" version "1.0.0"
resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0"
...@@ -2822,16 +3010,21 @@ commander@2.15.1: ...@@ -2822,16 +3010,21 @@ commander@2.15.1:
resolved "https://registry.yarnpkg.com/commander/-/commander-2.15.1.tgz#df46e867d0fc2aec66a34662b406a9ccafff5b0f" resolved "https://registry.yarnpkg.com/commander/-/commander-2.15.1.tgz#df46e867d0fc2aec66a34662b406a9ccafff5b0f"
integrity sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag== integrity sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==
commander@2.17.x: commander@2.17.x, commander@~2.17.1:
version "2.17.1" version "2.17.1"
resolved "https://registry.yarnpkg.com/commander/-/commander-2.17.1.tgz#bd77ab7de6de94205ceacc72f1716d29f20a77bf" resolved "https://registry.yarnpkg.com/commander/-/commander-2.17.1.tgz#bd77ab7de6de94205ceacc72f1716d29f20a77bf"
integrity sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg== integrity sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==
commander@^2.12.1, commander@^2.18.0, commander@^2.19.0, commander@^2.20.0, commander@~2.20.3: commander@^2.12.1, commander@^2.16.0, commander@^2.18.0, commander@^2.19.0, commander@^2.20.0, commander@~2.20.3:
version "2.20.3" version "2.20.3"
resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
commander@~2.14.1:
version "2.14.1"
resolved "https://registry.yarnpkg.com/commander/-/commander-2.14.1.tgz#2235123e37af8ca3c65df45b026dbd357b01b9aa"
integrity sha512-+YR16o3rK53SmWHU3rEM3tPAh2rwb1yPcQX5irVn7mb0gXbwuCCrnkbV5+PBfETdfg1vui07nM6PCG1zndcjQw==
commander@~2.19.0: commander@~2.19.0:
version "2.19.0" version "2.19.0"
resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a" resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a"
...@@ -3023,6 +3216,14 @@ cosmiconfig@^5.0.0: ...@@ -3023,6 +3216,14 @@ cosmiconfig@^5.0.0:
js-yaml "^3.13.1" js-yaml "^3.13.1"
parse-json "^4.0.0" parse-json "^4.0.0"
crc-32@~1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/crc-32/-/crc-32-1.2.0.tgz#cb2db6e29b88508e32d9dd0ec1693e7b41a18208"
integrity sha512-1uBwHxF+Y/4yF5G48fwnKq6QsIXheor3ZLPT80yGBV1oEUwpPojlEhQbWKVw1VwcTQyMGHK1/XMmTjmlsmTTGA==
dependencies:
exit-on-epipe "~1.0.1"
printj "~1.1.0"
create-ecdh@^4.0.0: create-ecdh@^4.0.0:
version "4.0.3" version "4.0.3"
resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.3.tgz#c9111b6f33045c4697f144787f9254cdc77c45ff" resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.3.tgz#c9111b6f33045c4697f144787f9254cdc77c45ff"
...@@ -3696,6 +3897,13 @@ ecc-jsbn@~0.1.1: ...@@ -3696,6 +3897,13 @@ ecc-jsbn@~0.1.1:
jsbn "~0.1.0" jsbn "~0.1.0"
safer-buffer "^2.1.0" safer-buffer "^2.1.0"
echarts@^4.6.0:
version "4.7.0"
resolved "https://registry.yarnpkg.com/echarts/-/echarts-4.7.0.tgz#5b3875a4c2f91e3929425fabab9eace7e4098b3f"
integrity sha512-NlOTdUcAsIyCCG+N4uh0ZEvXtrPW2jvcuqf03RyqYeCKzyPbiOQ4I3MdKXMhxG3lBdqQNdNXVT71SB4KTQjN0A==
dependencies:
zrender "4.3.0"
editorconfig@^0.15.3: editorconfig@^0.15.3:
version "0.15.3" version "0.15.3"
resolved "https://registry.yarnpkg.com/editorconfig/-/editorconfig-0.15.3.tgz#bef84c4e75fb8dcb0ce5cee8efd51c15999befc5" resolved "https://registry.yarnpkg.com/editorconfig/-/editorconfig-0.15.3.tgz#bef84c4e75fb8dcb0ce5cee8efd51c15999befc5"
...@@ -3726,6 +3934,13 @@ elegant-spinner@^1.0.1: ...@@ -3726,6 +3934,13 @@ elegant-spinner@^1.0.1:
resolved "https://registry.yarnpkg.com/elegant-spinner/-/elegant-spinner-1.0.1.tgz#db043521c95d7e303fd8f345bedc3349cfb0729e" resolved "https://registry.yarnpkg.com/elegant-spinner/-/elegant-spinner-1.0.1.tgz#db043521c95d7e303fd8f345bedc3349cfb0729e"
integrity sha1-2wQ1IcldfjA/2PNFvtwzSc+wcp4= integrity sha1-2wQ1IcldfjA/2PNFvtwzSc+wcp4=
element-resize-detector@^1.1.15:
version "1.2.1"
resolved "https://registry.yarnpkg.com/element-resize-detector/-/element-resize-detector-1.2.1.tgz#b0305194447a4863155e58f13323a0aef30851d1"
integrity sha512-BdFsPepnQr9fznNPF9nF4vQ457U/ZJXQDSNF1zBe7yaga8v9AdZf3/NElYxFdUh7SitSGt040QygiTo6dtatIw==
dependencies:
batch-processor "1.0.0"
element-resize-detector@^1.2.0: element-resize-detector@^1.2.0:
version "1.2.0" version "1.2.0"
resolved "https://registry.yarnpkg.com/element-resize-detector/-/element-resize-detector-1.2.0.tgz#63344fd6f4e5ecff6f018d027e17b281fd4fa338" resolved "https://registry.yarnpkg.com/element-resize-detector/-/element-resize-detector-1.2.0.tgz#63344fd6f4e5ecff6f018d027e17b281fd4fa338"
...@@ -4027,6 +4242,11 @@ exit-hook@^1.0.0: ...@@ -4027,6 +4242,11 @@ exit-hook@^1.0.0:
resolved "https://registry.yarnpkg.com/exit-hook/-/exit-hook-1.1.1.tgz#f05ca233b48c05d54fff07765df8507e95c02ff8" resolved "https://registry.yarnpkg.com/exit-hook/-/exit-hook-1.1.1.tgz#f05ca233b48c05d54fff07765df8507e95c02ff8"
integrity sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g= integrity sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g=
exit-on-epipe@~1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/exit-on-epipe/-/exit-on-epipe-1.0.1.tgz#0bdd92e87d5285d267daa8171d0eb06159689692"
integrity sha512-h2z5mrROTxce56S+pnvAV890uu7ls7f1kEvVGJbw1OlFH3/mlJ5bkXu0KRyW94v37zzHPiUd55iLn3DA7TjWpw==
exit@^0.1.2: exit@^0.1.2:
version "0.1.2" version "0.1.2"
resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c"
...@@ -4237,6 +4457,11 @@ file-loader@^4.2.0: ...@@ -4237,6 +4457,11 @@ file-loader@^4.2.0:
loader-utils "^1.2.3" loader-utils "^1.2.3"
schema-utils "^2.5.0" schema-utils "^2.5.0"
file-saver@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/file-saver/-/file-saver-2.0.2.tgz#06d6e728a9ea2df2cce2f8d9e84dfcdc338ec17a"
integrity sha512-Wz3c3XQ5xroCxd1G8b7yL0Ehkf0TC9oYC6buPFkNnU9EnaPlifeAFCyCh+iewXTyFRcg0a6j3J7FmJsIhlhBdw==
file-uri-to-path@1.0.0: file-uri-to-path@1.0.0:
version "1.0.0" version "1.0.0"
resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd"
...@@ -4383,6 +4608,11 @@ forwarded@~0.1.2: ...@@ -4383,6 +4608,11 @@ forwarded@~0.1.2:
resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84"
integrity sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ= integrity sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=
frac@~1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/frac/-/frac-1.1.2.tgz#3d74f7f6478c88a1b5020306d747dc6313c74d0b"
integrity sha512-w/XBfkibaTl3YDqASwfDUqkna4Z2p9cFSr1aHDt0WoMTECnRfBOv2WArlZILlqgWlmdIlALXGpM2AOhEk5W3IA==
fragment-cache@^0.2.1: fragment-cache@^0.2.1:
version "0.2.1" version "0.2.1"
resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19"
...@@ -5046,6 +5276,14 @@ ini@^1.3.4: ...@@ -5046,6 +5276,14 @@ ini@^1.3.4:
resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927"
integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==
interactjs@^1.6.3, interactjs@^1.9.4:
version "1.9.4"
resolved "https://registry.yarnpkg.com/interactjs/-/interactjs-1.9.4.tgz#fba80cd9060dba289530457daaf3c9e27e9e51e9"
integrity sha512-61IDdhxwhkrJqhl/CscFNbf2EyPzhnCIokxvEBpUomEJm4XrTy/VbWq6n/DhcqG1hpSiefU6XJwC+RdMLZpr1w==
dependencies:
"@interactjs/interactjs" "1.9.4"
"@interactjs/types" "1.9.4"
internal-ip@^4.3.0: internal-ip@^4.3.0:
version "4.3.0" version "4.3.0"
resolved "https://registry.yarnpkg.com/internal-ip/-/internal-ip-4.3.0.tgz#845452baad9d2ca3b69c635a137acb9a0dad0907" resolved "https://registry.yarnpkg.com/internal-ip/-/internal-ip-4.3.0.tgz#845452baad9d2ca3b69c635a137acb9a0dad0907"
...@@ -7879,6 +8117,11 @@ pretty@2.0.0: ...@@ -7879,6 +8117,11 @@ pretty@2.0.0:
extend-shallow "^2.0.1" extend-shallow "^2.0.1"
js-beautify "^1.6.12" js-beautify "^1.6.12"
printj@~1.1.0, printj@~1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/printj/-/printj-1.1.2.tgz#d90deb2975a8b9f600fb3a1c94e3f4c53c78a222"
integrity sha512-zA2SmoLaxZyArQTOPj5LXecR+RagfPSU5Kw1qP+jkWeNlrq+eJZyY2oS68SU1Z/7/myXM4lo9716laOFAVStCQ==
private@^0.1.6: private@^0.1.6:
version "0.1.8" version "0.1.8"
resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff"
...@@ -8072,6 +8315,11 @@ raw-body@2.4.0: ...@@ -8072,6 +8315,11 @@ raw-body@2.4.0:
iconv-lite "0.4.24" iconv-lite "0.4.24"
unpipe "1.0.0" unpipe "1.0.0"
raw-loader@~0.5.1:
version "0.5.1"
resolved "https://registry.yarnpkg.com/raw-loader/-/raw-loader-0.5.1.tgz#0c3d0beaed8a01c966d9787bf778281252a979aa"
integrity sha1-DD0L6u2KAclm2Xh793goElKpeao=
react-is@^16.8.4: react-is@^16.8.4:
version "16.12.0" version "16.12.0"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.12.0.tgz#2cc0fe0fba742d97fd527c42a13bec4eeb06241c" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.12.0.tgz#2cc0fe0fba742d97fd527c42a13bec4eeb06241c"
...@@ -8495,6 +8743,13 @@ schema-utils@^2.0.0, schema-utils@^2.5.0, schema-utils@^2.6.0, schema-utils@^2.6 ...@@ -8495,6 +8743,13 @@ schema-utils@^2.0.0, schema-utils@^2.5.0, schema-utils@^2.6.0, schema-utils@^2.6
ajv "^6.10.2" ajv "^6.10.2"
ajv-keywords "^3.4.1" ajv-keywords "^3.4.1"
script-loader@^0.7.2:
version "0.7.2"
resolved "https://registry.yarnpkg.com/script-loader/-/script-loader-0.7.2.tgz#2016db6f86f25f5cf56da38915d83378bb166ba7"
integrity sha512-UMNLEvgOAQuzK8ji8qIscM3GIrRCWN6MmMXGD4SD5l6cSycgGsCo0tX5xRnfQcoghqct0tjHjcykgI1PyBE2aA==
dependencies:
raw-loader "~0.5.1"
select-hose@^2.0.0: select-hose@^2.0.0:
version "2.0.0" version "2.0.0"
resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca"
...@@ -8840,6 +9095,13 @@ sprintf-js@~1.0.2: ...@@ -8840,6 +9095,13 @@ sprintf-js@~1.0.2:
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=
ssf@~0.10.3:
version "0.10.3"
resolved "https://registry.yarnpkg.com/ssf/-/ssf-0.10.3.tgz#8eae1fc29c90a552e7921208f81892d6f77acb2b"
integrity sha512-pRuUdW0WwyB2doSqqjWyzwCD6PkfxpHAHdZp39K3dp/Hq7f+xfMwNAWIi16DyrRg4gg9c/RvLYkJTSawTPTm1w==
dependencies:
frac "~1.1.2"
sshpk@^1.7.0: sshpk@^1.7.0:
version "1.16.1" version "1.16.1"
resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877"
...@@ -9751,6 +10013,14 @@ vue-class-component@^7.0.2, vue-class-component@^7.1.0: ...@@ -9751,6 +10013,14 @@ vue-class-component@^7.0.2, vue-class-component@^7.1.0:
resolved "https://registry.yarnpkg.com/vue-class-component/-/vue-class-component-7.2.2.tgz#aecc6d28801f64c61eb04407cf3a5476da26b0c0" resolved "https://registry.yarnpkg.com/vue-class-component/-/vue-class-component-7.2.2.tgz#aecc6d28801f64c61eb04407cf3a5476da26b0c0"
integrity sha512-QjVfjRffux0rUBNtxr1hvUxDrfifDvk9q/OSdB/sKIlfxAudDF2E1YTeiEC+qOYIOOBGWkgSKQSnast6H+S38w== integrity sha512-QjVfjRffux0rUBNtxr1hvUxDrfifDvk9q/OSdB/sKIlfxAudDF2E1YTeiEC+qOYIOOBGWkgSKQSnast6H+S38w==
vue-grid-layout@^2.3.7:
version "2.3.7"
resolved "https://registry.yarnpkg.com/vue-grid-layout/-/vue-grid-layout-2.3.7.tgz#d148f013ef2ca9dc1cb5d5298e7966aa50f54431"
integrity sha512-q3FMiuog0hPsK/IUKtlg2A/lwPo86YlLaX9+wEiCTjUU++GabM2o9hDhRVruDJZLUah55iTg8LRttBxrxPv0WQ==
dependencies:
element-resize-detector "^1.1.15"
interactjs "^1.6.3"
vue-hot-reload-api@^2.3.0: vue-hot-reload-api@^2.3.0:
version "2.3.4" version "2.3.4"
resolved "https://registry.yarnpkg.com/vue-hot-reload-api/-/vue-hot-reload-api-2.3.4.tgz#532955cc1eb208a3d990b3a9f9a70574657e08f2" resolved "https://registry.yarnpkg.com/vue-hot-reload-api/-/vue-hot-reload-api-2.3.4.tgz#532955cc1eb208a3d990b3a9f9a70574657e08f2"
...@@ -10074,6 +10344,11 @@ which@^2.0.1: ...@@ -10074,6 +10344,11 @@ which@^2.0.1:
dependencies: dependencies:
isexe "^2.0.0" isexe "^2.0.0"
wmf@~1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/wmf/-/wmf-1.0.2.tgz#7d19d621071a08c2bdc6b7e688a9c435298cc2da"
integrity sha512-/p9K7bEh0Dj6WbXg4JG0xvLQmIadrner1bi45VMJTfnbVHsc7yIajZyoSoK60/dtVBs12Fm6WkUI5/3WAVsNMw==
word-wrap@~1.2.3: word-wrap@~1.2.3:
version "1.2.3" version "1.2.3"
resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c"
...@@ -10157,6 +10432,20 @@ ws@^7.0.0: ...@@ -10157,6 +10432,20 @@ ws@^7.0.0:
resolved "https://registry.yarnpkg.com/ws/-/ws-7.2.1.tgz#03ed52423cd744084b2cf42ed197c8b65a936b8e" resolved "https://registry.yarnpkg.com/ws/-/ws-7.2.1.tgz#03ed52423cd744084b2cf42ed197c8b65a936b8e"
integrity sha512-sucePNSafamSKoOqoNfBd8V0StlkzJKL2ZAhGQinCfNQ+oacw+Pk7lcdAElecBF2VkLNZRiIb5Oi1Q5lVUVt2A== integrity sha512-sucePNSafamSKoOqoNfBd8V0StlkzJKL2ZAhGQinCfNQ+oacw+Pk7lcdAElecBF2VkLNZRiIb5Oi1Q5lVUVt2A==
xlsx@^0.15.6:
version "0.15.6"
resolved "https://registry.yarnpkg.com/xlsx/-/xlsx-0.15.6.tgz#461f841d6d9ea1a8375e2cd246bf23aece08a1d5"
integrity sha512-7vD9eutyLs65iDjNFimVN+gk/oDkfkCgpQUjdE82QgzJCrBHC4bGPH7fzKVyy0UPp3gyFVQTQEFJaWaAvZCShQ==
dependencies:
adler-32 "~1.2.0"
cfb "^1.1.4"
codepage "~1.14.0"
commander "~2.17.1"
crc-32 "~1.2.0"
exit-on-epipe "~1.0.1"
ssf "~0.10.3"
wmf "~1.0.1"
xml-name-validator@^3.0.0: xml-name-validator@^3.0.0:
version "3.0.0" version "3.0.0"
resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a" resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a"
...@@ -10298,3 +10587,8 @@ yorkie@^2.0.0: ...@@ -10298,3 +10587,8 @@ yorkie@^2.0.0:
is-ci "^1.0.10" is-ci "^1.0.10"
normalize-path "^1.0.0" normalize-path "^1.0.0"
strip-indent "^2.0.0" strip-indent "^2.0.0"
zrender@4.3.0:
version "4.3.0"
resolved "https://registry.yarnpkg.com/zrender/-/zrender-4.3.0.tgz#9f056121b20bbae44414d287bf6a119ff7042661"
integrity sha512-Dii6j2bDsPkxQayuVf2DXJeruIB/mKVxxcGRZQ9GExiBd4c3w7+oBuvo1O/JGHeFeA1nCmSDVDs/S7yKZG1nrA==
Markdown 格式
0% or
您添加了 0 到此讨论。请谨慎行事。
先完成此消息的编辑!
想要评论请 注册