diff --git a/.gitignore b/.gitignore index 3e759b7..a4222ae 100644 --- a/.gitignore +++ b/.gitignore @@ -328,3 +328,4 @@ ASALocalRun/ # MFractors (Xamarin productivity tool) working folder .mfractor/ +*.json diff --git a/src/JT808.DotNetty.Dashbord.UI/.babelrc b/src/JT808.DotNetty.Dashbord.UI/.babelrc new file mode 100644 index 0000000..2a81884 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/.babelrc @@ -0,0 +1,5 @@ +{ + "presets": [ + "@vue/app" + ] +} diff --git a/src/JT808.DotNetty.Dashbord.UI/.editorconfig b/src/JT808.DotNetty.Dashbord.UI/.editorconfig new file mode 100644 index 0000000..9d08a1a --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/.editorconfig @@ -0,0 +1,9 @@ +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 2 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true diff --git a/src/JT808.DotNetty.Dashbord.UI/.eslintignore b/src/JT808.DotNetty.Dashbord.UI/.eslintignore new file mode 100644 index 0000000..e69de29 diff --git a/src/JT808.DotNetty.Dashbord.UI/.eslintrc.js b/src/JT808.DotNetty.Dashbord.UI/.eslintrc.js new file mode 100644 index 0000000..2005c1a --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/.eslintrc.js @@ -0,0 +1,19 @@ +module.exports = { + root: true, + 'extends': [ + 'plugin:vue/essential', + '@vue/standard' + ], + rules: { + // allow async-await + 'generator-star-spacing': 'off', + // allow debugger during development + 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off', + 'vue/no-parsing-error': [2, { 'x-invalid-end-tag': false }], + 'no-undef': 'off', + 'camelcase': 'off' + }, + parserOptions: { + parser: 'babel-eslint' + } +} diff --git a/src/JT808.DotNetty.Dashbord.UI/.gitignore b/src/JT808.DotNetty.Dashbord.UI/.gitignore new file mode 100644 index 0000000..2056a84 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/.gitignore @@ -0,0 +1,26 @@ +.DS_Store +node_modules +/dist + +/tests/e2e/videos/ +/tests/e2e/screenshots/ + +# local env files +.env.local +.env.*.local + +# Log files +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Editor directories and files +.idea +.vscode +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw* + +build/env.js diff --git a/src/JT808.DotNetty.Dashbord.UI/.postcssrc.js b/src/JT808.DotNetty.Dashbord.UI/.postcssrc.js new file mode 100644 index 0000000..961986e --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/.postcssrc.js @@ -0,0 +1,5 @@ +module.exports = { + plugins: { + autoprefixer: {} + } +} diff --git a/src/JT808.DotNetty.Dashbord.UI/.travis.yml b/src/JT808.DotNetty.Dashbord.UI/.travis.yml new file mode 100644 index 0000000..07c971f --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/.travis.yml @@ -0,0 +1,5 @@ +language: node_js +node_js: stable +script: npm run lint +notifications: + email: false diff --git a/src/JT808.DotNetty.Dashbord.UI/LICENSE b/src/JT808.DotNetty.Dashbord.UI/LICENSE new file mode 100644 index 0000000..7ec88ac --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2017 iView + +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. diff --git a/src/JT808.DotNetty.Dashbord.UI/README.md b/src/JT808.DotNetty.Dashbord.UI/README.md new file mode 100644 index 0000000..9945af9 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/README.md @@ -0,0 +1,187 @@ +

+ + + +

