提交 bdfa2ed6 编写于 作者: ibizdev's avatar ibizdev

lab_qyk 发布系统代码

上级 4bb9425e

要显示的变更太多。

为了保持性能,仅显示文件中的 1000/1000+

# 系统概览 iBiz4j Spring R7 dev
> 1%
last 2 versions
## v7.0.0-alpha.11 [2020-6-21]
### Bug修复
修复标题工具栏样式遮挡bug
修复表格行编辑字段格式对齐
修复日历部件初始化压缩成一行问题
修复下拉多选组件最后一项数据无法删除
### 功能新增及优化
#### 模板
新增支持表单、表格新建默认值(当前时间)
新增行编辑浮点数精度格式化
新增首页面包屑导航模式
新增编辑视图第一条记录、上一条记录、下一条记录、最后一条记录界面行为
优化面板和多数据部件数据流向
优化表单在模态打开模式中padding样式
优化嵌入视图中工具栏消息数量提示样式
优化动态导航视图树样式
#### 基础文件
新增行编辑浮点数精度格式化
## v7.0.0-alpha.10 [2020-6-18]
### Bug修复
分页导航视图页面刷新bug
表单项更新,实体行为调用不到bug
关系界面子界面保存不触发父界面保存
表单样式调整
### 功能新增及优化
#### 模板
表格操作列只显示图标时显示tooltip
门户部件高度为0时自适应
面板和多数据部件数据流向
列表,数据视图保存功能
门户部件标题界面行为tooltip
新增面包屑、应用切换器组件
#### 基础文件
formitem样式调整,label适配位置
表格行编辑切换,app-picker不显示
文件上传下载参数格式处理
## v7.0.0-alpha.9 [2020-6-11]
### Bug修复
数值代码表多语言
树右键菜单滚动条样式bug
列表面板界面行为bug
多选视图界面逻辑修复
图表刷新bug修复
日历部件选中抛出数据逻辑调整
编辑视图,app-span显示0时不显示
树视图右键界面行为刷新bug
快捷菜单控制台报错bug
门户加载自定义模型错误时,正常显示默认看板
修复雷达图显示异常问题
修复编辑类、分页导航视图带数据标题问题
修复饼图、漏斗图 获取序列参数错误问题
### 功能新增及优化
#### 模板
看板和门户布局模板调整,支持门户部件标题栏界面行为组
支持数据选择、地址框、自动完成、下拉列表、标签、选项框列表、单选列表等编辑器导航参数调整
支持树导航栏、表格导航栏、列表导航栏、卡片导航栏、日历导航栏、表单关系界面、数据选择面板、分页导航面板、数据关系栏、界面行为、新建逻辑、编辑逻辑导航参数调整
支持图表无数据时显示暂无数据
支持表格新建默认值
支持日历部件右键菜单
支持表格列触发界面行为
面板布局调整
#### 基础文件
门户部件视图的样式
数据选择,地址框,自动完成,下拉列表,标签,选项框列表,单选列表等编辑器导航参数调整
表单项label位置
调整登录页面
穿梭框编辑器支持
## v7.0.0-alpha.8 [2020-6-4]
### Bug修复
修复树右键菜单事件传值bug
修复树节点图标样式
修复viewdata和viewparams解析不同步
修复界面行为多主键分隔符由";"改为","
修复多层导航失效
数据选择,自动填充编辑器参数处理,动态代码表编辑器参数
修复富文本国际化bug
修复坐标轴的自定义参数
修复分页面板配置导航参数
修复实体处理逻辑
修复应用级context对象特性丢失的问题
修复新建逻辑
修复动态代码表传递上下文、参数逻辑
### 功能新增及优化
#### 模板
树选择双击
列表快速分组和快速搜索表单
数据视图快速分组和快速搜索表单
日历图例、日历快速分组和批处理工具栏
实体国际化路径调整
面板界面行为支持
列表,数据视图下拉加载
增加图表名称代码表识别、雷达图支持
uaa菜单权限
增加数据看板动态模型数据存库
应用样式调整
#### 基础文件
人员选择标准控件样式调整
应用样式调整
## v7.0.0-alpha.7 [2020-5-28]
### Bug修复
修复门户部件flex布局
修复表格选择框列样式出现省略号
修复批删除传递参数调整
修复表单上界面行为参数传递bug
修复分页导航、编辑类视图标题
修复界面行为多主键分隔符由";"改为","
修复导航类视图宽度格式
修复图表排序
修复关系界面逻辑
修复401跳登录页清除user和token
### 功能新增及优化
#### 模板
列表,数据视图默认排序
面板项支持偏移
应用支持自定义默认端口
门户部件图标和容器样式
表格列头图片和头部样式
表格操作列图标
表格编辑项值规则
增加树选择双击事件
增加图表分组属性计数统计(srfcount)
增加雷达图支持
#### 基础文件
修复分页导航、编辑类视图标题
修复界面行为多主键分隔符由";"改为","
修复关系界面逻辑
修复401跳登录页清除user和token
## v7.0.0-alpha.6 [2020-5-23]
### Bug修复
修复处理快速分组模型动态数据部分
修复列表,数据视图默认排序
### 功能新增及优化
#### 模板
补充单位选择器、部门选择器、人员选择器
#### 基础文件
补充单位选择器、部门选择器、人员选择器
## v7.0.0-alpha.5 [2020-5-21]
### Bug修复
修复表格视图搜索placeholder显示为搜索字段
修复表单嵌表单分页异常
修复门户视图操作栏标题
修复看板部件高度自动撑
修复表单分组,界面行为组不显示
修复表格操作列数据异常
### 功能新增及优化
#### 模板
支持拷贝功能
支持实体甘特图视图
支持面板项隐藏表单项
支持表格列最小宽度和操作列样式支持
支持列表项、面板代码表转化
#### 基础文件
支持列表项、面板代码表转化
修复表单分组,界面行为组不显示
## v7.0.0-alpha.4 [2020-5-14]
### Bug修复
修复代码表代码项图标和数据
修复数据多项选择视图UI逻辑不匹配
修复列表高度异常
修复树节点上下文
修复表格(视图)高度,滚动条问题
修复表单loaddraft服务仿真主键丢失修复
修复user显示名称逻辑
修复issue地址为正式环境地址
### 功能新增及优化
#### 模板
模态时视图样式调整
增加菜单权限
增加快速分组搜索或快速搜索表单功能
增加表格内置工具栏
代码表多选控件分割符从分号转化为逗号
#### 基础文件
增加数据选择类插件表格呈现插件
## v7.0.0-alpha.3 [2020-5-10]
### Bug修复
分页导航栏传递srfparentdename和srfparentkey问题
提交流程、启动流程刷新表格数据问题
修复视图自定义导航参数大小写问题
修复批添加功能
修复树部件查询数据集合异常处理
修复图表排序问题
修复富文本国际化切换失效
### 功能新增及优化
#### 模板
搜索面板布局优化
表格checkbox宽度优化
选择类视图不显示标题
补充树节点关系导航上下文,导航参数上下文
#### 基础文件
登录页面调整
## v7.0.0-alpha.2 [2020-5-7]
### Bug修复
分页导航栏添加图标配置
### 功能新增及优化
#### 模板
表格文件上传信息显示
批添加、批删除
实体工作流动态视图
实体工作流动态导航表格视图
富文本信息模式
更新默认值
#### 基础文件
表格文件上传信息显示
实体工作流动态视图
实体工作流动态导航表格视图
## v7.0.0-alpha.1 [2020-4-29]
初始化文件
\ No newline at end of file
## 前言
### 1. 简介
该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
```
以下为 Windows 环境开发正常配置
<br>
<br>
![开发环境信息](./imgs/getting-started/development.png)
### 2. 安装依赖
打开前端项目,进入工作空间下,执行安装依赖命令
```bash
$ yarn install
```
### 3. 启动
在工作空间下,执行启动命令
```bash
$ yarn dev-serve
```
启动后,通过 vue.config.js 开发服务 devServer 下配置的本地启动端口号访问开发项目。<br>
示例:
```bash
$ http://localhost:8111
```
这儿需要注意一点,此时启动的项目访问的数据是我们前端的mock数据,如需与后台直接交互,请看第4点。
### 4. 远程代理
在工作空间下,执行启动命令
```bash
$ yarn serve
```
修改远程代理文件 vue.config.js 代理地址
![远程代理地址](./imgs/getting-started/proxy.png)
### 5. 打包
在工作空间下,执行打包命令
```bash
$ yarn build
```
打包完成,生成最终交付产物。
## 成果物结构
```
|─ ─ app_Web
​ |─ ─ public public文件夹
​ |─ ─ assets 静态文件夹
|─ ─ favicon.ico 图标
​ |─ ─ src 工程文件夹
|─ ─ assets 静态资源
|─ ─ codelist 动态代码表服务
|─ ─ components 基础组件,主要包含编辑器组件和其他全局使用的组件
|─ ─ counter 计数器服务
|─ ─ 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 工具类文件
|─ ─ utilservice 应用功能服务
|─ ─ 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 配置
```
## 如何贡献
如果你希望参与贡献,欢迎 [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自助服务群(中文)
<img src="./imgs/getting-started/vue-r7-group.png" height="400" width="400">
\ No newline at end of file
module.exports = {
presets: [
'@vue/cli-plugin-babel/preset'
]
}
{
"pluginsFile": "tests/e2e/plugins/index.js"
}
module.exports = {
preset: '@vue/cli-plugin-unit-jest/presets/typescript-and-babel'
}
{
"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"
}
}
}
}
{
"name": "app",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "node --max_old_space_size=8102 ./node_modules/@vue/cli-service/bin/vue-cli-service serve --mode test",
"dev-serve": "node --max_old_space_size=8102 ./node_modules/@vue/cli-service/bin/vue-cli-service serve --mode development",
"build": "node --max_old_space_size=8102 ./node_modules/@vue/cli-service/bin/vue-cli-service build",
"dev-build": "node --max_old_space_size=8102 ./node_modules/@vue/cli-service/bin/vue-cli-service build --mode development",
"test:unit": "vue-cli-service test:unit",
"test:e2e": "vue-cli-service test:e2e",
"lint": "vue-cli-service lint"
},
"dependencies": {
"@fullcalendar/core": "^4.4.0",
"@fullcalendar/daygrid": "^4.4.0",
"@fullcalendar/interaction": "^4.4.0",
"@fullcalendar/list": "^4.4.0",
"@fullcalendar/timegrid": "^4.4.0",
"@fullcalendar/vue": "^4.4.0",
"vuedraggable": "^2.23.2",
"async-validator": "^3.3.0",
"axios": "^0.19.1",
"core-js": "^3.4.4",
"echarts": "^4.6.0",
"element-ui": "^2.13.0",
"file-saver": "^2.0.2",
"font-awesome": "^4.7.0",
"ibiz-gantt-elastic": "^1.0.17",
"ibiz-vue-lib": "^0.1.10",
"interactjs": "^1.9.4",
"moment": "^2.24.0",
"path-to-regexp": "^6.1.0",
"qs": "^6.9.1",
"rxjs": "^6.5.4",
"tinymce": "4.8.5",
"view-design": "^4.1.0",
"vue": "^2.6.10",
"vue-class-component": "^7.0.2",
"vue-grid-layout": "^2.3.7",
"vue-i18n": "^8.15.3",
"vue-property-decorator": "^8.3.0",
"vue-router": "^3.1.3",
"vuex": "^3.1.2",
"xlsx": "^0.15.6"
},
"devDependencies": {
"@types/echarts": "^4.4.3",
"@types/jest": "^24.0.19",
"@types/mockjs": "^1.0.2",
"@types/qs": "^6.9.0",
"@vue/cli-plugin-babel": "^4.1.0",
"@vue/cli-plugin-e2e-cypress": "^4.1.0",
"@vue/cli-plugin-router": "^4.1.0",
"@vue/cli-plugin-typescript": "^4.1.0",
"@vue/cli-plugin-unit-jest": "^4.1.0",
"@vue/cli-plugin-vuex": "^4.1.0",
"@vue/cli-service": "^4.1.0",
"@vue/test-utils": "1.0.0-beta.29",
"axios-mock-adapter": "^1.17.0",
"compression-webpack-plugin": "^4.0.0",
"less": "^3.0.4",
"less-loader": "^5.0.0",
"mockjs": "^1.1.0",
"script-loader": "^0.7.2",
"typescript": "~3.5.3",
"vue-template-compiler": "^2.6.10"
}
}
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>ibzrt</artifactId>
<groupId>cn.ibizlab</groupId>
<version>1.0.0.0</version>
</parent>
<artifactId>ibzrt-web</artifactId>
<name>Ibzrt Web</name>
<description>Ibzrt Web</description>
<dependencies>
</dependencies>
</project>
<?xml version="1.0" encoding="UTF-8"?>
<svg width="277px" height="60px" viewBox="0 0 277 60" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 55.2 (78181) - https://sketchapp.com -->
<title>logo</title>
<desc>Created with Sketch.</desc>
<g id="页面1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Apple-TV" transform="translate(-822.000000, -80.000000)" fill-rule="nonzero">
<g id="logo" transform="translate(822.000000, 80.000000)">
<path d="M84.7587939,33 C84.3400314,33 83.9422129,32.855404 83.5653265,32.5662099 C83.1884404,32.2770158 83,31.9117221 83,31.4703186 C83,30.8006061 83.3517553,30.0547979 84.0552764,29.2328759 C84.7587975,28.4109559 85.4874333,28 86.2412061,28 C86.7437211,28 87.1624774,28.1407903 87.4974874,28.422375 C87.8324974,28.7039598 88,29.1111079 88,29.6438359 C88,30.2983298 87.6566197,31.0213058 86.9698493,31.8127843 C86.2830787,32.6042648 85.5460676,33 84.7587939,33 Z M87,43.1071413 L87,44.8800002 C85.4032842,46.9038197 83.913587,48.4297553 82.5308641,49.4578566 C81.1481411,50.4859558 79.9711982,51 79,51 C77.6501989,51 76.6460938,50.3038162 75.9876542,48.9114271 C75.3292146,47.51904 75,45.9971505 75,44.345713 C75,43.7142826 75.0658429,43.1111916 75.1975308,42.5364271 C75.3292186,41.9616625 75.4855956,41.4880956 75.6666665,41.1157137 C75.8477374,40.7433317 76.1851825,40.1604794 76.6790122,39.3671417 C79.0164725,35.7890278 81.1563689,34 83.0987653,34 C84.1028856,34 84.6049382,34.3804718 84.6049382,35.1414285 C84.6049382,35.6595252 84.2798385,36.4690405 83.6296296,37.5699981 C82.9794205,38.6709579 82.3991795,39.4561863 81.8888887,39.9257136 C80.4567829,41.2857195 79.5226359,42.2328532 79.0864196,42.7671425 C78.6502035,43.3014297 78.4320986,43.9085667 78.4320986,44.5885708 C78.4320986,45.1714317 78.6543186,45.6571409 79.0987654,46.0457134 C79.543212,46.4342859 80.119338,46.62857 80.8271605,46.62857 C81.6008269,46.62857 82.4526703,46.3492873 83.382716,45.7907132 C84.3127617,45.2321392 85.5185111,44.3376253 87,43.1071413 Z M93,51 L93,13 L105.747082,13 C116.805447,13 119.856031,16.3948127 119.856031,23.2391931 C119.856031,27.1815562 118.494163,29.8645533 114.354086,31.0144092 L114.354086,31.2334294 C118.766537,32.3832853 121,35.2853026 121,40.0489914 C121,46.9481268 117.949416,51 106.891051,51 L93,51 Z M101,29 L103.670157,29 C108.853403,29 111,28.1818182 111,24.4727273 C111,20.5454545 108.905759,20 103.670157,20 L101,20 L101,29 Z M101,44 L105.038462,44 C111.211538,44 113,43.1306818 113,39.5 C113,36.1761364 111.269231,35 105.038462,35 L101,35 L101,44 Z M134.5,17 C130.888889,17 130,16.5263158 130,12.9473684 C130,9.36842105 130.888889,9 134.5,9 C138.166667,9 139,9.36842105 139,12.9473684 C139,16.5263158 138.166667,17 134.5,17 Z M130,51 L130,22 L138,22 L138,51 L130,51 Z M147,51 L147,44.3944444 L161.004377,28.5518519 L161.004377,28.2296296 L148.039387,28.2296296 L148.039387,22 L170.851204,22 L170.851204,28.2296296 L156.5186,44.287037 L156.5186,44.6092593 L172,44.6092593 L172,51 L147,51 Z M189.523364,43.7723343 L205,43.7723343 L205,51 L181,51 L181,13 L189.523364,13 L189.523364,43.7723343 Z M225.419162,21 C235.53493,21 239,24.273703 239,30.391771 L239,50.4633274 L231.734531,50.4633274 L230.952096,47.0822898 C229.666667,49.2289803 226.313373,51 221.339321,51 C214.576846,51 211,48.1556351 211,42.1449016 C211,35.4364937 215.303393,33.0214669 223.407186,33.0214669 L230.896208,33.0214669 L230.896208,32.2701252 C230.896208,28.8354204 229.778443,27.4937388 224.469062,27.4937388 C222.289421,27.4937388 220.10978,27.6547406 218.041916,28.0304114 L218.041916,21.4293381 C220.333333,21.1610018 223.239521,21 225.419162,21 Z M222.450704,46 C226.225352,46 228.929577,44.5555556 230,42.5 L230,39 L223.690141,39 C219.633803,39 218,39.6666667 218,42.7222222 C218,45.1111111 219.295775,46 222.450704,46 Z M265.078394,20.4545455 C274.782027,20.4545455 277,26.3454545 277,35.7272727 C277,44.1818182 274.782027,51 265.078394,51 C259.367113,51 257.038241,49.1454545 255.873805,46.3090909 L255.319312,50.4545455 L248,50.4545455 L248,9 L256.040153,9 L256.040153,24.5454545 C257.204589,22.3636364 259.810707,20.4545455 265.078394,20.4545455 Z M262.827731,46 C268.289916,46 269,41.9473684 269,37.0526316 C269,31.8421053 268.180672,28 262.827731,28 C257.420168,28 256,31.3157895 256,37.0526316 C256,42.5263158 257.420168,46 262.827731,46 Z" id="注册iBizLab账号" fill="#333333"></path>
<g id="编组" fill="#01B0FF">
<path d="M33,53.9848293 C39.3232242,53.9848293 45.6616122,53.9848293 52,54 C48.6488428,49.9646018 45.2673584,45.9747155 41.8555467,42 C38.9896249,46.0505689 36.0478851,50.0556258 33,53.9848293 L33,53.9848293 Z M45,37.2539103 C48.4335443,41.4270073 51.7721519,45.6757039 55,50 C54.9525316,40.3383733 55,30.6616267 54.9683544,21 C51.9303797,26.5641293 48.7025316,32.052659 45,37.2539103 L45,37.2539103 Z M21,21 C21.2871111,31.3772333 25.5786667,40.9994895 30.4897778,50 C33.0586667,45.7958142 35.5217778,41.5472179 38,37.2838182 C32.4542222,31.7325166 27.0142222,26.0627871 21,21 L21,21 Z M4.24776231,8 C3.99247773,23.2587549 3.8010143,38.5324254 4.37540459,53.7762646 C11.9062995,54.0894942 19.4531498,53.9701686 27,54 C16.9481699,39.9345006 7.4228642,24.8845655 4.24776231,8 L4.24776231,8 Z M13,5 C22.6175691,13.1440536 31.7201818,21.8107202 40.2472548,31 C44.669822,22.4349525 48.8652025,13.7682858 53,5.07258514 C39.6717152,5.04355109 26.3434305,5.1451703 13,5 L13,5 Z M0,0 L59.7331546,0 C60.0637531,19.995 60.123862,40.005 59.7031002,60 L0,60 L0,0 Z" id="Fill-1"></path>
</g>
</g>
</g>
</g>
</svg>
\ No newline at end of file
[
{
"srfkey": "YesNo",
"emptytext": "未定义",
"codelisttype":"static",
"items": [
{
"id": "1",
"label": "是",
"text": "是",
"data":"",
"codename":"Item_1",
"value": "1",
"disabled": false
}
, {
"id": "0",
"label": "否",
"text": "否",
"data":"",
"codename":"Item_0",
"value": "0",
"disabled": false
}
]
},
{
"srfkey": "CLIBZSex",
"emptytext": "",
"codelisttype":"static",
"items": [
{
"id": "男",
"label": "男性",
"text": "男性",
"data":"",
"codename":"Item_1",
"value": "男",
"disabled": false
}
, {
"id": "女",
"label": "女性",
"text": "女性",
"data":"",
"codename":"Item_2",
"value": "女",
"disabled": false
}
, {
"id": "性别不详",
"label": "性别不详",
"text": "性别不详",
"data":"",
"codename":"Item_3",
"value": "性别不详",
"disabled": false
}
]
},
{
"srfkey": "CodeListJobStatus",
"emptytext": "未定义",
"codelisttype":"static",
"items": [
{
"id": "0",
"label": "ENABLED",
"text": "ENABLED",
"data":"",
"codename":"Item_0",
"color": "rgba(58, 116, 7, 1)",
"value": 0,
"disabled": false
}
, {
"id": "1",
"label": "DISABLED",
"text": "DISABLED",
"data":"",
"codename":"Item_1",
"color": "rgba(67, 65, 65, 1)",
"value": 1,
"disabled": false
}
]
},
{
"srfkey": "CLAuthCode",
"emptytext": "未定义",
"codelisttype":"static",
"items": [
{
"id": "200",
"label": "成功",
"text": "成功",
"data":"",
"codename":"Item_200",
"color": "rgba(0, 255, 0, 0)",
"value": "200",
"disabled": false
}
, {
"id": "400",
"label": "用户不存在",
"text": "用户不存在",
"data":"",
"codename":"Item_400",
"value": "400",
"disabled": false
}
, {
"id": "401.1",
"label": "密码错误",
"text": "密码错误",
"data":"",
"codename":"Item_3",
"value": "401.1",
"disabled": false
}
, {
"id": "401.2",
"label": "配置错误",
"text": "配置错误",
"data":"",
"codename":"Item_4",
"color": "rgba(22, 9, 170, 1)",
"value": "401.2",
"disabled": false
}
, {
"id": "403.6",
"label": "地址被拒绝",
"text": "地址被拒绝",
"data":"",
"codename":"Item_5",
"color": "rgba(0, 72, 255, 1)",
"value": "403.6",
"disabled": false
}
]
}
]
\ No newline at end of file
此差异已折叠。
.loader {
position: relative;
width: 12.5em;
height: 12.5em;
transform: rotate(165deg);
}
.loader:before, .loader:after {
content: '';
position: absolute;
top: 50%;
left: 50%;
display: block;
width: 2.5em;
height: 2.5em;
border-radius: 1.25em;
transform: translate(-50%, -50%);
}
.loader:before {
animation: before 2s infinite;
}
.loader:after {
animation: after 2s infinite;
}
@keyframes before {
0% {
width: 2.5em;
box-shadow: 5em -2.5em rgba(88, 163, 243, 0.75), -5em 2.5em rgba(153, 202, 255, 0.75);
}
35% {
width: 12.5em;
box-shadow: 0 -2.5em rgba(88, 163, 243, 0.75), 0 2.5em rgba(153, 202, 255, 0.75);
}
70% {
width: 2.5em;
box-shadow: -5em -2.5em rgba(88, 163, 243, 0.75), 5em 2.5em rgba(153, 202, 255, 0.75);
}
100% {
box-shadow: 5em -2.5em rgba(88, 163, 243, 0.75), -5em 2.5em rgba(153, 202, 255, 0.75);
}
}
@keyframes after {
0% {
height: 2.5em;
box-shadow: 2.5em 5em rgba(224, 224, 224, 0.75), -2.5em -5em rgba(198, 200, 210, 0.75);
}
35% {
height: 12.5em;
box-shadow: 2.5em 0 rgba(224, 224, 224, 0.75), -2.5em 0 rgba(198, 200, 210, 0.75);
}
70% {
height: 2.5em;
box-shadow: 2.5em -5em rgba(224, 224, 224, 0.75), -2.5em 5em rgba(198, 200, 210, 0.75);
}
100% {
box-shadow: 2.5em 5em rgba(224, 224, 224, 0.75), -2.5em -5em rgba(198, 200, 210, 0.75);
}
}
/** * Attempt to center the whole thing! */
html, body {
height: 100%;
}
.loader {
position: absolute;
top: calc(50% - 6.25em);
left: calc(50% - 6.25em);
}
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
此差异已折叠。
/* PrismJS 1.14.0
https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript */
/**
* prism.js default theme for JavaScript, CSS and HTML
* Based on dabblet (http://dabblet.com)
* @author Lea Verou
*/
code[class*="language-"],
pre[class*="language-"] {
color: black;
background: none;
text-shadow: 0 1px white;
font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
text-align: left;
white-space: pre;
word-spacing: normal;
word-break: normal;
word-wrap: normal;
line-height: 1.5;
-moz-tab-size: 4;
-o-tab-size: 4;
tab-size: 4;
-webkit-hyphens: none;
-moz-hyphens: none;
-ms-hyphens: none;
hyphens: none;
}
pre[class*="language-"]::-moz-selection, pre[class*="language-"] ::-moz-selection,
code[class*="language-"]::-moz-selection, code[class*="language-"] ::-moz-selection {
text-shadow: none;
background: #b3d4fc;
}
pre[class*="language-"]::selection, pre[class*="language-"] ::selection,
code[class*="language-"]::selection, code[class*="language-"] ::selection {
text-shadow: none;
background: #b3d4fc;
}
@media print {
code[class*="language-"],
pre[class*="language-"] {
text-shadow: none;
}
}
/* Code blocks */
pre[class*="language-"] {
padding: 1em;
margin: .5em 0;
overflow: auto;
}
:not(pre) > code[class*="language-"],
pre[class*="language-"] {
background: #f5f2f0;
}
/* Inline code */
:not(pre) > code[class*="language-"] {
padding: .1em;
border-radius: .3em;
white-space: normal;
}
.token.comment,
.token.prolog,
.token.doctype,
.token.cdata {
color: slategray;
}
.token.punctuation {
color: #999;
}
.namespace {
opacity: .7;
}
.token.property,
.token.tag,
.token.boolean,
.token.number,
.token.constant,
.token.symbol,
.token.deleted {
color: #905;
}
.token.selector,
.token.attr-name,
.token.string,
.token.char,
.token.builtin,
.token.inserted {
color: #690;
}
.token.operator,
.token.entity,
.token.url,
.language-css .token.string,
.style .token.string {
color: #9a6e3a;
background: hsla(0, 0%, 100%, .5);
}
.token.atrule,
.token.attr-value,
.token.keyword {
color: #07a;
}
.token.function,
.token.class-name {
color: #DD4A68;
}
.token.regex,
.token.important,
.token.variable {
color: #e90;
}
.token.important,
.token.bold {
font-weight: bold;
}
.token.italic {
font-style: italic;
}
.token.entity {
cursor: help;
}
.word-wrap{word-wrap:break-word;-ms-word-break:break-all;word-break:break-all;word-break:break-word;-ms-hyphens:auto;-moz-hyphens:auto;-webkit-hyphens:auto;hyphens:auto}.mce-content-body .mce-reset{margin:0;padding:0;border:0;outline:0;vertical-align:top;background:transparent;text-decoration:none;color:black;font-family:Arial;font-size:11px;text-shadow:none;float:none;position:static;width:auto;height:auto;white-space:nowrap;cursor:inherit;line-height:normal;font-weight:normal;text-align:left;-webkit-tap-highlight-color:transparent;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box;direction:ltr;max-width:none}.mce-object{border:1px dotted #3A3A3A;background:#D5D5D5 url(img/object.gif) no-repeat center}.mce-preview-object{display:inline-block;position:relative;margin:0 2px 0 2px;line-height:0;border:1px solid gray}.mce-preview-object[data-mce-selected="2"] .mce-shim{display:none}.mce-preview-object .mce-shim{position:absolute;top:0;left:0;width:100%;height:100%;background:url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)}figure.align-left{float:left}figure.align-right{float:right}figure.image.align-center{display:table;margin-left:auto;margin-right:auto}figure.image{display:inline-block;border:1px solid gray;margin:0 2px 0 1px;background:#f5f2f0}figure.image img{margin:8px 8px 0 8px}figure.image figcaption{margin:6px 8px 6px 8px;text-align:center}.mce-toc{border:1px solid gray}.mce-toc h2{margin:4px}.mce-toc li{list-style-type:none}.mce-pagebreak{cursor:default;display:block;border:0;width:100%;height:5px;border:1px dashed #666;margin-top:15px;page-break-before:always}@media print{.mce-pagebreak{border:0}}.mce-item-anchor{cursor:default;display:inline-block;-webkit-user-select:all;-webkit-user-modify:read-only;-moz-user-select:all;-moz-user-modify:read-only;user-select:all;user-modify:read-only;width:9px !important;height:9px !important;border:1px dotted #3A3A3A;background:#D5D5D5 url(img/anchor.gif) no-repeat center}.mce-nbsp,.mce-shy{background:#AAA}.mce-shy::after{content:'-'}.mce-match-marker{background:#AAA;color:#fff}.mce-match-marker-selected{background:#3399ff;color:#fff}.mce-spellchecker-word{border-bottom:2px solid rgba(208,2,27,0.5);cursor:default}.mce-spellchecker-grammar{border-bottom:2px solid #008000;cursor:default}.mce-item-table,.mce-item-table td,.mce-item-table th,.mce-item-table caption{border:1px dashed #BBB}td[data-mce-selected],th[data-mce-selected]{background-color:#2276d2 !important}.mce-edit-focus{outline:1px dotted #333}.mce-content-body *[contentEditable=false] *[contentEditable=true]:focus{outline:2px solid #2276d2}.mce-content-body *[contentEditable=false] *[contentEditable=true]:hover{outline:2px solid #2276d2}.mce-content-body *[contentEditable=false][data-mce-selected]{outline:2px solid #2276d2}.mce-content-body.mce-content-readonly *[contentEditable=true]:focus,.mce-content-body.mce-content-readonly *[contentEditable=true]:hover{outline:none}.mce-content-body *[data-mce-selected="inline-boundary"]{background:#bfe6ff}.mce-content-body .mce-item-anchor[data-mce-selected]{background:#D5D5D5 url(img/anchor.gif) no-repeat center}.mce-content-body hr{cursor:default}.mce-content-body table{-webkit-nbsp-mode:normal}.ephox-snooker-resizer-bar{background-color:#2276d2;opacity:0}.ephox-snooker-resizer-cols{cursor:col-resize}.ephox-snooker-resizer-rows{cursor:row-resize}.ephox-snooker-resizer-bar.ephox-snooker-resizer-bar-dragging{opacity:.2}.mce-content-body{line-height:1.3}
\ No newline at end of file
body{background-color:#FFFFFF;color:#000000;font-family:Verdana,Arial,Helvetica,sans-serif;font-size:14px;line-height:1.3;scrollbar-3dlight-color:#F0F0EE;scrollbar-arrow-color:#676662;scrollbar-base-color:#F0F0EE;scrollbar-darkshadow-color:#DDDDDD;scrollbar-face-color:#E0E0DD;scrollbar-highlight-color:#F0F0EE;scrollbar-shadow-color:#F0F0EE;scrollbar-track-color:#F5F5F5}td,th{font-family:Verdana,Arial,Helvetica,sans-serif;font-size:14px}.word-wrap{word-wrap:break-word;-ms-word-break:break-all;word-break:break-all;word-break:break-word;-ms-hyphens:auto;-moz-hyphens:auto;-webkit-hyphens:auto;hyphens:auto}.mce-content-body .mce-reset{margin:0;padding:0;border:0;outline:0;vertical-align:top;background:transparent;text-decoration:none;color:black;font-family:Arial;font-size:11px;text-shadow:none;float:none;position:static;width:auto;height:auto;white-space:nowrap;cursor:inherit;line-height:normal;font-weight:normal;text-align:left;-webkit-tap-highlight-color:transparent;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box;direction:ltr;max-width:none}.mce-object{border:1px dotted #3A3A3A;background:#D5D5D5 url(img/object.gif) no-repeat center}.mce-preview-object{display:inline-block;position:relative;margin:0 2px 0 2px;line-height:0;border:1px solid gray}.mce-preview-object[data-mce-selected="2"] .mce-shim{display:none}.mce-preview-object .mce-shim{position:absolute;top:0;left:0;width:100%;height:100%;background:url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)}figure.align-left{float:left}figure.align-right{float:right}figure.image.align-center{display:table;margin-left:auto;margin-right:auto}figure.image{display:inline-block;border:1px solid gray;margin:0 2px 0 1px;background:#f5f2f0}figure.image img{margin:8px 8px 0 8px}figure.image figcaption{margin:6px 8px 6px 8px;text-align:center}.mce-toc{border:1px solid gray}.mce-toc h2{margin:4px}.mce-toc li{list-style-type:none}.mce-pagebreak{cursor:default;display:block;border:0;width:100%;height:5px;border:1px dashed #666;margin-top:15px;page-break-before:always}@media print{.mce-pagebreak{border:0}}.mce-item-anchor{cursor:default;display:inline-block;-webkit-user-select:all;-webkit-user-modify:read-only;-moz-user-select:all;-moz-user-modify:read-only;user-select:all;user-modify:read-only;width:9px !important;height:9px !important;border:1px dotted #3A3A3A;background:#D5D5D5 url(img/anchor.gif) no-repeat center}.mce-nbsp,.mce-shy{background:#AAA}.mce-shy::after{content:'-'}.mce-match-marker{background:#AAA;color:#fff}.mce-match-marker-selected{background:#3399ff;color:#fff}.mce-spellchecker-word{border-bottom:2px solid rgba(208,2,27,0.5);cursor:default}.mce-spellchecker-grammar{border-bottom:2px solid #008000;cursor:default}.mce-item-table,.mce-item-table td,.mce-item-table th,.mce-item-table caption{border:1px dashed #BBB}td[data-mce-selected],th[data-mce-selected]{background-color:#2276d2 !important}.mce-edit-focus{outline:1px dotted #333}.mce-content-body *[contentEditable=false] *[contentEditable=true]:focus{outline:2px solid #2276d2}.mce-content-body *[contentEditable=false] *[contentEditable=true]:hover{outline:2px solid #2276d2}.mce-content-body *[contentEditable=false][data-mce-selected]{outline:2px solid #2276d2}.mce-content-body.mce-content-readonly *[contentEditable=true]:focus,.mce-content-body.mce-content-readonly *[contentEditable=true]:hover{outline:none}.mce-content-body *[data-mce-selected="inline-boundary"]{background:#bfe6ff}.mce-content-body .mce-item-anchor[data-mce-selected]{background:#D5D5D5 url(img/anchor.gif) no-repeat center}.mce-content-body hr{cursor:default}.mce-content-body table{-webkit-nbsp-mode:normal}.ephox-snooker-resizer-bar{background-color:#2276d2;opacity:0}.ephox-snooker-resizer-cols{cursor:col-resize}.ephox-snooker-resizer-rows{cursor:row-resize}.ephox-snooker-resizer-bar.ephox-snooker-resizer-bar-dragging{opacity:.2}
\ No newline at end of file
.tinymce-mobile-unfocused-selections .tinymce-mobile-unfocused-selection{position:absolute;display:inline-block;background-color:green;opacity:.5}body{-webkit-text-size-adjust:none}body img{max-width:96vw}body table img{max-width:95%}
\ No newline at end of file
<template>
<div id='app'>
<app-debug-actions />
<router-view v-if="isRouterAlive"/>
</div>
</template>
+<script lang='ts'>
import { Vue, Component, Provide } from 'vue-property-decorator';
import store from '@/store';
import { LoadAppData } from '@/utils';
@Component({
})
export default class App extends Vue {
/**
* 控制视图是否显示
*/
public isRouterAlive:boolean = false;
/**
* 向后代注入加载行为
*/
@Provide()
public reload = this.viewreload;
/**
* vue生命周期
*/
public created(){
this.loadAppData();
}
/**
* 视图重新加载
*/
public viewreload () {
this.isRouterAlive = false;
this.$nextTick(function () {
this.isRouterAlive = true;
})
}
/**
* 视图加载代码表
*/
public async loadAppData(){
const _store:any = store;
if(_store.state && _store.state.codelists && _store.state.codelists.length >0){
this.isRouterAlive = true;
return;
}else{
await LoadAppData.getInstance().load(store);
this.isRouterAlive = true;
}
}
}
</script>
<style lang='less'>
@import './styles/default.less';
</style>
此差异已折叠。
此差异已折叠。
html, body {
height: 100%;
}
.app-error-view {
height: 100%;
width: 100%;
.app-error-container {
height: 380px;
width: 670px;
position: absolute;
top: calc((100% - 400px) / 2);
left: calc((100% - 670px) / 2);
display: flex;
align-items: center;
.error-text {
padding-left: 20px;
.error-text1 {
font-size: 20px;
margin-bottom: 20px;
}
.error-text2 {
font-size: 14px;
}
}
}
}
\ No newline at end of file
<template>
<div class="app-error-view">
<div class="app-error-container">
<img src="/assets/img/404.png" />
<div class="error-text">
<div class="error-text1">{{$t('components.404.errorText1')}}</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>
</template>
<script lang="ts">
import { Vue, Component } from 'vue-property-decorator';
@Component({
})
export default class Error404 extends Vue {
/**
* 跳转首页
*
* @memberof Error404
*/
public gotoIndexView() {
this.$router.push('/');
}
}
</script>
<style lang='less'>
@import './404.less';
</style>
\ No newline at end of file
html, body {
height: 100%;
}
.app-error-view {
height: 100%;
width: 100%;
.app-error-container {
height: 380px;
width: 670px;
position: absolute;
top: calc((100% - 400px) / 2);
left: calc((100% - 670px) / 2);
display: flex;
align-items: center;
.error-text {
padding-left: 20px;
.error-text1 {
font-size: 20px;
margin-bottom: 20px;
}
.error-text2 {
font-size: 14px;
}
}
}
}
\ No newline at end of file
<template>
<div class="app-error-view">
<div class="app-error-container">
<img src="/assets/img/500.png" />
<div class="error-text">
<div class="error-text1">{{$t('components.500.errorText1')}}</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>
</template>
<script lang="ts">
import { Vue, Component } from 'vue-property-decorator';
@Component({
})
export default class Error404 extends Vue {
/**
* 跳转首页
*
* @memberof Error404
*/
public gotoIndexView() {
this.$router.push('/');
}
}
</script>
<style lang='less'>
@import './500.less';
</style>
\ No newline at end of file
.app-actionbar {
padding: 12px;
display: flex;
justify-content: flex-start;
align-items: center;
flex-wrap: wrap;
.app-actionbar-item{
margin-right:10px;
margin-bottom: 10px;
}
}
\ No newline at end of file
<template>
<div class="app-actionbar">
<div class="app-actionbar-item" v-for="(item,index) in items" :key="index">
<Badge v-if="item.counterService&&item.counterService.counterData" :count="item.counterService.counterData[item.counterId]" type="primary">
<i-button @click="handleClick(item.viewlogicname)">{{item.actionName}}</i-button>
</Badge>
<i-button v-else @click="handleClick(item.viewlogicname)">{{item.actionName}}</i-button>
</div>
</div>
</template>
<script lang="ts">
import { Vue, Component, Prop, Model, Emit } from "vue-property-decorator";
import { Subject } from "rxjs";
@Component({})
export default class AppActionBar extends Vue {
/**
* 传入操作栏模型数据
*
* @type {any}
* @memberof AppActionBar
*/
@Prop() public items!:any;
/**
* 触发界面行为
*
* @memberof AppActionBar
*/
public handleClick($event:any){
this.$emit('itemClick',$event);
}
}
</script>
<style lang='less'>
@import "./app-actionbar.less";
</style>
\ No newline at end of file
<template>
<div class="appAddressSelection">
<el-cascader
:disabled="disabled"
size ="medium"
v-model="CurrentVal"
:options="city">
</el-cascader>
</div>
</template>
<script lang='ts'>
import { Component, Vue, Prop, Model, Watch } from 'vue-property-decorator';
import { Subject } from 'rxjs';
import { debounceTime, distinctUntilChanged } from 'rxjs/operators';
import axios from 'axios';
@Component({})
export default class AppAddressSelection extends Vue {
/**
* 传入值
* @type {any}
* @memberof AppAddressSelection
*/
@Prop() public value?:any;
/**
* 是否禁用
* @type {boolean}
* @memberof AppAddressSelection
*/
@Prop() public disabled?: boolean;
/**
* 当前值
*
* @memberof AppAddressSelection
*/
get CurrentVal() {
return this.value;
}
/**
* 值变化
*
* @memberof AppAddressSelection
*/
set CurrentVal(val: any) {
this.$emit("change", val);
}
/**
* 城市数据
*
* @memberof AppAddressSelection
*/
public city :any = [];
/**
* 获取城市数据
*
* @memberof AppAddressSelection
*/
public getcity() {
axios.get("../../assets/json/city_code.json").then((response: any) => {
this.format(response.data);
}).catch((response: any) => {
console.log("城市数据加载失败");
});
}
/**
* 生命周期
*
* @memberof AppAddressSelection
*/
public created() {
this.getcity();
}
/**
* 数据格式化
*
* @memberof AppAddressSelection
*/
public format(data :any) {
let data1 = JSON.parse(JSON.stringify(data).replace(/city/g, 'children'))
let data2 = JSON.parse(JSON.stringify(data1).replace(/name/g, 'label'))
let data3 = JSON.parse(JSON.stringify(data2).replace(/area/g, 'children'))
let data4 = JSON.parse(JSON.stringify(data3).replace(/code/g, 'value'))
this.city = data4;
}
}
</script>
<style lang='less'>
@import './app-address-selection.less';
</style>
\ No newline at end of file
.ivu-auto-complete {
.ivu-select-dropdown-list {
height: 300px;
}
}
<template>
<el-autocomplete
class='text-value'
:value-key="deMajorField"
:disabled="disabled"
v-model="curvalue"
size='small'
:trigger-on-focus="true"
:fetch-suggestions="onSearch"
@select="onACSelect"
@input="onInput"
@blur="onBlur"
style='width:100%;'>
<template v-slot:suffix>
<i v-if="curvalue && !disabled" class='el-icon-circle-close' @click="onClear"></i>
<i class="el-icon-arrow-down"></i>
</template>
</el-autocomplete>
</template>
<script lang='ts'>
import { Component, Vue, Prop, Model, Watch } from 'vue-property-decorator';
import { Subject } from 'rxjs';
import { debounceTime, distinctUntilChanged } from 'rxjs/operators';
@Component({
})
export default class AppAutocomplete extends Vue {
/**
* 表单数据
*
* @type {*}
* @memberof AppAutocomplete
*/
@Prop() public data: any;
/**
* 视图上下文
*
* @type {*}
* @memberof AppAutocomplete
*/
@Prop() public context!: any;
/**
* 视图参数
*
* @type {*}
* @memberof AppFormDRUIPart
*/
@Prop() public viewparams!: any;
/**
* AC参数
*
* @type {*}
* @memberof AppFormDRUIPart
*/
@Prop({default: {}}) public acParams?: any;
/**
* 表单服务
*
* @type {*}
* @memberof AppFormDRUIPart
*/
@Prop() public service?: any;
/**
* 应用实体主信息属性名称
*
* @type {string}
* @memberof AppAutocomplete
*/
@Prop({default: 'srfmajortext'}) public deMajorField!: string;
/**
* 应用实体主键属性名称
*
* @type {string}
* @memberof AppAutocomplete
*/
@Prop({default: 'srfkey'}) public deKeyField!: string;
/**
* 是否启用
*
* @type {boolean}
* @memberof AppAutocomplete
*/
@Prop() public disabled?: boolean;
/**
* 属性项名称
*
* @type {string}
* @memberof AppAutocomplete
*/
@Prop() public name!: string;
/**
* 局部上下文导航参数
*
* @type {any}
* @memberof AppAutocomplete
*/
@Prop() public localContext!:any;
/**
* 局部导航参数
*
* @type {any}
* @memberof AppAutocomplete
*/
@Prop() public localParam!:any;
/**
* 值项名称
*
* @type {string}
* @memberof AppAutocomplete
*/
@Prop() public valueitem?: string;
/**
* 值
*
* @type {*}
* @memberof AppAutocomplete
*/
@Model('change') public value?: any;
/**
* 当前值
*
* @type {string}
* @memberof AppAutocomplete
*/
public curvalue: string = '';
/**
* 远程请求url 地址
*
* @type {string}
* @memberof AppAutocomplete
*/
@Prop() public url?: string;
/**
* 数组
*
* @type {any[]}
* @memberof AppAutocomplete
*/
public items: any[] = [];
/**
* 输入状态
*
* @type {boolean}
* @memberof AppAutocomplete
*/
public inputState: boolean = false;
/**
* 值变化
*
* @param {*} newVal
* @param {*} oldVal
* @memberof AppAutocomplete
*/
@Watch('value')
public onValueChange(newVal: any, oldVal: any) {
this.curvalue = newVal;
}
/**
* 执行搜索数据
* @param query
* @param callback
*/
public onSearch(query: any, callback: any): void {
// 公共参数处理
let data: any = {};
const bcancel: boolean = this.handlePublicParams(data);
if (!bcancel) {
return;
}
// 参数处理
let _context = data.context;
let _param = data.param;
// 处理搜索参数
query = !query ? '' : query;
if (!this.inputState && Object.is(query, this.value)) {
query = '';
}
this.inputState = false;
Object.assign(_param, { query: query });
// 错误信息国际化
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){
this.$Notice.error({ title: error, desc: miss+'service' });
} else if(!this.acParams.serviceName) {
this.$Notice.error({ title: error, desc: miss+'serviceName' });
} else if(!this.acParams.interfaceName) {
this.$Notice.error({ title: error, desc: miss+'interfaceName' });
} else {
this.service.getItems(this.acParams.serviceName,this.acParams.interfaceName, _context, _param).then((response: any) => {
if (!response) {
this.$Notice.error({ title: error, desc: requestException });
} else {
this.items = [...response];
}
if (callback) {
callback(this.items);
}
}).catch((error: any) => {
if (callback) {
callback([]);
}
});
}
}
/**
* 选中数据回调
* @param item
*/
public onACSelect(item: any): void {
if (this.name) {
this.$emit('formitemvaluechange', { name: this.name, value: item[this.deMajorField] });
}
if (this.valueitem) {
this.$emit('formitemvaluechange', { name: this.valueitem, value: item[this.deKeyField] });
}
}
/**
* 输入过程中
*
* @memberof AppAutocomplete
*/
public onInput($event: any) {
if (Object.is($event, this.value)) {
this.inputState = true;
}
}
/**
* 失去焦点事件
* @param e
*/
public onBlur(e: any): void {
let val: string = e.target.value;
if (!Object.is(val, this.value)) {
this.onACSelect({ [this.deMajorField]: val, [this.deKeyField]: '' });
}
this.$forceUpdate();
}
/**
* 清除
*/
public onClear($event: any): void {
if (this.name) {
this.$emit('formitemvaluechange', { name: this.name, value: '' });
}
if (this.valueitem) {
this.$emit('formitemvaluechange', { name: this.valueitem, value: '' });
}
this.$forceUpdate();
}
/**
* 公共参数处理
*
* @param {*} arg
* @returns
* @memberof AppAutocomplete
*/
public handlePublicParams(arg: any): boolean {
if (!this.data) {
this.$Notice.error({ title: (this.$t('components.AppAutocomplete.error') as any), desc: (this.$t('components.AppAutocomplete.formdataException') as any) });
return false;
}
// 合并表单参数
arg.param = this.viewparams ? JSON.parse(JSON.stringify(this.viewparams)) : {};
arg.context = this.context ? JSON.parse(JSON.stringify(this.context)) : {};
// 附加参数处理
if (this.localContext && Object.keys(this.localContext).length >0) {
let _context = this.$util.computedNavData(this.data,arg.context,arg.param,this.localContext);
Object.assign(arg.context,_context);
}
if (this.localParam && Object.keys(this.localParam).length >0) {
let _param = this.$util.computedNavData(this.data,arg.param,arg.param,this.localParam);
Object.assign(arg.param,_param);
}
return true;
}
}
</script>
<style lang='less'>
@import './app-autocomplete.less';
</style>
\ No newline at end of file
.el-breadcrumb__inner,
.el-breadcrumb__inner a {
font-weight: 400 !important;
}
.app-breadcrumb.el-breadcrumb {
display: inline-block;
font-size: 14px;
line-height: 50px;
margin-left: 8px;
.no-redirect {
color: #97a8be;
cursor: text;
.curselected{
color: #2196F3;
font-weight: bold;
}
.app-breadcrumb-selected{
cursor: pointer;
}
}
}
\ No newline at end of file
<template>
<el-breadcrumb class="app-breadcrumb" separator="/">
<transition-group name="breadcrumb">
<template v-if="Object.is(this.navModel,'route')">
<el-breadcrumb-item v-for="(item, index) in breadcrumbs" :key="item.id">
<span v-if="index === breadcrumbs.length-1" class="no-redirect">{{ item.title }}
<span v-if="isShowSelected(item)">
<dropdown trigger='click' @on-click="selectNavData($event,item)">
<span class="app-breadcrumb-selected">
<i class="el-icon-caret-bottom"></i>
</span>
<dropdown-menu slot='list'>
<dropdown-item v-for="(dataitem) in getPreNavData(item)" :name="dataitem.srfkey" :key="dataitem.srfkey">
<span :class="{'curselected':isCurSelected(item,dataitem)}">{{dataitem.srfmajortext}}</span>
</dropdown-item>
</dropdown-menu>
</dropdown>
</span>
</span>
<a v-else @click.prevent="handleLink(item)">{{ item.title }}</a>
</el-breadcrumb-item>
</template>
<template v-if="!Object.is(this.navModel,'route')">
<el-breadcrumb-item v-for="(item, index) in breadcrumbs" :key="item.path">
<span v-if="index === breadcrumbs.length-1" class="no-redirect" >{{ $t(item.meta.caption)}}</span>
<a v-else @click.prevent="handleLink(item)" >{{ $t(item.meta.caption) }}</a>
</el-breadcrumb-item>
</template>
</transition-group>
</el-breadcrumb>
</template>
<script lang="ts">
import { Component, Vue, Watch, Prop } from 'vue-property-decorator'
import { RouteRecord, Route } from 'vue-router'
import { Environment } from "@/environments/environment";
import NavDataService from '@/service/app/navdata-service';
import {Subscription } from 'rxjs';
@Component({
})
export default class Breadcrumb extends Vue {
/**
* 面包屑列表
*
* @memberof Breadcrumb
*/
private breadcrumbs: Array<any> = [];
/**
* 导航服务
*
* @memberof Breadcrumb
*/
private navDataService = NavDataService.getInstance(this.$store);
/**
* 默认视图标识
*
* @memberof Breadcrumb
*/
@Prop() public indexViewTag!: string;
/**
* 导航模式
*
* @memberof Breadcrumb
*/
@Prop({default:'tab'}) public navModel?:string;
/**
* 监听路由
*
* @memberof Breadcrumb
*/
@Watch('$route')
private onRouteChange(route: Route) {
this.getBreadcrumb()
}
/**
* 导航服务事件
*
* @public
* @type {(Subscription | undefined)}
* @memberof Dev
*/
public serviceStateEvent: Subscription | undefined;
/**
* vue 生命周期
*
* @memberof Breadcrumb
*/
created() {
this.getBreadcrumb();
if(Object.is(this.navModel,"route")){
this.serviceStateEvent = this.navDataService.serviceState.subscribe(({ action,name, data }:{ action:string,name:any,data:any }) => {
if (Object.is(action, 'datarefresh')) {
this.getBreadcrumb();
}
});
}
}
/**
* 获取面包屑数据
*
* @memberof Breadcrumb
*/
private getBreadcrumb() {
if(Object.is(this.navModel,"route")){
this.breadcrumbs = this.navDataService.getNavData();
this.$forceUpdate();
}else{
this.breadcrumbs = this.$route.matched.filter((item) => {
return item.meta && item.meta.caption
})
}
}
/**
* 获取面包屑指定元素前一条数据
*
* @memberof Breadcrumb
*/
private getPreNavData(item:any){
let preNavData:any = this.navDataService.getPreNavDataById(item.id);
return preNavData.data;
}
/**
* 判断是否为当前选中项
*
* @memberof Breadcrumb
*/
private isCurSelected(item:any,singleItem:any){
return item.srfkey === singleItem.srfkey;
}
/**
* 面包屑点击行为
*
* @memberof Breadcrumb
*/
private handleLink(item: any) {
if(Object.is(this.navModel,"route")){
// 首页
if(Object.is(item.id,this.indexViewTag)){
this.$router.push((window.sessionStorage.getItem(Environment.AppName))as string);
}else{
// 非首页
this.$router.push(item.path).catch(err => {
console.warn(err);
});
}
this.navDataService.removeNavData(item.id);
}else{
if(item && item.meta && item.meta.viewType && Object.is(item.meta.viewType,"APPINDEX")){
let path: string | null = window.sessionStorage.getItem(Environment.AppName);
if (path) {
this.$router.push({ path: path });
} else {
this.$router.push("/");
}
}else{
this.$router.push(item).catch(err => {
console.warn(err);
});
}
}
}
/**
* 切换导航行为
*
* @memberof Breadcrumb
*/
private selectNavData($event:any,item:any){
let preNavData:any = this.getPreNavData(item);
let curSrfkey:any = $event;
this.navDataService.serviceState.next({action:'viewrefresh',name:item.id, data:curSrfkey});
}
/**
* 组件销毁
*
* @memberof Breadcrumb
*/
public destroyed() {
if (this.serviceStateEvent) {
this.serviceStateEvent.unsubscribe();
}
}
/**
* 是否显示下拉列表
*
* @memberof Breadcrumb
*/
public isShowSelected(item:any){
return item.isselected && !this.$util.isEmpty(item.srfkey);
}
}
</script>
<style lang='less'>
@import "./app-breadcrumb.less";
</style>
\ No newline at end of file
.show-type {
text-align: right;
position: absolute;
z-index: 99;
right: 0;
top: 2px;
.ivu-btn-group {
.collapse-btn {
padding: 0;
}
}
}
\ No newline at end of file
<template>
<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>
</button-group>
<button-group v-show="showTypeDir">
<el-tooltip :content="$t('components.appBuild.custom')">
<i-button icon="md-build" type="primary" @click="handleClick"></i-button>
</el-tooltip>
<i-button class="collapse-btn" type="primary" @click="clickCollapse('right')">
<icon type="ios-arrow-forward"/>
</i-button>
</button-group>
</div>
</template>
<script lang="ts">
import {Vue, Component, Prop, Watch} from 'vue-property-decorator';
@Component({
})
export default class AppBuild extends Vue {
/**
* 工具栏伸缩
*
* @protected
* @type {boolean}
* @memberof AppBuild
*/
public showTypeDir: boolean = false;
/**
* 点击伸缩
*
* @param {*} type
* @memberof AppBuild
*/
public clickCollapse(type: string) {
this.showTypeDir = Object.is(type, 'left') ? true : false;
}
/**
* 工具点击
*
*@memberof AppBuild
*/
public handleClick(){
this.$emit("handleClick")
}
}
</script>
<style lang="less">
@import './app-build.less';
</style>
\ No newline at end of file
.app-checkbox-list {
overflow: auto;
}
\ No newline at end of file
<template>
<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">
<span>{{Object.is(codelistType,'STATIC') ? $t('codelist.'+tag+'.'+item.value) : item.text}}</span>
</checkbox>
</checkbox-group >
</template>
<script lang="ts">
import { Component, Vue, Prop, Model, Watch } from 'vue-property-decorator';
import CodeListService from "@service/app/codelist-service";
@Component({
})
export default class AppCheckBox extends Vue {
/**
* 代码表服务对象
*
* @type {CodeListService}
* @memberof AppCheckBox
*/
public codeListService:CodeListService = new CodeListService({ $store: this.$store });
/**
* 代码表标识
*
* @type {string}
* @memberof AppCheckBox
*/
@Prop() public tag?: string;
/**
* 代码表类型
*
* @type {string}
* @memberof AppCheckBox
*/
@Prop() public codelistType?: string;
/**
* 代码表值分隔符
*
* @type {string}
* @memberof AppCheckBox
*/
@Prop({default:','}) public valueSeparator?: string;
/**
* 是否禁用
*
* @type {boolean}
* @memberof AppCheckBox
*/
@Prop() disabled?: boolean;
/**
* 传入表单数据
*
* @type {*}
* @memberof AppCheckBox
*/
@Prop() public data?: any;
/**
* 局部上下文导航参数
*
* @type {any}
* @memberof AppCheckBox
*/
@Prop() public localContext!:any;
/**
* 局部导航参数
*
* @type {any}
* @memberof AppCheckBox
*/
@Prop() public localParam!:any;
/**
* 视图上下文
*
* @type {*}
* @memberof AppCheckBox
*/
@Prop() public context!: any;
/**
* 视图参数
*
* @type {*}
* @memberof AppCheckBox
*/
@Prop() public viewparams!: any;
/**
* 获取启用禁用状态
*
* @readonly
* @memberof AppCheckBox
*/
get isDisabled() {
if (this.disabled) {
return true;
} else {
return false;
}
}
/**
* 属性名称
*
* @type {*}
* @memberof AppCheckBox
*/
@Prop() name?: any;
/**
* 模式(数字或者字符串)
*
* @type {*}
* @memberof AppCheckBox
*/
@Prop() mode: any;
/**
* 当前模式
*
* @readonly
* @memberof AppCheckBox
*/
get currentmode() {
if (this.mode) {
return this.mode;
} else {
return 'str';
}
}
/**
* 选中值
*
* @type {*}
* @memberof AppCheckBox
*/
@Model('change') selects?: any;
/**
* 选中数组
*
* @memberof AppCheckBox
*/
get selectArray() {
if (this.selects) {
if (Object.is(this.currentmode, 'num') && this.items) {
let selectsArray: Array<any> = [];
let num: number = parseInt(this.selects, 10);
this.items.forEach((item: any) => {
if ((num & item.value) == item.value) {
selectsArray.push(item.value);
}
});
return selectsArray;
} else if (Object.is(this.currentmode, 'str')) {
if (this.selects !== '') {
return this.selects.split(this.valueSeparator);
}
}
} else {
return [];
}
}
/**
* 设置选中
*
* @memberof AppCheckBox
*/
set selectArray(val: any) {
let value: null | string | number = null;
if (Object.is(this.currentmode, 'num')) {
let temp: number = 0;
val.forEach((item: any) => {
temp = temp | parseInt(item, 10);
});
value = temp;
} else if (Object.is(this.currentmode, 'str')) {
let _datas: string[] = [];
this.items.forEach((item: any) => {
const index = val.findIndex((_key: any) => Object.is(item.value, _key));
if (index === -1) {
return;
}
_datas.push(item.value);
});
value = _datas.join(this.valueSeparator);
}
this.$emit('change', value);
}
/**
* 代码表数组
*
* @type {any[]}
* @memberof AppCheckBox
*/
public items: any[] = [];
/**
* 公共参数处理
*
* @param {*} arg
* @returns
* @memberof AppCheckBox
*/
public handlePublicParams(arg: any) {
// 合并表单参数
arg.param = this.viewparams ? JSON.parse(JSON.stringify(this.viewparams)) : {};
arg.context = this.context ? JSON.parse(JSON.stringify(this.context)) : {};
// 附加参数处理
if (this.localContext && Object.keys(this.localContext).length >0) {
let _context = this.$util.computedNavData(this.data,arg.context,arg.param,this.localContext);
Object.assign(arg.context,_context);
}
if (this.localParam && Object.keys(this.localParam).length >0) {
let _param = this.$util.computedNavData(this.data,arg.param,arg.param,this.localParam);
Object.assign(arg.param,_param);
}
}
/**
* vue 生命周期
*
* @memberof AppCheckBox
*/
public created() {
if(this.tag){
if (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}----$t('components.appCheckBox.notExist')`);
}
} else if (Object.is(this.codelistType,"DYNAMIC")) {
// 公共参数处理
let data: any = {};
this.handlePublicParams(data);
// 参数处理
let _context = data.context;
let _param = data.param;
this.codeListService.getItems(this.tag,_context,_param).then((res:any) => {
this.items = res;
}).catch((error:any) => {
console.log(`----${this.tag}----$t('components.appCheckBox.notExist')`);
});
}
}
}
/**
* 监听表单数据变化
*
* @memberof AppCheckBox
*/
@Watch('data',{immediate:true,deep:true})
onDataChange(newVal: any, oldVal: any) {
if(newVal){
if(this.tag && this.codelistType == 'DYNAMIC'){
// 公共参数处理
let data: any = {};
this.handlePublicParams(data);
// 参数处理
let _context = data.context;
let _param = data.param;
this.codeListService.getItems(this.tag,_context,_param).then((res:any) => {
this.items = res;
}).catch((error:any)=>{
console.log(`----${this.tag}----代码表不存在!`);
})
}
}
}
}
</script>
<style lang='less'>
@import './app-checkbox-list.less';
</style>
\ No newline at end of file
.app-checkbox-list {
overflow: auto;
}
\ No newline at end of file
<template>
<div class="checkbox">
<checkbox v-model="CurrentVal" :disabled="disabled"></checkbox>
</div>
</template>
<script lang="ts">
import { Vue, Component, Prop, Model, Emit } from "vue-property-decorator";
import { Subject } from "rxjs";
import { debounceTime, distinctUntilChanged } from "rxjs/operators";
@Component({})
export default class AppCheckbox extends Vue {
/**
* 传入值
* @type {any}
* @memberof checkbox
*/
@Prop() public value?:any;
/**
* 是否禁用
* @type {boolean}
* @memberof checkbox
*/
@Prop() public disabled?: boolean;
/**
* 当前值
*
* @memberof checkbox
*/
get CurrentVal() {
if(this.value == 0){
return false;
}else if(this.value ==1){
return true;
}
}
/**
* 值变化
*
* @memberof checkbox
*/
set CurrentVal(val: any) {
this.$emit("change", val?1:0);
}
}
</script>
<style lang='less'>
@import "./app-checkbox.less";
</style>
\ No newline at end of file
.app-column-format{
display: inline-block;
}
\ No newline at end of file
<template>
<div class="app-column-format">
{{text}}
</div>
</template>
<script lang="ts">
import { Vue, Component, Prop, Model, Emit, Watch } from "vue-property-decorator";
/**
* 表格列格式化json数组,数据格式为"[{"srfkey":"001","srfmajortext":"TEST1"},{"srfkey":"002","srfmajortext":"TEST2"}......]"
*/
@Component({
})
export default class AppColumnFormat extends Vue {
/**
* 值
* @type {any}
* @memberof AppColumnFormat
*/
@Prop() public value?: any;
/**
* 显示文本
* @type {any}
* @memberof AppColumnFormat
*/
get text(){
if(this.value){
let returnStr:string = "";
let tempData:Array<any> =[];
if(typeof(this.value) === 'string'){
tempData= JSON.parse(this.value);
}else{
tempData = JSON.parse(JSON.stringify(this.value));
}
tempData.forEach((item:any,index:number) =>{
if(index >0){
returnStr +="、";
}
returnStr +=item.srfmajortext;
})
return returnStr;
}else{
return "";
}
}
}
</script>
<style lang='less'>
@import "./app-column-format.less";
</style>
\ No newline at end of file
.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 = this.viewparams ? JSON.parse(JSON.stringify(this.viewparams)) : {};
arg.context = this.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
.column-render{
.input-unit{
display: inline-block;
}
}
\ No newline at end of file
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown 格式
0% or
您添加了 0 到此讨论。请谨慎行事。
先完成此消息的编辑!
想要评论请 注册