+ +# iView Admin + +[![](https://img.shields.io/github/release/iview/iview-admin.svg)](https://github.com/iview/iview-admin/releases) +[![](https://img.shields.io/travis/iview/iview-admin.svg?style=flat-square)](https://travis-ci.org/iview/iview-admin) +[![vue](https://img.shields.io/badge/vue-2.5.10-brightgreen.svg?style=flat-square)](https://github.com/vuejs/vue) +[![iview ui](https://img.shields.io/badge/iview-3.0.0-brightgreen.svg?style=flat-square)](https://github.com/iview/iview) +[![npm](https://img.shields.io/npm/l/express.svg)]() + +[更新日志](https://github.com/iview/iview-admin/releases) + +[使用文档](https://lison16.github.io/iview-admin-doc/#/) + +[在线访问](https://admin.iviewui.com/) + +[简化版模板](https://github.com/iview/iview-admin/tree/template) + +[教学视频(26课时)](https://segmentfault.com/ls/1650000016221751?utm_source=banner) + +`注:在线版本会在开发版本新小版本发布后更新到相应版本,所以如果想体验最新版本iview-admin,请clone完整项目代码到本地运行。` + +## Install +```bush +// install dependencies +npm install +``` +## Run +### Development +```bush +npm run dev +``` +### Production(Build) +```bush +npm run build +``` + +## 简介 +  iView admin是基于Vue.js,搭配使用[iView](https://www.iviewui.com) UI组件库形成的一套后台集成解决方案,由TalkingData前端可视化团队部分成员开发维护。iView admin遵守iView设计和开发约定,风格统一,设计考究,并且更多功能在不停开发中。 +如果您想查看iview-admin的更新动态,您可以到[更新日志](https://github.com/iview/iview-admin/releases)查看了解最新更新;如果您是新手,想快速入手iview-admin,您可以到[使用教程](https://github.com/iview/iview-admin/wiki)查看讲解;如果您想在线体验iview-admin,您可以到[在线访问](https://admin.iviewui.com/)体验。如果你只是想要一个清醒爽朗的界面,那你可以下载[简化版模板](https://github.com/iview/iview-admin/tree/template)来做开发。 + +## 功能 + +- 登录/登出 +- 权限管理 + - 列表过滤 + - 权限切换 +- 多语言切换 +- 组件 + - 富文本编辑器 + - Markdown编辑器 + - 城市级联 + - 图片预览编辑 + - 可拖拽列表 + - 文件上传 + - 数字渐变 + - split-pane +- 表单编辑 + - 文章发布 + - 工作流 +- 表格 + - 可拖拽排序 + - 可编辑表格 + - 行内编辑 + - 单元格编辑 + - 可搜索表格 + - 表格导出数据 + - 导出为Csv文件 + - 导出为Xls文件 + - 表格转图片 +- 错误页面 + - 403页面 + - 404页面 + - 500页面 +- 高级路由 + - 动态路由 + - 带参页面 +- 换肤 +- 收缩侧边栏 +- tag标签导航 +- 面包屑导航 +- 全屏/退出全屏 +- 锁屏 +- 消息中心 +- 个人中心 + +## 文件结构 +```shell +. +├── build 项目构建配置 +├── config 开发相关配置 +├── public 打包所需静态资源 +└── src + ├── api AJAX请求 + └── assets 项目静态资源 + ├── icons 自定义图标资源 + └── images 图片资源 + ├── components 业务组件 + ├── config 项目运行配置 + ├── directive 自定义指令 + ├── libs 封装工具函数 + ├── locale 多语言文件 + ├── mock mock模拟数据 + ├── router 路由配置 + ├── store Vuex配置 + ├── view 页面文件 + └── tests 测试相关 +``` + +## Links + +- [TalkingData](https://github.com/TalkingData) +- [iView](https://github.com/iview/iview) +- [Vue](https://github.com/vuejs/vue) +- [Webpack](https://github.com/webpack/webpack) + +## 效果展示 + +- 响应式布局首页 +![image](https://github.com/iview/iview-admin/raw/dev/github-gif/home.gif) + +- 标签导航 +![image](https://github.com/iview/iview-admin/raw/dev/github-gif/page-tags.gif) + +- 权限管理 +![image](https://github.com/iview/iview-admin/raw/dev/github-gif/access.gif) + +- 可拖拽列表 +![image](https://github.com/iview/iview-admin/raw/dev/github-gif/dragable-list.gif) + +- 图片预览编辑 +![image](https://github.com/iview/iview-admin/raw/dev/github-gif/image-editor.gif) + +- 文件上传 +![image](https://github.com/iview/iview-admin/raw/dev/github-gif/upload.gif) + +- 数字渐变 +![image](https://github.com/iview/iview-admin/raw/dev/github-gif/count-to.gif) + +- split-pane +![image](https://github.com/iview/iview-admin/raw/dev/github-gif/split-pane.gif) + +- 文章发布 +![image](https://github.com/iview/iview-admin/raw/dev/github-gif/article-publish.gif) + +- 工作流 +![image](https://github.com/iview/iview-admin/raw/dev/github-gif/workflow.gif) + +- 可拖拽表格 +![image](https://github.com/iview/iview-admin/raw/dev/github-gif/dragable-table.gif) + +- 可编辑表格 +![image](https://github.com/iview/iview-admin/raw/dev/github-gif/editable-table.gif) + +- 表格导出数据 +![image](https://github.com/iview/iview-admin/raw/dev/github-gif/exportable-table.gif) + +- 表格转图片 +![image](https://github.com/iview/iview-admin/raw/dev/github-gif/table2image.gif) + +- 错误页面 +![image](https://github.com/iview/iview-admin/raw/dev/github-gif/error-page.gif) + +- 锁屏 +![image](https://github.com/iview/iview-admin/raw/dev/github-gif/locking.gif) + +- 可收缩侧边栏 +![image](https://github.com/iview/iview-admin/raw/dev/github-gif/sidebarmenu.gif) + +- 主题切换 +![image](https://github.com/iview/iview-admin/raw/dev/github-gif/theme.gif) + +- 消息中心 +![image](https://github.com/iview/iview-admin/raw/dev/github-gif/message.gif) + +### 💖💖 If you find this project helpful, maybe you can buy me a coffee. 💖💖 +![image](https://github.com/iview/iview-admin/raw/dev/github-gif/code.png) + + +## License +[MIT](http://opensource.org/licenses/MIT) + +Copyright (c) 2016-present, iView diff --git a/src/JT808.DotNetty.Dashbord.UI/public/favicon.ico b/src/JT808.DotNetty.Dashbord.UI/public/favicon.ico new file mode 100644 index 0000000..97131e9 Binary files /dev/null and b/src/JT808.DotNetty.Dashbord.UI/public/favicon.ico differ diff --git a/src/JT808.DotNetty.Dashbord.UI/public/index.html b/src/JT808.DotNetty.Dashbord.UI/public/index.html new file mode 100644 index 0000000..8e8eeaf --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/public/index.html @@ -0,0 +1,17 @@ + + + + + + + + + + + +
+ + + diff --git a/src/JT808.DotNetty.Dashbord.UI/src/App.vue b/src/JT808.DotNetty.Dashbord.UI/src/App.vue new file mode 100644 index 0000000..01c4743 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/App.vue @@ -0,0 +1,27 @@ + + + + + diff --git a/src/JT808.DotNetty.Dashbord.UI/src/api/atomicCounter.js b/src/JT808.DotNetty.Dashbord.UI/src/api/atomicCounter.js new file mode 100644 index 0000000..b77eadc --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/api/atomicCounter.js @@ -0,0 +1,8 @@ +import axios from '@/libs/api.request' + +export const GetAtomicCounter = () => { + return axios.request({ + url: 'AtomicCounter/GetAtomicCounter', + method: 'get' + }) +} diff --git a/src/JT808.DotNetty.Dashbord.UI/src/api/data.js b/src/JT808.DotNetty.Dashbord.UI/src/api/data.js new file mode 100644 index 0000000..ca4286a --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/api/data.js @@ -0,0 +1,37 @@ +import axios from '@/libs/api.request' + +export const getTableData = () => { + return axios.request({ + url: 'get_table_data', + method: 'get' + }) +} + +export const getDragList = () => { + return axios.request({ + url: 'get_drag_list', + method: 'get' + }) +} + +export const errorReq = () => { + return axios.request({ + url: 'error_url', + method: 'post' + }) +} + +export const saveErrorLogger = info => { + return axios.request({ + url: 'save_error_logger', + data: info, + method: 'post' + }) +} + +export const uploadImg = formData => { + return axios.request({ + url: 'image/upload', + data: formData + }) +} diff --git a/src/JT808.DotNetty.Dashbord.UI/src/api/routers.js b/src/JT808.DotNetty.Dashbord.UI/src/api/routers.js new file mode 100644 index 0000000..04a03a9 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/api/routers.js @@ -0,0 +1,11 @@ +import axios from '@/libs/api.request' + +export const getRouterReq = (access) => { + return axios.request({ + url: 'get_router', + params: { + access + }, + method: 'get' + }) +} diff --git a/src/JT808.DotNetty.Dashbord.UI/src/api/session.js b/src/JT808.DotNetty.Dashbord.UI/src/api/session.js new file mode 100644 index 0000000..a6003b6 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/api/session.js @@ -0,0 +1,22 @@ +import axios from '@/libs/api.request' + +export const RemoveByTerminalPhoneNo = (terminalPhoneN) => { + return axios.request({ + url: 'Session/RemoveByTerminalPhoneNo/' + terminalPhoneN, + method: 'get' + }) +} + +export const RemoveByChannelId = (channelId) => { + return axios.request({ + url: 'Session/RemoveByChannelId/' + channelId, + method: 'get' + }) +} + +export const GetAll = () => { + return axios.request({ + url: 'Session/GetAll', + method: 'get' + }) +} diff --git a/src/JT808.DotNetty.Dashbord.UI/src/api/sourcePackage.js b/src/JT808.DotNetty.Dashbord.UI/src/api/sourcePackage.js new file mode 100644 index 0000000..fb449b5 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/api/sourcePackage.js @@ -0,0 +1,32 @@ +import axios from '@/libs/api.request' + +export const Add = ({ Host, Port }) => { + const data = { + Host, + Port + } + return axios.request({ + url: 'SourcePackage/Add', + data, + method: 'post' + }) +} + +export const Remove = ({ Host, Port }) => { + const data = { + Host, + Port + } + return axios.request({ + url: 'SourcePackage/Remove', + data, + method: 'post' + }) +} + +export const GetAll = () => { + return axios.request({ + url: 'SourcePackage/GetAll', + method: 'get' + }) +} diff --git a/src/JT808.DotNetty.Dashbord.UI/src/api/transmit.js b/src/JT808.DotNetty.Dashbord.UI/src/api/transmit.js new file mode 100644 index 0000000..dc75362 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/api/transmit.js @@ -0,0 +1,32 @@ +import axios from '@/libs/api.request' + +export const Add = ({ Host, Port }) => { + const data = { + Host, + Port + } + return axios.request({ + url: 'Transmit/Add', + data, + method: 'post' + }) +} + +export const Remove = ({ Host, Port }) => { + const data = { + Host, + Port + } + return axios.request({ + url: 'Transmit/Remove', + data, + method: 'post' + }) +} + +export const GetAll = () => { + return axios.request({ + url: 'Transmit/GetAll', + method: 'get' + }) +} diff --git a/src/JT808.DotNetty.Dashbord.UI/src/api/unificationSend.js b/src/JT808.DotNetty.Dashbord.UI/src/api/unificationSend.js new file mode 100644 index 0000000..ea95d65 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/api/unificationSend.js @@ -0,0 +1,8 @@ +import axios from '@/libs/api.request' + +export const SendText = ({ terminalPhoneNo, text }) => { + return axios.request({ + url: 'UnificationSend/SendText/' + terminalPhoneNo + '/' + text, + method: 'get' + }) +} diff --git a/src/JT808.DotNetty.Dashbord.UI/src/api/user.js b/src/JT808.DotNetty.Dashbord.UI/src/api/user.js new file mode 100644 index 0000000..2d6d4d1 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/api/user.js @@ -0,0 +1,84 @@ +import axios from '@/libs/api.request' + +export const login = ({ userName, password }) => { + const data = { + userName, + password + } + return axios.request({ + url: 'login', + data, + method: 'post' + }) +} + +export const getUserInfo = (token) => { + return axios.request({ + url: 'get_info', + params: { + token + }, + method: 'get' + }) +} + +export const logout = (token) => { + return axios.request({ + url: 'logout', + method: 'post' + }) +} + +export const getUnreadCount = () => { + return axios.request({ + url: 'message/count', + method: 'get' + }) +} + +export const getMessage = () => { + return axios.request({ + url: 'message/init', + method: 'get' + }) +} + +export const getContentByMsgId = msg_id => { + return axios.request({ + url: 'message/content', + method: 'get', + params: { + msg_id + } + }) +} + +export const hasRead = msg_id => { + return axios.request({ + url: 'message/has_read', + method: 'post', + data: { + msg_id + } + }) +} + +export const removeReaded = msg_id => { + return axios.request({ + url: 'message/remove_readed', + method: 'post', + data: { + msg_id + } + }) +} + +export const restoreTrash = msg_id => { + return axios.request({ + url: 'message/restore', + method: 'post', + data: { + msg_id + } + }) +} diff --git a/src/JT808.DotNetty.Dashbord.UI/src/assets/icons/iconfont.css b/src/JT808.DotNetty.Dashbord.UI/src/assets/icons/iconfont.css new file mode 100644 index 0000000..80a476c --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/assets/icons/iconfont.css @@ -0,0 +1,37 @@ + +@font-face {font-family: "iconfont"; + src: url('iconfont.eot?t=1541579316141'); /* IE9*/ + src: url('iconfont.eot?t=1541579316141#iefix') format('embedded-opentype'), /* IE6-IE8 */ + url('data:application/x-font-woff;charset=utf-8;base64,d09GRgABAAAAAAiEAAsAAAAADmgAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABHU1VCAAABCAAAADMAAABCsP6z7U9TLzIAAAE8AAAARAAAAFY8eUnXY21hcAAAAYAAAACjAAACLi+YJuBnbHlmAAACJAAABAgAAAcg4dRWHmhlYWQAAAYsAAAAMQAAADYTL8piaGhlYQAABmAAAAAgAAAAJAfdA4xobXR4AAAGgAAAABQAAAAsLAD//2xvY2EAAAaUAAAAGAAAABgImgpGbWF4cAAABqwAAAAfAAAAIAEcAG5uYW1lAAAGzAAAAUUAAAJtPlT+fXBvc3QAAAgUAAAAbgAAAI54roygeJxjYGRgYOBikGPQYWB0cfMJYeBgYGGAAJAMY05meiJQDMoDyrGAaQ4gZoOIAgCKIwNPAHicY2BkYWCcwMDKwMHUyXSGgYGhH0IzvmYwYuRgYGBiYGVmwAoC0lxTGByeMTx/ytzwv4EhhrmBoRkozAiSAwDuUwzMeJzlkUEKwkAMRd/YabXFhQvxFF6qPYPrUujGY7jyIr1JoZNjtMnEhag3MOEN5MMk8D9QAoVyVSKEJwGrh6oh6wVN1iM3nc+cVImJVKdOehlklElmWdYVstp+ql8VdIv15a1NLW0zFXsO7Kjz3erH/3+rY37vr6kxnx1LKNWOJZlaxxJNnWOpSu+ot8jgqMvI6KjfyOSo88jsaAbI4tBsig89rQB4nLVUTWwbRRSeNzO767i2g7N/FP9s7MRrE5ON4/V6rSZyU0PiINSSNImES4IUoapWz6hEiqiMBDQqEojkAkiFStyKRC+9VSoFCeUEyqESVUAqEkcu3OAQb3hrJxAXwSGI3X0/szPz5vvm2x0i7O/vf8IJe5VkSJnUyUtklRBQJE1VIjRtUafkmk6pSu2ipleh4+xikkKxSksWTUeo8m8NoagpYtoslTmxrLl37z64e33esuJjU8P5Wd262LxoPVnPZ06Pxfe+C0YjkhSJygPhQCA8ABPOykwuN7NyuRvgUnAgLEnhATkaCQQiUe/7XKUyV6nQz+t2o7l66+rs7NVbq82GXTdrdjxjRGU5amTids2bUDMFtzCsqsMYMqr3IDY6OT05GjsI8Exv/6CSkOWEQigh+y3clxY5QVTcEZFIGtHLxDUJs6WsHR1y9SFKdr1HggCp3V1ICYL36OOpVmvKN9bC1u6R3vZ0qwWtVovgJfqOfUvfIYxIWL+fyETHNVJqSkIT1JTjW8ZWh3yDJDz0ctvsyt51etvrg9/QHhqGlzMM+vbmizPnDWPLMNbW19e7tffvsBzL99aWEfBRY46t+tbe3PypXv/IMDYN43WsQBe9HL2NC33RuxABrPsG+xH3o4bVRE2KgCRqulbWNf8W/UYVHM129aKra24VshZkq+CWD/Oy6Xt8cGYEthgHVlVliCfynAlqjo6oysTKlYUAD4docMI5/1ZioN+GwZNBcTwWUmTdBUqhTwX29QebXzF4An4JJMzwfMl+WQ01+IlQZVR4yhie53ycA16pOI/ODiYNGK4MChdCgXNnX5gIJXPCSYnf2OF850aQ+zJIyOs+u8+mMO8jQdwtg1TIWVRjKAnFcslMi8KfGUPoSUCergUyUk77dMyS69Ms6tijKZKYwUGKbpfdzu+iYeZYAHMFiOVi+MD7h9mb99qC0L7X8c+XatMfTj97KZ5IxJt/pd43tYYQKEjAnXMOB6kQEBrwg+LPjindAPOHNdC3q3ait0I3/ZIunZEARLNYNEUA6czSP3N/7j9wz6ZESdX0VNl1zGNS/szbQaQSIGk4DtVPcZf8AgXpf9A2OyTit5s2syZmand46bhEe2WtodLHkvaoqtTXuXN2/c42WADP9HGfbUcUW7JgqHss4xHtlMys679FqUomdP9VJBQBdnlPABBubpuNwqnmQj6/0HwNQzKxDUJFgKiXurBG6dqFjmeBzsvtRPJgGIZThYa5fdOvsReOticPh6JHHXxsv7ItJpOniYPYsmZ/x0QD/o5P105DeQwF6MH33ogoLi+KQp7zpY3HQV5bFMURzheXeds7gpP+jKNXljjHuYvXHke7cdCxLLZf6YX7B63UcCV4nGNgZGBgAOKAN2ZR8fw2Xxm4WRhA4AbHYRMY/f///1oWBuYGIJeDgQkkCgAvWgs2AAAAeJxjYGRgYG7438AQw8Lw/z8DAwsDA1AEBXADAHXiBHJ4nGNhYGBgYfj/nwVM48cATwECKwAAAAAAjAC6AOgBFAGAAf4CbgLqAzgDkHicY2BkYGDgZkhiYGcAASYg5gJCBob/YD4DABOmAYsAeJxlj01OwzAQhV/6B6QSqqhgh+QFYgEo/RGrblhUavdddN+mTpsqiSPHrdQDcB6OwAk4AtyAO/BIJ5s2lsffvHljTwDc4Acejt8t95E9XDI7cg0XuBeuU38QbpBfhJto41W4Rf1N2MczpsJtdGF5g9e4YvaEd2EPHXwI13CNT+E69S/hBvlbuIk7/Aq30PHqwj7mXle4jUcv9sdWL5xeqeVBxaHJIpM5v4KZXu+Sha3S6pxrW8QmU4OgX0lTnWlb3VPs10PnIhVZk6oJqzpJjMqt2erQBRvn8lGvF4kehCblWGP+tsYCjnEFhSUOjDFCGGSIyujoO1Vm9K+xQ8Jee1Y9zed0WxTU/3OFAQL0z1xTurLSeTpPgT1fG1J1dCtuy56UNJFezUkSskJe1rZUQuoBNmVXjhF6XNGJPyhnSP8ACVpuyAAAAHicbYhdDoIwEAb3a6k/YIIX8VArWewmdJFWJOnpJTG+OQ+TzJCjLy39p4ODR4OAA4444YwWHS7U3IVzn6Voldtb8ksHnvohrlqjjmw1rmzXsvdT7fEbblnCmOfNfJIYStJJfGIL27yb6AOCGR89AAA=') format('woff'), + url('iconfont.ttf?t=1541579316141') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+*/ + url('iconfont.svg?t=1541579316141#iconfont') format('svg'); /* iOS 4.1- */ +} + +.iconfont { + font-family:"iconfont" !important; + font-size:16px; + font-style:normal; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +.icon-bear:before { content: "\e600"; } + +.icon-resize-vertical:before { content: "\e7c3"; } + +.icon-chuizhifanzhuan:before { content: "\e661"; } + +.icon-shuipingfanzhuan:before { content: "\e662"; } + +.icon-qq:before { content: "\e609"; } + +.icon-frown:before { content: "\e77e"; } + +.icon-meh:before { content: "\e780"; } + +.icon-smile:before { content: "\e783"; } + +.icon-man:before { content: "\e7e2"; } + +.icon-woman:before { content: "\e7e5"; } + diff --git a/src/JT808.DotNetty.Dashbord.UI/src/assets/icons/iconfont.eot b/src/JT808.DotNetty.Dashbord.UI/src/assets/icons/iconfont.eot new file mode 100644 index 0000000..045499d Binary files /dev/null and b/src/JT808.DotNetty.Dashbord.UI/src/assets/icons/iconfont.eot differ diff --git a/src/JT808.DotNetty.Dashbord.UI/src/assets/icons/iconfont.svg b/src/JT808.DotNetty.Dashbord.UI/src/assets/icons/iconfont.svg new file mode 100644 index 0000000..6aa3270 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/assets/icons/iconfont.svg @@ -0,0 +1,56 @@ + + + + + +Created by iconfont + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/JT808.DotNetty.Dashbord.UI/src/assets/icons/iconfont.ttf b/src/JT808.DotNetty.Dashbord.UI/src/assets/icons/iconfont.ttf new file mode 100644 index 0000000..0c557de Binary files /dev/null and b/src/JT808.DotNetty.Dashbord.UI/src/assets/icons/iconfont.ttf differ diff --git a/src/JT808.DotNetty.Dashbord.UI/src/assets/icons/iconfont.woff b/src/JT808.DotNetty.Dashbord.UI/src/assets/icons/iconfont.woff new file mode 100644 index 0000000..105adab Binary files /dev/null and b/src/JT808.DotNetty.Dashbord.UI/src/assets/icons/iconfont.woff differ diff --git a/src/JT808.DotNetty.Dashbord.UI/src/assets/images/error-page/error-401.svg b/src/JT808.DotNetty.Dashbord.UI/src/assets/images/error-page/error-401.svg new file mode 100644 index 0000000..19e2f9f --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/assets/images/error-page/error-401.svg @@ -0,0 +1 @@ +tasting \ No newline at end of file diff --git a/src/JT808.DotNetty.Dashbord.UI/src/assets/images/error-page/error-404.svg b/src/JT808.DotNetty.Dashbord.UI/src/assets/images/error-page/error-404.svg new file mode 100644 index 0000000..77d97f7 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/assets/images/error-page/error-404.svg @@ -0,0 +1 @@ +drone_delivery \ No newline at end of file diff --git a/src/JT808.DotNetty.Dashbord.UI/src/assets/images/error-page/error-500.svg b/src/JT808.DotNetty.Dashbord.UI/src/assets/images/error-page/error-500.svg new file mode 100644 index 0000000..ef72fd3 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/assets/images/error-page/error-500.svg @@ -0,0 +1 @@ +co-working \ No newline at end of file diff --git a/src/JT808.DotNetty.Dashbord.UI/src/assets/images/login-bg.jpg b/src/JT808.DotNetty.Dashbord.UI/src/assets/images/login-bg.jpg new file mode 100644 index 0000000..94b8f51 Binary files /dev/null and b/src/JT808.DotNetty.Dashbord.UI/src/assets/images/login-bg.jpg differ diff --git a/src/JT808.DotNetty.Dashbord.UI/src/assets/images/logo-min.jpg b/src/JT808.DotNetty.Dashbord.UI/src/assets/images/logo-min.jpg new file mode 100644 index 0000000..18abf21 Binary files /dev/null and b/src/JT808.DotNetty.Dashbord.UI/src/assets/images/logo-min.jpg differ diff --git a/src/JT808.DotNetty.Dashbord.UI/src/assets/images/logo.jpg b/src/JT808.DotNetty.Dashbord.UI/src/assets/images/logo.jpg new file mode 100644 index 0000000..11638b3 Binary files /dev/null and b/src/JT808.DotNetty.Dashbord.UI/src/assets/images/logo.jpg differ diff --git a/src/JT808.DotNetty.Dashbord.UI/src/assets/images/qq-group1.jpg b/src/JT808.DotNetty.Dashbord.UI/src/assets/images/qq-group1.jpg new file mode 100644 index 0000000..3e6dd60 Binary files /dev/null and b/src/JT808.DotNetty.Dashbord.UI/src/assets/images/qq-group1.jpg differ diff --git a/src/JT808.DotNetty.Dashbord.UI/src/assets/images/qq-group2.jpg b/src/JT808.DotNetty.Dashbord.UI/src/assets/images/qq-group2.jpg new file mode 100644 index 0000000..526b081 Binary files /dev/null and b/src/JT808.DotNetty.Dashbord.UI/src/assets/images/qq-group2.jpg differ diff --git a/src/JT808.DotNetty.Dashbord.UI/src/assets/images/talkingdata.png b/src/JT808.DotNetty.Dashbord.UI/src/assets/images/talkingdata.png new file mode 100644 index 0000000..87ad50e Binary files /dev/null and b/src/JT808.DotNetty.Dashbord.UI/src/assets/images/talkingdata.png differ diff --git a/src/JT808.DotNetty.Dashbord.UI/src/components/charts/bar.vue b/src/JT808.DotNetty.Dashbord.UI/src/components/charts/bar.vue new file mode 100644 index 0000000..b0a2709 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/components/charts/bar.vue @@ -0,0 +1,58 @@ + + + diff --git a/src/JT808.DotNetty.Dashbord.UI/src/components/charts/index.js b/src/JT808.DotNetty.Dashbord.UI/src/components/charts/index.js new file mode 100644 index 0000000..2ca3c91 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/components/charts/index.js @@ -0,0 +1,3 @@ +import ChartPie from './pie.vue' +import ChartBar from './bar.vue' +export { ChartPie, ChartBar } diff --git a/src/JT808.DotNetty.Dashbord.UI/src/components/charts/pie.vue b/src/JT808.DotNetty.Dashbord.UI/src/components/charts/pie.vue new file mode 100644 index 0000000..c86d68c --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/components/charts/pie.vue @@ -0,0 +1,70 @@ + + + diff --git a/src/JT808.DotNetty.Dashbord.UI/src/components/common-icon/common-icon.vue b/src/JT808.DotNetty.Dashbord.UI/src/components/common-icon/common-icon.vue new file mode 100644 index 0000000..768fa1b --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/components/common-icon/common-icon.vue @@ -0,0 +1,42 @@ + + + + + diff --git a/src/JT808.DotNetty.Dashbord.UI/src/components/common-icon/index.js b/src/JT808.DotNetty.Dashbord.UI/src/components/common-icon/index.js new file mode 100644 index 0000000..1207d15 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/components/common-icon/index.js @@ -0,0 +1,2 @@ +import CommonIcon from './common-icon.vue' +export default CommonIcon diff --git a/src/JT808.DotNetty.Dashbord.UI/src/components/common/common.less b/src/JT808.DotNetty.Dashbord.UI/src/components/common/common.less new file mode 100644 index 0000000..3c3e5b1 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/components/common/common.less @@ -0,0 +1,8 @@ +.no-select{ + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} diff --git a/src/JT808.DotNetty.Dashbord.UI/src/components/common/util.js b/src/JT808.DotNetty.Dashbord.UI/src/components/common/util.js new file mode 100644 index 0000000..2129e7a --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/components/common/util.js @@ -0,0 +1,3 @@ +export const showTitle = (item, vm) => { + return vm.$config.useI18n ? vm.$t(item.name) : ((item.meta && item.meta.title) || item.name) +} diff --git a/src/JT808.DotNetty.Dashbord.UI/src/components/count-to/count-to.vue b/src/JT808.DotNetty.Dashbord.UI/src/components/count-to/count-to.vue new file mode 100644 index 0000000..a10e3ff --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/components/count-to/count-to.vue @@ -0,0 +1,174 @@ + + + diff --git a/src/JT808.DotNetty.Dashbord.UI/src/components/count-to/index.js b/src/JT808.DotNetty.Dashbord.UI/src/components/count-to/index.js new file mode 100644 index 0000000..17b3332 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/components/count-to/index.js @@ -0,0 +1,2 @@ +import countTo from './count-to.vue' +export default countTo diff --git a/src/JT808.DotNetty.Dashbord.UI/src/components/count-to/index.less b/src/JT808.DotNetty.Dashbord.UI/src/components/count-to/index.less new file mode 100644 index 0000000..e17d7c6 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/components/count-to/index.less @@ -0,0 +1,10 @@ +@prefix: ~"count-to"; + +.@{prefix}-wrapper{ + .content-outer{ + display: inline-block; + .@{prefix}-unit-text{ + font-style: normal; + } + } +} diff --git a/src/JT808.DotNetty.Dashbord.UI/src/components/cropper/index.js b/src/JT808.DotNetty.Dashbord.UI/src/components/cropper/index.js new file mode 100644 index 0000000..e7db5ea --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/components/cropper/index.js @@ -0,0 +1,2 @@ +import Cropper from './index.vue' +export default Cropper diff --git a/src/JT808.DotNetty.Dashbord.UI/src/components/cropper/index.less b/src/JT808.DotNetty.Dashbord.UI/src/components/cropper/index.less new file mode 100644 index 0000000..cdf431d --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/components/cropper/index.less @@ -0,0 +1,35 @@ +.bg{ + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC") +} +.cropper-wrapper{ + width: 600px; + height: 340px; + .img-box{ + height: 340px; + width: 430px; + border: 1px solid #ebebeb; + display: inline-block; + .bg; + img{ + max-width: 100%; + display: block; + } + } + .right-con{ + display: inline-block; + width: 170px; + vertical-align: top; + box-sizing: border-box; + padding: 0 10px; + .preview-box{ + height: 150px !important; + width: 100% !important; + overflow: hidden; + border: 1px solid #ebebeb; + .bg; + } + .button-box{ + padding: 10px 0 0; + } + } +} diff --git a/src/JT808.DotNetty.Dashbord.UI/src/components/cropper/index.vue b/src/JT808.DotNetty.Dashbord.UI/src/components/cropper/index.vue new file mode 100644 index 0000000..7bb664f --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/components/cropper/index.vue @@ -0,0 +1,139 @@ + + + diff --git a/src/JT808.DotNetty.Dashbord.UI/src/components/drag-list/drag-list.vue b/src/JT808.DotNetty.Dashbord.UI/src/components/drag-list/drag-list.vue new file mode 100644 index 0000000..664abc9 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/components/drag-list/drag-list.vue @@ -0,0 +1,92 @@ + + + diff --git a/src/JT808.DotNetty.Dashbord.UI/src/components/drag-list/index.js b/src/JT808.DotNetty.Dashbord.UI/src/components/drag-list/index.js new file mode 100644 index 0000000..d2bb972 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/components/drag-list/index.js @@ -0,0 +1,2 @@ +import DragList from './drag-list.vue' +export default DragList diff --git a/src/JT808.DotNetty.Dashbord.UI/src/components/editor/editor.vue b/src/JT808.DotNetty.Dashbord.UI/src/components/editor/editor.vue new file mode 100644 index 0000000..881c73e --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/components/editor/editor.vue @@ -0,0 +1,75 @@ + + + + + diff --git a/src/JT808.DotNetty.Dashbord.UI/src/components/editor/index.js b/src/JT808.DotNetty.Dashbord.UI/src/components/editor/index.js new file mode 100644 index 0000000..56e8de2 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/components/editor/index.js @@ -0,0 +1,2 @@ +import Editor from './editor.vue' +export default Editor diff --git a/src/JT808.DotNetty.Dashbord.UI/src/components/icons/icons.vue b/src/JT808.DotNetty.Dashbord.UI/src/components/icons/icons.vue new file mode 100644 index 0000000..50b7183 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/components/icons/icons.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/JT808.DotNetty.Dashbord.UI/src/components/icons/index.js b/src/JT808.DotNetty.Dashbord.UI/src/components/icons/index.js new file mode 100644 index 0000000..bdc38b2 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/components/icons/index.js @@ -0,0 +1,2 @@ +import Icons from './icons.vue' +export default Icons diff --git a/src/JT808.DotNetty.Dashbord.UI/src/components/info-card/index.js b/src/JT808.DotNetty.Dashbord.UI/src/components/info-card/index.js new file mode 100644 index 0000000..354419b --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/components/info-card/index.js @@ -0,0 +1,2 @@ +import InforCard from './infor-card.vue' +export default InforCard diff --git a/src/JT808.DotNetty.Dashbord.UI/src/components/info-card/infor-card.vue b/src/JT808.DotNetty.Dashbord.UI/src/components/info-card/infor-card.vue new file mode 100644 index 0000000..6240d0e --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/components/info-card/infor-card.vue @@ -0,0 +1,94 @@ + + + + + diff --git a/src/JT808.DotNetty.Dashbord.UI/src/components/login-form/index.js b/src/JT808.DotNetty.Dashbord.UI/src/components/login-form/index.js new file mode 100644 index 0000000..d480c28 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/components/login-form/index.js @@ -0,0 +1,2 @@ +import LoginForm from './login-form.vue' +export default LoginForm diff --git a/src/JT808.DotNetty.Dashbord.UI/src/components/login-form/login-form.vue b/src/JT808.DotNetty.Dashbord.UI/src/components/login-form/login-form.vue new file mode 100644 index 0000000..497c08c --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/components/login-form/login-form.vue @@ -0,0 +1,72 @@ + + diff --git a/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/a-back-top/index.js b/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/a-back-top/index.js new file mode 100644 index 0000000..4da0014 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/a-back-top/index.js @@ -0,0 +1,2 @@ +import ABackTop from './index.vue' +export default ABackTop diff --git a/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/a-back-top/index.vue b/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/a-back-top/index.vue new file mode 100644 index 0000000..f26f95c --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/a-back-top/index.vue @@ -0,0 +1,90 @@ + + diff --git a/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/error-store/error-store.vue b/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/error-store/error-store.vue new file mode 100644 index 0000000..9941677 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/error-store/error-store.vue @@ -0,0 +1,49 @@ + + + + + diff --git a/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/error-store/index.js b/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/error-store/index.js new file mode 100644 index 0000000..a777df1 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/error-store/index.js @@ -0,0 +1,2 @@ +import ErrorStore from './error-store.vue' +export default ErrorStore diff --git a/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/fullscreen/fullscreen.vue b/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/fullscreen/fullscreen.vue new file mode 100644 index 0000000..d5213fa --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/fullscreen/fullscreen.vue @@ -0,0 +1,84 @@ + + + + + diff --git a/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/fullscreen/index.js b/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/fullscreen/index.js new file mode 100644 index 0000000..422c7c1 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/fullscreen/index.js @@ -0,0 +1,2 @@ +import Fullscreen from './fullscreen.vue' +export default Fullscreen diff --git a/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/header-bar/custom-bread-crumb/custom-bread-crumb.less b/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/header-bar/custom-bread-crumb/custom-bread-crumb.less new file mode 100644 index 0000000..1ace1eb --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/header-bar/custom-bread-crumb/custom-bread-crumb.less @@ -0,0 +1,4 @@ +.custom-bread-crumb{ + display: inline-block; + vertical-align: top; +} diff --git a/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/header-bar/custom-bread-crumb/custom-bread-crumb.vue b/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/header-bar/custom-bread-crumb/custom-bread-crumb.vue new file mode 100644 index 0000000..51b121d --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/header-bar/custom-bread-crumb/custom-bread-crumb.vue @@ -0,0 +1,46 @@ + + diff --git a/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/header-bar/custom-bread-crumb/index.js b/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/header-bar/custom-bread-crumb/index.js new file mode 100644 index 0000000..a590fe0 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/header-bar/custom-bread-crumb/index.js @@ -0,0 +1,2 @@ +import customBreadCrumb from './custom-bread-crumb.vue' +export default customBreadCrumb diff --git a/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/header-bar/header-bar.less b/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/header-bar/header-bar.less new file mode 100644 index 0000000..c245d19 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/header-bar/header-bar.less @@ -0,0 +1,14 @@ +.header-bar{ + width: 100%; + height: 100%; + position: relative; + .custom-content-con{ + float: right; + height: auto; + padding-right: 20px; + line-height: 64px; + & > *{ + float: right; + } + } +} diff --git a/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/header-bar/header-bar.vue b/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/header-bar/header-bar.vue new file mode 100644 index 0000000..1452146 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/header-bar/header-bar.vue @@ -0,0 +1,34 @@ + + diff --git a/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/header-bar/index.js b/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/header-bar/index.js new file mode 100644 index 0000000..3d4a170 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/header-bar/index.js @@ -0,0 +1,2 @@ +import HeaderBar from './header-bar' +export default HeaderBar diff --git a/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/header-bar/sider-trigger/index.js b/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/header-bar/sider-trigger/index.js new file mode 100644 index 0000000..15853f4 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/header-bar/sider-trigger/index.js @@ -0,0 +1,2 @@ +import siderTrigger from './sider-trigger.vue' +export default siderTrigger diff --git a/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/header-bar/sider-trigger/sider-trigger.less b/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/header-bar/sider-trigger/sider-trigger.less new file mode 100644 index 0000000..eb50999 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/header-bar/sider-trigger/sider-trigger.less @@ -0,0 +1,21 @@ +.trans{ + transition: transform .2s ease; +} +@size: 40px; +.sider-trigger-a{ + padding: 6px; + width: @size; + height: @size; + display: inline-block; + text-align: center; + color: #5c6b77; + margin-top: 12px; + i{ + .trans; + vertical-align: top; + } + &.collapsed i{ + transform: rotateZ(90deg); + .trans; + } +} diff --git a/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/header-bar/sider-trigger/sider-trigger.vue b/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/header-bar/sider-trigger/sider-trigger.vue new file mode 100644 index 0000000..200e18f --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/header-bar/sider-trigger/sider-trigger.vue @@ -0,0 +1,27 @@ + + + diff --git a/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/language/index.js b/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/language/index.js new file mode 100644 index 0000000..de2a90a --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/language/index.js @@ -0,0 +1,2 @@ +import Language from './language.vue' +export default Language diff --git a/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/language/language.vue b/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/language/language.vue new file mode 100644 index 0000000..b1d92ec --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/language/language.vue @@ -0,0 +1,51 @@ + + + diff --git a/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/side-menu/collapsed-menu.vue b/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/side-menu/collapsed-menu.vue new file mode 100644 index 0000000..73ac93e --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/side-menu/collapsed-menu.vue @@ -0,0 +1,51 @@ + + diff --git a/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/side-menu/index.js b/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/side-menu/index.js new file mode 100644 index 0000000..5b36868 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/side-menu/index.js @@ -0,0 +1,2 @@ +import SideMenu from './side-menu.vue' +export default SideMenu diff --git a/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/side-menu/item-mixin.js b/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/side-menu/item-mixin.js new file mode 100644 index 0000000..8b807af --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/side-menu/item-mixin.js @@ -0,0 +1,21 @@ +export default { + props: { + parentItem: { + type: Object, + default: () => {} + }, + theme: String, + iconSize: Number + }, + computed: { + parentName () { + return this.parentItem.name + }, + children () { + return this.parentItem.children + }, + textColor () { + return this.theme === 'dark' ? '#fff' : '#495060' + } + } +} diff --git a/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/side-menu/mixin.js b/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/side-menu/mixin.js new file mode 100644 index 0000000..21b618b --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/side-menu/mixin.js @@ -0,0 +1,18 @@ +import CommonIcon from '_c/common-icon' +import { showTitle } from '@/libs/util' +export default { + components: { + CommonIcon + }, + methods: { + showTitle (item) { + return showTitle(item, this) + }, + showChildren (item) { + return item.children && (item.children.length > 1 || (item.meta && item.meta.showAlways)) + }, + getNameOrHref (item, children0) { + return item.href ? `isTurnByHref_${item.href}` : (children0 ? item.children[0].name : item.name) + } + } +} diff --git a/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/side-menu/side-menu-item.vue b/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/side-menu/side-menu-item.vue new file mode 100644 index 0000000..12338a6 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/side-menu/side-menu-item.vue @@ -0,0 +1,26 @@ + + diff --git a/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/side-menu/side-menu.less b/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/side-menu/side-menu.less new file mode 100644 index 0000000..4716d82 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/side-menu/side-menu.less @@ -0,0 +1,40 @@ +.side-menu-wrapper{ + user-select: none; + .menu-collapsed{ + padding-top: 10px; + + .ivu-dropdown{ + width: 100%; + .ivu-dropdown-rel a{ + width: 100%; + } + } + .ivu-tooltip{ + width: 100%; + .ivu-tooltip-rel{ + width: 100%; + } + .ivu-tooltip-popper .ivu-tooltip-content{ + .ivu-tooltip-arrow{ + border-right-color: #fff; + } + .ivu-tooltip-inner{ + background: #fff; + color: #495060; + } + } + } + + + } + a.drop-menu-a{ + display: inline-block; + padding: 6px 15px; + width: 100%; + text-align: center; + color: #495060; + } +} +.menu-title{ + padding-left: 6px; +} diff --git a/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/side-menu/side-menu.vue b/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/side-menu/side-menu.vue new file mode 100644 index 0000000..ee18e86 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/side-menu/side-menu.vue @@ -0,0 +1,114 @@ + + + diff --git a/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/tags-nav/index.js b/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/tags-nav/index.js new file mode 100644 index 0000000..585792a --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/tags-nav/index.js @@ -0,0 +1,2 @@ +import TagsNav from './tags-nav.vue' +export default TagsNav diff --git a/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/tags-nav/tags-nav.less b/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/tags-nav/tags-nav.less new file mode 100644 index 0000000..a4c8c5d --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/tags-nav/tags-nav.less @@ -0,0 +1,87 @@ +.no-select{ + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} +.size{ + width: 100%; + height: 100%; +} +.tags-nav{ + position: relative; + border-top: 1px solid #F0F0F0; + border-bottom: 1px solid #F0F0F0; + .no-select; + .size; + .close-con{ + position: absolute; + right: 0; + top: 0; + height: 100%; + width: 32px; + background: #fff; + text-align: center; + z-index: 10; + } + .btn-con{ + position: absolute; + top: 0px; + height: 100%; + background: #fff; + padding-top: 3px; + z-index: 10; + button{ + padding: 6px 4px; + line-height: 14px; + text-align: center; + } + &.left-btn{ + left: 0px; + } + &.right-btn{ + right: 32px; + border-right: 1px solid #F0F0F0; + } + } + .scroll-outer{ + position: absolute; + left: 28px; + right: 61px; + top: 0; + bottom: 0; + box-shadow: 0px 0 3px 2px rgba(100,100,100,.1) inset; + .scroll-body{ + height: ~"calc(100% - 1px)"; + display: inline-block; + padding: 1px 4px 0; + position: absolute; + overflow: visible; + white-space: nowrap; + transition: left .3s ease; + .ivu-tag-dot-inner{ + transition: background .2s ease; + } + } + } + .contextmenu { + position: absolute; + margin: 0; + padding: 5px 0; + background: #fff; + z-index: 100; + list-style-type: none; + border-radius: 4px; + box-shadow: 2px 2px 3px 0 rgba(0, 0, 0, .3); + li { + margin: 0; + padding: 5px 15px; + cursor: pointer; + &:hover { + background: #eee; + } + } + } +} diff --git a/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/tags-nav/tags-nav.vue b/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/tags-nav/tags-nav.vue new file mode 100644 index 0000000..2dbca44 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/tags-nav/tags-nav.vue @@ -0,0 +1,209 @@ + + + + + diff --git a/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/user/index.js b/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/user/index.js new file mode 100644 index 0000000..3d04a5c --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/user/index.js @@ -0,0 +1,2 @@ +import User from './user.vue' +export default User diff --git a/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/user/user.less b/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/user/user.less new file mode 100644 index 0000000..a3c95af --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/user/user.less @@ -0,0 +1,12 @@ +.user{ + &-avator-dropdown{ + cursor: pointer; + display: inline-block; + // height: 64px; + vertical-align: middle; + // line-height: 64px; + .ivu-badge-dot{ + top: 16px; + } + } +} diff --git a/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/user/user.vue b/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/user/user.vue new file mode 100644 index 0000000..3d4689d --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/components/main/components/user/user.vue @@ -0,0 +1,59 @@ + + + diff --git a/src/JT808.DotNetty.Dashbord.UI/src/components/main/index.js b/src/JT808.DotNetty.Dashbord.UI/src/components/main/index.js new file mode 100644 index 0000000..7df2a08 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/components/main/index.js @@ -0,0 +1,2 @@ +import Main from './main.vue' +export default Main diff --git a/src/JT808.DotNetty.Dashbord.UI/src/components/main/main.less b/src/JT808.DotNetty.Dashbord.UI/src/components/main/main.less new file mode 100644 index 0000000..fd0cd41 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/components/main/main.less @@ -0,0 +1,75 @@ +.main{ + .logo-con{ + height: 64px; + padding: 10px; + img{ + height: 44px; + width: auto; + display: block; + margin: 0 auto; + } + } + .header-con{ + background: #fff; + padding: 0 20px; + width: 100%; + } + .main-layout-con{ + height: 100%; + overflow: hidden; + } + .main-content-con{ + height: ~"calc(100% - 60px)"; + overflow: hidden; + } + .tag-nav-wrapper{ + padding: 0; + height:40px; + background:#F0F0F0; + } + .content-wrapper{ + padding: 18px; + height: ~"calc(100% - 80px)"; + overflow: auto; + } + .left-sider{ + .ivu-layout-sider-children{ + overflow-y: scroll; + margin-right: -18px; + } + } +} +.ivu-menu-item > i{ + margin-right: 12px !important; +} +.ivu-menu-submenu > .ivu-menu > .ivu-menu-item > i { + margin-right: 8px !important; +} +.collased-menu-dropdown{ + width: 100%; + margin: 0; + line-height: normal; + padding: 7px 0 6px 16px; + clear: both; + font-size: 12px !important; + white-space: nowrap; + list-style: none; + cursor: pointer; + transition: background 0.2s ease-in-out; + &:hover{ + background: rgba(100, 100, 100, 0.1); + } + & * { + color: #515a6e; + } + .ivu-menu-item > i{ + margin-right: 12px !important; + } + .ivu-menu-submenu > .ivu-menu > .ivu-menu-item > i { + margin-right: 8px !important; + } +} + +.ivu-select-dropdown.ivu-dropdown-transfer{ + max-height: 400px; +} diff --git a/src/JT808.DotNetty.Dashbord.UI/src/components/main/main.vue b/src/JT808.DotNetty.Dashbord.UI/src/components/main/main.vue new file mode 100644 index 0000000..3c1603f --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/components/main/main.vue @@ -0,0 +1,183 @@ + + diff --git a/src/JT808.DotNetty.Dashbord.UI/src/components/markdown/index.js b/src/JT808.DotNetty.Dashbord.UI/src/components/markdown/index.js new file mode 100644 index 0000000..99e0cda --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/components/markdown/index.js @@ -0,0 +1,2 @@ +import MarkdownEditor from './markdown.vue' +export default MarkdownEditor diff --git a/src/JT808.DotNetty.Dashbord.UI/src/components/markdown/markdown.vue b/src/JT808.DotNetty.Dashbord.UI/src/components/markdown/markdown.vue new file mode 100644 index 0000000..242b3cc --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/components/markdown/markdown.vue @@ -0,0 +1,76 @@ + + + + + diff --git a/src/JT808.DotNetty.Dashbord.UI/src/components/parent-view/index.js b/src/JT808.DotNetty.Dashbord.UI/src/components/parent-view/index.js new file mode 100644 index 0000000..a959c65 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/components/parent-view/index.js @@ -0,0 +1,2 @@ +import ParentView from './parent-view.vue' +export default ParentView diff --git a/src/JT808.DotNetty.Dashbord.UI/src/components/parent-view/parent-view.vue b/src/JT808.DotNetty.Dashbord.UI/src/components/parent-view/parent-view.vue new file mode 100644 index 0000000..84259f3 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/components/parent-view/parent-view.vue @@ -0,0 +1,20 @@ + + diff --git a/src/JT808.DotNetty.Dashbord.UI/src/components/paste-editor/index.js b/src/JT808.DotNetty.Dashbord.UI/src/components/paste-editor/index.js new file mode 100644 index 0000000..f02331a --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/components/paste-editor/index.js @@ -0,0 +1,2 @@ +import PasteEditor from './paste-editor.vue' +export default PasteEditor diff --git a/src/JT808.DotNetty.Dashbord.UI/src/components/paste-editor/paste-editor.less b/src/JT808.DotNetty.Dashbord.UI/src/components/paste-editor/paste-editor.less new file mode 100644 index 0000000..2ffd2bd --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/components/paste-editor/paste-editor.less @@ -0,0 +1,26 @@ +.paste-editor-wrapper{ + width: 100%; + height: 100%; + border: 1px dashed gainsboro; + textarea.textarea-el{ + width: 100%; + height: 100%; + } + .CodeMirror{ + height: 100%; + padding: 0; + .CodeMirror-code div .CodeMirror-line > span > span.cm-tab{ + &::after{ + content: '→'; + color: #BFBFBF; + } + } + } + .first-row{ + font-weight: 700; + font-size: 14px; + } + .incorrect-row{ + background: #F5CBD1; + } +} diff --git a/src/JT808.DotNetty.Dashbord.UI/src/components/paste-editor/paste-editor.vue b/src/JT808.DotNetty.Dashbord.UI/src/components/paste-editor/paste-editor.vue new file mode 100644 index 0000000..083d6c4 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/components/paste-editor/paste-editor.vue @@ -0,0 +1,115 @@ + + + diff --git a/src/JT808.DotNetty.Dashbord.UI/src/components/paste-editor/plugins/placeholder.js b/src/JT808.DotNetty.Dashbord.UI/src/components/paste-editor/plugins/placeholder.js new file mode 100644 index 0000000..d9bf77e --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/components/paste-editor/plugins/placeholder.js @@ -0,0 +1,58 @@ +export default (codemirror) => { + (function (mod) { + mod(codemirror) + })(function (CodeMirror) { + CodeMirror.defineOption('placeholder', '', function (cm, val, old) { + var prev = old && old !== CodeMirror.Init + if (val && !prev) { + cm.on('blur', onBlur) + cm.on('change', onChange) + cm.on('swapDoc', onChange) + onChange(cm) + } else if (!val && prev) { + cm.off('blur', onBlur) + cm.off('change', onChange) + cm.off('swapDoc', onChange) + clearPlaceholder(cm) + var wrapper = cm.getWrapperElement() + wrapper.className = wrapper.className.replace(' CodeMirror-empty', '') + } + + if (val && !cm.hasFocus()) onBlur(cm) + }) + + function clearPlaceholder (cm) { + if (cm.state.placeholder) { + cm.state.placeholder.parentNode.removeChild(cm.state.placeholder) + cm.state.placeholder = null + } + } + function setPlaceholder (cm) { + clearPlaceholder(cm) + var elt = cm.state.placeholder = document.createElement('pre') + elt.style.cssText = 'height: 0; overflow: visible; color: #80848f;' + elt.style.direction = cm.getOption('direction') + elt.className = 'CodeMirror-placeholder' + var placeHolder = cm.getOption('placeholder') + if (typeof placeHolder === 'string') placeHolder = document.createTextNode(placeHolder) + elt.appendChild(placeHolder) + cm.display.lineSpace.insertBefore(elt, cm.display.lineSpace.firstChild) + } + + function onBlur (cm) { + if (isEmpty(cm)) setPlaceholder(cm) + } + function onChange (cm) { + let wrapper = cm.getWrapperElement() + let empty = isEmpty(cm) + wrapper.className = wrapper.className.replace(' CodeMirror-empty', '') + (empty ? ' CodeMirror-empty' : '') + + if (empty) setPlaceholder(cm) + else clearPlaceholder(cm) + } + + function isEmpty (cm) { + return (cm.lineCount() === 1) && (cm.getLine(0) === '') + } + }) +} diff --git a/src/JT808.DotNetty.Dashbord.UI/src/components/split-pane/index.js b/src/JT808.DotNetty.Dashbord.UI/src/components/split-pane/index.js new file mode 100644 index 0000000..f5ed60e --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/components/split-pane/index.js @@ -0,0 +1,2 @@ +import Split from './split.vue' +export default Split diff --git a/src/JT808.DotNetty.Dashbord.UI/src/components/split-pane/index.less b/src/JT808.DotNetty.Dashbord.UI/src/components/split-pane/index.less new file mode 100644 index 0000000..2583d90 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/components/split-pane/index.less @@ -0,0 +1,114 @@ +@split-prefix-cls: ~"ivu-split"; +@box-shadow: 0 0 4px 0 rgba(28, 36, 56, 0.4); +@trigger-bar-background: rgba(23, 35, 61, 0.25); +@trigger-background: #F8F8F9; +@trigger-width: 6px; +@trigger-bar-width: 4px; +@trigger-bar-offset: (@trigger-width - @trigger-bar-width) / 2; +@trigger-bar-interval: 3px; +@trigger-bar-weight: 1px; +@trigger-bar-con-height: (@trigger-bar-weight + @trigger-bar-interval) * 8; + +.@{split-prefix-cls}{ + &-wrapper{ + position: relative; + width: 100%; + height: 100%; + } + &-pane{ + position: absolute; + &.left-pane, &.right-pane{ + top: 0px; + bottom: 0px; + } + &.left-pane{ + left: 0px; + } + &.right-pane{ + right: 0px; + } + &.top-pane, &.bottom-pane{ + left: 0px; + right: 0px; + } + &.top-pane{ + top: 0px; + } + &.bottom-pane{ + bottom: 0px; + } + } + &-trigger{ + &-con{ + position: absolute; + transform: translate(-50%, -50%); + z-index: 10; + } + &-bar-con{ + position: absolute; + overflow: hidden; + &.vertical{ + left: @trigger-bar-offset; + top: 50%; + height: @trigger-bar-con-height; + transform: translate(0, -50%); + } + &.horizontal{ + left: 50%; + top: @trigger-bar-offset; + width: @trigger-bar-con-height; + transform: translate(-50%, 0); + } + } + &-vertical{ + width: @trigger-width; + height: 100%; + background: @trigger-background; + box-shadow: @box-shadow; + cursor: col-resize; + .@{split-prefix-cls}-trigger-bar{ + width: @trigger-bar-width; + height: 1px; + background: @trigger-bar-background; + float: left; + margin-top: @trigger-bar-interval; + } + } + &-horizontal{ + height: @trigger-width; + width: 100%; + background: @trigger-background; + box-shadow: @box-shadow; + cursor: row-resize; + .@{split-prefix-cls}-trigger-bar{ + height: @trigger-bar-width; + width: 1px; + background: @trigger-bar-background; + float: left; + margin-right: @trigger-bar-interval; + } + } + } + &-horizontal{ + .@{split-prefix-cls}-trigger-con{ + top: 50%; + height: 100%; + width: 0; + } + } + &-vertical{ + .@{split-prefix-cls}-trigger-con{ + left: 50%; + height: 0; + width: 100%; + } + } + .no-select{ + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + } +} diff --git a/src/JT808.DotNetty.Dashbord.UI/src/components/split-pane/split.vue b/src/JT808.DotNetty.Dashbord.UI/src/components/split-pane/split.vue new file mode 100644 index 0000000..409982e --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/components/split-pane/split.vue @@ -0,0 +1,158 @@ + + + + + diff --git a/src/JT808.DotNetty.Dashbord.UI/src/components/split-pane/trigger.vue b/src/JT808.DotNetty.Dashbord.UI/src/components/split-pane/trigger.vue new file mode 100644 index 0000000..9abdf03 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/components/split-pane/trigger.vue @@ -0,0 +1,43 @@ + + + + + diff --git a/src/JT808.DotNetty.Dashbord.UI/src/components/tables/edit.vue b/src/JT808.DotNetty.Dashbord.UI/src/components/tables/edit.vue new file mode 100644 index 0000000..e1066ef --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/components/tables/edit.vue @@ -0,0 +1,73 @@ + + + + + diff --git a/src/JT808.DotNetty.Dashbord.UI/src/components/tables/handle-btns.js b/src/JT808.DotNetty.Dashbord.UI/src/components/tables/handle-btns.js new file mode 100644 index 0000000..551b2e3 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/components/tables/handle-btns.js @@ -0,0 +1,33 @@ +const btns = { + delete: (h, params, vm) => { + return h('Poptip', { + props: { + confirm: true, + title: '你确定要删除吗?' + }, + on: { + 'on-ok': () => { + vm.$emit('on-delete', params) + vm.$emit('input', params.tableData.filter((item, index) => index !== params.row.initRowIndex)) + } + } + }, [ + h('Button', { + props: { + type: 'text', + ghost: true + } + }, [ + h('Icon', { + props: { + type: 'md-trash', + size: 18, + color: '#000000' + } + }) + ]) + ]) + } +} + +export default btns diff --git a/src/JT808.DotNetty.Dashbord.UI/src/components/tables/index.js b/src/JT808.DotNetty.Dashbord.UI/src/components/tables/index.js new file mode 100644 index 0000000..4dabfab --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/components/tables/index.js @@ -0,0 +1,2 @@ +import Tables from './tables.vue' +export default Tables diff --git a/src/JT808.DotNetty.Dashbord.UI/src/components/tables/index.less b/src/JT808.DotNetty.Dashbord.UI/src/components/tables/index.less new file mode 100644 index 0000000..3c352e1 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/components/tables/index.less @@ -0,0 +1,17 @@ +.search-con{ + padding: 10px 0; + .search{ + &-col{ + display: inline-block; + width: 200px; + } + &-input{ + display: inline-block; + width: 200px; + margin-left: 2px; + } + &-btn{ + margin-left: 2px; + } + } +} diff --git a/src/JT808.DotNetty.Dashbord.UI/src/components/tables/tables.vue b/src/JT808.DotNetty.Dashbord.UI/src/components/tables/tables.vue new file mode 100644 index 0000000..fa2c235 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/components/tables/tables.vue @@ -0,0 +1,277 @@ + + + diff --git a/src/JT808.DotNetty.Dashbord.UI/src/config/index.js b/src/JT808.DotNetty.Dashbord.UI/src/config/index.js new file mode 100644 index 0000000..6739a85 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/config/index.js @@ -0,0 +1,36 @@ +export default { + /** + * @description 配置显示在浏览器标签的title + */ + title: 'iView-admin', + /** + * @description token在Cookie中存储的天数,默认1天 + */ + cookieExpires: 1, + /** + * @description 是否使用国际化,默认为false + * 如果不使用,则需要在路由中给需要在菜单中展示的路由设置meta: {title: 'xxx'} + * 用来在菜单中显示文字 + */ + useI18n: true, + /** + * @description api请求基础路径 + */ + baseUrl: { + dev: 'https://www.easy-mock.com/mock/5add9213ce4d0e69998a6f51/iview-admin/', + pro: 'https://produce.com' + }, + /** + * @description 默认打开的首页的路由name值,默认为home + */ + homeName: 'home', + /** + * @description 需要加载的插件 + */ + plugin: { + 'error-store': { + showInHeader: true, // 设为false后不会在顶部显示错误日志徽标 + developmentOff: true // 设为true后在开发环境不会收集错误信息,方便开发中排查错误 + } + } +} diff --git a/src/JT808.DotNetty.Dashbord.UI/src/directive/directives.js b/src/JT808.DotNetty.Dashbord.UI/src/directive/directives.js new file mode 100644 index 0000000..fffd62c --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/directive/directives.js @@ -0,0 +1,9 @@ +import draggable from './module/draggable' +import clipboard from './module/clipboard' + +const directives = { + draggable, + clipboard +} + +export default directives diff --git a/src/JT808.DotNetty.Dashbord.UI/src/directive/index.js b/src/JT808.DotNetty.Dashbord.UI/src/directive/index.js new file mode 100644 index 0000000..aa98c10 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/directive/index.js @@ -0,0 +1,24 @@ +import directive from './directives' + +const importDirective = Vue => { + /** + * 拖拽指令 v-draggable="options" + * options = { + * trigger: /这里传入作为拖拽触发器的CSS选择器/, + * body: /这里传入需要移动容器的CSS选择器/, + * recover: /拖动结束之后是否恢复到原来的位置/ + * } + */ + Vue.directive('draggable', directive.draggable) + /** + * clipboard指令 v-draggable="options" + * options = { + * value: /在输入框中使用v-model绑定的值/, + * success: /复制成功后的回调/, + * error: /复制失败后的回调/ + * } + */ + Vue.directive('clipboard', directive.clipboard) +} + +export default importDirective diff --git a/src/JT808.DotNetty.Dashbord.UI/src/directive/module/clipboard.js b/src/JT808.DotNetty.Dashbord.UI/src/directive/module/clipboard.js new file mode 100644 index 0000000..655bdf8 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/directive/module/clipboard.js @@ -0,0 +1,30 @@ +import Clipboard from 'clipboard' +export default { + bind: (el, binding) => { + const clipboard = new Clipboard(el, { + text: () => binding.value.value + }) + el.__success_callback__ = binding.value.success + el.__error_callback__ = binding.value.error + clipboard.on('success', e => { + const callback = el.__success_callback__ + callback && callback(e) + }) + clipboard.on('error', e => { + const callback = el.__error_callback__ + callback && callback(e) + }) + el.__clipboard__ = clipboard + }, + update: (el, binding) => { + el.__clipboard__.text = () => binding.value.value + el.__success_callback__ = binding.value.success + el.__error_callback__ = binding.value.error + }, + unbind: (el, binding) => { + delete el.__success_callback__ + delete el.__error_callback__ + el.__clipboard__.destroy() + delete el.__clipboard__ + } +} diff --git a/src/JT808.DotNetty.Dashbord.UI/src/directive/module/draggable.js b/src/JT808.DotNetty.Dashbord.UI/src/directive/module/draggable.js new file mode 100644 index 0000000..b609e50 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/directive/module/draggable.js @@ -0,0 +1,41 @@ +import { on } from '@/libs/tools' +export default { + inserted: (el, binding, vnode) => { + let triggerDom = document.querySelector(binding.value.trigger) + triggerDom.style.cursor = 'move' + let bodyDom = document.querySelector(binding.value.body) + let pageX = 0 + let pageY = 0 + let transformX = 0 + let transformY = 0 + let canMove = false + const handleMousedown = e => { + let transform = /\(.*\)/.exec(bodyDom.style.transform) + if (transform) { + transform = transform[0].slice(1, transform[0].length - 1) + let splitxy = transform.split('px, ') + transformX = parseFloat(splitxy[0]) + transformY = parseFloat(splitxy[1].split('px')[0]) + } + pageX = e.pageX + pageY = e.pageY + canMove = true + } + const handleMousemove = e => { + let xOffset = e.pageX - pageX + transformX + let yOffset = e.pageY - pageY + transformY + if (canMove) bodyDom.style.transform = `translate(${xOffset}px, ${yOffset}px)` + } + const handleMouseup = e => { + canMove = false + } + on(triggerDom, 'mousedown', handleMousedown) + on(document, 'mousemove', handleMousemove) + on(document, 'mouseup', handleMouseup) + }, + update: (el, binding, vnode) => { + if (!binding.value.recover) return + let bodyDom = document.querySelector(binding.value.body) + bodyDom.style.transform = '' + } +} diff --git a/src/JT808.DotNetty.Dashbord.UI/src/index.less b/src/JT808.DotNetty.Dashbord.UI/src/index.less new file mode 100644 index 0000000..2f8be69 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/index.less @@ -0,0 +1,5 @@ +@import '~iview/src/styles/index.less'; + +@menu-dark-title: #001529; +@menu-dark-active-bg: #000c17; +@layout-sider-background: #001529; diff --git a/src/JT808.DotNetty.Dashbord.UI/src/libs/api.request.js b/src/JT808.DotNetty.Dashbord.UI/src/libs/api.request.js new file mode 100644 index 0000000..01cb87b --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/libs/api.request.js @@ -0,0 +1,6 @@ +import HttpRequest from '@/libs/axios' +import config from '@/config' +const baseUrl = process.env.NODE_ENV === 'development' ? config.baseUrl.dev : config.baseUrl.pro + +const axios = new HttpRequest(baseUrl) +export default axios diff --git a/src/JT808.DotNetty.Dashbord.UI/src/libs/axios.js b/src/JT808.DotNetty.Dashbord.UI/src/libs/axios.js new file mode 100644 index 0000000..4c06b4c --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/libs/axios.js @@ -0,0 +1,74 @@ +import axios from 'axios' +import store from '@/store' +// import { Spin } from 'iview' +const addErrorLog = errorInfo => { + const { statusText, status, request: { responseURL } } = errorInfo + let info = { + type: 'ajax', + code: status, + mes: statusText, + url: responseURL + } + if (!responseURL.includes('save_error_logger')) store.dispatch('addErrorLog', info) +} + +class HttpRequest { + constructor (baseUrl = baseURL) { + this.baseUrl = baseUrl + this.queue = {} + } + getInsideConfig () { + const config = { + baseURL: this.baseUrl, + headers: { + // + } + } + return config + } + destroy (url) { + delete this.queue[url] + if (!Object.keys(this.queue).length) { + // Spin.hide() + } + } + interceptors (instance, url) { + // 请求拦截 + instance.interceptors.request.use(config => { + // 添加全局的loading... + if (!Object.keys(this.queue).length) { + // Spin.show() // 不建议开启,因为界面不友好 + } + this.queue[url] = true + return config + }, error => { + return Promise.reject(error) + }) + // 响应拦截 + instance.interceptors.response.use(res => { + this.destroy(url) + const { data, status } = res + return { data, status } + }, error => { + this.destroy(url) + let errorInfo = error.response + if (!errorInfo) { + const { request: { statusText, status }, config } = JSON.parse(JSON.stringify(error)) + errorInfo = { + statusText, + status, + request: { responseURL: config.url } + } + } + addErrorLog(errorInfo) + return Promise.reject(error) + }) + } + request (options) { + const instance = axios.create() + options = Object.assign(this.getInsideConfig(), options) + this.interceptors(instance, options.url) + return instance(options) + } +} +export default HttpRequest diff --git a/src/JT808.DotNetty.Dashbord.UI/src/libs/excel.js b/src/JT808.DotNetty.Dashbord.UI/src/libs/excel.js new file mode 100644 index 0000000..ba9d406 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/libs/excel.js @@ -0,0 +1,113 @@ +/* eslint-disable */ +import XLSX from 'xlsx'; + +function auto_width(ws, data){ + /*set worksheet max width per col*/ + const colWidth = data.map(row => row.map(val => { + /*if null/undefined*/ + if (val == null) { + return {'wch': 10}; + } + /*if chinese*/ + else if (val.toString().charCodeAt(0) > 255) { + return {'wch': val.toString().length * 2}; + } else { + return {'wch': val.toString().length}; + } + })) + /*start in the first row*/ + let result = colWidth[0]; + for (let i = 1; i < colWidth.length; i++) { + for (let j = 0; j < colWidth[i].length; j++) { + if (result[j]['wch'] < colWidth[i][j]['wch']) { + result[j]['wch'] = colWidth[i][j]['wch']; + } + } + } + ws['!cols'] = result; +} + +function json_to_array(key, jsonData){ + return jsonData.map(v => key.map(j => { return v[j] })); +} + +// fix data,return string +function fixdata(data) { + let o = '' + let l = 0 + const w = 10240 + for (; l < data.byteLength / w; ++l) o += String.fromCharCode.apply(null, new Uint8Array(data.slice(l * w, l * w + w))) + o += String.fromCharCode.apply(null, new Uint8Array(data.slice(l * w))) + return o +} + +// get head from excel file,return array +function get_header_row(sheet) { + const headers = [] + const range = XLSX.utils.decode_range(sheet['!ref']) + let C + const R = range.s.r /* start in the first row */ + for (C = range.s.c; C <= range.e.c; ++C) { /* walk every column in the range */ + var cell = sheet[XLSX.utils.encode_cell({ c: C, r: R })] /* find the cell in the first row */ + var hdr = 'UNKNOWN ' + C // <-- replace with your desired default + if (cell && cell.t) hdr = XLSX.utils.format_cell(cell) + headers.push(hdr) + } + return headers +} + +export const export_table_to_excel= (id, filename) => { + const table = document.getElementById(id); + const wb = XLSX.utils.table_to_book(table); + XLSX.writeFile(wb, filename); + + /* the second way */ + // const table = document.getElementById(id); + // const wb = XLSX.utils.book_new(); + // const ws = XLSX.utils.table_to_sheet(table); + // XLSX.utils.book_append_sheet(wb, ws, filename); + // XLSX.writeFile(wb, filename); +} + +export const export_json_to_excel = ({data, key, title, filename, autoWidth}) => { + const wb = XLSX.utils.book_new(); + data.unshift(title); + const ws = XLSX.utils.json_to_sheet(data, {header: key, skipHeader: true}); + if(autoWidth){ + const arr = json_to_array(key, data); + auto_width(ws, arr); + } + XLSX.utils.book_append_sheet(wb, ws, filename); + XLSX.writeFile(wb, filename + '.xlsx'); +} + +export const export_array_to_excel = ({key, data, title, filename, autoWidth}) => { + const wb = XLSX.utils.book_new(); + const arr = json_to_array(key, data); + arr.unshift(title); + const ws = XLSX.utils.aoa_to_sheet(arr); + if(autoWidth){ + auto_width(ws, arr); + } + XLSX.utils.book_append_sheet(wb, ws, filename); + XLSX.writeFile(wb, filename + '.xlsx'); +} + +export const read = (data, type) => { + /* if type == 'base64' must fix data first */ + // const fixedData = fixdata(data) + // const workbook = XLSX.read(btoa(fixedData), { type: 'base64' }) + const workbook = XLSX.read(data, { type: type }); + const firstSheetName = workbook.SheetNames[0]; + const worksheet = workbook.Sheets[firstSheetName]; + const header = get_header_row(worksheet); + const results = XLSX.utils.sheet_to_json(worksheet); + return {header, results}; +} + +export default { + export_table_to_excel, + export_array_to_excel, + export_json_to_excel, + read +} diff --git a/src/JT808.DotNetty.Dashbord.UI/src/libs/tools.js b/src/JT808.DotNetty.Dashbord.UI/src/libs/tools.js new file mode 100644 index 0000000..0ca81d6 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/libs/tools.js @@ -0,0 +1,215 @@ +export const forEach = (arr, fn) => { + if (!arr.length || !fn) return + let i = -1 + let len = arr.length + while (++i < len) { + let item = arr[i] + fn(item, i, arr) + } +} + +/** + * @param {Array} arr1 + * @param {Array} arr2 + * @description 得到两个数组的交集, 两个数组的元素为数值或字符串 + */ +export const getIntersection = (arr1, arr2) => { + let len = Math.min(arr1.length, arr2.length) + let i = -1 + let res = [] + while (++i < len) { + const item = arr2[i] + if (arr1.indexOf(item) > -1) res.push(item) + } + return res +} + +/** + * @param {Array} arr1 + * @param {Array} arr2 + * @description 得到两个数组的并集, 两个数组的元素为数值或字符串 + */ +export const getUnion = (arr1, arr2) => { + return Array.from(new Set([...arr1, ...arr2])) +} + +/** + * @param {Array} target 目标数组 + * @param {Array} arr 需要查询的数组 + * @description 判断要查询的数组是否至少有一个元素包含在目标数组中 + */ +export const hasOneOf = (targetarr, arr) => { + return targetarr.some(_ => arr.indexOf(_) > -1) +} + +/** + * @param {String|Number} value 要验证的字符串或数值 + * @param {*} validList 用来验证的列表 + */ +export function oneOf (value, validList) { + for (let i = 0; i < validList.length; i++) { + if (value === validList[i]) { + return true + } + } + return false +} + +/** + * @param {Number} timeStamp 判断时间戳格式是否是毫秒 + * @returns {Boolean} + */ +const isMillisecond = timeStamp => { + const timeStr = String(timeStamp) + return timeStr.length > 10 +} + +/** + * @param {Number} timeStamp 传入的时间戳 + * @param {Number} currentTime 当前时间时间戳 + * @returns {Boolean} 传入的时间戳是否早于当前时间戳 + */ +const isEarly = (timeStamp, currentTime) => { + return timeStamp < currentTime +} + +/** + * @param {Number} num 数值 + * @returns {String} 处理后的字符串 + * @description 如果传入的数值小于10,即位数只有1位,则在前面补充0 + */ +const getHandledValue = num => { + return num < 10 ? '0' + num : num +} + +/** + * @param {Number} timeStamp 传入的时间戳 + * @param {Number} startType 要返回的时间字符串的格式类型,传入'year'则返回年开头的完整时间 + */ +const getDate = (timeStamp, startType) => { + const d = new Date(timeStamp * 1000) + const year = d.getFullYear() + const month = getHandledValue(d.getMonth() + 1) + const date = getHandledValue(d.getDate()) + const hours = getHandledValue(d.getHours()) + const minutes = getHandledValue(d.getMinutes()) + const second = getHandledValue(d.getSeconds()) + let resStr = '' + if (startType === 'year') resStr = year + '-' + month + '-' + date + ' ' + hours + ':' + minutes + ':' + second + else resStr = month + '-' + date + ' ' + hours + ':' + minutes + return resStr +} + +/** + * @param {String|Number} timeStamp 时间戳 + * @returns {String} 相对时间字符串 + */ +export const getRelativeTime = timeStamp => { + // 判断当前传入的时间戳是秒格式还是毫秒 + const IS_MILLISECOND = isMillisecond(timeStamp) + // 如果是毫秒格式则转为秒格式 + if (IS_MILLISECOND) Math.floor(timeStamp /= 1000) + // 传入的时间戳可以是数值或字符串类型,这里统一转为数值类型 + timeStamp = Number(timeStamp) + // 获取当前时间时间戳 + const currentTime = Math.floor(Date.parse(new Date()) / 1000) + // 判断传入时间戳是否早于当前时间戳 + const IS_EARLY = isEarly(timeStamp, currentTime) + // 获取两个时间戳差值 + let diff = currentTime - timeStamp + // 如果IS_EARLY为false则差值取反 + if (!IS_EARLY) diff = -diff + let resStr = '' + const dirStr = IS_EARLY ? '前' : '后' + // 少于等于59秒 + if (diff <= 59) resStr = diff + '秒' + dirStr + // 多于59秒,少于等于59分钟59秒 + else if (diff > 59 && diff <= 3599) resStr = Math.floor(diff / 60) + '分钟' + dirStr + // 多于59分钟59秒,少于等于23小时59分钟59秒 + else if (diff > 3599 && diff <= 86399) resStr = Math.floor(diff / 3600) + '小时' + dirStr + // 多于23小时59分钟59秒,少于等于29天59分钟59秒 + else if (diff > 86399 && diff <= 2623859) resStr = Math.floor(diff / 86400) + '天' + dirStr + // 多于29天59分钟59秒,少于364天23小时59分钟59秒,且传入的时间戳早于当前 + else if (diff > 2623859 && diff <= 31567859 && IS_EARLY) resStr = getDate(timeStamp) + else resStr = getDate(timeStamp, 'year') + return resStr +} + +/** + * @returns {String} 当前浏览器名称 + */ +export const getExplorer = () => { + const ua = window.navigator.userAgent + const isExplorer = (exp) => { + return ua.indexOf(exp) > -1 + } + if (isExplorer('MSIE')) return 'IE' + else if (isExplorer('Firefox')) return 'Firefox' + else if (isExplorer('Chrome')) return 'Chrome' + else if (isExplorer('Opera')) return 'Opera' + else if (isExplorer('Safari')) return 'Safari' +} + +/** + * @description 绑定事件 on(element, event, handler) + */ +export const on = (function () { + if (document.addEventListener) { + return function (element, event, handler) { + if (element && event && handler) { + element.addEventListener(event, handler, false) + } + } + } else { + return function (element, event, handler) { + if (element && event && handler) { + element.attachEvent('on' + event, handler) + } + } + } +})() + +/** + * @description 解绑事件 off(element, event, handler) + */ +export const off = (function () { + if (document.removeEventListener) { + return function (element, event, handler) { + if (element && event) { + element.removeEventListener(event, handler, false) + } + } + } else { + return function (element, event, handler) { + if (element && event) { + element.detachEvent('on' + event, handler) + } + } + } +})() + +/** + * 判断一个对象是否存在key,如果传入第二个参数key,则是判断这个obj对象是否存在key这个属性 + * 如果没有传入key这个参数,则判断obj对象是否有键值对 + */ +export const hasKey = (obj, key) => { + if (key) return key in obj + else { + let keysArr = Object.keys(obj) + return keysArr.length + } +} + +/** + * @param {*} obj1 对象 + * @param {*} obj2 对象 + * @description 判断两个对象是否相等,这两个对象的值只能是数字或字符串 + */ +export const objEqual = (obj1, obj2) => { + const keysArr1 = Object.keys(obj1) + const keysArr2 = Object.keys(obj2) + if (keysArr1.length !== keysArr2.length) return false + else if (keysArr1.length === 0 && keysArr2.length === 0) return true + /* eslint-disable-next-line */ + else return !keysArr1.some(key => obj1[key] != obj2[key]) +} diff --git a/src/JT808.DotNetty.Dashbord.UI/src/libs/util.js b/src/JT808.DotNetty.Dashbord.UI/src/libs/util.js new file mode 100644 index 0000000..1457b20 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/libs/util.js @@ -0,0 +1,399 @@ +import Cookies from 'js-cookie' +// cookie保存的天数 +import config from '@/config' +import { forEach, hasOneOf, objEqual } from '@/libs/tools' +const { title, cookieExpires, useI18n } = config + +export const TOKEN_KEY = 'token' + +export const setToken = (token) => { + Cookies.set(TOKEN_KEY, token, {expires: cookieExpires || 1}) +} + +export const getToken = () => { + const token = Cookies.get(TOKEN_KEY) + if (token) return token + else return false +} + +export const hasChild = (item) => { + return item.children && item.children.length !== 0 +} + +const showThisMenuEle = (item, access) => { + if (item.meta && item.meta.access && item.meta.access.length) { + if (hasOneOf(item.meta.access, access)) return true + else return false + } else return true +} +/** + * @param {Array} list 通过路由列表得到菜单列表 + * @returns {Array} + */ +export const getMenuByRouter = (list, access) => { + let res = [] + forEach(list, item => { + if (!item.meta || (item.meta && !item.meta.hideInMenu)) { + let obj = { + icon: (item.meta && item.meta.icon) || '', + name: item.name, + meta: item.meta + } + if ((hasChild(item) || (item.meta && item.meta.showAlways)) && showThisMenuEle(item, access)) { + obj.children = getMenuByRouter(item.children, access) + } + if (item.meta && item.meta.href) obj.href = item.meta.href + if (showThisMenuEle(item, access)) res.push(obj) + } + }) + return res +} + +/** + * @param {Array} routeMetched 当前路由metched + * @returns {Array} + */ +export const getBreadCrumbList = (route, homeRoute) => { + let homeItem = { ...homeRoute, icon: homeRoute.meta.icon } + let routeMetched = route.matched + if (routeMetched.some(item => item.name === homeRoute.name)) return [homeItem] + let res = routeMetched.filter(item => { + return item.meta === undefined || !item.meta.hideInBread + }).map(item => { + let meta = {...item.meta} + if (meta.title && typeof meta.title === 'function') { + meta.__titleIsFunction__ = true + meta.title = meta.title(route) + } + let obj = { + icon: (item.meta && item.meta.icon) || '', + name: item.name, + meta: meta + } + return obj + }) + res = res.filter(item => { + return !item.meta.hideInMenu + }) + return [{...homeItem, to: homeRoute.path}, ...res] +} + +export const getRouteTitleHandled = (route) => { + let router = {...route} + let meta = {...route.meta} + let title = '' + if (meta.title) { + if (typeof meta.title === 'function') { + meta.__titleIsFunction__ = true + title = meta.title(router) + } else title = meta.title + } + meta.title = title + router.meta = meta + return router +} + +export const showTitle = (item, vm) => { + let { title, __titleIsFunction__ } = item.meta + if (!title) return + if (useI18n) { + if (title.includes('{{') && title.includes('}}') && useI18n) title = title.replace(/({{[\s\S]+?}})/, (m, str) => str.replace(/{{([\s\S]*)}}/, (m, _) => vm.$t(_.trim()))) + else if (__titleIsFunction__) title = item.meta.title + else title = vm.$t(item.name) + } else title = (item.meta && item.meta.title) || item.name + return title +} + +/** + * @description 本地存储和获取标签导航列表 + */ +export const setTagNavListInLocalstorage = list => { + localStorage.tagNaveList = JSON.stringify(list) +} +/** + * @returns {Array} 其中的每个元素只包含路由原信息中的name, path, meta三项 + */ +export const getTagNavListFromLocalstorage = () => { + const list = localStorage.tagNaveList + return list ? JSON.parse(list) : [] +} + +/** + * @param {Array} routers 路由列表数组 + * @description 用于找到路由列表中name为home的对象 + */ +export const getHomeRoute = (routers, homeName = 'home') => { + let i = -1 + let len = routers.length + let homeRoute = {} + while (++i < len) { + let item = routers[i] + if (item.children && item.children.length) { + let res = getHomeRoute(item.children, homeName) + if (res.name) return res + } else { + if (item.name === homeName) homeRoute = item + } + } + return homeRoute +} + +/** + * @param {*} list 现有标签导航列表 + * @param {*} newRoute 新添加的路由原信息对象 + * @description 如果该newRoute已经存在则不再添加 + */ +export const getNewTagList = (list, newRoute) => { + const { name, path, meta } = newRoute + let newList = [...list] + if (newList.findIndex(item => item.name === name) >= 0) return newList + else newList.push({ name, path, meta }) + return newList +} + +/** + * @param {*} access 用户权限数组,如 ['super_admin', 'admin'] + * @param {*} route 路由列表 + */ +const hasAccess = (access, route) => { + if (route.meta && route.meta.access) return hasOneOf(access, route.meta.access) + else return true +} + +/** + * 权鉴 + * @param {*} name 即将跳转的路由name + * @param {*} access 用户权限数组 + * @param {*} routes 路由列表 + * @description 用户是否可跳转到该页 + */ +export const canTurnTo = (name, access, routes) => { + const routePermissionJudge = (list) => { + return list.some(item => { + if (item.children && item.children.length) { + return routePermissionJudge(item.children) + } else if (item.name === name) { + return hasAccess(access, item) + } + }) + } + + return routePermissionJudge(routes) +} + +/** + * @param {String} url + * @description 从URL中解析参数 + */ +export const getParams = url => { + const keyValueArr = url.split('?')[1].split('&') + let paramObj = {} + keyValueArr.forEach(item => { + const keyValue = item.split('=') + paramObj[keyValue[0]] = keyValue[1] + }) + return paramObj +} + +/** + * @param {Array} list 标签列表 + * @param {String} name 当前关闭的标签的name + */ +export const getNextRoute = (list, route) => { + let res = {} + if (list.length === 2) { + res = getHomeRoute(list) + } else { + const index = list.findIndex(item => routeEqual(item, route)) + if (index === list.length - 1) res = list[list.length - 2] + else res = list[index + 1] + } + return res +} + +/** + * @param {Number} times 回调函数需要执行的次数 + * @param {Function} callback 回调函数 + */ +export const doCustomTimes = (times, callback) => { + let i = -1 + while (++i < times) { + callback(i) + } +} + +/** + * @param {Object} file 从上传组件得到的文件对象 + * @returns {Promise} resolve参数是解析后的二维数组 + * @description 从Csv文件中解析出表格,解析成二维数组 + */ +export const getArrayFromFile = (file) => { + let nameSplit = file.name.split('.') + let format = nameSplit[nameSplit.length - 1] + return new Promise((resolve, reject) => { + let reader = new FileReader() + reader.readAsText(file) // 以文本格式读取 + let arr = [] + reader.onload = function (evt) { + let data = evt.target.result // 读到的数据 + let pasteData = data.trim() + arr = pasteData.split((/[\n\u0085\u2028\u2029]|\r\n?/g)).map(row => { + return row.split('\t') + }).map(item => { + return item[0].split(',') + }) + if (format === 'csv') resolve(arr) + else reject(new Error('[Format Error]:你上传的不是Csv文件')) + } + }) +} + +/** + * @param {Array} array 表格数据二维数组 + * @returns {Object} { columns, tableData } + * @description 从二维数组中获取表头和表格数据,将第一行作为表头,用于在iView的表格中展示数据 + */ +export const getTableDataFromArray = (array) => { + let columns = [] + let tableData = [] + if (array.length > 1) { + let titles = array.shift() + columns = titles.map(item => { + return { + title: item, + key: item + } + }) + tableData = array.map(item => { + let res = {} + item.forEach((col, i) => { + res[titles[i]] = col + }) + return res + }) + } + return { + columns, + tableData + } +} + +export const findNodeUpper = (ele, tag) => { + if (ele.parentNode) { + if (ele.parentNode.tagName === tag.toUpperCase()) { + return ele.parentNode + } else { + return findNodeUpper(ele.parentNode, tag) + } + } +} + +export const findNodeUpperByClasses = (ele, classes) => { + let parentNode = ele.parentNode + if (parentNode) { + let classList = parentNode.classList + if (classList && classes.every(className => classList.contains(className))) { + return parentNode + } else { + return findNodeUpperByClasses(parentNode, classes) + } + } +} + +export const findNodeDownward = (ele, tag) => { + const tagName = tag.toUpperCase() + if (ele.childNodes.length) { + let i = -1 + let len = ele.childNodes.length + while (++i < len) { + let child = ele.childNodes[i] + if (child.tagName === tagName) return child + else return findNodeDownward(child, tag) + } + } +} + +export const showByAccess = (access, canViewAccess) => { + return hasOneOf(canViewAccess, access) +} + +/** + * @description 根据name/params/query判断两个路由对象是否相等 + * @param {*} route1 路由对象 + * @param {*} route2 路由对象 + */ +export const routeEqual = (route1, route2) => { + const params1 = route1.params || {} + const params2 = route2.params || {} + const query1 = route1.query || {} + const query2 = route2.query || {} + return (route1.name === route2.name) && objEqual(params1, params2) && objEqual(query1, query2) +} + +/** + * 判断打开的标签列表里是否已存在这个新添加的路由对象 + */ +export const routeHasExist = (tagNavList, routeItem) => { + let len = tagNavList.length + let res = false + doCustomTimes(len, (index) => { + if (routeEqual(tagNavList[index], routeItem)) res = true + }) + return res +} + +export const localSave = (key, value) => { + localStorage.setItem(key, value) +} + +export const localRead = (key) => { + return localStorage.getItem(key) || '' +} + +// scrollTop animation +export const scrollTop = (el, from = 0, to, duration = 500, endCallback) => { + if (!window.requestAnimationFrame) { + window.requestAnimationFrame = ( + window.webkitRequestAnimationFrame || + window.mozRequestAnimationFrame || + window.msRequestAnimationFrame || + function (callback) { + return window.setTimeout(callback, 1000 / 60) + } + ) + } + const difference = Math.abs(from - to) + const step = Math.ceil(difference / duration * 50) + + const scroll = (start, end, step) => { + if (start === end) { + endCallback && endCallback() + return + } + + let d = (start + step > end) ? end : start + step + if (start > end) { + d = (start - step < end) ? end : start - step + } + + if (el === window) { + window.scrollTo(d, d) + } else { + el.scrollTop = d + } + window.requestAnimationFrame(() => scroll(d, end, step)) + } + scroll(from, to, step) +} + +/** + * @description 根据当前跳转的路由设置显示在浏览器标签的title + * @param {Object} routeItem 路由对象 + * @param {Object} vm Vue实例 + */ +export const setTitle = (routeItem, vm) => { + const handledRoute = getRouteTitleHandled(routeItem) + const pageTitle = showTitle(handledRoute, vm) + const resTitle = pageTitle ? `${title} - ${pageTitle}` : title + window.document.title = resTitle +} diff --git a/src/JT808.DotNetty.Dashbord.UI/src/locale/index.js b/src/JT808.DotNetty.Dashbord.UI/src/locale/index.js new file mode 100644 index 0000000..c35492e --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/locale/index.js @@ -0,0 +1,37 @@ +import Vue from 'vue' +import VueI18n from 'vue-i18n' +import { localRead } from '@/libs/util' +import customZhCn from './lang/zh-CN' +import customZhTw from './lang/zh-TW' +import customEnUs from './lang/en-US' +import zhCnLocale from 'iview/src/locale/lang/zh-CN' +import enUsLocale from 'iview/src/locale/lang/en-US' +import zhTwLocale from 'iview/src/locale/lang/zh-TW' + +Vue.use(VueI18n) + +// 自动根据浏览器系统语言设置语言 +const navLang = navigator.language +const localLang = (navLang === 'zh-CN' || navLang === 'en-US') ? navLang : false +let lang = localLang || localRead('local') || 'zh-CN' + +Vue.config.lang = lang + +// vue-i18n 6.x+写法 +Vue.locale = () => {} +const messages = { + 'zh-CN': Object.assign(zhCnLocale, customZhCn), + 'zh-TW': Object.assign(zhTwLocale, customZhTw), + 'en-US': Object.assign(enUsLocale, customEnUs) +} +const i18n = new VueI18n({ + locale: lang, + messages +}) + +export default i18n + +// vue-i18n 5.x写法 +// Vue.locale('zh-CN', Object.assign(zhCnLocale, customZhCn)) +// Vue.locale('en-US', Object.assign(zhTwLocale, customZhTw)) +// Vue.locale('zh-TW', Object.assign(enUsLocale, customEnUs)) diff --git a/src/JT808.DotNetty.Dashbord.UI/src/locale/lang/en-US.js b/src/JT808.DotNetty.Dashbord.UI/src/locale/lang/en-US.js new file mode 100644 index 0000000..d915372 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/locale/lang/en-US.js @@ -0,0 +1,42 @@ +export default { + home: 'Home', + components: 'Components', + count_to_page: 'Count-to', + tables_page: 'Table', + split_pane_page: 'Split-pane', + markdown_page: 'Markdown-editor', + editor_page: 'Rich-Text-Editor', + icons_page: 'Custom-icon', + img_cropper_page: 'Image-editor', + update: 'Update', + doc: 'Document', + join_page: 'QQ Group', + update_table_page: 'Update .CSV', + update_paste_page: 'Paste Table Data', + multilevel: 'multilevel', + directive_page: 'Directive', + level_1: 'Level-1', + level_2: 'Level-2', + level_2_1: 'Level-2-1', + level_2_3: 'Level-2-3', + level_2_2: 'Level-2-2', + level_2_2_1: 'Level-2-2-1', + level_2_2_2: 'Level-2-2-2', + excel: 'Excel', + 'upload-excel': 'Upload Excel', + 'export-excel': 'Export Excel', + tools_methods_page: 'Tools Methods', + drag_list_page: 'Drag-list', + i18n_page: 'Internationalization', + modalTitle: 'Modal Title', + content: 'This is the modal box content.', + buttonText: 'Show Modal', + 'i18n-tip': 'Note: Only this page is multi-language, other pages do not add language content to the multi-language package.', + error_store_page: 'Error Collection', + error_logger_page: 'Error Logger', + query: 'Query', + params: 'Params', + cropper_page: 'Cropper', + message_page: 'Message Center', + tree_table_page: 'Tree Table' +} diff --git a/src/JT808.DotNetty.Dashbord.UI/src/locale/lang/zh-CN.js b/src/JT808.DotNetty.Dashbord.UI/src/locale/lang/zh-CN.js new file mode 100644 index 0000000..4393738 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/locale/lang/zh-CN.js @@ -0,0 +1,42 @@ +export default { + home: '首页', + components: '组件', + count_to_page: '数字渐变', + tables_page: '多功能表格', + split_pane_page: '分割窗口', + markdown_page: 'Markdown编辑器', + editor_page: '富文本编辑器', + icons_page: '自定义图标', + img_cropper_page: '图片编辑器', + update: '上传数据', + join_page: 'QQ群', + doc: '文档', + update_table_page: '上传CSV文件', + update_paste_page: '粘贴表格数据', + multilevel: '多级菜单', + directive_page: '指令', + level_1: 'Level-1', + level_2: 'Level-2', + level_2_1: 'Level-2-1', + level_2_3: 'Level-2-3', + level_2_2: 'Level-2-2', + level_2_2_1: 'Level-2-2-1', + level_2_2_2: 'Level-2-2-2', + excel: 'Excel', + 'upload-excel': '上传excel', + 'export-excel': '导出excel', + tools_methods_page: '工具函数', + drag_list_page: '拖拽列表', + i18n_page: '多语言', + modalTitle: '模态框题目', + content: '这是模态框内容', + buttonText: '显示模态框', + 'i18n-tip': '注:仅此页做了多语言,其他页面没有在多语言包中添加语言内容', + error_store_page: '错误收集', + error_logger_page: '错误日志', + query: '带参路由', + params: '动态路由', + cropper_page: '图片裁剪', + message_page: '消息中心', + tree_table_page: '树状表格' +} diff --git a/src/JT808.DotNetty.Dashbord.UI/src/locale/lang/zh-TW.js b/src/JT808.DotNetty.Dashbord.UI/src/locale/lang/zh-TW.js new file mode 100644 index 0000000..fed4b1d --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/locale/lang/zh-TW.js @@ -0,0 +1,42 @@ +export default { + home: '首頁', + components: '组件', + count_to_page: '数字渐变', + tables_page: '多功能表格', + split_pane_page: '分割窗口', + markdown_page: 'Markdown編輯器', + editor_page: '富文本編輯器', + icons_page: '自定義圖標', + img_cropper_page: '圖片編輯器', + update: '上傳數據', + join_page: 'QQ群', + doc: '文檔', + update_table_page: '上傳CSV文件', + update_paste_page: '粘貼表格數據', + multilevel: '多级菜单', + directive_page: '指令', + level_1: 'Level-1', + level_2: 'Level-2', + level_2_1: 'Level-2-1', + level_2_3: 'Level-2-3', + level_2_2: 'Level-2-2', + level_2_2_1: 'Level-2-2-1', + level_2_2_2: 'Level-2-2-2', + excel: 'Excel', + 'upload-excel': '上傳excel', + 'export-excel': '導出excel', + tools_methods_page: '工具函數', + drag_list_page: '拖拽列表', + i18n_page: '多語言', + modalTitle: '模態框題目', + content: '這是模態框內容', + buttonText: '顯示模態框', + 'i18n-tip': '注:僅此頁做了多語言,其他頁面沒有在多語言包中添加語言內容', + error_store_page: '錯誤收集', + error_logger_page: '錯誤日誌', + query: '帶參路由', + params: '動態路由', + cropper_page: '圖片裁剪', + message_page: '消息中心', + tree_table_page: '樹狀表格' +} diff --git a/src/JT808.DotNetty.Dashbord.UI/src/main.js b/src/JT808.DotNetty.Dashbord.UI/src/main.js new file mode 100644 index 0000000..37180aa --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/main.js @@ -0,0 +1,47 @@ +// The Vue build version to load with the `import` command +// (runtime-only or standalone) has been set in webpack.base.conf with an alias. +import Vue from 'vue' +import App from './App' +import router from './router' +import store from './store' +import iView from 'iview' +import i18n from '@/locale' +import config from '@/config' +import importDirective from '@/directive' +import installPlugin from '@/plugin' +import './index.less' +import '@/assets/icons/iconfont.css' +import TreeTable from 'tree-table-vue' +// 实际打包时应该不引入mock +/* eslint-disable */ +if (process.env.NODE_ENV !== 'production') require('@/mock') + +Vue.use(iView, { + i18n: (key, value) => i18n.t(key, value) +}) +Vue.use(TreeTable) +/** + * @description 注册admin内置插件 + */ +installPlugin(Vue) +/** + * @description 生产环境关掉提示 + */ +Vue.config.productionTip = false +/** + * @description 全局注册应用配置 + */ +Vue.prototype.$config = config +/** + * 注册指令 + */ +importDirective(Vue) + +/* eslint-disable no-new */ +new Vue({ + el: '#app', + router, + i18n, + store, + render: h => h(App) +}) diff --git a/src/JT808.DotNetty.Dashbord.UI/src/mock/atomicCounter.js b/src/JT808.DotNetty.Dashbord.UI/src/mock/atomicCounter.js new file mode 100644 index 0000000..53d103f --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/mock/atomicCounter.js @@ -0,0 +1,9 @@ +import Mock from 'mockjs' +import { setData } from '@/mock/commonResultData' + +export const GetAtomicCounter = () => { + return setData(Mock.mock({ + 'MsgSuccessCount|1-10000000': 100, + 'MsgFailCount|1-10000000': 100 + })) +} diff --git a/src/JT808.DotNetty.Dashbord.UI/src/mock/commonResultData.js b/src/JT808.DotNetty.Dashbord.UI/src/mock/commonResultData.js new file mode 100644 index 0000000..50e076b --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/mock/commonResultData.js @@ -0,0 +1,7 @@ +export const setData = (data, code = 200) => { + return { + 'Code': code, + 'Message': '', + 'Data': data + } +} diff --git a/src/JT808.DotNetty.Dashbord.UI/src/mock/data.js b/src/JT808.DotNetty.Dashbord.UI/src/mock/data.js new file mode 100644 index 0000000..e0d36ae --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/mock/data.js @@ -0,0 +1,30 @@ +import Mock from 'mockjs' +import { doCustomTimes } from '@/libs/util' +const Random = Mock.Random + +export const getTableData = req => { + let tableData = [] + doCustomTimes(5, () => { + tableData.push(Mock.mock({ + name: '@name', + email: '@email', + createTime: '@date' + })) + }) + return tableData +} + +export const getDragList = req => { + let dragList = [] + doCustomTimes(5, () => { + dragList.push(Mock.mock({ + name: Random.csentence(10, 13), + id: Random.increment(10) + })) + }) + return dragList +} + +export const uploadImage = req => { + return Promise.resolve() +} diff --git a/src/JT808.DotNetty.Dashbord.UI/src/mock/index.js b/src/JT808.DotNetty.Dashbord.UI/src/mock/index.js new file mode 100644 index 0000000..e8da037 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/mock/index.js @@ -0,0 +1,47 @@ +import Mock from 'mockjs' +import { login, logout, getUserInfo } from './login' +import { getTableData, getDragList, uploadImage } from './data' +import { getMessageInit, getContentByMsgId, hasRead, removeReaded, restoreTrash, messageCount } from './user' +import { GetAtomicCounter } from './atomicCounter' +import sourcePackage from './sourcePackage' +import session from './session' +import transmit from './transmit' +import unificationSend from './unificationSend' + +// 配置Ajax请求延时,可用来测试网络延迟大时项目中一些效果 +Mock.setup({ + timeout: 1000 +}) + +// 登录相关和获取用户信息 +Mock.mock(/\/login/, login) +Mock.mock(/\/get_info/, getUserInfo) +Mock.mock(/\/logout/, logout) +Mock.mock(/\/get_table_data/, getTableData) +Mock.mock(/\/get_drag_list/, getDragList) +Mock.mock(/\/save_error_logger/, 'success') +Mock.mock(/\/image\/upload/, uploadImage) +Mock.mock(/\/message\/init/, getMessageInit) +Mock.mock(/\/message\/content/, getContentByMsgId) +Mock.mock(/\/message\/has_read/, hasRead) +Mock.mock(/\/message\/remove_readed/, removeReaded) +Mock.mock(/\/message\/restore/, restoreTrash) +Mock.mock(/\/message\/count/, messageCount) + +Mock.mock(/\/AtomicCounter\/GetAtomicCounter/, GetAtomicCounter) + +Mock.mock(/\/SourcePackage\/Add/, sourcePackage.Add) +Mock.mock(/\/SourcePackage\/Remove/, sourcePackage.Remove) +Mock.mock(/\/SourcePackage\/GetAll/, sourcePackage.GetAll) + +Mock.mock(/\/Session\/RemoveByTerminalPhoneNo/, session.RemoveByTerminalPhoneNo) +Mock.mock(/\/Session\/RemoveByChannelId/, session.RemoveByChannelId) +Mock.mock(/\/Session\/GetAll/, session.GetAll) + +Mock.mock(/\/Transmit\/Add/, transmit.Add) +Mock.mock(/\/Transmit\/Remove/, transmit.Remove) +Mock.mock(/\/Transmit\/GetAll/, transmit.GetAll) + +Mock.mock(/\/UnificationSend\/SendText/, unificationSend.SendText) + +export default Mock diff --git a/src/JT808.DotNetty.Dashbord.UI/src/mock/login.js b/src/JT808.DotNetty.Dashbord.UI/src/mock/login.js new file mode 100644 index 0000000..9e84a55 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/mock/login.js @@ -0,0 +1,31 @@ +import { getParams } from '@/libs/util' +const USER_MAP = { + super_admin: { + name: 'super_admin', + user_id: '1', + access: ['super_admin', 'admin'], + token: 'super_admin', + avator: 'https://file.iviewui.com/dist/a0e88e83800f138b94d2414621bd9704.png' + }, + admin: { + name: 'admin', + user_id: '2', + access: ['admin'], + token: 'admin', + avator: 'https://avatars0.githubusercontent.com/u/20942571?s=460&v=4' + } +} + +export const login = req => { + req = JSON.parse(req.body) + return {token: USER_MAP[req.userName].token} +} + +export const getUserInfo = req => { + const params = getParams(req.url) + return USER_MAP[params.token] +} + +export const logout = req => { + return null +} diff --git a/src/JT808.DotNetty.Dashbord.UI/src/mock/session.js b/src/JT808.DotNetty.Dashbord.UI/src/mock/session.js new file mode 100644 index 0000000..becf0e9 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/mock/session.js @@ -0,0 +1,32 @@ +import Mock from 'mockjs' +import { setData } from '@/mock/commonResultData' + +export default { + RemoveByTerminalPhoneNo () { + return setData(Mock.mock({ + 'boolean|1': true + })) + }, + RemoveByChannelId () { + return setData(Mock.mock({ + 'boolean|1': true + })) + }, + GetAll () { + return setData([{ + 'ChannelId': 'eadad23', + 'LastActiveTime': '2018-11-27 20:00:00', + 'StartTime': '2018-11-25 20:00:00', + 'TerminalPhoneNo': '123456789012', + 'WebApiPort': 828, + 'RemoteAddressIP': '127.0.0.1:11808' + }, { + 'ChannelId': 'eadad23', + 'LastActiveTime': '2018-11-27 20:00:00', + 'StartTime': '2018-11-25 20:00:00', + 'TerminalPhoneNo': '123456789013', + 'WebApiPort': 828, + 'RemoteAddressIP': '127.0.0.1:11808' + }]) + } +} diff --git a/src/JT808.DotNetty.Dashbord.UI/src/mock/sourcePackage.js b/src/JT808.DotNetty.Dashbord.UI/src/mock/sourcePackage.js new file mode 100644 index 0000000..c045661 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/mock/sourcePackage.js @@ -0,0 +1,30 @@ +import Mock from 'mockjs' +import { setData } from '@/mock/commonResultData' + +export default { + Add () { + return setData(Mock.mock({ + 'boolean|1': true + })) + }, + Remove () { + return setData(Mock.mock({ + 'boolean|1': true + })) + }, + GetAll () { + return setData([{ + 'RemoteAddress': '127.0.0.1:6665', + 'LocalAddress': '127.0.0.1:6664', + 'Registered': true, + 'Active': true, + 'Open': true + }, { + 'RemoteAddress': '127.0.0.1:6667', + 'LocalAddress': '127.0.0.1:6666', + 'Registered': true, + 'Active': true, + 'Open': true + }]) + } +} diff --git a/src/JT808.DotNetty.Dashbord.UI/src/mock/transmit.js b/src/JT808.DotNetty.Dashbord.UI/src/mock/transmit.js new file mode 100644 index 0000000..feb1e8d --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/mock/transmit.js @@ -0,0 +1,21 @@ +import Mock from 'mockjs' +import { setData } from '@/mock/commonResultData' + +export default { + Add () { + return setData(Mock.mock({ + 'boolean|1': true + })) + }, + Remove () { + return setData(Mock.mock({ + 'boolean|1': true + })) + }, + GetAll () { + return setData([ + '127.0.0.1:6665', + '127.0.0.1:6667' + ]) + } +} diff --git a/src/JT808.DotNetty.Dashbord.UI/src/mock/unificationSend.js b/src/JT808.DotNetty.Dashbord.UI/src/mock/unificationSend.js new file mode 100644 index 0000000..ab68c85 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/mock/unificationSend.js @@ -0,0 +1,10 @@ +import Mock from 'mockjs' +import { setData } from '@/mock/commonResultData' + +export default { + SendText () { + return setData(Mock.mock({ + 'boolean|1': true + })) + } +} diff --git a/src/JT808.DotNetty.Dashbord.UI/src/mock/user.js b/src/JT808.DotNetty.Dashbord.UI/src/mock/user.js new file mode 100644 index 0000000..9b28641 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/mock/user.js @@ -0,0 +1,55 @@ +import Mock from 'mockjs' +import { doCustomTimes } from '@/libs/util' +const Random = Mock.Random + +export const getMessageInit = () => { + let unreadList = [] + doCustomTimes(3, () => { + unreadList.push(Mock.mock({ + title: Random.cword(10, 15), + create_time: '@date', + msg_id: Random.increment(100) + })) + }) + let readedList = [] + doCustomTimes(4, () => { + readedList.push(Mock.mock({ + title: Random.cword(10, 15), + create_time: '@date', + msg_id: Random.increment(100) + })) + }) + let trashList = [] + doCustomTimes(2, () => { + trashList.push(Mock.mock({ + title: Random.cword(10, 15), + create_time: '@date', + msg_id: Random.increment(100) + })) + }) + return { + unread: unreadList, + readed: readedList, + trash: trashList + } +} + +export const getContentByMsgId = () => { + return `
        这是消息内容,这个内容是使用富文本编辑器编辑的,所以你可以看到一些格式
  1. 你可以查看Mock返回的数据格式,和api请求的接口,来确定你的后端接口的开发
  2. 使用你的真实接口后,前端页面基本不需要修改即可满足基本需求
  3. 快来试试吧

${Random.csentence(100, 200)}

` +} + +export const hasRead = () => { + return true +} + +export const removeReaded = () => { + return true +} + +export const restoreTrash = () => { + return true +} + +export const messageCount = () => { + return 3 +} diff --git a/src/JT808.DotNetty.Dashbord.UI/src/plugin/error-store/index.js b/src/JT808.DotNetty.Dashbord.UI/src/plugin/error-store/index.js new file mode 100644 index 0000000..46b5941 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/plugin/error-store/index.js @@ -0,0 +1,17 @@ +import store from '@/store' +export default { + install (Vue, options) { + if (options.developmentOff && process.env.NODE_ENV === 'development') return + Vue.config.errorHandler = (error, vm, mes) => { + let info = { + type: 'script', + code: 0, + mes: error.message, + url: window.location.href + } + Vue.nextTick(() => { + store.dispatch('addErrorLog', info) + }) + } + } +} diff --git a/src/JT808.DotNetty.Dashbord.UI/src/plugin/index.js b/src/JT808.DotNetty.Dashbord.UI/src/plugin/index.js new file mode 100644 index 0000000..c47165b --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/plugin/index.js @@ -0,0 +1,9 @@ +import config from '@/config' +const { plugin } = config + +export default (Vue) => { + for (let name in plugin) { + const value = plugin[name] + Vue.use(require(`./${name}`).default, typeof value === 'object' ? value : undefined) + } +} diff --git a/src/JT808.DotNetty.Dashbord.UI/src/router/before-close.js b/src/JT808.DotNetty.Dashbord.UI/src/router/before-close.js new file mode 100644 index 0000000..3320f1c --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/router/before-close.js @@ -0,0 +1,17 @@ +import { Modal } from 'iview' + +const beforeClose = { + before_close_normal: (resolve) => { + Modal.confirm({ + title: '确定要关闭这一页吗', + onOk: () => { + resolve(true) + }, + onCancel: () => { + resolve(false) + } + }) + } +} + +export default beforeClose diff --git a/src/JT808.DotNetty.Dashbord.UI/src/router/index.js b/src/JT808.DotNetty.Dashbord.UI/src/router/index.js new file mode 100644 index 0000000..db0cb84 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/router/index.js @@ -0,0 +1,61 @@ +import Vue from 'vue' +import Router from 'vue-router' +import routes from './routers' +import store from '@/store' +import iView from 'iview' +import { setToken, getToken, canTurnTo, setTitle } from '@/libs/util' +import config from '@/config' +const { homeName } = config + +Vue.use(Router) +const router = new Router({ + routes, + mode: 'history' +}) +const LOGIN_PAGE_NAME = 'login' + +const turnTo = (to, access, next) => { + if (canTurnTo(to.name, access, routes)) next() // 有权限,可访问 + else next({ replace: true, name: 'error_401' }) // 无权限,重定向到401页面 +} + +router.beforeEach((to, from, next) => { + iView.LoadingBar.start() + const token = getToken() + if (!token && to.name !== LOGIN_PAGE_NAME) { + // 未登录且要跳转的页面不是登录页 + next({ + name: LOGIN_PAGE_NAME // 跳转到登录页 + }) + } else if (!token && to.name === LOGIN_PAGE_NAME) { + // 未登陆且要跳转的页面是登录页 + next() // 跳转 + } else if (token && to.name === LOGIN_PAGE_NAME) { + // 已登录且要跳转的页面是登录页 + next({ + name: homeName // 跳转到homeName页 + }) + } else { + if (store.state.user.hasGetInfo) { + turnTo(to, store.state.user.access, next) + } else { + store.dispatch('getUserInfo').then(user => { + // 拉取用户信息,通过用户权限和跳转的页面的name来判断是否有权限访问;access必须是一个数组,如:['super_admin'] ['super_admin', 'admin'] + turnTo(to, user.access, next) + }).catch(() => { + setToken('') + next({ + name: 'login' + }) + }) + } + } +}) + +router.afterEach(to => { + setTitle(to, router.app) + iView.LoadingBar.finish() + window.scrollTo(0, 0) +}) + +export default router diff --git a/src/JT808.DotNetty.Dashbord.UI/src/router/routers.js b/src/JT808.DotNetty.Dashbord.UI/src/router/routers.js new file mode 100644 index 0000000..4757c3e --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/router/routers.js @@ -0,0 +1,195 @@ +import Main from '@/components/main' +import parentView from '@/components/parent-view' + +/** + * iview-admin中meta除了原生参数外可配置的参数: + * meta: { + * title: { String|Number|Function } + * 显示在侧边栏、面包屑和标签栏的文字 + * 使用'{{ 多语言字段 }}'形式结合多语言使用,例子看多语言的路由配置; + * 可以传入一个回调函数,参数是当前路由对象,例子看动态路由和带参路由 + * hideInBread: (false) 设为true后此级路由将不会出现在面包屑中,示例看QQ群路由配置 + * hideInMenu: (false) 设为true后在左侧菜单不会显示该页面选项 + * notCache: (false) 设为true后页面在切换标签后不会缓存,如果需要缓存,无需设置这个字段,而且需要设置页面组件name属性和路由配置的name一致 + * access: (null) 可访问该页面的权限数组,当前路由设置的权限会影响子路由 + * icon: (-) 该页面在左侧菜单、面包屑和标签导航处显示的图标,如果是自定义图标,需要在图标名称前加下划线'_' + * beforeCloseName: (-) 设置该字段,则在关闭当前tab页时会去'@/router/before-close.js'里寻找该字段名对应的方法,作为关闭前的钩子函数 + * } + */ + +export default [ + { + path: '/login', + name: 'login', + meta: { + title: 'Login - 登录', + hideInMenu: true + }, + component: () => import('@/view/login/login.vue') + }, + { + path: '/', + name: '_home', + redirect: '/home', + component: Main, + meta: { + hideInMenu: true, + notCache: true + }, + children: [ + { + path: '/home', + name: 'home', + meta: { + hideInMenu: true, + title: '首页', + notCache: true, + icon: 'md-home' + }, + component: () => import('@/view/single-page/home') + } + ] + }, + { + path: '/message', + name: 'message', + component: Main, + meta: { + hideInBread: true, + hideInMenu: true + }, + children: [ + { + path: 'message_page', + name: 'message_page', + meta: { + icon: 'md-notifications', + title: '消息中心' + }, + component: () => import('@/view/single-page/message/index.vue') + } + ] + }, + { + path: '/session', + name: 'session', + meta: { + hideInBread: true + }, + component: Main, + children: [ + { + path: '/session', + name: '会话管理', + meta: { + icon: 'ios-hammer', + title: '会话管理' + }, + component: () => import('@/view/session/session.vue') + } + ] + }, + { + path: '/sourcepackage', + name: 'sourcePackage', + meta: { + hideInBread: true + }, + component: Main, + children: [ + { + path: '/sourcepackage', + name: '原包管理', + meta: { + icon: 'ios-hammer', + title: '原包管理', + beforeCloseName: 'before_close_normal' + }, + component: () => import('@/view/sourcepackage/sourcepackage.vue') + } + ] + }, + { + path: '/transmit', + name: 'transmit', + meta: { + hideInBread: true + }, + component: Main, + children: [ + { + path: '/transmit', + name: '转发管理', + meta: { + icon: 'ios-hammer', + title: '转发管理', + beforeCloseName: 'before_close_normal' + }, + component: () => import('@/view/transmit/transmit.vue') + } + ] + }, + { + path: '/error_store', + name: 'error_store', + meta: { + hideInBread: true + }, + component: Main, + children: [ + { + path: 'error_store_page', + name: 'error_store_page', + meta: { + icon: 'ios-bug', + title: '错误收集' + }, + component: () => import('@/view/error-store/error-store.vue') + } + ] + }, + { + path: '/error_logger', + name: 'error_logger', + meta: { + hideInBread: true, + hideInMenu: true + }, + component: Main, + children: [ + { + path: 'error_logger_page', + name: 'error_logger_page', + meta: { + icon: 'ios-bug', + title: '错误收集' + }, + component: () => import('@/view/single-page/error-logger.vue') + } + ] + }, + { + path: '/401', + name: 'error_401', + meta: { + hideInMenu: true + }, + component: () => import('@/view/error-page/401.vue') + }, + { + path: '/500', + name: 'error_500', + meta: { + hideInMenu: true + }, + component: () => import('@/view/error-page/500.vue') + }, + { + path: '*', + name: 'error_404', + meta: { + hideInMenu: true + }, + component: () => import('@/view/error-page/404.vue') + } +] diff --git a/src/JT808.DotNetty.Dashbord.UI/src/store/index.js b/src/JT808.DotNetty.Dashbord.UI/src/store/index.js new file mode 100644 index 0000000..2c8c77e --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/store/index.js @@ -0,0 +1,23 @@ +import Vue from 'vue' +import Vuex from 'vuex' + +import user from './module/user' +import app from './module/app' + +Vue.use(Vuex) + +export default new Vuex.Store({ + state: { + // + }, + mutations: { + // + }, + actions: { + // + }, + modules: { + user, + app + } +}) diff --git a/src/JT808.DotNetty.Dashbord.UI/src/store/module/app.js b/src/JT808.DotNetty.Dashbord.UI/src/store/module/app.js new file mode 100644 index 0000000..227c42e --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/store/module/app.js @@ -0,0 +1,115 @@ +import { + getBreadCrumbList, + setTagNavListInLocalstorage, + getMenuByRouter, + getTagNavListFromLocalstorage, + getHomeRoute, + getNextRoute, + routeHasExist, + routeEqual, + getRouteTitleHandled, + localSave, + localRead +} from '@/libs/util' +import beforeClose from '@/router/before-close' +import { saveErrorLogger } from '@/api/data' +import router from '@/router' +import routers from '@/router/routers' +import config from '@/config' +const { homeName } = config + +const closePage = (state, route) => { + const nextRoute = getNextRoute(state.tagNavList, route) + state.tagNavList = state.tagNavList.filter(item => { + return !routeEqual(item, route) + }) + router.push(nextRoute) +} + +export default { + state: { + breadCrumbList: [], + tagNavList: [], + homeRoute: {}, + local: localRead('local'), + errorList: [], + hasReadErrorPage: false + }, + getters: { + menuList: (state, getters, rootState) => getMenuByRouter(routers, rootState.user.access), + errorCount: state => state.errorList.length + }, + mutations: { + setBreadCrumb (state, route) { + state.breadCrumbList = getBreadCrumbList(route, state.homeRoute) + }, + setHomeRoute (state, routes) { + state.homeRoute = getHomeRoute(routes, homeName) + }, + setTagNavList (state, list) { + let tagList = [] + if (list) { + tagList = [...list] + } else tagList = getTagNavListFromLocalstorage() || [] + if (tagList[0] && tagList[0].name !== homeName) tagList.shift() + let homeTagIndex = tagList.findIndex(item => item.name === homeName) + if (homeTagIndex > 0) { + let homeTag = tagList.splice(homeTagIndex, 1)[0] + tagList.unshift(homeTag) + } + state.tagNavList = tagList + setTagNavListInLocalstorage([...tagList]) + }, + closeTag (state, route) { + let tag = state.tagNavList.filter(item => routeEqual(item, route)) + route = tag[0] ? tag[0] : null + if (!route) return + if (route.meta && route.meta.beforeCloseName && route.meta.beforeCloseName in beforeClose) { + new Promise(beforeClose[route.meta.beforeCloseName]).then(close => { + if (close) { + closePage(state, route) + } + }) + } else { + closePage(state, route) + } + }, + addTag (state, { route, type = 'unshift' }) { + let router = getRouteTitleHandled(route) + if (!routeHasExist(state.tagNavList, router)) { + if (type === 'push') state.tagNavList.push(router) + else { + if (router.name === homeName) state.tagNavList.unshift(router) + else state.tagNavList.splice(1, 0, router) + } + setTagNavListInLocalstorage([...state.tagNavList]) + } + }, + setLocal (state, lang) { + localSave('local', lang) + state.local = lang + }, + addError (state, error) { + state.errorList.push(error) + }, + setHasReadErrorLoggerStatus (state, status = true) { + state.hasReadErrorPage = status + } + }, + actions: { + addErrorLog ({ commit, rootState }, info) { + if (!window.location.href.includes('error_logger_page')) commit('setHasReadErrorLoggerStatus', false) + const { user: { token, userId, userName } } = rootState + let data = { + ...info, + time: Date.parse(new Date()), + token, + userId, + userName + } + saveErrorLogger(info).then(() => { + commit('addError', data) + }) + } + } +} diff --git a/src/JT808.DotNetty.Dashbord.UI/src/store/module/user.js b/src/JT808.DotNetty.Dashbord.UI/src/store/module/user.js new file mode 100644 index 0000000..e1aa311 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/store/module/user.js @@ -0,0 +1,217 @@ +import { + login, + logout, + getUserInfo, + getMessage, + getContentByMsgId, + hasRead, + removeReaded, + restoreTrash, + getUnreadCount +} from '@/api/user' +import { setToken, getToken } from '@/libs/util' + +export default { + state: { + userName: '', + userId: '', + avatorImgPath: '', + token: getToken(), + access: '', + hasGetInfo: false, + unreadCount: 0, + messageUnreadList: [], + messageReadedList: [], + messageTrashList: [], + messageContentStore: {} + }, + mutations: { + setAvator (state, avatorPath) { + state.avatorImgPath = avatorPath + }, + setUserId (state, id) { + state.userId = id + }, + setUserName (state, name) { + state.userName = name + }, + setAccess (state, access) { + state.access = access + }, + setToken (state, token) { + state.token = token + setToken(token) + }, + setHasGetInfo (state, status) { + state.hasGetInfo = status + }, + setMessageCount (state, count) { + state.unreadCount = count + }, + setMessageUnreadList (state, list) { + state.messageUnreadList = list + }, + setMessageReadedList (state, list) { + state.messageReadedList = list + }, + setMessageTrashList (state, list) { + state.messageTrashList = list + }, + updateMessageContentStore (state, { msg_id, content }) { + state.messageContentStore[msg_id] = content + }, + moveMsg (state, { from, to, msg_id }) { + const index = state[from].findIndex(_ => _.msg_id === msg_id) + const msgItem = state[from].splice(index, 1)[0] + msgItem.loading = false + state[to].unshift(msgItem) + } + }, + getters: { + messageUnreadCount: state => state.messageUnreadList.length, + messageReadedCount: state => state.messageReadedList.length, + messageTrashCount: state => state.messageTrashList.length + }, + actions: { + // 登录 + handleLogin ({ commit }, {userName, password}) { + userName = userName.trim() + return new Promise((resolve, reject) => { + login({ + userName, + password + }).then(res => { + const data = res.data + commit('setToken', data.token) + resolve() + }).catch(err => { + reject(err) + }) + }) + }, + // 退出登录 + handleLogOut ({ state, commit }) { + return new Promise((resolve, reject) => { + logout(state.token).then(() => { + commit('setToken', '') + commit('setAccess', []) + resolve() + }).catch(err => { + reject(err) + }) + // 如果你的退出登录无需请求接口,则可以直接使用下面三行代码而无需使用logout调用接口 + // commit('setToken', '') + // commit('setAccess', []) + // resolve() + }) + }, + // 获取用户相关信息 + getUserInfo ({ state, commit }) { + return new Promise((resolve, reject) => { + try { + getUserInfo(state.token).then(res => { + const data = res.data + commit('setAvator', data.avator) + commit('setUserName', data.name) + commit('setUserId', data.user_id) + commit('setAccess', data.access) + commit('setHasGetInfo', true) + resolve(data) + }).catch(err => { + reject(err) + }) + } catch (error) { + reject(error) + } + }) + }, + // 此方法用来获取未读消息条数,接口只返回数值,不返回消息列表 + getUnreadMessageCount ({ state, commit }) { + getUnreadCount().then(res => { + const { data } = res + commit('setMessageCount', data) + }) + }, + // 获取消息列表,其中包含未读、已读、回收站三个列表 + getMessageList ({ state, commit }) { + return new Promise((resolve, reject) => { + getMessage().then(res => { + const { unread, readed, trash } = res.data + commit('setMessageUnreadList', unread.sort((a, b) => new Date(b.create_time) - new Date(a.create_time))) + commit('setMessageReadedList', readed.map(_ => { + _.loading = false + return _ + }).sort((a, b) => new Date(b.create_time) - new Date(a.create_time))) + commit('setMessageTrashList', trash.map(_ => { + _.loading = false + return _ + }).sort((a, b) => new Date(b.create_time) - new Date(a.create_time))) + resolve() + }).catch(error => { + reject(error) + }) + }) + }, + // 根据当前点击的消息的id获取内容 + getContentByMsgId ({ state, commit }, { msg_id }) { + return new Promise((resolve, reject) => { + let contentItem = state.messageContentStore[msg_id] + if (contentItem) { + resolve(contentItem) + } else { + getContentByMsgId(msg_id).then(res => { + const content = res.data + commit('updateMessageContentStore', { msg_id, content }) + resolve(content) + }) + } + }) + }, + // 把一个未读消息标记为已读 + hasRead ({ state, commit }, { msg_id }) { + return new Promise((resolve, reject) => { + hasRead(msg_id).then(() => { + commit('moveMsg', { + from: 'messageUnreadList', + to: 'messageReadedList', + msg_id + }) + commit('setMessageCount', state.unreadCount - 1) + resolve() + }).catch(error => { + reject(error) + }) + }) + }, + // 删除一个已读消息到回收站 + removeReaded ({ commit }, { msg_id }) { + return new Promise((resolve, reject) => { + removeReaded(msg_id).then(() => { + commit('moveMsg', { + from: 'messageReadedList', + to: 'messageTrashList', + msg_id + }) + resolve() + }).catch(error => { + reject(error) + }) + }) + }, + // 还原一个已删除消息到已读消息 + restoreTrash ({ commit }, { msg_id }) { + return new Promise((resolve, reject) => { + restoreTrash(msg_id).then(() => { + commit('moveMsg', { + from: 'messageTrashList', + to: 'messageReadedList', + msg_id + }) + resolve() + }).catch(error => { + reject(error) + }) + }) + } + } +} diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/components/charts/bar.vue b/src/JT808.DotNetty.Dashbord.UI/src/view/components/charts/bar.vue new file mode 100644 index 0000000..b0a2709 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/components/charts/bar.vue @@ -0,0 +1,58 @@ + + + diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/components/charts/index.js b/src/JT808.DotNetty.Dashbord.UI/src/view/components/charts/index.js new file mode 100644 index 0000000..2ca3c91 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/components/charts/index.js @@ -0,0 +1,3 @@ +import ChartPie from './pie.vue' +import ChartBar from './bar.vue' +export { ChartPie, ChartBar } diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/components/charts/pie.vue b/src/JT808.DotNetty.Dashbord.UI/src/view/components/charts/pie.vue new file mode 100644 index 0000000..c86d68c --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/components/charts/pie.vue @@ -0,0 +1,70 @@ + + + diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/components/common-icon/common-icon.vue b/src/JT808.DotNetty.Dashbord.UI/src/view/components/common-icon/common-icon.vue new file mode 100644 index 0000000..768fa1b --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/components/common-icon/common-icon.vue @@ -0,0 +1,42 @@ + + + + + diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/components/common-icon/index.js b/src/JT808.DotNetty.Dashbord.UI/src/view/components/common-icon/index.js new file mode 100644 index 0000000..1207d15 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/components/common-icon/index.js @@ -0,0 +1,2 @@ +import CommonIcon from './common-icon.vue' +export default CommonIcon diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/components/common/common.less b/src/JT808.DotNetty.Dashbord.UI/src/view/components/common/common.less new file mode 100644 index 0000000..3c3e5b1 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/components/common/common.less @@ -0,0 +1,8 @@ +.no-select{ + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/components/common/util.js b/src/JT808.DotNetty.Dashbord.UI/src/view/components/common/util.js new file mode 100644 index 0000000..2129e7a --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/components/common/util.js @@ -0,0 +1,3 @@ +export const showTitle = (item, vm) => { + return vm.$config.useI18n ? vm.$t(item.name) : ((item.meta && item.meta.title) || item.name) +} diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/components/count-to/count-to.vue b/src/JT808.DotNetty.Dashbord.UI/src/view/components/count-to/count-to.vue new file mode 100644 index 0000000..a10e3ff --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/components/count-to/count-to.vue @@ -0,0 +1,174 @@ + + + diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/components/count-to/index.js b/src/JT808.DotNetty.Dashbord.UI/src/view/components/count-to/index.js new file mode 100644 index 0000000..17b3332 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/components/count-to/index.js @@ -0,0 +1,2 @@ +import countTo from './count-to.vue' +export default countTo diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/components/count-to/index.less b/src/JT808.DotNetty.Dashbord.UI/src/view/components/count-to/index.less new file mode 100644 index 0000000..e17d7c6 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/components/count-to/index.less @@ -0,0 +1,10 @@ +@prefix: ~"count-to"; + +.@{prefix}-wrapper{ + .content-outer{ + display: inline-block; + .@{prefix}-unit-text{ + font-style: normal; + } + } +} diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/components/cropper/cropper.vue b/src/JT808.DotNetty.Dashbord.UI/src/view/components/cropper/cropper.vue new file mode 100644 index 0000000..6b7c3a6 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/components/cropper/cropper.vue @@ -0,0 +1,48 @@ + + + + + diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/components/cropper/index.js b/src/JT808.DotNetty.Dashbord.UI/src/view/components/cropper/index.js new file mode 100644 index 0000000..e7db5ea --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/components/cropper/index.js @@ -0,0 +1,2 @@ +import Cropper from './index.vue' +export default Cropper diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/components/cropper/index.less b/src/JT808.DotNetty.Dashbord.UI/src/view/components/cropper/index.less new file mode 100644 index 0000000..cdf431d --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/components/cropper/index.less @@ -0,0 +1,35 @@ +.bg{ + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC") +} +.cropper-wrapper{ + width: 600px; + height: 340px; + .img-box{ + height: 340px; + width: 430px; + border: 1px solid #ebebeb; + display: inline-block; + .bg; + img{ + max-width: 100%; + display: block; + } + } + .right-con{ + display: inline-block; + width: 170px; + vertical-align: top; + box-sizing: border-box; + padding: 0 10px; + .preview-box{ + height: 150px !important; + width: 100% !important; + overflow: hidden; + border: 1px solid #ebebeb; + .bg; + } + .button-box{ + padding: 10px 0 0; + } + } +} diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/components/cropper/index.vue b/src/JT808.DotNetty.Dashbord.UI/src/view/components/cropper/index.vue new file mode 100644 index 0000000..7bb664f --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/components/cropper/index.vue @@ -0,0 +1,139 @@ + + + diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/components/drag-list/drag-list.vue b/src/JT808.DotNetty.Dashbord.UI/src/view/components/drag-list/drag-list.vue new file mode 100644 index 0000000..664abc9 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/components/drag-list/drag-list.vue @@ -0,0 +1,92 @@ + + + diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/components/drag-list/index.js b/src/JT808.DotNetty.Dashbord.UI/src/view/components/drag-list/index.js new file mode 100644 index 0000000..d2bb972 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/components/drag-list/index.js @@ -0,0 +1,2 @@ +import DragList from './drag-list.vue' +export default DragList diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/components/editor/editor.vue b/src/JT808.DotNetty.Dashbord.UI/src/view/components/editor/editor.vue new file mode 100644 index 0000000..881c73e --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/components/editor/editor.vue @@ -0,0 +1,75 @@ + + + + + diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/components/editor/index.js b/src/JT808.DotNetty.Dashbord.UI/src/view/components/editor/index.js new file mode 100644 index 0000000..56e8de2 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/components/editor/index.js @@ -0,0 +1,2 @@ +import Editor from './editor.vue' +export default Editor diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/components/icons/icons.vue b/src/JT808.DotNetty.Dashbord.UI/src/view/components/icons/icons.vue new file mode 100644 index 0000000..50b7183 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/components/icons/icons.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/components/icons/index.js b/src/JT808.DotNetty.Dashbord.UI/src/view/components/icons/index.js new file mode 100644 index 0000000..bdc38b2 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/components/icons/index.js @@ -0,0 +1,2 @@ +import Icons from './icons.vue' +export default Icons diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/components/info-card/index.js b/src/JT808.DotNetty.Dashbord.UI/src/view/components/info-card/index.js new file mode 100644 index 0000000..354419b --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/components/info-card/index.js @@ -0,0 +1,2 @@ +import InforCard from './infor-card.vue' +export default InforCard diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/components/info-card/infor-card.vue b/src/JT808.DotNetty.Dashbord.UI/src/view/components/info-card/infor-card.vue new file mode 100644 index 0000000..6240d0e --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/components/info-card/infor-card.vue @@ -0,0 +1,94 @@ + + + + + diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/components/login-form/index.js b/src/JT808.DotNetty.Dashbord.UI/src/view/components/login-form/index.js new file mode 100644 index 0000000..d480c28 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/components/login-form/index.js @@ -0,0 +1,2 @@ +import LoginForm from './login-form.vue' +export default LoginForm diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/components/login-form/login-form.vue b/src/JT808.DotNetty.Dashbord.UI/src/view/components/login-form/login-form.vue new file mode 100644 index 0000000..497c08c --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/components/login-form/login-form.vue @@ -0,0 +1,72 @@ + + diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/a-back-top/index.js b/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/a-back-top/index.js new file mode 100644 index 0000000..4da0014 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/a-back-top/index.js @@ -0,0 +1,2 @@ +import ABackTop from './index.vue' +export default ABackTop diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/a-back-top/index.vue b/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/a-back-top/index.vue new file mode 100644 index 0000000..f26f95c --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/a-back-top/index.vue @@ -0,0 +1,90 @@ + + diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/error-store/error-store.vue b/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/error-store/error-store.vue new file mode 100644 index 0000000..9941677 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/error-store/error-store.vue @@ -0,0 +1,49 @@ + + + + + diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/error-store/index.js b/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/error-store/index.js new file mode 100644 index 0000000..a777df1 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/error-store/index.js @@ -0,0 +1,2 @@ +import ErrorStore from './error-store.vue' +export default ErrorStore diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/fullscreen/fullscreen.vue b/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/fullscreen/fullscreen.vue new file mode 100644 index 0000000..d5213fa --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/fullscreen/fullscreen.vue @@ -0,0 +1,84 @@ + + + + + diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/fullscreen/index.js b/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/fullscreen/index.js new file mode 100644 index 0000000..422c7c1 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/fullscreen/index.js @@ -0,0 +1,2 @@ +import Fullscreen from './fullscreen.vue' +export default Fullscreen diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/header-bar/custom-bread-crumb/custom-bread-crumb.less b/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/header-bar/custom-bread-crumb/custom-bread-crumb.less new file mode 100644 index 0000000..1ace1eb --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/header-bar/custom-bread-crumb/custom-bread-crumb.less @@ -0,0 +1,4 @@ +.custom-bread-crumb{ + display: inline-block; + vertical-align: top; +} diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/header-bar/custom-bread-crumb/custom-bread-crumb.vue b/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/header-bar/custom-bread-crumb/custom-bread-crumb.vue new file mode 100644 index 0000000..51b121d --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/header-bar/custom-bread-crumb/custom-bread-crumb.vue @@ -0,0 +1,46 @@ + + diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/header-bar/custom-bread-crumb/index.js b/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/header-bar/custom-bread-crumb/index.js new file mode 100644 index 0000000..a590fe0 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/header-bar/custom-bread-crumb/index.js @@ -0,0 +1,2 @@ +import customBreadCrumb from './custom-bread-crumb.vue' +export default customBreadCrumb diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/header-bar/header-bar.less b/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/header-bar/header-bar.less new file mode 100644 index 0000000..c245d19 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/header-bar/header-bar.less @@ -0,0 +1,14 @@ +.header-bar{ + width: 100%; + height: 100%; + position: relative; + .custom-content-con{ + float: right; + height: auto; + padding-right: 20px; + line-height: 64px; + & > *{ + float: right; + } + } +} diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/header-bar/header-bar.vue b/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/header-bar/header-bar.vue new file mode 100644 index 0000000..1452146 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/header-bar/header-bar.vue @@ -0,0 +1,34 @@ + + diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/header-bar/index.js b/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/header-bar/index.js new file mode 100644 index 0000000..3d4a170 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/header-bar/index.js @@ -0,0 +1,2 @@ +import HeaderBar from './header-bar' +export default HeaderBar diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/header-bar/sider-trigger/index.js b/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/header-bar/sider-trigger/index.js new file mode 100644 index 0000000..15853f4 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/header-bar/sider-trigger/index.js @@ -0,0 +1,2 @@ +import siderTrigger from './sider-trigger.vue' +export default siderTrigger diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/header-bar/sider-trigger/sider-trigger.less b/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/header-bar/sider-trigger/sider-trigger.less new file mode 100644 index 0000000..eb50999 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/header-bar/sider-trigger/sider-trigger.less @@ -0,0 +1,21 @@ +.trans{ + transition: transform .2s ease; +} +@size: 40px; +.sider-trigger-a{ + padding: 6px; + width: @size; + height: @size; + display: inline-block; + text-align: center; + color: #5c6b77; + margin-top: 12px; + i{ + .trans; + vertical-align: top; + } + &.collapsed i{ + transform: rotateZ(90deg); + .trans; + } +} diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/header-bar/sider-trigger/sider-trigger.vue b/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/header-bar/sider-trigger/sider-trigger.vue new file mode 100644 index 0000000..200e18f --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/header-bar/sider-trigger/sider-trigger.vue @@ -0,0 +1,27 @@ + + + diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/language/index.js b/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/language/index.js new file mode 100644 index 0000000..de2a90a --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/language/index.js @@ -0,0 +1,2 @@ +import Language from './language.vue' +export default Language diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/language/language.vue b/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/language/language.vue new file mode 100644 index 0000000..b1d92ec --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/language/language.vue @@ -0,0 +1,51 @@ + + + diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/side-menu/collapsed-menu.vue b/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/side-menu/collapsed-menu.vue new file mode 100644 index 0000000..73ac93e --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/side-menu/collapsed-menu.vue @@ -0,0 +1,51 @@ + + diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/side-menu/index.js b/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/side-menu/index.js new file mode 100644 index 0000000..5b36868 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/side-menu/index.js @@ -0,0 +1,2 @@ +import SideMenu from './side-menu.vue' +export default SideMenu diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/side-menu/item-mixin.js b/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/side-menu/item-mixin.js new file mode 100644 index 0000000..8b807af --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/side-menu/item-mixin.js @@ -0,0 +1,21 @@ +export default { + props: { + parentItem: { + type: Object, + default: () => {} + }, + theme: String, + iconSize: Number + }, + computed: { + parentName () { + return this.parentItem.name + }, + children () { + return this.parentItem.children + }, + textColor () { + return this.theme === 'dark' ? '#fff' : '#495060' + } + } +} diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/side-menu/mixin.js b/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/side-menu/mixin.js new file mode 100644 index 0000000..21b618b --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/side-menu/mixin.js @@ -0,0 +1,18 @@ +import CommonIcon from '_c/common-icon' +import { showTitle } from '@/libs/util' +export default { + components: { + CommonIcon + }, + methods: { + showTitle (item) { + return showTitle(item, this) + }, + showChildren (item) { + return item.children && (item.children.length > 1 || (item.meta && item.meta.showAlways)) + }, + getNameOrHref (item, children0) { + return item.href ? `isTurnByHref_${item.href}` : (children0 ? item.children[0].name : item.name) + } + } +} diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/side-menu/side-menu-item.vue b/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/side-menu/side-menu-item.vue new file mode 100644 index 0000000..12338a6 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/side-menu/side-menu-item.vue @@ -0,0 +1,26 @@ + + diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/side-menu/side-menu.less b/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/side-menu/side-menu.less new file mode 100644 index 0000000..4716d82 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/side-menu/side-menu.less @@ -0,0 +1,40 @@ +.side-menu-wrapper{ + user-select: none; + .menu-collapsed{ + padding-top: 10px; + + .ivu-dropdown{ + width: 100%; + .ivu-dropdown-rel a{ + width: 100%; + } + } + .ivu-tooltip{ + width: 100%; + .ivu-tooltip-rel{ + width: 100%; + } + .ivu-tooltip-popper .ivu-tooltip-content{ + .ivu-tooltip-arrow{ + border-right-color: #fff; + } + .ivu-tooltip-inner{ + background: #fff; + color: #495060; + } + } + } + + + } + a.drop-menu-a{ + display: inline-block; + padding: 6px 15px; + width: 100%; + text-align: center; + color: #495060; + } +} +.menu-title{ + padding-left: 6px; +} diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/side-menu/side-menu.vue b/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/side-menu/side-menu.vue new file mode 100644 index 0000000..ee18e86 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/side-menu/side-menu.vue @@ -0,0 +1,114 @@ + + + diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/tags-nav/index.js b/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/tags-nav/index.js new file mode 100644 index 0000000..585792a --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/tags-nav/index.js @@ -0,0 +1,2 @@ +import TagsNav from './tags-nav.vue' +export default TagsNav diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/tags-nav/tags-nav.less b/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/tags-nav/tags-nav.less new file mode 100644 index 0000000..a4c8c5d --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/tags-nav/tags-nav.less @@ -0,0 +1,87 @@ +.no-select{ + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} +.size{ + width: 100%; + height: 100%; +} +.tags-nav{ + position: relative; + border-top: 1px solid #F0F0F0; + border-bottom: 1px solid #F0F0F0; + .no-select; + .size; + .close-con{ + position: absolute; + right: 0; + top: 0; + height: 100%; + width: 32px; + background: #fff; + text-align: center; + z-index: 10; + } + .btn-con{ + position: absolute; + top: 0px; + height: 100%; + background: #fff; + padding-top: 3px; + z-index: 10; + button{ + padding: 6px 4px; + line-height: 14px; + text-align: center; + } + &.left-btn{ + left: 0px; + } + &.right-btn{ + right: 32px; + border-right: 1px solid #F0F0F0; + } + } + .scroll-outer{ + position: absolute; + left: 28px; + right: 61px; + top: 0; + bottom: 0; + box-shadow: 0px 0 3px 2px rgba(100,100,100,.1) inset; + .scroll-body{ + height: ~"calc(100% - 1px)"; + display: inline-block; + padding: 1px 4px 0; + position: absolute; + overflow: visible; + white-space: nowrap; + transition: left .3s ease; + .ivu-tag-dot-inner{ + transition: background .2s ease; + } + } + } + .contextmenu { + position: absolute; + margin: 0; + padding: 5px 0; + background: #fff; + z-index: 100; + list-style-type: none; + border-radius: 4px; + box-shadow: 2px 2px 3px 0 rgba(0, 0, 0, .3); + li { + margin: 0; + padding: 5px 15px; + cursor: pointer; + &:hover { + background: #eee; + } + } + } +} diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/tags-nav/tags-nav.vue b/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/tags-nav/tags-nav.vue new file mode 100644 index 0000000..2dbca44 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/tags-nav/tags-nav.vue @@ -0,0 +1,209 @@ + + + + + diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/user/index.js b/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/user/index.js new file mode 100644 index 0000000..3d04a5c --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/user/index.js @@ -0,0 +1,2 @@ +import User from './user.vue' +export default User diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/user/user.less b/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/user/user.less new file mode 100644 index 0000000..a3c95af --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/user/user.less @@ -0,0 +1,12 @@ +.user{ + &-avator-dropdown{ + cursor: pointer; + display: inline-block; + // height: 64px; + vertical-align: middle; + // line-height: 64px; + .ivu-badge-dot{ + top: 16px; + } + } +} diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/user/user.vue b/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/user/user.vue new file mode 100644 index 0000000..3d4689d --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/components/user/user.vue @@ -0,0 +1,59 @@ + + + diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/index.js b/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/index.js new file mode 100644 index 0000000..7df2a08 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/index.js @@ -0,0 +1,2 @@ +import Main from './main.vue' +export default Main diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/main.less b/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/main.less new file mode 100644 index 0000000..fd0cd41 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/main.less @@ -0,0 +1,75 @@ +.main{ + .logo-con{ + height: 64px; + padding: 10px; + img{ + height: 44px; + width: auto; + display: block; + margin: 0 auto; + } + } + .header-con{ + background: #fff; + padding: 0 20px; + width: 100%; + } + .main-layout-con{ + height: 100%; + overflow: hidden; + } + .main-content-con{ + height: ~"calc(100% - 60px)"; + overflow: hidden; + } + .tag-nav-wrapper{ + padding: 0; + height:40px; + background:#F0F0F0; + } + .content-wrapper{ + padding: 18px; + height: ~"calc(100% - 80px)"; + overflow: auto; + } + .left-sider{ + .ivu-layout-sider-children{ + overflow-y: scroll; + margin-right: -18px; + } + } +} +.ivu-menu-item > i{ + margin-right: 12px !important; +} +.ivu-menu-submenu > .ivu-menu > .ivu-menu-item > i { + margin-right: 8px !important; +} +.collased-menu-dropdown{ + width: 100%; + margin: 0; + line-height: normal; + padding: 7px 0 6px 16px; + clear: both; + font-size: 12px !important; + white-space: nowrap; + list-style: none; + cursor: pointer; + transition: background 0.2s ease-in-out; + &:hover{ + background: rgba(100, 100, 100, 0.1); + } + & * { + color: #515a6e; + } + .ivu-menu-item > i{ + margin-right: 12px !important; + } + .ivu-menu-submenu > .ivu-menu > .ivu-menu-item > i { + margin-right: 8px !important; + } +} + +.ivu-select-dropdown.ivu-dropdown-transfer{ + max-height: 400px; +} diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/main.vue b/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/main.vue new file mode 100644 index 0000000..3c1603f --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/components/main/main.vue @@ -0,0 +1,183 @@ + + diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/components/markdown/index.js b/src/JT808.DotNetty.Dashbord.UI/src/view/components/markdown/index.js new file mode 100644 index 0000000..99e0cda --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/components/markdown/index.js @@ -0,0 +1,2 @@ +import MarkdownEditor from './markdown.vue' +export default MarkdownEditor diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/components/markdown/markdown.vue b/src/JT808.DotNetty.Dashbord.UI/src/view/components/markdown/markdown.vue new file mode 100644 index 0000000..242b3cc --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/components/markdown/markdown.vue @@ -0,0 +1,76 @@ + + + + + diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/components/parent-view/index.js b/src/JT808.DotNetty.Dashbord.UI/src/view/components/parent-view/index.js new file mode 100644 index 0000000..a959c65 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/components/parent-view/index.js @@ -0,0 +1,2 @@ +import ParentView from './parent-view.vue' +export default ParentView diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/components/parent-view/parent-view.vue b/src/JT808.DotNetty.Dashbord.UI/src/view/components/parent-view/parent-view.vue new file mode 100644 index 0000000..84259f3 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/components/parent-view/parent-view.vue @@ -0,0 +1,20 @@ + + diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/components/paste-editor/index.js b/src/JT808.DotNetty.Dashbord.UI/src/view/components/paste-editor/index.js new file mode 100644 index 0000000..f02331a --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/components/paste-editor/index.js @@ -0,0 +1,2 @@ +import PasteEditor from './paste-editor.vue' +export default PasteEditor diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/components/paste-editor/paste-editor.less b/src/JT808.DotNetty.Dashbord.UI/src/view/components/paste-editor/paste-editor.less new file mode 100644 index 0000000..2ffd2bd --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/components/paste-editor/paste-editor.less @@ -0,0 +1,26 @@ +.paste-editor-wrapper{ + width: 100%; + height: 100%; + border: 1px dashed gainsboro; + textarea.textarea-el{ + width: 100%; + height: 100%; + } + .CodeMirror{ + height: 100%; + padding: 0; + .CodeMirror-code div .CodeMirror-line > span > span.cm-tab{ + &::after{ + content: '→'; + color: #BFBFBF; + } + } + } + .first-row{ + font-weight: 700; + font-size: 14px; + } + .incorrect-row{ + background: #F5CBD1; + } +} diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/components/paste-editor/paste-editor.vue b/src/JT808.DotNetty.Dashbord.UI/src/view/components/paste-editor/paste-editor.vue new file mode 100644 index 0000000..083d6c4 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/components/paste-editor/paste-editor.vue @@ -0,0 +1,115 @@ + + + diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/components/paste-editor/plugins/placeholder.js b/src/JT808.DotNetty.Dashbord.UI/src/view/components/paste-editor/plugins/placeholder.js new file mode 100644 index 0000000..d9bf77e --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/components/paste-editor/plugins/placeholder.js @@ -0,0 +1,58 @@ +export default (codemirror) => { + (function (mod) { + mod(codemirror) + })(function (CodeMirror) { + CodeMirror.defineOption('placeholder', '', function (cm, val, old) { + var prev = old && old !== CodeMirror.Init + if (val && !prev) { + cm.on('blur', onBlur) + cm.on('change', onChange) + cm.on('swapDoc', onChange) + onChange(cm) + } else if (!val && prev) { + cm.off('blur', onBlur) + cm.off('change', onChange) + cm.off('swapDoc', onChange) + clearPlaceholder(cm) + var wrapper = cm.getWrapperElement() + wrapper.className = wrapper.className.replace(' CodeMirror-empty', '') + } + + if (val && !cm.hasFocus()) onBlur(cm) + }) + + function clearPlaceholder (cm) { + if (cm.state.placeholder) { + cm.state.placeholder.parentNode.removeChild(cm.state.placeholder) + cm.state.placeholder = null + } + } + function setPlaceholder (cm) { + clearPlaceholder(cm) + var elt = cm.state.placeholder = document.createElement('pre') + elt.style.cssText = 'height: 0; overflow: visible; color: #80848f;' + elt.style.direction = cm.getOption('direction') + elt.className = 'CodeMirror-placeholder' + var placeHolder = cm.getOption('placeholder') + if (typeof placeHolder === 'string') placeHolder = document.createTextNode(placeHolder) + elt.appendChild(placeHolder) + cm.display.lineSpace.insertBefore(elt, cm.display.lineSpace.firstChild) + } + + function onBlur (cm) { + if (isEmpty(cm)) setPlaceholder(cm) + } + function onChange (cm) { + let wrapper = cm.getWrapperElement() + let empty = isEmpty(cm) + wrapper.className = wrapper.className.replace(' CodeMirror-empty', '') + (empty ? ' CodeMirror-empty' : '') + + if (empty) setPlaceholder(cm) + else clearPlaceholder(cm) + } + + function isEmpty (cm) { + return (cm.lineCount() === 1) && (cm.getLine(0) === '') + } + }) +} diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/components/split-pane/index.js b/src/JT808.DotNetty.Dashbord.UI/src/view/components/split-pane/index.js new file mode 100644 index 0000000..f5ed60e --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/components/split-pane/index.js @@ -0,0 +1,2 @@ +import Split from './split.vue' +export default Split diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/components/split-pane/index.less b/src/JT808.DotNetty.Dashbord.UI/src/view/components/split-pane/index.less new file mode 100644 index 0000000..2583d90 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/components/split-pane/index.less @@ -0,0 +1,114 @@ +@split-prefix-cls: ~"ivu-split"; +@box-shadow: 0 0 4px 0 rgba(28, 36, 56, 0.4); +@trigger-bar-background: rgba(23, 35, 61, 0.25); +@trigger-background: #F8F8F9; +@trigger-width: 6px; +@trigger-bar-width: 4px; +@trigger-bar-offset: (@trigger-width - @trigger-bar-width) / 2; +@trigger-bar-interval: 3px; +@trigger-bar-weight: 1px; +@trigger-bar-con-height: (@trigger-bar-weight + @trigger-bar-interval) * 8; + +.@{split-prefix-cls}{ + &-wrapper{ + position: relative; + width: 100%; + height: 100%; + } + &-pane{ + position: absolute; + &.left-pane, &.right-pane{ + top: 0px; + bottom: 0px; + } + &.left-pane{ + left: 0px; + } + &.right-pane{ + right: 0px; + } + &.top-pane, &.bottom-pane{ + left: 0px; + right: 0px; + } + &.top-pane{ + top: 0px; + } + &.bottom-pane{ + bottom: 0px; + } + } + &-trigger{ + &-con{ + position: absolute; + transform: translate(-50%, -50%); + z-index: 10; + } + &-bar-con{ + position: absolute; + overflow: hidden; + &.vertical{ + left: @trigger-bar-offset; + top: 50%; + height: @trigger-bar-con-height; + transform: translate(0, -50%); + } + &.horizontal{ + left: 50%; + top: @trigger-bar-offset; + width: @trigger-bar-con-height; + transform: translate(-50%, 0); + } + } + &-vertical{ + width: @trigger-width; + height: 100%; + background: @trigger-background; + box-shadow: @box-shadow; + cursor: col-resize; + .@{split-prefix-cls}-trigger-bar{ + width: @trigger-bar-width; + height: 1px; + background: @trigger-bar-background; + float: left; + margin-top: @trigger-bar-interval; + } + } + &-horizontal{ + height: @trigger-width; + width: 100%; + background: @trigger-background; + box-shadow: @box-shadow; + cursor: row-resize; + .@{split-prefix-cls}-trigger-bar{ + height: @trigger-bar-width; + width: 1px; + background: @trigger-bar-background; + float: left; + margin-right: @trigger-bar-interval; + } + } + } + &-horizontal{ + .@{split-prefix-cls}-trigger-con{ + top: 50%; + height: 100%; + width: 0; + } + } + &-vertical{ + .@{split-prefix-cls}-trigger-con{ + left: 50%; + height: 0; + width: 100%; + } + } + .no-select{ + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + } +} diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/components/split-pane/split-pane.vue b/src/JT808.DotNetty.Dashbord.UI/src/view/components/split-pane/split-pane.vue new file mode 100644 index 0000000..9afe011 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/components/split-pane/split-pane.vue @@ -0,0 +1,79 @@ + + + + + diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/components/split-pane/split.vue b/src/JT808.DotNetty.Dashbord.UI/src/view/components/split-pane/split.vue new file mode 100644 index 0000000..409982e --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/components/split-pane/split.vue @@ -0,0 +1,158 @@ + + + + + diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/components/split-pane/trigger.vue b/src/JT808.DotNetty.Dashbord.UI/src/view/components/split-pane/trigger.vue new file mode 100644 index 0000000..9abdf03 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/components/split-pane/trigger.vue @@ -0,0 +1,43 @@ + + + + + diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/components/tables/edit.vue b/src/JT808.DotNetty.Dashbord.UI/src/view/components/tables/edit.vue new file mode 100644 index 0000000..e1066ef --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/components/tables/edit.vue @@ -0,0 +1,73 @@ + + + + + diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/components/tables/handle-btns.js b/src/JT808.DotNetty.Dashbord.UI/src/view/components/tables/handle-btns.js new file mode 100644 index 0000000..551b2e3 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/components/tables/handle-btns.js @@ -0,0 +1,33 @@ +const btns = { + delete: (h, params, vm) => { + return h('Poptip', { + props: { + confirm: true, + title: '你确定要删除吗?' + }, + on: { + 'on-ok': () => { + vm.$emit('on-delete', params) + vm.$emit('input', params.tableData.filter((item, index) => index !== params.row.initRowIndex)) + } + } + }, [ + h('Button', { + props: { + type: 'text', + ghost: true + } + }, [ + h('Icon', { + props: { + type: 'md-trash', + size: 18, + color: '#000000' + } + }) + ]) + ]) + } +} + +export default btns diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/components/tables/index.js b/src/JT808.DotNetty.Dashbord.UI/src/view/components/tables/index.js new file mode 100644 index 0000000..4dabfab --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/components/tables/index.js @@ -0,0 +1,2 @@ +import Tables from './tables.vue' +export default Tables diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/components/tables/index.less b/src/JT808.DotNetty.Dashbord.UI/src/view/components/tables/index.less new file mode 100644 index 0000000..3c352e1 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/components/tables/index.less @@ -0,0 +1,17 @@ +.search-con{ + padding: 10px 0; + .search{ + &-col{ + display: inline-block; + width: 200px; + } + &-input{ + display: inline-block; + width: 200px; + margin-left: 2px; + } + &-btn{ + margin-left: 2px; + } + } +} diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/components/tables/tables.vue b/src/JT808.DotNetty.Dashbord.UI/src/view/components/tables/tables.vue new file mode 100644 index 0000000..fa2c235 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/components/tables/tables.vue @@ -0,0 +1,277 @@ + + + diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/components/tree-table/index.vue b/src/JT808.DotNetty.Dashbord.UI/src/view/components/tree-table/index.vue new file mode 100644 index 0000000..6af71d1 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/components/tree-table/index.vue @@ -0,0 +1,194 @@ + + + + + diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/directive/directive.vue b/src/JT808.DotNetty.Dashbord.UI/src/view/directive/directive.vue new file mode 100644 index 0000000..d731335 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/directive/directive.vue @@ -0,0 +1,121 @@ + + + + + diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/error-page/401.vue b/src/JT808.DotNetty.Dashbord.UI/src/view/error-page/401.vue new file mode 100644 index 0000000..1032326 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/error-page/401.vue @@ -0,0 +1,19 @@ + + + diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/error-page/404.vue b/src/JT808.DotNetty.Dashbord.UI/src/view/error-page/404.vue new file mode 100644 index 0000000..473df42 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/error-page/404.vue @@ -0,0 +1,19 @@ + + + diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/error-page/500.vue b/src/JT808.DotNetty.Dashbord.UI/src/view/error-page/500.vue new file mode 100644 index 0000000..6a885da --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/error-page/500.vue @@ -0,0 +1,19 @@ + + + diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/error-page/back-btn-group.vue b/src/JT808.DotNetty.Dashbord.UI/src/view/error-page/back-btn-group.vue new file mode 100644 index 0000000..4bbda48 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/error-page/back-btn-group.vue @@ -0,0 +1,38 @@ + + + diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/error-page/error-content.vue b/src/JT808.DotNetty.Dashbord.UI/src/view/error-page/error-content.vue new file mode 100644 index 0000000..3c9a0f4 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/error-page/error-content.vue @@ -0,0 +1,28 @@ + + + diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/error-page/error.less b/src/JT808.DotNetty.Dashbord.UI/src/view/error-page/error.less new file mode 100644 index 0000000..6380245 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/error-page/error.less @@ -0,0 +1,46 @@ +.error-page{ + width: 100%; + height: 100%; + position: relative; + background: #f8f8f9; + .content-con{ + width: 700px; + height: 600px; + position: absolute; + left: 50%; + top: 50%; + transform: translate(-50%, -60%); + img{ + display: block; + width: 100%; + height: 100%; + } + .text-con{ + position: absolute; + left: 0px; + top: 0px; + h4{ + position: absolute; + left: 0px; + top: 0px; + font-size: 80px; + font-weight: 700; + color: #348EED; + } + h5{ + position: absolute; + width: 700px; + left: 0px; + top: 100px; + font-size: 20px; + font-weight: 700; + color: #67647D; + } + } + .back-btn-group{ + position: absolute; + right: 0px; + bottom: 20px; + } + } +} diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/error-store/error-store.vue b/src/JT808.DotNetty.Dashbord.UI/src/view/error-store/error-store.vue new file mode 100644 index 0000000..e66631c --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/error-store/error-store.vue @@ -0,0 +1,39 @@ + + + + + diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/login/login.less b/src/JT808.DotNetty.Dashbord.UI/src/view/login/login.less new file mode 100644 index 0000000..e986ed4 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/login/login.less @@ -0,0 +1,29 @@ +.login{ + width: 100%; + height: 100%; + background-image: url('../../assets/images/login-bg.jpg'); + background-size: cover; + background-position: center; + position: relative; + &-con{ + position: absolute; + right: 160px; + top: 50%; + transform: translateY(-60%); + width: 300px; + &-header{ + font-size: 16px; + font-weight: 300; + text-align: center; + padding: 30px 0; + } + .form-con{ + padding: 10px 0 0; + } + .login-tip{ + font-size: 10px; + text-align: center; + color: #c3c3c3; + } + } +} diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/login/login.vue b/src/JT808.DotNetty.Dashbord.UI/src/view/login/login.vue new file mode 100644 index 0000000..7595e01 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/login/login.vue @@ -0,0 +1,45 @@ + + + + + + + diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/session/session.vue b/src/JT808.DotNetty.Dashbord.UI/src/view/session/session.vue new file mode 100644 index 0000000..33f3ce3 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/session/session.vue @@ -0,0 +1,34 @@ + + + + + diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/single-page/error-logger.vue b/src/JT808.DotNetty.Dashbord.UI/src/view/single-page/error-logger.vue new file mode 100644 index 0000000..a4b4ac2 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/single-page/error-logger.vue @@ -0,0 +1,91 @@ + + + + + diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/single-page/home/example.vue b/src/JT808.DotNetty.Dashbord.UI/src/view/single-page/home/example.vue new file mode 100644 index 0000000..5fb3465 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/single-page/home/example.vue @@ -0,0 +1,114 @@ + + + diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/single-page/home/home.vue b/src/JT808.DotNetty.Dashbord.UI/src/view/single-page/home/home.vue new file mode 100644 index 0000000..0240022 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/single-page/home/home.vue @@ -0,0 +1,83 @@ + + + + + diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/single-page/home/index.js b/src/JT808.DotNetty.Dashbord.UI/src/view/single-page/home/index.js new file mode 100644 index 0000000..de4ced1 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/single-page/home/index.js @@ -0,0 +1,2 @@ +import home from './home.vue' +export default home diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/single-page/message/index.vue b/src/JT808.DotNetty.Dashbord.UI/src/view/single-page/message/index.vue new file mode 100644 index 0000000..11b43f9 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/single-page/message/index.vue @@ -0,0 +1,194 @@ + + + + + diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/sourcepackage/sourcepackage.vue b/src/JT808.DotNetty.Dashbord.UI/src/view/sourcepackage/sourcepackage.vue new file mode 100644 index 0000000..04edf70 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/sourcepackage/sourcepackage.vue @@ -0,0 +1,34 @@ + + + + + diff --git a/src/JT808.DotNetty.Dashbord.UI/src/view/transmit/transmit.vue b/src/JT808.DotNetty.Dashbord.UI/src/view/transmit/transmit.vue new file mode 100644 index 0000000..f21961d --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/src/view/transmit/transmit.vue @@ -0,0 +1,33 @@ + + + + + diff --git a/src/JT808.DotNetty.Dashbord.UI/tests/e2e/.eslintrc b/src/JT808.DotNetty.Dashbord.UI/tests/e2e/.eslintrc new file mode 100644 index 0000000..02023fb --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/tests/e2e/.eslintrc @@ -0,0 +1,12 @@ +{ + "plugins": [ + "cypress" + ], + "env": { + "mocha": true, + "cypress/globals": true + }, + "rules": { + "strict": "off" + } +} diff --git a/src/JT808.DotNetty.Dashbord.UI/tests/e2e/plugins/index.js b/src/JT808.DotNetty.Dashbord.UI/tests/e2e/plugins/index.js new file mode 100644 index 0000000..cfefc78 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/tests/e2e/plugins/index.js @@ -0,0 +1,9 @@ +// https://docs.cypress.io/guides/guides/plugins-guide.html + +module.exports = (on, config) => Object.assign({}, config, { + fixturesFolder: 'tests/e2e/fixtures', + integrationFolder: 'tests/e2e/specs', + screenshotsFolder: 'tests/e2e/screenshots', + videosFolder: 'tests/e2e/videos', + supportFile: 'tests/e2e/support/index.js' +}) diff --git a/src/JT808.DotNetty.Dashbord.UI/tests/e2e/specs/test.js b/src/JT808.DotNetty.Dashbord.UI/tests/e2e/specs/test.js new file mode 100644 index 0000000..41ad94a --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/tests/e2e/specs/test.js @@ -0,0 +1,8 @@ +// https://docs.cypress.io/api/introduction/api.html + +describe('My First Test', () => { + it('Visits the app root url', () => { + cy.visit('/') + cy.contains('h1', 'Welcome to Your Vue.js App') + }) +}) diff --git a/src/JT808.DotNetty.Dashbord.UI/tests/e2e/support/commands.js b/src/JT808.DotNetty.Dashbord.UI/tests/e2e/support/commands.js new file mode 100644 index 0000000..c1f5a77 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/tests/e2e/support/commands.js @@ -0,0 +1,25 @@ +// *********************************************** +// This example commands.js shows you how to +// create various custom commands and overwrite +// existing commands. +// +// For more comprehensive examples of custom +// commands please read more here: +// https://on.cypress.io/custom-commands +// *********************************************** +// +// +// -- This is a parent command -- +// Cypress.Commands.add("login", (email, password) => { ... }) +// +// +// -- This is a child command -- +// Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... }) +// +// +// -- This is a dual command -- +// Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... }) +// +// +// -- This is will overwrite an existing command -- +// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... }) diff --git a/src/JT808.DotNetty.Dashbord.UI/tests/e2e/support/index.js b/src/JT808.DotNetty.Dashbord.UI/tests/e2e/support/index.js new file mode 100644 index 0000000..d68db96 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/tests/e2e/support/index.js @@ -0,0 +1,20 @@ +// *********************************************************** +// This example support/index.js is processed and +// loaded automatically before your test files. +// +// This is a great place to put global configuration and +// behavior that modifies Cypress. +// +// You can change the location of this file or turn off +// automatically serving support files with the +// 'supportFile' configuration option. +// +// You can read more here: +// https://on.cypress.io/configuration +// *********************************************************** + +// Import commands.js using ES2015 syntax: +import './commands' + +// Alternatively you can use CommonJS syntax: +// require('./commands') diff --git a/src/JT808.DotNetty.Dashbord.UI/tests/unit/.eslintrc.js b/src/JT808.DotNetty.Dashbord.UI/tests/unit/.eslintrc.js new file mode 100644 index 0000000..74fe627 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/tests/unit/.eslintrc.js @@ -0,0 +1,8 @@ +module.exports = { + env: { + mocha: true + }, + rules: { + 'import/no-extraneous-dependencies': 'off' + } +} \ No newline at end of file diff --git a/src/JT808.DotNetty.Dashbord.UI/tests/unit/HelloWorld.spec.js b/src/JT808.DotNetty.Dashbord.UI/tests/unit/HelloWorld.spec.js new file mode 100644 index 0000000..bb668bf --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/tests/unit/HelloWorld.spec.js @@ -0,0 +1,13 @@ +import { expect } from 'chai' +import { shallow } from '@vue/test-utils' +import HelloWorld from '@/components/HelloWorld.vue' + +describe('HelloWorld.vue', () => { + it('renders props.msg when passed', () => { + const msg = 'new message' + const wrapper = shallow(HelloWorld, { + propsData: { msg } + }) + expect(wrapper.text()).to.include(msg) + }) +}) diff --git a/src/JT808.DotNetty.Dashbord.UI/vue.config.js b/src/JT808.DotNetty.Dashbord.UI/vue.config.js new file mode 100644 index 0000000..5d6c1d4 --- /dev/null +++ b/src/JT808.DotNetty.Dashbord.UI/vue.config.js @@ -0,0 +1,43 @@ +const path = require('path') + +const resolve = dir => { + return path.join(__dirname, dir) +} + +// 项目部署基础 +// 默认情况下,我们假设你的应用将被部署在域的根目录下, +// 例如:https://www.my-app.com/ +// 默认:'/' +// 如果您的应用程序部署在子路径中,则需要在这指定子路径 +// 例如:https://www.foobar.com/my-app/ +// 需要将它改为'/my-app/' +// iview-admin线上演示打包路径: https://file.iviewui.com/admin-dist/ +const BASE_URL = process.env.NODE_ENV === 'production' + ? '/' + : '/' + +module.exports = { + // Project deployment base + // By default we assume your app will be deployed at the root of a domain, + // e.g. https://www.my-app.com/ + // If your app is deployed at a sub-path, you will need to specify that + // sub-path here. For example, if your app is deployed at + // https://www.foobar.com/my-app/ + // then change this to '/my-app/' + baseUrl: BASE_URL, + // tweak internal webpack configuration. + // see https://github.com/vuejs/vue-cli/blob/dev/docs/webpack.md + // 如果你不需要使用eslint,把lintOnSave设为false即可 + lintOnSave: true, + chainWebpack: config => { + config.resolve.alias + .set('@', resolve('src')) // key,value自行定义,比如.set('@@', resolve('src/components')) + .set('_c', resolve('src/components')) + }, + // 设为false打包时不生成.map文件 + productionSourceMap: false + // 这里写你调用接口的基础路径,来解决跨域,如果设置了代理,那你本地开发环境的axios的baseUrl要写为 '' ,即空字符串 + // devServer: { + // proxy: 'localhost:3000' + // } +} diff --git a/src/JT808.DotNetty.Dashbord/Controllers/JT808AtomicCounterController.cs b/src/JT808.DotNetty.Dashbord/Controllers/JT808AtomicCounterController.cs index 402657d..31f5d18 100644 --- a/src/JT808.DotNetty.Dashbord/Controllers/JT808AtomicCounterController.cs +++ b/src/JT808.DotNetty.Dashbord/Controllers/JT808AtomicCounterController.cs @@ -18,6 +18,8 @@ namespace JT808.DotNetty.Dashbord.Controllers /// 获取包计算器 /// /// + [HttpGet] + [Route("GetAtomicCounter")] public ActionResult GetAtomicCounter() { return new JT808AtomicCounterDto { diff --git a/src/JT808.DotNetty.Dashbord/Controllers/JT808SessionController.cs b/src/JT808.DotNetty.Dashbord/Controllers/JT808SessionController.cs index 32f6354..259e550 100644 --- a/src/JT808.DotNetty.Dashbord/Controllers/JT808SessionController.cs +++ b/src/JT808.DotNetty.Dashbord/Controllers/JT808SessionController.cs @@ -20,6 +20,7 @@ namespace JT808.DotNetty.Dashbord.Controllers /// /// [HttpGet] + [Route("RemoveByTerminalPhoneNo")] public ActionResult RemoveByTerminalPhoneNo(string terminalPhoneNo) { return true; @@ -31,6 +32,7 @@ namespace JT808.DotNetty.Dashbord.Controllers /// /// [HttpGet] + [Route("RemoveByChannelId")] public ActionResult RemoveByChannelId(string channelId) { return true; @@ -42,6 +44,7 @@ namespace JT808.DotNetty.Dashbord.Controllers /// /// [HttpGet] + [Route("GetAll")] public ActionResult> GetAll() { return new List() { diff --git a/src/JT808.DotNetty.Dashbord/Controllers/JT808SourcePackageController.cs b/src/JT808.DotNetty.Dashbord/Controllers/JT808SourcePackageController.cs index aa1a969..6df492a 100644 --- a/src/JT808.DotNetty.Dashbord/Controllers/JT808SourcePackageController.cs +++ b/src/JT808.DotNetty.Dashbord/Controllers/JT808SourcePackageController.cs @@ -20,6 +20,7 @@ namespace JT808.DotNetty.Dashbord.Controllers /// /// [HttpPost] + [Route("Add")] public ActionResult Add([FromBody]JT808IPAddressDto jT808IPAddressDto) { return true; @@ -31,17 +32,19 @@ namespace JT808.DotNetty.Dashbord.Controllers /// /// [HttpPost] + [Route("Remove")] public ActionResult Remove([FromBody]JT808IPAddressDto jT808IPAddressDto) { return true; } /// - /// 删除地址 + /// 获取原包通道信息集合 /// /// /// [HttpGet] + [Route("GetAll")] public ActionResult> GetAll() { return new List() { diff --git a/src/JT808.DotNetty.Dashbord/Controllers/JT808TransmitController.cs b/src/JT808.DotNetty.Dashbord/Controllers/JT808TransmitController.cs index 6fde62d..198b267 100644 --- a/src/JT808.DotNetty.Dashbord/Controllers/JT808TransmitController.cs +++ b/src/JT808.DotNetty.Dashbord/Controllers/JT808TransmitController.cs @@ -20,6 +20,7 @@ namespace JT808.DotNetty.Dashbord.Controllers /// /// [HttpPost] + [Route("Add")] public ActionResult Add([FromBody]JT808IPAddressDto jT808IPAddressDto) { return true; @@ -31,6 +32,7 @@ namespace JT808.DotNetty.Dashbord.Controllers /// /// [HttpPost] + [Route("Remove")] public ActionResult Remove([FromBody]JT808IPAddressDto jT808IPAddressDto) { return true; @@ -42,6 +44,7 @@ namespace JT808.DotNetty.Dashbord.Controllers /// /// [HttpGet] + [Route("GetAll")] public ActionResult> GetAll() { return new List() { "127.0.0.1:80", "127.0.0.1:81" }; diff --git a/src/JT808.DotNetty.Dashbord/Controllers/JT808UnificationSendController.cs b/src/JT808.DotNetty.Dashbord/Controllers/JT808UnificationSendController.cs index 0035f5b..244251e 100644 --- a/src/JT808.DotNetty.Dashbord/Controllers/JT808UnificationSendController.cs +++ b/src/JT808.DotNetty.Dashbord/Controllers/JT808UnificationSendController.cs @@ -20,10 +20,10 @@ namespace JT808.DotNetty.Dashbord.Controllers /// 下发文本信息 /// [HttpGet("{terminalPhoneNo}/{text}")] - public ActionResult SendText(string terminalPhoneNo, string text) + public ActionResult SendText(string terminalPhoneNo, string text) { - return "value"; + return true; } } }