├── .vscode
└── settings.json
├── src
├── assets
│ ├── tip
│ │ ├── help
│ │ │ ├── project.md
│ │ │ ├── body.md
│ │ │ ├── baseObject.md
│ │ │ └── group.md
│ │ └── requestparams
│ │ │ ├── body.md
│ │ │ ├── path.md
│ │ │ └── query.md
│ ├── image
│ │ ├── jt.png
│ │ ├── comp.png
│ │ ├── logo.png
│ │ ├── noImg.png
│ │ ├── audioImg.png
│ │ ├── javascr.jpg
│ │ ├── login
│ │ │ └── 1.png
│ │ ├── Arrow_Down.png
│ │ ├── project
│ │ │ ├── qr.png
│ │ │ ├── folder.png
│ │ │ ├── cover-media.jpg
│ │ │ └── cover-other.jpg
│ │ ├── view-source.gif
│ │ ├── group
│ │ │ └── default.png
│ │ └── header
│ │ │ └── default.png
│ ├── data
│ │ ├── group_new
│ │ ├── user.json
│ │ ├── content.yaml
│ │ ├── group_list
│ │ ├── apis.json
│ │ ├── editorSetting.json
│ │ ├── project.json
│ │ ├── menu.json
│ │ └── draf.json
│ ├── js
│ │ ├── metadata.js
│ │ ├── vuelint.js
│ │ └── base.js
│ └── style
│ │ └── app.styl
├── store
│ ├── getters.js
│ ├── lng
│ │ └── en.js
│ ├── mutations.js
│ ├── index.js
│ ├── actions.js
│ └── metadata.js
├── config
│ ├── default.js
│ ├── production.js
│ ├── local.js
│ └── index.js
├── login.js
├── emailActive.js
├── updatePassword.js
├── components
│ ├── Footer.vue
│ ├── User
│ │ └── Item.vue
│ ├── Content.vue
│ ├── Dialogs.vue
│ ├── Welcome.vue
│ ├── CodeEditer.vue
│ ├── pie-chart.vue
│ ├── Upload.vue
│ ├── PageRouter.vue
│ ├── Tags.vue
│ ├── Sidebar.vue
│ └── Header.vue
├── RouterMap.js
├── emailActive.vue
├── dialog
│ ├── DAddGroup.vue
│ ├── DGroupsNew.vue
│ ├── DAddPage.vue
│ └── DCopyPage.vue
├── pages
│ ├── projects
│ │ ├── new.vue
│ │ └── data.vue
│ ├── 404.vue
│ ├── noPage.vue
│ ├── groups
│ │ ├── new.vue
│ │ └── CNew.vue
│ ├── user.vue
│ ├── pages
│ │ ├── CDoc.vue
│ │ ├── history.vue
│ │ └── CNew.vue
│ ├── dashboard
│ │ ├── groups.vue
│ │ └── component.vue
│ ├── component
│ │ └── editer.vue
│ ├── completePage.vue
│ ├── project.vue
│ └── page.vue
├── extend
│ ├── BaseComponent.js
│ ├── Server.js
│ ├── BasePage.js
│ ├── BaseDialog.js
│ ├── chartOptions.js
│ ├── filter.js
│ ├── UploadImg.js
│ └── Util.js
├── main.js
├── app.vue
└── updatePassword.vue
├── babel.config.js
├── .eslintignore
├── .gitignore
├── login.tpl
├── emailActive.tpl
├── updatePassword.tpl
├── .eslintrc.js
├── LICENSE
├── index.tpl
├── package.json
├── README.md
├── vue.config.js
└── public
└── fullpage.min.css
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | }
--------------------------------------------------------------------------------
/src/assets/tip/help/project.md:
--------------------------------------------------------------------------------
1 | 1. 每个项目存在很多页面
2 | 2. 不知道说啥
3 |
4 |
--------------------------------------------------------------------------------
/src/store/getters.js:
--------------------------------------------------------------------------------
1 | export const getTwoNav = state => {
2 | }
3 |
--------------------------------------------------------------------------------
/src/store/lng/en.js:
--------------------------------------------------------------------------------
1 | var Lng = {
2 | common: {}
3 | }
4 | export default Lng
5 |
--------------------------------------------------------------------------------
/src/assets/tip/help/body.md:
--------------------------------------------------------------------------------
1 | ##### body 参数说明
2 | 一般在POST,PUT,PATCH 等操作的时候通过body传递整块的数据
--------------------------------------------------------------------------------
/src/assets/tip/requestparams/body.md:
--------------------------------------------------------------------------------
1 | ##### body 参数说明
2 | 一般在POST,PUT,PATCH 等操作的时候通过body传递整块的数据
--------------------------------------------------------------------------------
/src/assets/image/jt.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ymm-tech/gods-pen-admin/HEAD/src/assets/image/jt.png
--------------------------------------------------------------------------------
/src/assets/tip/requestparams/path.md:
--------------------------------------------------------------------------------
1 | ##### path 参数说明
2 | 一般在url上 例如 http://xxx/xx/:id 其中id的参数就是path替换的地方
--------------------------------------------------------------------------------
/src/assets/image/comp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ymm-tech/gods-pen-admin/HEAD/src/assets/image/comp.png
--------------------------------------------------------------------------------
/src/assets/image/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ymm-tech/gods-pen-admin/HEAD/src/assets/image/logo.png
--------------------------------------------------------------------------------
/src/assets/image/noImg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ymm-tech/gods-pen-admin/HEAD/src/assets/image/noImg.png
--------------------------------------------------------------------------------
/src/assets/image/audioImg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ymm-tech/gods-pen-admin/HEAD/src/assets/image/audioImg.png
--------------------------------------------------------------------------------
/src/assets/image/javascr.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ymm-tech/gods-pen-admin/HEAD/src/assets/image/javascr.jpg
--------------------------------------------------------------------------------
/src/assets/image/login/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ymm-tech/gods-pen-admin/HEAD/src/assets/image/login/1.png
--------------------------------------------------------------------------------
/src/assets/tip/help/baseObject.md:
--------------------------------------------------------------------------------
1 | 基础对象
2 | 基础对象可以理解为该项目的常用MODEL对象。可以导入项目中的model对象到基础对象中方便后续再页面数据返回的的时候快速使用已经定义好的对象
--------------------------------------------------------------------------------
/src/assets/image/Arrow_Down.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ymm-tech/gods-pen-admin/HEAD/src/assets/image/Arrow_Down.png
--------------------------------------------------------------------------------
/src/assets/image/project/qr.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ymm-tech/gods-pen-admin/HEAD/src/assets/image/project/qr.png
--------------------------------------------------------------------------------
/src/assets/image/view-source.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ymm-tech/gods-pen-admin/HEAD/src/assets/image/view-source.gif
--------------------------------------------------------------------------------
/src/assets/image/group/default.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ymm-tech/gods-pen-admin/HEAD/src/assets/image/group/default.png
--------------------------------------------------------------------------------
/src/assets/tip/requestparams/query.md:
--------------------------------------------------------------------------------
1 | ##### query 参数说明
2 | 一般在GET 等操作的时候在地址上的查询参数值,例如 http://xxx/index.html?id=1&k=2 中的 id和k等参数值
--------------------------------------------------------------------------------
/src/assets/image/header/default.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ymm-tech/gods-pen-admin/HEAD/src/assets/image/header/default.png
--------------------------------------------------------------------------------
/src/assets/image/project/folder.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ymm-tech/gods-pen-admin/HEAD/src/assets/image/project/folder.png
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | comments: true,
3 | presets: [
4 | ['@vue/app', {useBuiltIns: false}]
5 | ]
6 | }
7 |
--------------------------------------------------------------------------------
/src/assets/data/group_new:
--------------------------------------------------------------------------------
1 | {
2 | "visibilitylevel":1,
3 | "description":"描述",
4 | "img":"url",
5 | "name":"项目名称",
6 | "id":12
7 | }
--------------------------------------------------------------------------------
/src/assets/image/project/cover-media.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ymm-tech/gods-pen-admin/HEAD/src/assets/image/project/cover-media.jpg
--------------------------------------------------------------------------------
/src/assets/image/project/cover-other.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ymm-tech/gods-pen-admin/HEAD/src/assets/image/project/cover-other.jpg
--------------------------------------------------------------------------------
/src/assets/tip/help/group.md:
--------------------------------------------------------------------------------
1 | 1. 所有项目都会在一个项目组里面。
2 | 2. 每个人在组里面有不同的权限
3 | 创建者: 可以管理组里面的人和组的基本信息,并且在该组的项目里面有管理员的权限
4 | 管理员: 在该组项目中有管理员权限
5 | 开发者: 在该组项目中有开发者权限
6 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | # Created by .ignore support plugin (hsz.mobi)
2 | dist/
3 | src/assets/
4 | src/assets/js/
5 | src/components/PageRouter.vue
6 | src/components/Dialogs.vue
7 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.log
2 | .cache
3 | .DS_Store
4 | .idea
5 | build
6 | dist
7 | node_modules
8 | .gitkeep
9 | converage
10 | yarn-error.log
11 | npm-debug.log
12 | .yarnclean
13 | src/config/docker.js
--------------------------------------------------------------------------------
/src/config/default.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | VIEW_PATH: 'view',
3 | ADMIN_PATH: 'admin',
4 | EDITOR_PATH: 'editor',
5 | API_PATH: 'api',
6 | EDITOR_TITLE: '编辑器',
7 | ADMIN_TITLE: '管理后台',
8 | BAIDU_TONGJI: ''
9 | }
10 |
--------------------------------------------------------------------------------
/src/assets/data/user.json:
--------------------------------------------------------------------------------
1 | {
2 | "code":1,
3 | "list":[1,1,1],
4 | "data":{
5 | "id":12,
6 | "name":"王坤明",
7 | "email":"fdsa@qq.com",
8 | "account":"stoneship",
9 | "createTime":1481870187006,
10 | "updateTime":1481870187006
11 | }
12 | }
13 |
14 |
15 |
--------------------------------------------------------------------------------
/src/config/production.js:
--------------------------------------------------------------------------------
1 | /*
2 | * 对于三个web项目,在构建阶段,web项目不再需要启动本地服务,一般来说,
3 | * 构建完成后会将所有静态资源文件部署在同一个(nginx)服务下,因此,
4 | * web项目的默认访问路径就是域名加项目名,如 xxxx.com/admin,
5 | * xxxx.com/editor,如无更名要求,无需再配置
6 | *
7 | * 对于 api 服务,服务启动以后,本地/内部访问地址为 http://127.0.0.1:7051/api,
8 | * 如果最终能通过 nginx 反代等操作使之与 web 服务同域名同端口号,
9 | * 则可以保持以下配置(无需配置)即可,否则,请将 API_PATH 配置为 api 服务外部实际访
10 | * 问路径,如 http://abc.125:7051/api
11 | */
12 |
13 | module.exports = {
14 | }
15 |
--------------------------------------------------------------------------------
/src/config/local.js:
--------------------------------------------------------------------------------
1 | /*
2 | * 在本地开发调试时,三个web项目和一个node项目都是在独立运行的
3 | * 因此需要配置每个服务的本地访问地址,以使能互相调用/请求
4 | * admin、editor、view、api 四个服务的默认端口号分别为
5 | * 8567、8565、8566、7051,因此默认配置如下
6 | */
7 |
8 | module.exports = {
9 | ADMIN_PATH: 'http://127.0.0.1:8567/', // 管理后台访问地址
10 | EDITOR_PATH: 'http://127.0.0.1:8565/', // 编辑器访问地址
11 | VIEW_PATH: 'http://127.0.0.1:8566/', // 页面客户端访问地址
12 | API_PATH: 'http://127.0.0.1:7051/api', // api 服务端访问地址
13 | }
14 |
--------------------------------------------------------------------------------
/src/login.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import ElementUI from 'element-ui'
3 | import Login from './login.vue'
4 | import EmaProxy from 'ema-proxy'
5 | import 'element-ui/lib/theme-chalk/index.css'
6 | require('./assets/js/base')
7 | window.EMA = new EmaProxy()
8 | require('./assets/style/base.css')
9 |
10 | Vue.use(ElementUI)
11 | Vue.config.devtools = !(process.env.NODE_ENV === 'production')
12 |
13 | new Vue({
14 | el: '#app',
15 | render: h => h(Login)
16 | })
17 |
--------------------------------------------------------------------------------
/src/emailActive.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import ElementUI from 'element-ui'
3 | import emailActive from './emailActive.vue'
4 | import 'element-ui/lib/theme-chalk/index.css'
5 | require('./assets/js/base')
6 | require('./assets/style/base.css')
7 | import EmaProxy from 'ema-proxy'
8 | window.EMA = new EmaProxy()
9 |
10 | Vue.use(ElementUI)
11 | Vue.config.devtools = !(process.env.NODE_ENV === 'production')
12 |
13 | new Vue({
14 | el: '#app',
15 | render: h => h(emailActive)
16 | })
17 |
--------------------------------------------------------------------------------
/src/assets/data/content.yaml:
--------------------------------------------------------------------------------
1 | path: /name
2 | type: get
3 | description: 获取用户姓名
4 | parameters:
5 | id: int|用户id
6 | name: string|用户姓名
7 | responses:
8 | 200:
9 | pageSize: int
10 | list:
11 | - name: int|描述
12 | url: string|描述
13 | pets:
14 | - $ref: $Pet
15 | age: int
16 | 500:
17 | code: int
18 | error: string
19 | definitions:
20 | Pet:
21 | product_id: string|Unique identifier
22 | description: string|Description of product.
23 |
--------------------------------------------------------------------------------
/src/updatePassword.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import ElementUI from 'element-ui'
3 | import updatePassword from './updatePassword.vue'
4 | import 'element-ui/lib/theme-chalk/index.css'
5 | require('./assets/js/base')
6 | require('./assets/style/base.css')
7 | import EmaProxy from 'ema-proxy'
8 | window.EMA = new EmaProxy()
9 |
10 | Vue.use(ElementUI)
11 | Vue.config.devtools = !(process.env.NODE_ENV === 'production')
12 |
13 | new Vue({
14 | el: '#app',
15 | render: h => h(updatePassword)
16 | })
17 |
--------------------------------------------------------------------------------
/src/assets/data/group_list:
--------------------------------------------------------------------------------
1 | {
2 | "pageSize": "12",
3 | "list": [
4 | {
5 | "visibilitylevel":1,
6 | "description":"描述",
7 | "img":"http://secure.gravatar.com/avatar/fc5654afbe167b98e93674175607b80e?s=52&d=identicon",
8 | "name":"项目名称",
9 | "member":12,
10 | "role":1
11 | },
12 | {
13 | "visibilitylevel":1,
14 | "description":"描述",
15 | "img":"http://secure.gravatar.com/avatar/fc5654afbe167b98e93674175607b80e?s=52&d=identicon",
16 | "name":"项目名2称",
17 | "member":12,
18 | "role":2
19 | }
20 | ]
21 | }
22 |
--------------------------------------------------------------------------------
/src/assets/data/apis.json:
--------------------------------------------------------------------------------
1 | {
2 | "list": [
3 | {
4 | "createTime":1481870187006,
5 | "updateTime":1481870187006,
6 | "version":"1.1.2",
7 | "content":"",
8 | "path":"/home/user",
9 | "type":"get",
10 | "desc":"好多联系哈哈",
11 | "pid":10,
12 | "id":12
13 | },
14 | {
15 | "createTime":1481870187006,
16 | "updateTime":1481870187006,
17 | "version":"1.1.2",
18 | "content":"",
19 | "path":"/home/add",
20 | "type":"post",
21 | "desc":"好多联系哈哈",
22 | "pid":10,
23 | "id":12
24 | }
25 | ]
26 | }
27 |
--------------------------------------------------------------------------------
/src/config/index.js:
--------------------------------------------------------------------------------
1 | const defaultConfig = require('./default')
2 |
3 | let config = Object.assign(defaultConfig, require('./' + (process.env.CODE_ENV || 'local')))
4 |
5 | ;['VIEW_PATH', 'ADMIN_PATH', 'EDITOR_PATH', 'API_PATH'].map(k => {
6 | if (config[k] === '/') return
7 | if (/^(https?:)?\/\//.test(config[k])) {
8 | config[k] = config[k].replace(/\/*$/, '/')
9 | } else {
10 | config[k] = config[k].replace(/^\/*|\/*$/g, '/')
11 | }
12 | })
13 |
14 | config.ADMIN_NAME = process.env.NODE_ENV === 'development' ? '' : (config.ADMIN_PATH.match(/([^/]+)\/?$/) || ['', 'admin'])[1]
15 |
16 | config.enableGithub = config.github && config.github.clientId && config.github.clientSecret
17 |
18 | module.exports = config
19 |
--------------------------------------------------------------------------------
/login.tpl:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | <%= htmlWebpackPlugin.options.title %>
7 |
8 |
9 |
10 | <% if (/^[0-9a-zA-Z]{10,}$/.test(htmlWebpackPlugin.options.hmid)) { %>
11 |
12 | <% } %>
13 | <% if (process.env.NODE_ENV === 'production') { %>
14 |
15 | <% } %>
16 |
17 |
18 |
--------------------------------------------------------------------------------
/emailActive.tpl:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | <%= htmlWebpackPlugin.options.title %>
7 |
8 |
9 |
10 | <% if (/^[0-9a-zA-Z]{10,}$/.test(htmlWebpackPlugin.options.hmid)) { %>
11 |
12 | <% } %>
13 | <% if (process.env.NODE_ENV === 'production') { %>
14 |
15 | <% } %>
16 |
17 |
18 |
--------------------------------------------------------------------------------
/updatePassword.tpl:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | <%= htmlWebpackPlugin.options.title %>
7 |
8 |
9 |
10 | <% if (/^[0-9a-zA-Z]{10,}$/.test(htmlWebpackPlugin.options.hmid)) { %>
11 |
12 | <% } %>
13 | <% if (process.env.NODE_ENV === 'production') { %>
14 |
15 | <% } %>
16 |
17 |
18 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | parserOptions: {
4 | sourceType: 'module',
5 | "allowImportExportEverywhere": true
6 | },
7 | // https://github.com/feross/standard/blob/master/RULES.md#javascript-standard-style
8 | extends: 'standard',
9 | // required to lint *.vue files
10 | plugins: [
11 | 'html'
12 | ],
13 | // add your custom rules here
14 | 'rules': {
15 | "indent": 0,
16 | "no-multi-spaces": 0,
17 | "no-eval": 0,
18 | "no-new": 0,
19 | // allow paren-less arrow functions
20 | 'arrow-parens': 0,
21 | // allow debugger during development
22 | 'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0,
23 | "eqeqeq": 0,//必须使用全等
24 | "comma-dangle": [ 2, "only-multiline" ] //定义数组或对象最后多余的逗号
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/components/Footer.vue:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
13 |
28 |
29 |
--------------------------------------------------------------------------------
/src/RouterMap.js:
--------------------------------------------------------------------------------
1 | import PageRouter from './components/PageRouter.vue'
2 | const config = require('./config/index.js')
3 | var map = {
4 | mode: 'hash',
5 | base: '/' + config.ADMIN_NAME,
6 | routes: [
7 | {
8 | path: '/:name/:name1/:name2/:name3/:name4/name5',
9 | component: PageRouter
10 | },
11 | {
12 | path: '/:name/:name1/:name2/:name3/:name4',
13 | component: PageRouter
14 | },
15 | {
16 | path: '/:name/:name1/:name2/:name3',
17 | component: PageRouter
18 | },
19 | {
20 | path: '/:name/:name1/:name2',
21 | component: PageRouter
22 | },
23 | {
24 | path: '/:name/:name1',
25 | component: PageRouter
26 | },
27 | {
28 | path: '/:name',
29 | component: PageRouter
30 | },
31 | {
32 | path: '/',
33 | redirect: '/home'
34 | }
35 | ]
36 | }
37 | export default map
38 |
--------------------------------------------------------------------------------
/src/components/User/Item.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
{{item.name}}
8 |
9 |
10 |
11 |
12 |
16 |
36 |
37 |
--------------------------------------------------------------------------------
/src/store/mutations.js:
--------------------------------------------------------------------------------
1 | export const initMenuData = (state, data) => {
2 | state.app.menuData = data
3 | }
4 | export const initUserInfo = (state, data) => {
5 | state.userInfo = { ...state.userInfo,
6 | ...data
7 | }
8 | }
9 |
10 | export const changeActiveIndex = (state, data) => {
11 | // 通过更新子节点修改对应导航的列表信息
12 | state.app.activeIndex = data
13 | }
14 |
15 | export const changeNavIndex = (state, data) => {
16 | state.app.navIndex = data || 0
17 | }
18 |
19 | export const changeNavTwoIndex = (state, data) => {
20 | state.app.navTwoIndex = data || 0
21 | }
22 |
23 | export const updataTheme = (state, data) => {
24 | Object.assign(state.app.theme, data)
25 | window.localStorage.setItem('theme', JSON.stringify(state.app.theme))
26 | }
27 |
28 | export const changeAppSize = (state, data) => {
29 | if (data.width) {
30 | state.app.size.width = data.width
31 | }
32 | if (data.height) {
33 | state.app.size.height = data.height
34 | }
35 | }
36 | export const initCategorys = (state, data) => {
37 | state.Categorys = data
38 | }
39 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 Full Truck Alliance
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/src/emailActive.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
8 |
9 |
37 |
--------------------------------------------------------------------------------
/src/store/index.js:
--------------------------------------------------------------------------------
1 | import Vuex from 'vuex'
2 | import Vue from 'vue'
3 | import Metadata from 'src/store/metadata'
4 | import Lng from 'src/store/lng/en'
5 | import * as getters from './getters'
6 | import * as actions from './actions'
7 | import * as mutations from './mutations'
8 | var packageInfo = require('../../package.json')
9 | const debug = process.env.NODE_ENV !== 'production'
10 | if (debug) {
11 | Vue.use(Vuex)
12 | }
13 | // 初始化主题信息
14 | var theme = {
15 | isOpen: false,
16 | isLock: true
17 | }
18 | var localTheme = window.localStorage.getItem('theme')
19 | if (localTheme) {
20 | Object.assign(theme, JSON.parse(localTheme))
21 | }
22 | const state = {
23 | app: {
24 | theme: theme, // 应用主题信息。
25 | packageInfo,
26 | navIndex: 0, // 导航索引
27 | navTwoIndex: 0, // 导航索引
28 | activeIndex: null, // 当前被选中的页面唯一编号id,
29 | size: {
30 | width: 0,
31 | height: 0
32 | },
33 | menuData: [] // 功能菜单列表信息
34 | },
35 | Lng: Lng,
36 | userInfo: {},
37 | Categorys: [],
38 | Metadata
39 | }
40 |
41 | export default new Vuex.Store({
42 | strict: debug,
43 | state,
44 | actions,
45 | getters: getters,
46 | mutations
47 | })
48 |
--------------------------------------------------------------------------------
/src/dialog/DAddGroup.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
8 |
9 |
10 |
24 |
51 |
52 |
--------------------------------------------------------------------------------
/src/dialog/DGroupsNew.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
11 |
52 |
53 |
--------------------------------------------------------------------------------
/src/pages/projects/new.vue:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
13 |
24 |
25 |
52 |
--------------------------------------------------------------------------------
/src/assets/data/editorSetting.json:
--------------------------------------------------------------------------------
1 | {
2 | "selectionStyle": "line",
3 | "highlightActiveLine": true,
4 | "highlightSelectedWord": true,
5 | "readOnly": false,
6 | "cursorStyle": "ace",
7 | "mergeUndoDeltas": true,
8 | "behavioursEnabled": true,
9 | "wrapBehavioursEnabled": true,
10 | "hScrollBarAlwaysVisible": false,
11 | "vScrollBarAlwaysVisible": false,
12 | "highlightGutterLine": true,
13 | "animatedScroll": false,
14 | "showInvisibles": false,
15 | "showPrintMargin": true,
16 | "printMarginColumn": 80,
17 | "printMargin": 80,
18 | "fadeFoldWidgets": false,
19 | "showFoldWidgets": true,
20 | "showLineNumbers": true,
21 | "showGutter": true,
22 | "displayIndentGuides": true,
23 | "fontSize": 14,
24 | "scrollPastEnd": 0,
25 | "theme": "ace/theme/solarized_dark",
26 | "scrollSpeed": 2,
27 | "dragDelay": 150,
28 | "dragEnabled": true,
29 | "focusTimout": 0,
30 | "tooltipFollowsMouse": true,
31 | "firstLineNumber": 1,
32 | "overwrite": false,
33 | "newLineMode": "auto",
34 | "useWorker": true,
35 | "useSoftTabs": true,
36 | "tabSize": 2,
37 | "wrap": "free",
38 | "indentedSoftWrap": true,
39 | "mode": "ace/mode/yaml",
40 | "enableMultiselect": true,
41 | "enableBlockSelect": true,
42 | "enableBasicAutocompletion": true,
43 | "enableSnippets": true,
44 | "enableLiveAutocompletion": true
45 | }
--------------------------------------------------------------------------------
/src/extend/BaseComponent.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by stone on 2016/6/23.
3 | */
4 | export default {
5 | replace: true,
6 | data: function () {
7 | return {}
8 | },
9 | // 组件是你刚被创建,组件属性计算前
10 | beforeCreated: function () {
11 | },
12 | // 组件创建完成,属性已绑定,但是dom还没生产,$el还不存在
13 | created: function () {
14 | this.ema = window.EMA.getProxy()
15 | },
16 | // 模板编译挂载前
17 | beforeMount: function () {
18 | },
19 | // 模板编译挂载之后,不保证组件已经在document中。
20 | mounted: function () {
21 | },
22 | // 组件更新之前
23 | beforeUpdate: function () {
24 | },
25 | // 组件更新之后
26 | updated: function () {
27 | },
28 | // keep-alive 会用到
29 | // 组件被激活
30 | activated: function () {
31 | },
32 | // 组件被移除
33 | deactivated: function () {
34 | },
35 | beforDestroy: function () {
36 | },
37 | destroyed: function () {
38 | this.ema.dispose()
39 | },
40 | methods: {
41 | /**
42 | * 组件内部范围绑定事件
43 | * @param key
44 | * @param fn
45 | */
46 | bindEvent: function (key, fn) {
47 | if (!this.$options.name) {
48 | }
49 | this.ema.bind(`${this.$options.name}.${key}`, fn)
50 | },
51 | /**
52 | * 打开一个弹出框
53 | * @param data
54 | * {
55 | * name:'', //弹出框名称,dialog目录下弹出框名称
56 | * data:{}, //传给弹出框的基础数据 data能包含数据
57 | * methods:{} //传给弹出框的基础方法。方便回调等操作
58 | * }
59 | */
60 | openDialog: function (data) {
61 | this.ema.fire('Dialogs.push', data)
62 | }
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/index.tpl:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | <%= htmlWebpackPlugin.options.title %>
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | <% if (/^[0-9a-zA-Z]{10,}$/.test(htmlWebpackPlugin.options.hmid)) { %>
18 |
19 | <% } %>
20 | <% if (process.env.NODE_ENV === 'production') { %>
21 |
22 |
23 |
24 | <% } %>
25 |
26 |
27 |
--------------------------------------------------------------------------------
/src/components/Content.vue:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
12 |
13 |
50 |
51 |
--------------------------------------------------------------------------------
/src/assets/js/metadata.js:
--------------------------------------------------------------------------------
1 | //中心内容块
2 | export const contentPart = {
3 | 1: {
4 | name: '项目权限清晰',
5 | description: '类 gitlab 权限管理体系',
6 | img: require('../image/login/1.png')
7 | },
8 | 2: {
9 | name: '编辑操作高效',
10 | description: '拖拽挪移,随心所欲',
11 | img: require('../image/login/1.png')
12 | },
13 | 3: {
14 | name: '组件接入简单',
15 | description: '命令行工具一条龙服务',
16 | img: require('../image/login/1.png')
17 | },
18 | 4: {
19 | name: '分发机制健全',
20 | description: '短链、二维码、分享能力应有尽有',
21 | img: require('../image/login/1.png')
22 | },
23 | }
24 |
25 | // 底部区域块
26 | export const footerPart = {
27 | 1: {
28 | title: '相关资源',
29 | list: [
30 | {
31 | name: '码良脚手架',
32 | des: '',
33 | link: 'https://github.com/ymm-tech/gods-pen-cli'
34 | },
35 | {
36 | name: '码良部署',
37 | des: '',
38 | link: 'https://github.com/ymm-tech/gods-pen-docker'
39 | },
40 | {
41 | name: '码良文档',
42 | des: '',
43 | link: 'https://github.com/ymm-tech/gods-pen-doc'
44 | }
45 | ]
46 | },
47 | 2: {
48 | title: '社区',
49 | list: [
50 | // {
51 | // name: '在线讨论',
52 | // link: 'http://www.baidu.com'
53 | // },
54 | {
55 | name: '错误反馈',
56 | link: 'https://github.com/ymm-tech/gods-pen/issues'
57 | },
58 | ]
59 | },
60 | 3: {
61 | title: '关于我们',
62 | list: [
63 | {
64 | name: '运满满',
65 | link: 'http://www.ymm56.com/'
66 | }
67 | ]
68 | }
69 | }
--------------------------------------------------------------------------------
/src/pages/404.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
404
4 |
5 |
页面找不到了
6 |
7 | 回到首页
8 |
9 |
10 |
11 |
12 |
13 |
65 |
66 |
73 |
--------------------------------------------------------------------------------
/src/pages/noPage.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
404
4 |
5 |
页面找不到了
6 |
7 | 回到首页
8 |
9 |
10 |
11 |
12 |
13 |
65 |
66 |
73 |
--------------------------------------------------------------------------------
/src/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import ElementUI from 'element-ui'
3 | import App from './app'
4 | import VueRouter from 'vue-router'
5 | import 'element-ui/lib/theme-chalk/index.css'
6 | import EmaProxy from 'ema-proxy'
7 | import store from './store'
8 | require('./assets/js/base')
9 | require('./extend/filter')
10 | require('./assets/style/base.css')
11 | import * as monaco from 'monaco-editor'
12 | import vuelint from './assets/js/vuelint'
13 | import routerMap from './RouterMap'
14 |
15 | Vue.use(ElementUI)
16 | Vue.use(VueRouter)
17 | Vue.config.devtools = !(process.env.NODE_ENV === 'production')
18 |
19 | const router = new VueRouter(routerMap)
20 | window.router = router
21 | let appData = {
22 | el: '#app',
23 | store: store,
24 | router: router,
25 | render: h => h(App)
26 | }
27 |
28 | window.EMA = new EmaProxy()
29 |
30 | // 脚本编辑器配置自动提醒
31 | monaco.languages.registerCompletionItemProvider('javascript', {
32 | provideCompletionItems: () => {
33 | return vuelint || []
34 | }
35 | })
36 |
37 | monaco.editor.defineTheme('maliang', {
38 | base: 'vs',
39 | inherit: true,
40 | rules: [
41 | { token: 'keyword', foreground: '001dbf' },
42 | { token: 'string', foreground: '42a071' },
43 | { token: 'comment.js', fontStyle: 'italic', foreground: '93A1A1' },
44 | { token: 'delimiter.bracket.js', foreground: 'd63300' },
45 | { token: 'delimiter.parenthesis.js', foreground: 'd63300' },
46 | // { token: '', background: 'fefaef', foreground: '657B83'},
47 | // { token: 'identifier.js', foreground: '061232' },
48 | ],
49 | colors: {
50 | 'editor.lineHighlightBackground': '#cccccc35',
51 | // 'editor.foreground': '#657B83',
52 | // 'editor.background': '#fefaef',
53 | }
54 | })
55 |
56 | export default new Vue(appData)
57 |
--------------------------------------------------------------------------------
/src/pages/groups/new.vue:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
13 |
24 |
25 |
69 |
--------------------------------------------------------------------------------
/src/extend/Server.js:
--------------------------------------------------------------------------------
1 | import axios from 'axios'
2 | const config = require('../config')
3 |
4 | let instance = axios.create({
5 | baseURL: config.API_PATH,
6 | timeout: 30000,
7 | headers: {},
8 | withCredentials: true,
9 | needLoading: false, // 是否需要加载效果
10 | ignoreCode: false // 是否忽略服务端的错误提示
11 | })
12 |
13 | instance.interceptors.request.use(function (config) {
14 | if (config.needLoading) {
15 | window.EMA.fire('loading.show')
16 | }
17 | return config
18 | }, function (error) {
19 | return Promise.reject(error)
20 | })
21 |
22 | instance.interceptors.response.use(function (response) {
23 | if (response.config.needLoading) {
24 | window.EMA.fire('loading.hide')
25 | }
26 | var code = response.data.code
27 | if (response.data.code && response.data.code != 1 && !response.config.ignoreCode) {
28 | switch (code) {
29 | case 999:
30 | window.EMA.fire('alert.show', '用户认证失败,重新登录', function () {
31 | window.EMA.fire('logout')
32 | })
33 | break
34 | default:
35 | window.EMA.fire('alert.show', response.data.msg, function () {})
36 | }
37 | throw new Error(response)
38 | } else {
39 | return response
40 | }
41 | }, function (error) {
42 | window.console.log(error)
43 | var status = error.response.status
44 | var message = error.message
45 | if (status != 200) {
46 | if (status == 401) {
47 | window.EMA.fire('alert.show', '用户认证失败,重新登录', function () {
48 | window.EMA.fire('logout')
49 | })
50 | } else if (status == 403) {
51 | window.EMA.fire('alert.show', '用户无权限,重新登录', function () {
52 | window.EMA.fire('logout')
53 | })
54 | } else if (status == 422) {
55 | window.EMA.fire('alert.show', '传递参数错误', function () {})
56 | } else {
57 | window.EMA.fire('alert.show', message, function () {})
58 | }
59 | }
60 | return Promise.reject(error)
61 | })
62 |
63 | export default instance
64 |
--------------------------------------------------------------------------------
/src/pages/user.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
18 |
19 |
20 | {{info.name}}
21 |
22 |
23 |
24 | 邮箱:{{info.email}}
25 |
26 |
27 |
28 | 电话:{{info.telephone}}
29 |
30 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
45 |
46 |
78 |
--------------------------------------------------------------------------------
/src/store/actions.js:
--------------------------------------------------------------------------------
1 | var findMenuByKey = function (data, key, path) {
2 | if (data && data.length) {
3 | for (var i = 0; i < data.length; i++) {
4 | var val = data[i]
5 | if (val.resKey == key) {
6 | return {
7 | path: path,
8 | value: val
9 | }
10 | } else {
11 | var res = findMenuByKey(val.child, key, path.concat([i]))
12 | if (res) {
13 | return res
14 | }
15 | }
16 | }
17 | }
18 | }
19 |
20 | export const updataTheme = ({
21 | commit
22 | }, data) => {
23 | commit('updataTheme', data)
24 | }
25 |
26 | /**
27 | *
28 | * @param context
29 | */
30 | export const initUserInfo = ({
31 | commit
32 | }, data) => {
33 | commit('initUserInfo', data)
34 | }
35 | /**
36 | *
37 | * @param context
38 | */
39 | export const initMenuData = ({
40 | commit
41 | }, data) => {
42 | commit('initMenuData', data)
43 | }
44 |
45 | /**
46 | *
47 | * @param context
48 | */
49 | export const changeActiveIndex = ({
50 | state,
51 | commit
52 | }, data) => {
53 | var info = findMenuByKey(state.app.menuData, data, [])
54 | console.log('info', info)
55 | if (!info) {
56 | return
57 | }
58 | commit('changeNavIndex', info.path[0])
59 | commit('changeNavTwoIndex', info.path[1])
60 | setTimeout(function () {
61 | commit('changeActiveIndex', data)
62 | }, 100)
63 | }
64 |
65 | /**
66 | *
67 | * @param context
68 | */
69 | export const changeNavIndex = ({
70 | commit
71 | }, data) => {
72 | commit('changeNavIndex', data)
73 | }
74 |
75 | /**
76 | *
77 | * @param context
78 | */
79 | export const changeNavTwoIndex = ({
80 | commit
81 | }, data) => {
82 | commit('changeNavTwoIndex', data)
83 | }
84 |
85 | /**
86 | *
87 | * @param context
88 | */
89 | export const changeAppSize = ({
90 | commit
91 | }, data) => {
92 | commit('changeAppSize', data)
93 | }
94 |
95 | export const initAllCategory = ({
96 | commit
97 | }, data) => {
98 | commit('initCategorys', data)
99 | }
100 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "gods-pen-admin",
3 | "version": "1.0.0",
4 | "description": "码良管理后台",
5 | "private": false,
6 | "keywords": [],
7 | "scripts": {
8 | "dev": "cross-env CODE_ENV=local vue-cli-service serve",
9 | "build": "cross-env CODE_ENV=production vue-cli-service build",
10 | "build-docker": "cross-env CODE_ENV=docker vue-cli-service build"
11 | },
12 | "license": "ISC",
13 | "dependencies": {
14 | "axios": "^0.15.2",
15 | "babel-polyfill": "*",
16 | "caniuse-lite": "^1.0.0",
17 | "clipboard": "^1.5.16",
18 | "cross-env": "^3.1.3",
19 | "crypto-js": "^3.1.8",
20 | "dayjs": "^1.5.22",
21 | "deep-assign": "^2.0.0",
22 | "element-theme": "^0.7.1",
23 | "element-theme-default": "^1.2.3",
24 | "element-ui": "^2.3.6",
25 | "ema-proxy": "^1.0.1",
26 | "eslint-plugin-html": "^1.6.0",
27 | "global": "^4.3.2",
28 | "interface-import-javabean": "^1.0.0",
29 | "js-cookie": "^2.1.4",
30 | "js-yaml": "^3.7.0",
31 | "loader-utils": "^1.1.0",
32 | "lodash": "^4.17.4",
33 | "markdown-loader": "4.0.0",
34 | "monaco-editor": "^0.14.3",
35 | "monaco-editor-webpack-plugin": "^1.5.2",
36 | "qs": "^6.3.1",
37 | "title-notify": "^1.0.13",
38 | "vue": "^2.5.16",
39 | "vue-clipboards": "^1.1.0",
40 | "vue-echarts": "^3.0.7",
41 | "vue-router": "^2.0.1",
42 | "vue-template-compiler": "^2.5.16",
43 | "vuex": "^2.1.1"
44 | },
45 | "devDependencies": {
46 | "@vue/cli-plugin-babel": "^3.1.1",
47 | "@vue/cli-plugin-eslint": "^3.1.1",
48 | "@vue/cli-service": "^3.1.1",
49 | "cross-env": "^3.1.3",
50 | "eslint": "^3.9.1",
51 | "eslint-config-standard": "^6.2.1",
52 | "eslint-plugin-promise": "^3.4.0",
53 | "eslint-plugin-standard": "^2.0.1",
54 | "html-loader": "0.5.5",
55 | "less": "3.9.0",
56 | "less-loader": "4.0.6",
57 | "stylus": "^0.54.5",
58 | "stylus-loader": "3.0.2"
59 | },
60 | "postcss": {
61 | "plugins": {
62 | "autoprefixer": {}
63 | }
64 | },
65 | "browserslist": [
66 | "> 1%",
67 | "last 2 versions",
68 | "not ie <= 8"
69 | ]
70 | }
71 |
--------------------------------------------------------------------------------
/src/assets/data/project.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "name": "id",
4 | "require": "true",
5 | "type": "string",
6 | "mock": "@id",
7 | "description": ""
8 | },
9 | {
10 | "name": "name",
11 | "require": "true",
12 | "type": "string",
13 | "mock": "@cname",
14 | "description": ""
15 | },
16 | {
17 | "name": "description",
18 | "require": "true",
19 | "type": "string",
20 | "mock": "@url",
21 | "description": ""
22 | },
23 | {
24 | "name": "version",
25 | "require": "true",
26 | "type": "string",
27 | "mock": "@email",
28 | "description": ""
29 | },
30 | {
31 | "name": "createTime",
32 | "require": "true",
33 | "type": "number",
34 | "mock": "",
35 | "description": ""
36 | },
37 | {
38 | "name": "cat",
39 | "require": "true",
40 | "type": "object",
41 | "mock": "",
42 | "description": "",
43 | "child": [
44 | {
45 | "name": "id",
46 | "require": "true",
47 | "type": "number",
48 | "mock": "@image",
49 | "description": ""
50 | }
51 | ]
52 | },
53 | {
54 | "name": "apis",
55 | "require": "true",
56 | "type": "array",
57 | "mock": "|5",
58 | "description": "",
59 | "child": [
60 | {
61 | "name": "createTime",
62 | "require": "true",
63 | "type": "number",
64 | "mock": "@data",
65 | "description": ""
66 | },
67 | {
68 | "name": "updateTime",
69 | "require": "true",
70 | "type": "number",
71 | "mock": "@image",
72 | "description": ""
73 | },
74 | {
75 | "name": "version",
76 | "require": "true",
77 | "type": "string",
78 | "mock": "",
79 | "description": ""
80 | },
81 | {
82 | "name": "content",
83 | "require": "true",
84 | "type": "string",
85 | "mock": "",
86 | "description": ""
87 | },
88 | {
89 | "name": "id",
90 | "require": "true",
91 | "type": "number",
92 | "mock": "",
93 | "description": ""
94 | }
95 | ]
96 | }
97 | ]
--------------------------------------------------------------------------------
/src/components/Dialogs.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
11 |
12 |
77 |
78 |
--------------------------------------------------------------------------------
/src/extend/BasePage.js:
--------------------------------------------------------------------------------
1 | /**
2 | * 所有页面基础类
3 | */
4 | import {mapState} from 'vuex'
5 | export default {
6 | /* 父类向下传递的参数数据 */
7 | props: [],
8 | computed: mapState({
9 | packageInfo: state => state.app.packageInfo,
10 | userInfo: state => state.userInfo
11 | }),
12 | data: function () {
13 | return {}
14 | },
15 | // 组件是你刚被创建,组件属性计算前
16 | beforeCreated: function () {
17 | },
18 | // 组件创建完成,属性已绑定,但是dom还没生产,$el还不存在
19 | created: function () {
20 | this.ema = window.EMA.getProxy()
21 | },
22 | // 模板编译挂载前
23 | beforeMount: function () {
24 | },
25 | // 模板编译挂载之后,不保证组件已经在document中。
26 | mounted: function () {
27 | this.$options.initPageTitle()
28 | // 更新页面定位信息
29 | this.$store.dispatch('changeActiveIndex', this.$options.name)
30 | console.info('当前页面', this.$options.name)
31 | },
32 | // 组件更新之前
33 | beforeUpdate: function () {
34 | },
35 | // 组件更新之后
36 | updated: function () {
37 | },
38 | // keep-alive 会用到
39 | // 组件被激活
40 | activated: function () {
41 | },
42 | // 组件被移除
43 | deactivated: function () {
44 | },
45 | beforDestroy: function () {
46 | },
47 | destroyed: function () {
48 | this.ema.dispose()
49 | },
50 | initPageTitle: function () {
51 | if (this.pageName) {
52 | document.title = this.pageName
53 | }
54 | },
55 | methods: {
56 | /**
57 | * 组件内部范围绑定事件
58 | * @param key
59 | * @param fn
60 | */
61 | bindEvent: function (key, fn) {
62 | if (!this.$options.name) {
63 | console.warn('绑定事件的组件不存在组件名称', key)
64 | }
65 | this.ema.bind(`${this.$options.name}.${key}`, fn)
66 | },
67 | /**
68 | * 打开一个弹出框
69 | * @param data
70 | * {
71 | * name:'', //弹出框名称,dialog目录下弹出框名称
72 | * data:{}, //传给弹出框的基础数据 data能包含数据
73 | * methods:{} //传给弹出框的基础方法。方便回调等操作
74 | * }
75 | */
76 | openDialog: function (data) {
77 | this.ema.fire('Dialogs.push', data)
78 | },
79 | /**
80 | * 添加一个页面到当前页面,必要参数
81 | * {
82 | * name: 页面名称
83 | * data:{} 数据覆盖
84 | * methods:{} 方法覆盖
85 | * }
86 | * @param data
87 | */
88 | addPage: function (data) {
89 | this.ema.fire('Page.push', data)
90 | }
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 码良管理后台
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | ## :house: 官网
13 |
14 | 官网: https://godspen.ymm56.com/
15 |
16 | 使用手册: https://godspen.ymm56.com/doc/cookbook/introduce.html
17 |
18 | 在线体验: https://godspen.ymm56.com/admin/#/home
19 |
20 | 私有部署: https://godspen.ymm56.com/doc/cookbook/install.html
21 |
22 |
23 | 
24 |
25 |
26 | :point_right: `喜欢别忘了加star支持我们,你的支持是我们坚持的动力` :point_left:
27 |
28 | ## 项目构成
29 |
30 | 码良系统由3个项目构成,分别是 [gods-pen-server](https://github.com/ymm-tech/gods-pen-server) 码良服务端、
31 |
32 | [gods-pen-admin](https://github.com/ymm-tech/gods-pen-admin)
33 |
34 | 码良管理后台以及于7月份就已经开源的 [gods-pen](https://github.com/ymm-tech/gods-pen) 码良编辑器。
35 |
36 |
37 | ## 详细部署文档
38 |
39 | https://godspen.ymm56.com/doc/cookbook/source.html
40 |
41 | ### 安装依赖
42 |
43 | ```bash
44 | yarn
45 | ```
46 |
47 | ### 开发
48 |
49 | ```bash
50 | npm run dev
51 | ```
52 |
53 | ### 打包
54 |
55 | ``` bash
56 | npm run build
57 | ```
58 |
59 | ### 配置说明
60 |
61 | 配置文件位于 src/config/ 下,default.js 为默认配置,请不要修改
62 |
63 | 开发配置:
64 |
65 | local.js 为本地开发环境使的配置,一般情况下保持默认即可。
66 |
67 | 在本地开发调试时,三个 web 项目(admin、editor、view)和一个 node 项目(api)都是在独立运行的,因此需要配置每个服务的本地访问地址,以使项目之间能互相调用/请求,四个服务的默认端口号分别为 8567、8565、8566、7051,因此默认配置如 local.js
68 |
69 | 构建/部署配置:
70 |
71 | production.js 为构建阶段使用的配置,默认留空,全部使用了 default.js 配置,原因如下
72 |
73 | 对于三个 web 项目(admin、editor、view),在构建完成后,web 项目不在是分别启动服务,一般来说,会将所有静态资源文件部署在同一个(nginx)服务下,因此,web 项目的访问路径就是域名加项目名,如 xxxx.com/admin,xxxx.com/editor, 如无更换一级路径要求,无需再进行配置
74 |
75 | 对于 api 服务,服务启动以后,本地/内部访问地址为 http://127.0.0.1:7051/api, 如果最终能通过 nginx 反代等操作使之与 web 服务**同域名同端口**号,则也可以不用配置 API_PATH。否则,请将 API_PATH 配置为 api 服务**外部实际访问路径**,如 http://xxxx.com:7051/api
76 |
77 | 总之,所有的 XX_PATH 配置都应该与实际访问地址一致,其中特殊的是在与本服务同端口同域名时,可写成相对地址(即默认配置的值)。
78 |
--------------------------------------------------------------------------------
/src/extend/BaseDialog.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by stone on 2016/6/23.
3 | */
4 | export default {
5 | replace: true,
6 | data: function () {
7 | return {
8 | title: '',
9 | size: 'small',
10 | Visible: true // 弹出框显示状态
11 | }
12 | },
13 | // 组件是你刚被创建,组件属性计算前
14 | beforeCreated: function () {
15 | console.log('dialog---beforeCreated', this.$options.name)
16 | },
17 | // 组件创建完成,属性已绑定,但是dom还没生产,$el还不存在
18 | created: function () {
19 | this.ema = window.EMA.getProxy()
20 | console.log('dialog---created', this.$options.name)
21 | },
22 | // 模板编译挂载前
23 | beforeMount: function () {
24 | console.log('dialog---beforeMount', this.$options.name)
25 | },
26 | // 模板编译挂载之后,不保证组件已经在document中。
27 | mounted: function () {
28 | console.log('dialog---mounted', this.$options.name)
29 | },
30 | // 组件更新之前
31 | beforeUpdate: function () {
32 | console.log('dialog---beforeUpdate', this.$options.name)
33 | },
34 | // 组件更新之后
35 | updated: function () {
36 | console.log('dialog---updated', this.$options.name)
37 | },
38 | // keep-alive 会用到
39 | // 组件被激活
40 | activated: function () {
41 | console.log('dialog---activated', this.$options.name)
42 | },
43 | // 组件被移除
44 | deactivated: function () {
45 | console.log('dialog---deactivated', this.$options.name)
46 | },
47 | beforDestroy: function () {
48 | console.log('dialog---beforDestroy', this.$options.name)
49 | },
50 | destroyed: function () {
51 | this.ema.dispose()
52 | console.log('dialog---destroyed', this.$options.name)
53 | },
54 | methods: {
55 | /**
56 | * 组件内部范围绑定事件
57 | * @param key
58 | * @param fn
59 | */
60 | bindEvent: function (key, fn) {
61 | if (!this.$options.name) {
62 | console.warn('绑定事件的组件不存在组件名称', key)
63 | }
64 | this.ema.bind(`${this.$options.name}.${key}`, fn)
65 | },
66 | /**
67 | * 打开一个弹出框
68 | * @param data
69 | * {
70 | * name:'', //弹出框名称,dialog目录下弹出框名称
71 | * data:{}, //传给弹出框的基础数据 data能包含数据
72 | * methods:{} //传给弹出框的基础方法。方便回调等操作
73 | * }
74 | */
75 | openDialog: function (data) {
76 | this.ema.fire('Dialogs.push', data)
77 | },
78 | close: function () {
79 | console.log('close')
80 | this.ema.fire('Dialogs.close', this.$options.name)
81 | }
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/src/assets/data/menu.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "resCode": "01",
4 | "resKey": "01",
5 | "resName": "测试例子",
6 | "data": {},
7 | "child": [
8 | {
9 | "resCode": "0101",
10 | "resKey": "0101",
11 | "resName": "弹框",
12 | "data": {},
13 | "child": [
14 | {
15 | "resCode": "010101",
16 | "resKey": "demo-dialog1-1",
17 | "resName": "弹出框",
18 | "query": {
19 | "a": 1
20 | },
21 | "child": [],
22 | "data": {}
23 | },
24 | {
25 | "resCode": "010102",
26 | "resKey": "demo-dialog1-2",
27 | "resName": "弹出框2",
28 | "child": [],
29 | "data": {}
30 | }
31 | ]
32 | },
33 | {
34 | "resCode": "0101",
35 | "resKey": "0102",
36 | "resName": "弹框",
37 | "data": {},
38 | "child": [
39 | {
40 | "resCode": "010201",
41 | "resKey": "demo-2dialog1-1",
42 | "resName": "弹出框",
43 | "child": [],
44 | "data": {}
45 | },
46 | {
47 | "resCode": "010102",
48 | "resKey": "demo-2dialog1-2",
49 | "resName": "弹出框2",
50 | "child": [],
51 | "data": {}
52 | }
53 | ]
54 | }
55 | ]
56 | },
57 | {
58 | "resCode": "02",
59 | "resKey": "02",
60 | "resName": "测试例子2",
61 | "data": {},
62 | "child": [
63 | {
64 | "resCode": "0202",
65 | "resKey": "0202",
66 | "resName": "弹框222",
67 | "data": {},
68 | "child": [
69 | {
70 | "resCode": "020202",
71 | "resKey": "demo-dialog2-2",
72 | "resName": "弹出框2222",
73 | "child": [],
74 | "data": {}
75 | },
76 | {
77 | "resCode": "020202",
78 | "resKey": "demo-dialog2-1",
79 | "resName": "弹出框22222",
80 | "child": [],
81 | "data": {}
82 | },
83 | {
84 | "resCode": "020202",
85 | "resKey": "demo-dialog",
86 | "resName": "弹出框22222",
87 | "child": [],
88 | "data": {}
89 | }
90 | ]
91 | }
92 | ]
93 | }
94 | ]
--------------------------------------------------------------------------------
/src/app.vue:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
14 |
25 |
83 |
--------------------------------------------------------------------------------
/vue.config.js:
--------------------------------------------------------------------------------
1 | const path = require('path')
2 | const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin')
3 | const config = require('./src/config/index')
4 |
5 | const configureWebpack = {
6 | resolve: {
7 | alias: {
8 | 'src': path.join(__dirname, 'src')
9 | }
10 | },
11 | externals: {
12 | 'jQuery': 'jQuery',
13 | 'plupload': 'plupload',
14 | },
15 | module: {
16 | rules: [{
17 | test: /\.md$/,
18 | use: [
19 | { loader: 'html-loader' },
20 | { loader: 'markdown-loader' }
21 | ]
22 | }]
23 | },
24 | plugins: [new MonacoWebpackPlugin()]
25 | }
26 |
27 | if (process.env.NODE_ENV === 'production') {
28 | configureWebpack.externals.vue = 'Vue'
29 | configureWebpack.externals['vue-router'] = 'VueRouter'
30 | configureWebpack.externals.vuex = 'Vuex'
31 | }
32 |
33 | module.exports = {
34 | publicPath: '/' + config.ADMIN_NAME,
35 | assetsDir: 'static',
36 | outputDir: `dist/${config.ADMIN_NAME || 'admin'}`,
37 | lintOnSave: process.env.NODE_ENV !== 'production',
38 | productionSourceMap: process.env.NODE_ENV !== 'production',
39 | pages: {
40 | index: {
41 | entry: './src/main.js',
42 | filename: 'index.html',
43 | template: './index.tpl',
44 | title: config.ADMIN_TITLE,
45 | hmid: config.BAIDU_TONGJI
46 | },
47 | login: {
48 | entry: './src/login.js',
49 | filename: 'login.html',
50 | template: './login.tpl',
51 | title: config.ADMIN_TITLE,
52 | hmid: config.BAIDU_TONGJI
53 | },
54 | emailActive: {
55 | entry: './src/emailActive.js',
56 | filename: 'emailActive.html',
57 | template: './emailActive.tpl',
58 | title: config.ADMIN_TITLE,
59 | hmid: config.BAIDU_TONGJI
60 | },
61 | updatePassword: {
62 | entry: './src/updatePassword.js',
63 | filename: 'updatePassword.html',
64 | template: './updatePassword.tpl',
65 | title: config.ADMIN_TITLE,
66 | hmid: config.BAIDU_TONGJI
67 | }
68 | },
69 | devServer: {
70 | disableHostCheck: true,
71 | port: 8567,
72 | publicPath: '/',
73 | },
74 | configureWebpack: configureWebpack,
75 | chainWebpack: config => {
76 | config.plugins.delete('preload-index')
77 | config.plugins.delete('prefetch-index')
78 |
79 | config.plugin('define').tap(args => {
80 | args[0]['process.env'].CODE_ENV = JSON.stringify(process.env.CODE_ENV)
81 | return args
82 | })
83 | config.module
84 | .rule('wasm')
85 | .test(/\.wasm$/)
86 | .use('file-loader')
87 | .loader('file-loader')
88 | .tap(options => {
89 | return {
90 | limit: 0
91 | }
92 | })
93 | }
94 | }
--------------------------------------------------------------------------------
/src/assets/data/draf.json:
--------------------------------------------------------------------------------
1 | {
2 | "id": "12",
3 | "apis": [{
4 | "request": "{\"query\":[],\"path\":[],\"body\":[{\"name\":\"list\",\"require\":false,\"type\":\"array\",\"mock\":\"1\",\"description\":\"\"},{\"name\":\"pageDTO\",\"require\":false,\"type\":\"array\",\"mock\":\"2\",\"description\":\"\"},{\"name\":\"\",\"require\":\"true\",\"type\":\"string\",\"mock\":\"3\",\"description\":\"\"}]}",
5 | "response": "[{\"name\":\"salesId\",\"require\":false,\"type\":\"number\",\"mock\":\"1\",\"description\":\"员工ID\"},{\"name\":\"teamId\",\"require\":false,\"type\":\"number\",\"mock\":\"2\",\"description\":\"在职人\"},{\"name\":\"teamName\",\"require\":false,\"type\":\"string\",\"mock\":\"34\",\"description\":\"在职人\"},{\"name\":\"memberNum\",\"require\":false,\"type\":\"number\",\"mock\":\"5\",\"description\":\"\"},{\"name\":\"signInNum\",\"require\":false,\"type\":\"number\",\"mock\":\"6\",\"description\":\"\"},{\"name\":\"salesLevelCode\",\"require\":false,\"type\":\"number\",\"mock\":\"7\",\"description\":\"\"}]",
6 | "description": "432",
7 | "name": "用户信息",
8 | "method": "post",
9 | "path": "xts/info"
10 | },{
11 | "request": "{\"query\":[],\"path\":[],\"body\":[{\"name\":\"list\",\"require\":false,\"type\":\"array\",\"mock\":\"1\",\"description\":\"\"},{\"name\":\"pageDTO\",\"require\":false,\"type\":\"array\",\"mock\":\"2\",\"description\":\"\"},{\"name\":\"\",\"require\":\"true\",\"type\":\"string\",\"mock\":\"3\",\"description\":\"\"}]}",
12 | "response": "[{\"name\":\"salesId\",\"require\":false,\"type\":\"number\",\"mock\":\"1\",\"description\":\"员工ID\"},{\"name\":\"teamId\",\"require\":false,\"type\":\"number\",\"mock\":\"2\",\"description\":\"在职人\"},{\"name\":\"teamName\",\"require\":false,\"type\":\"string\",\"mock\":\"34\",\"description\":\"在职人\"},{\"name\":\"memberNum\",\"require\":false,\"type\":\"number\",\"mock\":\"5\",\"description\":\"\"},{\"name\":\"signInNum\",\"require\":false,\"type\":\"number\",\"mock\":\"6\",\"description\":\"\"},{\"name\":\"salesLevelCode\",\"require\":false,\"type\":\"number\",\"mock\":\"7\",\"description\":\"\"}]",
13 | "description": "432",
14 | "name": "用户信息",
15 | "method": "post",
16 | "path": "xts/info"
17 | }],
18 | "metadata": [{
19 | "name": "BaseResponseUnE",
20 | "content": "[{\"name\":\"errorMsg\",\"require\":false,\"type\":\"string\",\"mock\":\"\",\"description\":\"\"},{\"name\":\"result\",\"require\":false,\"type\":\"number\",\"mock\":\"\",\"description\":\"\"}]",
21 | "remark": ""
22 | },
23 | {
24 | "name": "BaseResponseUnE",
25 | "content": "[{\"name\":\"errorMsg\",\"require\":false,\"type\":\"string\",\"mock\":\"\",\"description\":\"\"},{\"name\":\"result\",\"require\":false,\"type\":\"number\",\"mock\":\"\",\"description\":\"\"}]",
26 | "remark": ""
27 | }]
28 | }
--------------------------------------------------------------------------------
/src/assets/js/vuelint.js:
--------------------------------------------------------------------------------
1 | const lint = [
2 | {label: 'silent'},
3 | {label: 'optionMergeStrategies'},
4 | {label: 'devtools'},
5 | {label: 'errorHandler'},
6 | {label: 'warnHandler'},
7 | {label: 'ignoredElements'},
8 | {label: 'keyCodes'},
9 | {label: 'performance'},
10 | {label: 'productionTip'},
11 | {label: 'extend'},
12 | {label: 'nextTick'},
13 | {label: 'set'},
14 | {label: 'delete'},
15 | {label: 'directive'},
16 | {label: 'filter'},
17 | {label: 'component'},
18 | {label: 'use'},
19 | {label: 'mixin'},
20 | {label: 'compile'},
21 | {label: 'version'},
22 | {label: 'data'},
23 | {label: 'props'},
24 | {label: 'propsData'},
25 | {label: 'computed'},
26 | {label: 'methods'},
27 | {label: 'watch'},
28 | {label: 'el'},
29 | {label: 'template'},
30 | {label: 'render'},
31 | {label: 'renderError'},
32 | {label: 'beforeCreate'},
33 | {label: 'created'},
34 | {label: 'beforeMount'},
35 | {label: 'mounted'},
36 | {label: 'beforeUpdate'},
37 | {label: 'updated'},
38 | {label: 'activated'},
39 | {label: 'deactivated'},
40 | {label: 'beforeDestroy'},
41 | {label: 'destroyed'},
42 | {label: 'directives'},
43 | {label: 'filters'},
44 | {label: 'components'},
45 | {label: 'parent'},
46 | {label: 'mixins'},
47 | {label: 'extends'},
48 | {label: 'provide'},
49 | {label: 'inject'},
50 | {label: 'name'},
51 | {label: 'delimiters'},
52 | {label: 'functional'},
53 | {label: 'model'},
54 | {label: 'inheritAttrs'},
55 | {label: 'comments'},
56 | {label: '$data'},
57 | {label: '$props'},
58 | {label: '$el'},
59 | {label: '$options'},
60 | {label: '$parent'},
61 | {label: '$root'},
62 | {label: '$children'},
63 | {label: '$slots'},
64 | {label: '$scopedSlots'},
65 | {label: '$refs'},
66 | {label: '$isServer'},
67 | {label: '$attrs'},
68 | {label: '$listeners'},
69 | {label: '$watch'},
70 | {label: '$set'},
71 | {label: '$delete'},
72 | {label: '$on'},
73 | {label: '$once'},
74 | {label: '$off'},
75 | {label: '$emit'},
76 | {label: '$mount'},
77 | {label: '$forceUpdate'},
78 | {label: '$nextTick'},
79 | {label: '$destroy'},
80 | {label: 'v-text'},
81 | {label: 'v-html'},
82 | {label: 'v-show'},
83 | {label: 'v-if'},
84 | {label: 'v-else'},
85 | {label: 'v-else-if'},
86 | {label: 'v-for'},
87 | {label: 'v-on'},
88 | {label: 'v-bind'},
89 | {label: 'v-model'},
90 | {label: 'v-pre'},
91 | {label: 'v-cloak'},
92 | {label: 'v-once'},
93 | {label: 'key'},
94 | {label: 'ref'},
95 | {label: 'slot'},
96 | {label: 'is'},
97 | {label: 'component'},
98 | {label: 'transition'},
99 | {label: 'transition-group'},
100 | {label: 'keep-alive'},
101 | {label: 'slot'},
102 | {label: 'immediate'},
103 | {label: 'handler'},
104 | {label: 'editerMethods'},
105 | {label: 'params'},
106 | {label: 'desc'},
107 | ]
108 |
109 | export default lint
110 |
--------------------------------------------------------------------------------
/src/updatePassword.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
重置密码
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 | 提交
15 |
16 |
17 |
18 |
19 |
20 |
40 |
41 |
96 |
--------------------------------------------------------------------------------
/src/extend/chartOptions.js:
--------------------------------------------------------------------------------
1 | function line ({title, seriesNames, x, y, log, unit, legend = true, legendAlign = 'right', tooltip = true, dataZoom = true, dataZoomLimit = 30},
2 | {seriesNames: seriesNames2, y: y2, log: log2, unit: unit2} = {}) {
3 | var xLength = x.length
4 | var option = {
5 | title: {
6 | text: title || '历史趋势',
7 | left: 'center',
8 | top: 10,
9 | textStyle: {
10 | color: '#666',
11 | fontWeight: '500'
12 | }
13 | },
14 | legend: legend && {
15 | orient: 'vertical',
16 | right: legendAlign == 'right' ? 10 : 'auto',
17 | left: legendAlign == 'left' ? 60 : 'auto',
18 | top: 30,
19 | data: [...seriesNames, ...(seriesNames2 || [])].map(name => {
20 | return {
21 | name: name,
22 | }
23 | })
24 | },
25 | grid: {
26 | left: 60,
27 | right: 60,
28 | top: 40,
29 | bottom: 40,
30 | },
31 | xAxis: {
32 | data: x,
33 | boundaryGap: seriesNames2 && seriesNames2.length > 0
34 | },
35 | yAxis: [
36 | {
37 | type: log ? 'log' : 'value',
38 | splitLine: {
39 | show: false
40 | },
41 | axisLabel: {
42 | formatter: '{value} ' + (unit || '')
43 | }
44 | },
45 | seriesNames2 && seriesNames2.length && {
46 | type: log2 ? 'log' : 'value',
47 | splitLine: {
48 | show: false
49 | },
50 | axisLabel: {
51 | formatter: '{value} ' + (unit2 || '')
52 | }
53 | }
54 | ],
55 | tooltip: tooltip && {
56 | trigger: 'axis',
57 | axisPointer: {
58 | type: 'cross'
59 | },
60 | textStyle: {
61 | fontSize: 12,
62 | fontWeight: 'lighter'
63 | }
64 | },
65 | dataZoom: dataZoom && [
66 | {
67 | type: 'slider',
68 | show: true,
69 | xAxisIndex: [0],
70 | start: (1 - dataZoomLimit / xLength) * 100,
71 | end: 100
72 | }
73 | ],
74 | sampling: 'average',
75 | series: [
76 | ...y.map((s, i) => {
77 | return {
78 | itemStyle: {
79 | opacity: 0
80 | },
81 | lineStyle: {
82 | // color: 'rgba(0,0,0,0)',
83 | width: 1,
84 | },
85 | areaStyle: {
86 | // opacity: 0.8 - 0.1 * i
87 | },
88 | smooth: true,
89 | name: seriesNames[i],
90 | type: 'line',
91 | data: s,
92 | }
93 | }),
94 | ...(seriesNames2 && seriesNames2.length && y2.map((s, i) => {
95 | return {
96 | itemStyle: {
97 | opacity: 0.8
98 | },
99 | barMaxWidth: 30,
100 | yAxisIndex: 1,
101 | smooth: true,
102 | name: seriesNames2[i],
103 | type: 'bar',
104 | z: 20,
105 | data: s,
106 | }
107 | }) || [])
108 | ]
109 | }
110 | return option
111 | }
112 |
113 | export {
114 | line
115 | }
116 |
--------------------------------------------------------------------------------
/src/pages/pages/CDoc.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
8 |
9 |
10 |
11 |
12 |
13 | 暂无页面信息,请先添加页面
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
75 |
76 |
128 |
--------------------------------------------------------------------------------
/src/extend/filter.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import {numberSplit} from './Util'
3 | import Metadata from '../store/metadata'
4 | var defaultHeaderIcon = require('../assets/image/header/default.png')
5 | var defaultProjectIcon = require('../assets/image/project/cover-media.jpg')
6 | var defaultGroupIcon = require('../assets/image/group/default.png')
7 | /**
8 | * 时间格式化
9 | */
10 | Vue.filter('datetime', function (value, format) {
11 | return (new Date(value)).Format(format || 'yyyy-MM-dd hh:mm')
12 | })
13 | /**
14 | * 充值时间格式化,value是以秒为单位
15 | */
16 | Vue.filter('sdatetime', function (value, format) {
17 | var val = parseInt(value + '000')
18 | return (new Date(val)).Format(format || 'yyyy-MM-dd hh:mm')
19 | })
20 | /**
21 | * 时间格式化,只显示月日
22 | */
23 | Vue.filter('daytime', function (value, format) {
24 | return (new Date(value)).Format(format || 'MM-dd')
25 | })
26 |
27 | /**
28 | * 金额格式化
29 | * value 金额,以分为单位
30 | */
31 | Vue.filter('moneyFormat', function (value, num) {
32 | value = value / 100 // 转换为元
33 | num = typeof num === 'undefined' ? 2 : num
34 | if (parseFloat(value) > 0) {
35 | var str = parseFloat(value).toFixed(num)
36 | var strArr = str.split('.')
37 | return (/^0+$/.test(strArr[ 1 ])) ? strArr[ 0 ] : str
38 | } else {
39 | return 0
40 | }
41 | })
42 | /**
43 | * 金额格式化(保存不同位小数)
44 | * value 金额,以分为单位
45 | */
46 | Vue.filter('moneyDecFormat', function (value) {
47 | value = parseFloat(value)
48 | if (isNaN(value)) {
49 | return ''
50 | }
51 | value = value / 100// 转换为元
52 | if (value > 10) {
53 | value = value.toFixed(0)
54 | return value
55 | }
56 | if (value >= 1 && value <= 10) {
57 | value = value.toFixed(1)
58 | return value
59 | }
60 | if (value < 1) {
61 | value = value.toFixed(2)
62 | return value
63 | }
64 | })
65 |
66 | /**
67 | * 金额格式化(保存不同位小数)
68 | * value 金额,以分为单位
69 | */
70 | Vue.filter('toArray', function (value) {
71 | var array = []
72 | value.forEach(function (value, key) {
73 | })
74 | return array
75 | })
76 | /**
77 | * 组角色过滤
78 | */
79 | Vue.filter('groupRole', function (value) {
80 | var obj = Metadata.groupPower[ value - 1 ]
81 | if (obj) {
82 | return obj.label
83 | }
84 | return ''
85 | })
86 | /**
87 | * 项目角色过滤
88 | */
89 | Vue.filter('projectRole', function (value) {
90 | var obj = Metadata.projectPower[ value - 1 ]
91 | if (obj) {
92 | return obj.label
93 | }
94 | return ''
95 | })
96 | /**
97 | * 默认头像
98 | */
99 | Vue.filter('defaultHeader', function (value) {
100 | value = value || defaultHeaderIcon
101 | return value
102 | })
103 | /**
104 | * 默认项目图片
105 | */
106 | Vue.filter('defaultProject', function (value) {
107 | value = value || defaultProjectIcon
108 | return value
109 | })
110 | /**
111 | * 默认团队图片
112 | */
113 | Vue.filter('defaultGroup', function (value) {
114 | value = value || defaultGroupIcon
115 | return value
116 | })
117 | /**
118 | * 数字分隔
119 | */
120 | Vue.filter('numberSplit', function (val, round) {
121 | var num = numberSplit(round ? Math.round(val) : val) || 0
122 | return /NaN/.test(num) || !num ? 0 : num
123 | })
124 |
--------------------------------------------------------------------------------
/src/extend/UploadImg.js:
--------------------------------------------------------------------------------
1 | import plupload from 'plupload'
2 | import Utils from './Util'
3 | import Server from '../extend/Server'
4 | var getUploadConfig = function (callback) {
5 | Server({
6 | url: 'upload/getTocken',
7 | method: 'get', // default
8 | needLoading: false,
9 | data: {}
10 | }).then((respond) => {
11 | var data = respond.data.data
12 | callback(data)
13 | })
14 | }
15 |
16 | var UploadImage = function ({
17 | id,
18 | fileName,
19 | filters,
20 | isAddUploadFile,
21 | callback
22 | }) {
23 | this.imgSrc = ''
24 | var uploadControll = false
25 | var me = this
26 | var acceptFilters = {
27 | image: {
28 | title: '资源选择',
29 | extensions: 'jpg,gif,png,jpeg'
30 | },
31 | video: {
32 | title: '资源选择',
33 | extensions: 'mp4'
34 | },
35 | audio: {
36 | title: '资源选择',
37 | extensions: 'mp3'
38 | }
39 | }
40 | this.uploader = new plupload.Uploader({
41 | runtimes: 'html5',
42 | browse_button: id,
43 | url: 'https://oss.aliyuncs.com',
44 | filters: [acceptFilters[filters]],
45 | prevent_duplicates: true,
46 | max_file_size: '100mb',
47 | init: {
48 | PostInit () {},
49 | FilesAdded (up, files) {
50 | if (uploadControll) {
51 | return false
52 | }
53 | uploadControll = true
54 | let that = this
55 | let name = files[0].name
56 | if (isAddUploadFile) {
57 | let pos = name.lastIndexOf('.')
58 | if (pos !== -1) {
59 | name = 'ymm_' + new Date().getTime() + name.substring(pos)
60 | }
61 | Utils.readAsDataURL(files[0].getNative(), function (src) {
62 | var filesSource = new window.File([Utils.getBlobBydataURI(src, files[0].type)], name, {
63 | type: files[0].type
64 | })
65 | that.addFile(filesSource)
66 | that.removeFile(files[0])
67 | me.send(name)
68 | })
69 | }
70 | },
71 | BeforeUpload (up, file) {},
72 | UploadProgress (up, file) {},
73 | FileUploaded (up, file, info) {
74 | if (info.status === 200) {
75 | me.imgSrc = me.imgSrc.replace('ymm.oss-cn-hangzhou.aliyuncs.com', 'imagecdn.ymm56.com')
76 | callback(me.imgSrc)
77 | } else {}
78 | uploadControll = false
79 | },
80 | Error (up, err) {}
81 | }
82 | })
83 | this.uploader.init()
84 | }
85 |
86 | UploadImage.prototype.send = function (name) {
87 | name = name || 'ymm' + new Date().getTime() + '.png'
88 | getUploadConfig((configUplaod) => {
89 | configUplaod.key = configUplaod.dir + name
90 | this.imgSrc = configUplaod.host + '/' + configUplaod.key
91 | let newMultipartParams = {
92 | 'key': configUplaod.key,
93 | 'policy': configUplaod.policy,
94 | 'OSSAccessKeyId': configUplaod.accessid,
95 | 'success_action_status': '200',
96 | 'signature': configUplaod.signature
97 | }
98 | console.log('newMultipartParams', newMultipartParams)
99 | this.uploader.setOption({
100 | 'url': configUplaod.host,
101 | 'multipart_params': newMultipartParams
102 | })
103 | this.uploader.start()
104 | })
105 | }
106 | export default UploadImage
107 |
--------------------------------------------------------------------------------
/src/components/Welcome.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 恭喜你注册成功,但是还需要在你的邮件里面去激活邮箱{{user.email}},
6 |
7 | 重新激活
8 | 登出
9 |
10 |
11 |
12 |
13 |
{{loadingDesc}}
14 |
15 |
16 |
17 |
58 |
124 |
125 |
--------------------------------------------------------------------------------
/src/extend/Util.js:
--------------------------------------------------------------------------------
1 | import Server from '../extend/Server'
2 |
3 | function pipe () {
4 | var args = [].slice.call(arguments, 0)
5 | var val = args[ 0 ]
6 | for (let arg of args) {
7 | if (args.indexOf(arg) != 0 && typeof arg === 'function') val = arg(val)
8 | }
9 | return val
10 | }
11 |
12 | function baiduTongjiAjax (body) {
13 | return Server({
14 | url: 'statistics/baidu',
15 | method: 'post',
16 | data: body
17 | }).then(({data}) => {
18 | let {header, body} = data
19 | if (header && header.desc === 'success') {
20 | return body && body.data && body.data[0] && body.data[0].result
21 | } else {
22 | return null
23 | }
24 | })
25 | }
26 |
27 | function numberSplit (num) {
28 | return String(num).split('').reverse().map((a, i) => `${i % 3 === 2 ? ', ' : ''}${a}`).reverse().join('').replace(/^,/, '')
29 | }
30 |
31 | function combineTongjiData ({fields = [], items = []}, verbose = false) {
32 | if (verbose) {
33 | var [category, list] = items
34 | items = category.map((c, i) => [c[0], ...list[i]])
35 | }
36 | var obj = []
37 | for (let item of items) {
38 | obj.push(item.map((a, i) => [i, a]).reduce((a, b) => {
39 | var val = b[1] && b[1].val || b[1]
40 | var key = fields[b[0]]
41 | if (typeof val === 'number') {
42 | switch (key) {
43 | case 'pv_count':
44 | case 'visitor_count':
45 | case 'ip_count':
46 | val = numberSplit(val)
47 | break
48 | case 'bounce_ratio':
49 | val = val + '%'
50 | break
51 | case 'avg_visit_time':
52 | val = `${val / 60 | 0}分${val % 60}秒`
53 | }
54 | }
55 | a[key] = val
56 | return a
57 | }, {}))
58 | }
59 | return obj
60 | }
61 |
62 | function splitTrendData (result, pickedFields) {
63 | var sumData = result.sum && result.sum[0]
64 | var fields = result.fields.slice(1)
65 | var sumFields = fields.filter(f => f.indexOf('ratio') == -1)
66 | var items = result.items || []
67 | var x = items[0].map(x => x[0])
68 | var y = pickedFields
69 | .map(f => [f, fields.indexOf(f)])
70 | .reduce((o, [k, i]) => {
71 | o[k] = items[1].map(d => d[i])
72 | return o
73 | }, {})
74 | var sum = pickedFields
75 | .map(f => [f, sumFields.indexOf(f)])
76 | .reduce((o, [k, i]) => {
77 | o[k] = sumData[i]
78 | return o
79 | }, {})
80 |
81 | return {
82 | x,
83 | y,
84 | sum,
85 | }
86 | }
87 | function getBlobBydataURI (dataURI, type) {
88 | var binary = window.atob(dataURI.split(',')[1])
89 | var array = []
90 | for (let i = 0, leng = binary.length; i < leng; i++) {
91 | array.push(binary.charCodeAt(i))
92 | }
93 | let blob = new window.Blob([new Uint8Array(array)], {
94 | type: type
95 | })
96 | return blob
97 | }
98 | function readAsDataURL (file, callback) {
99 | const reader = new window.FileReader()
100 | reader.readAsDataURL(file)
101 | reader.onload = function (e) {
102 | callback && callback(this.result)
103 | }
104 | }
105 |
106 | export {
107 | readAsDataURL,
108 | getBlobBydataURI,
109 | splitTrendData,
110 | numberSplit,
111 | combineTongjiData,
112 | pipe,
113 | baiduTongjiAjax,
114 | }
115 |
116 | export default {
117 | readAsDataURL,
118 | getBlobBydataURI,
119 | splitTrendData,
120 | numberSplit,
121 | combineTongjiData,
122 | pipe,
123 | baiduTongjiAjax,
124 | }
125 |
--------------------------------------------------------------------------------
/src/store/metadata.js:
--------------------------------------------------------------------------------
1 | /**
2 | * 基本元数据配置
3 | */
4 | const state = {
5 | resourceType: {
6 |
7 | },
8 | paramsType: [
9 | 'string',
10 | 'number',
11 | 'boolean',
12 | 'object',
13 | 'array',
14 | 'array(string)',
15 | 'array(number)',
16 | 'array(boolean)',
17 | 'array(object)',
18 | 'array(array)'
19 | ],
20 | methods: [
21 | { value: 'get', label: 'GET' },
22 | { value: 'post', label: 'POST' },
23 | { value: 'put', label: 'PUT' },
24 | { value: 'delete', label: 'DELETE' },
25 | { value: 'patch', label: 'PATCH' },
26 | { value: 'head', label: 'HEAD' },
27 | { value: 'options', label: 'OPTIONS' }
28 | ],
29 | projectPower: [
30 | {
31 | value: '1',
32 | label: '所有者'
33 | },
34 | {
35 | value: '2',
36 | label: '管理员'
37 | },
38 | {
39 | value: '3',
40 | label: '开发人'
41 | },
42 | {
43 | value: '4',
44 | label: '游客'
45 | }
46 | ],
47 | groupPower: [
48 | {
49 | value: '1',
50 | label: '所有者'
51 | },
52 | {
53 | value: '2',
54 | label: '管理员'
55 | },
56 | {
57 | value: '3',
58 | label: '开发人'
59 | }
60 | ],
61 | pageType: [
62 | {value: '0', label: 'web'},
63 | {value: 1, label: 'flutter'},
64 | ],
65 | mockAdvice: [
66 | { value: '@id', desc: '随机id' },
67 | { value: '@increment', desc: '自增id' },
68 | { value: '@image', desc: '' },
69 | { value: '@email', desc: '' },
70 | { value: '@title', desc: '标题' },
71 | { value: '@word', desc: '单词' },
72 | { value: '@cparagraph', desc: '中文段落' },
73 | { value: '@csentence', desc: '中文句子' },
74 | { value: '@url', desc: '' },
75 | { value: '@pick', desc: '挑选数组中的一个' },
76 | { value: '@now', desc: '' },
77 |
78 | { value: '@boolean', desc: '' },
79 | { value: '@natural', desc: '' },
80 | { value: '@integer', desc: '' },
81 | { value: '@float', desc: '' },
82 | { value: '@character', desc: '' },
83 | { value: '@string', desc: '' },
84 | { value: '@range', desc: '' },
85 | { value: '@date', desc: '' },
86 | { value: '@time', desc: '' },
87 | { value: '@datetime', desc: '' },
88 | { value: '@dataImage', desc: '' },
89 | { value: '@color', desc: '' },
90 | { value: '@hex', desc: 'hex格式颜色' },
91 | { value: '@rgb', desc: 'rgb格式颜色' },
92 | { value: '@rgba', desc: 'rgba格式颜色' },
93 | { value: '@hsl', desc: 'hsl格式颜色' },
94 | { value: '@paragraph', desc: '段落' },
95 | { value: '@sentence', desc: '句子' },
96 | { value: '@cword', desc: '' },
97 | { value: '@ctitle', desc: '' },
98 | { value: '@first', desc: '' },
99 | { value: '@last', desc: '' },
100 | { value: '@name', desc: '' },
101 | { value: '@cfirst', desc: '' },
102 | { value: '@clast', desc: '' },
103 | { value: '@cname', desc: '' },
104 | { value: '@domain', desc: '域名' },
105 | { value: '@protocol', desc: '' },
106 | { value: '@tld', desc: '' },
107 | { value: '@ip', desc: '' },
108 | { value: '@region', desc: '地区' },
109 | { value: '@province', desc: '' },
110 | { value: '@city', desc: '' },
111 | { value: '@county', desc: '' },
112 | { value: '@zip', desc: '邮编' },
113 | { value: '@capitalize', desc: '' },
114 | { value: '@upper', desc: '' },
115 | { value: '@lower', desc: '' },
116 | { value: '@shuffle', desc: '' },
117 | { value: '@guid', desc: '32位唯一id' }
118 | ]
119 | }
120 | export default state
121 |
--------------------------------------------------------------------------------
/src/pages/dashboard/groups.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | 新建团队
18 |
19 |
20 |
21 |
22 |
23 |
25 |
26 |
27 | {{item.name}}
28 |
29 | 我是 {{item.role | groupRole}}
30 |
31 |
32 |
{{item.description}}
33 |
34 |
35 |
36 |
37 |
38 |
41 |
42 |
43 | {{item.name}}
44 |
45 | 我是 {{item.role | groupRole}}
46 |
47 |
48 |
{{item.description}}
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
60 |
61 |
112 |
--------------------------------------------------------------------------------
/src/components/CodeEditer.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
11 |
120 |
121 |
--------------------------------------------------------------------------------
/public/fullpage.min.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * fullPage 3.0.2
3 | * https://github.com/alvarotrigo/fullPage.js
4 | *
5 | * @license GPLv3 for open source use only
6 | * or Fullpage Commercial License for commercial use
7 | * http://alvarotrigo.com/fullPage/pricing/
8 | *
9 | * Copyright (C) 2018 http://alvarotrigo.com/fullPage - A project by Alvaro Trigo
10 | */.fp-enabled body,html.fp-enabled{margin:0;padding:0;overflow:hidden;-webkit-tap-highlight-color:rgba(0,0,0,0)}.fp-section{position:relative;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.fp-slide{float:left}.fp-slide,.fp-slidesContainer{height:100%;display:block}.fp-slides{z-index:1;height:100%;overflow:hidden;position:relative;-webkit-transition:all .3s ease-out;transition:all .3s ease-out}.fp-section.fp-table,.fp-slide.fp-table{display:table;table-layout:fixed;width:100%}.fp-tableCell{display:table-cell;vertical-align:middle;width:100%;height:100%}.fp-slidesContainer{float:left;position:relative}.fp-controlArrow{-webkit-user-select:none;-moz-user-select:none;-khtml-user-select:none;-ms-user-select:none;position:absolute;z-index:4;top:50%;cursor:pointer;width:0;height:0;border-style:solid;margin-top:-38px;-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.fp-controlArrow.fp-prev{left:15px;width:0;border-width:38.5px 34px 38.5px 0;border-color:transparent #fff transparent transparent}.fp-controlArrow.fp-next{right:15px;border-width:38.5px 0 38.5px 34px;border-color:transparent transparent transparent #fff}.fp-scrollable{overflow:hidden;position:relative}.fp-scroller{overflow:hidden}.iScrollIndicator{border:0!important}.fp-notransition{-webkit-transition:none!important;transition:none!important}#fp-nav{position:fixed;z-index:100;margin-top:-32px;top:50%;opacity:1;-webkit-transform:translate3d(0,0,0)}#fp-nav.fp-right{right:17px}#fp-nav.fp-left{left:17px}.fp-slidesNav{position:absolute;z-index:4;opacity:1;-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0);left:0!important;right:0;margin:0 auto!important}.fp-slidesNav.fp-bottom{bottom:17px}.fp-slidesNav.fp-top{top:17px}#fp-nav ul,.fp-slidesNav ul{margin:0;padding:0}#fp-nav ul li,.fp-slidesNav ul li{display:block;width:14px;height:13px;margin:7px;position:relative}.fp-slidesNav ul li{display:inline-block}#fp-nav ul li a,.fp-slidesNav ul li a{display:block;position:relative;z-index:1;width:100%;height:100%;cursor:pointer;text-decoration:none}#fp-nav ul li a.active span,#fp-nav ul li:hover a.active span,.fp-slidesNav ul li a.active span,.fp-slidesNav ul li:hover a.active span{height:12px;width:12px;margin:-6px 0 0 -6px;border-radius:100%}#fp-nav ul li a span,.fp-slidesNav ul li a span{border-radius:50%;position:absolute;z-index:1;height:4px;width:4px;border:0;background:#333;left:50%;top:50%;margin:-2px 0 0 -2px;-webkit-transition:all .1s ease-in-out;-moz-transition:all .1s ease-in-out;-o-transition:all .1s ease-in-out;transition:all .1s ease-in-out}#fp-nav ul li:hover a span,.fp-slidesNav ul li:hover a span{width:10px;height:10px;margin:-5px 0 0 -5px}#fp-nav ul li .fp-tooltip{position:absolute;top:-2px;color:#fff;font-size:14px;font-family:arial,helvetica,sans-serif;white-space:nowrap;max-width:220px;overflow:hidden;display:block;opacity:0;width:0;cursor:pointer}#fp-nav ul li:hover .fp-tooltip,#fp-nav.fp-show-active a.active+.fp-tooltip{-webkit-transition:opacity .2s ease-in;transition:opacity .2s ease-in;width:auto;opacity:1}#fp-nav ul li .fp-tooltip.fp-right{right:20px}#fp-nav ul li .fp-tooltip.fp-left{left:20px}.fp-auto-height .fp-slide,.fp-auto-height .fp-tableCell,.fp-auto-height.fp-section{height:auto!important}.fp-responsive .fp-auto-height-responsive .fp-slide,.fp-responsive .fp-auto-height-responsive .fp-tableCell,.fp-responsive .fp-auto-height-responsive.fp-section{height:auto!important}
11 | /*# sourceMappingURL=fullpage.min.css.map */
12 | #fp-nav ul li a span, .fp-slidesNav ul li a span {
13 | background-color: #888;
14 | }
--------------------------------------------------------------------------------
/src/assets/js/base.js:
--------------------------------------------------------------------------------
1 | Date.prototype.Format = function (fmt) { //author: meizz
2 | var o = {
3 | "M+": this.getMonth() + 1, //月份
4 | "d+": this.getDate(), //日
5 | "h+": this.getHours(), //小时
6 | "m+": this.getMinutes(), //分
7 | "s+": this.getSeconds(), //秒
8 | "q+": Math.floor((this.getMonth() + 3) / 3), //季度
9 | "S": this.getMilliseconds() //毫秒
10 | };
11 | if (/(y+)/.test(fmt))
12 | fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
13 | for (var k in o)
14 | if (new RegExp("(" + k + ")").test(fmt))
15 | fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[ k ]) : (("00" + o[ k ]).substr(("" + o[ k ]).length)));
16 | return fmt;
17 | };
18 | +function () {
19 | "use strict";
20 | var e = /\[([^\[]*)\]$/, n = /^(?:([a-z]*):)?(?:\/\/)?(?:([^:@]*)(?::([^@]*))?@)?([0-9a-z-._]+)?(?::([0-9]*))?(\/[^?#]*)?(?:\?([^#]*))?(?:#(.*))?$/i, t = [ "mailto", "bitcoin" ], o = {
21 | get: function (n, t) {
22 | n = n || "", "undefined" == typeof t && (t = {}), "undefined" == typeof t.full && (t.full = !1), "undefined" == typeof t.array && (t.array = !1), t.full === !0 && (n = o.parse(n, { get: !1 }).query || "");
23 | for (var u = {}, d = n.split("&"), r = 0; r < d.length; r++)if (d[ r ].length) {
24 | var f = d[ r ].indexOf("="), i = d[ r ], s = !0;
25 | if (f >= 0 && (i = d[ r ].substr(0, f), s = d[ r ].substr(f + 1), s = decodeURIComponent(s)), t.array) {
26 | for (var a, p = [], y = u, c = i; a = c.match(e);)c = c.substr(0, a.index), p.unshift(decodeURIComponent(a[ 1 ]));
27 | if (c = decodeURIComponent(c), p.some(function (e) {return "undefined" == typeof y[ c ] && (y[ c ] = []), Array.isArray(y[ c ]) ? (y = y[ c ], "" === e && (e = y.length), void(c = e)) : !0}))continue;
28 | y[ c ] = s
29 | } else i = decodeURIComponent(i), u[ i ] = s
30 | }
31 | return u
32 | }, buildget: function (e, n) {
33 | var t = [];
34 | for (var u in e) {
35 | var d = encodeURIComponent(u);
36 | "undefined" != typeof n && (d = n + "[" + d + "]");
37 | var r = e[ u ];
38 | switch (typeof r) {
39 | case"boolean":
40 | r && t.push(d);
41 | break;
42 | case"number":
43 | r = r.toString();
44 | case"string":
45 | t.push(d + "=" + encodeURIComponent(r));
46 | break;
47 | case"object":
48 | t.push(o.buildget(r, d))
49 | }
50 | }
51 | return t.join("&")
52 | }, parse: function (e, t) {
53 | "undefined" == typeof t && (t = {});
54 | var u = e.match(n) || [], d = {
55 | url: e,
56 | scheme: u[ 1 ],
57 | user: u[ 2 ],
58 | pass: u[ 3 ],
59 | host: u[ 4 ],
60 | port: u[ 5 ] && +u[ 5 ],
61 | path: u[ 6 ],
62 | query: u[ 7 ],
63 | hash: u[ 8 ]
64 | };
65 | return t.get !== !1 && (d.get = d.query && o.get(d.query, t.get)), d
66 | }, build: function (e, n) {
67 | n = n || {};
68 | var u = "";
69 | if ("undefined" != typeof e.scheme && (u += e.scheme, u += t.indexOf(e.scheme) >= 0 ? ":" : "://"), "undefined" != typeof e.user && (u += e.user, "undefined" == typeof e.pass && (u += "@")), "undefined" != typeof e.pass && (u += ":" + e.pass + "@"), "undefined" != typeof e.host && (u += e.host), "undefined" != typeof e.port && (u += ":" + e.port), "undefined" != typeof e.path && (u += e.path), n.useemptyget) "undefined" != typeof e.get ? u += "?" + o.buildget(e.get) : "undefined" != typeof e.query && (u += "?" + e.query); else {
70 | var d = e.get && o.buildget(e.get) || e.query;
71 | d && (u += "?" + d)
72 | }
73 | return "undefined" != typeof e.hash && (u += "#" + e.hash), u || e.url || ""
74 | }
75 | };
76 | window.url = o
77 | }();
78 |
--------------------------------------------------------------------------------
/src/components/pie-chart.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | {{pie.percentage}}
7 |
8 |
9 |
10 |
11 |
12 | {{pie.name === '__all__' ? '' : pie.name}} {{pie.percentage}}
13 |
14 |
15 |
{{title}}
16 |
17 |
18 |
51 |
52 |
119 |
120 |
--------------------------------------------------------------------------------
/src/components/Upload.vue:
--------------------------------------------------------------------------------
1 |
2 | 上传
3 |
4 |
5 |
6 |
8 |
141 |
142 |
--------------------------------------------------------------------------------
/src/components/PageRouter.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
15 |
126 |
127 |
--------------------------------------------------------------------------------
/src/pages/dashboard/component.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | {{item.name}}
22 |
23 |
26 |
27 | 编辑
28 | 禁用
29 | 启用
30 |
31 |
32 |
33 |
34 |
35 |
36 | 我还没有组件
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
62 |
63 |
145 |
--------------------------------------------------------------------------------
/src/pages/groups/CNew.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 | 只能上传jpg/png文件,且不超过500kb
12 |
13 |
14 |
15 |
21 |
22 |
23 |
24 |
29 |
30 |
31 |
32 |
43 |
44 |
45 |
46 | 立即修改
47 | 立即创建
48 |
49 |
50 |
51 |
52 |
53 |
54 |
64 |
65 |
153 |
--------------------------------------------------------------------------------
/src/components/Tags.vue:
--------------------------------------------------------------------------------
1 |
2 |
19 |
20 |
35 |
169 |
170 |
--------------------------------------------------------------------------------
/src/pages/pages/history.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | 恢复使用
11 | 恢复到草稿
12 |
16 | 删除
17 | 预览
18 |
19 |
20 |
21 |
22 | 删除后不可恢复,您确定要删除吗
23 |
27 |
28 |
29 |
30 |
31 |
33 |
151 |
--------------------------------------------------------------------------------
/src/components/Sidebar.vue:
--------------------------------------------------------------------------------
1 |
2 |
73 |
74 |
75 |
82 |
83 |
143 |
144 |
--------------------------------------------------------------------------------
/src/assets/style/app.styl:
--------------------------------------------------------------------------------
1 | put = #c5862b
2 | head = #c5862b
3 | delete = #c5862b
4 | post = #10a54a
5 | patch = #D38042
6 | get = #0f6ab4
7 | options = #0f6ab4
8 |
9 | .nav-links.el-tabs {
10 |
11 | }
12 |
13 | .nav-links.el-tabs .el-tabs__header {
14 | border: 0;
15 | margin: 0;
16 | }
17 |
18 | .nav-links.el-tabs .el-tabs__item {
19 | height: 53px;
20 | line-height: 60px;
21 | font-size: 16px;
22 | }
23 |
24 |
25 | .el-upload__input {
26 | display: none !important;
27 | }
28 |
29 | /*=========api 列表展示样式========*/
30 | .type.post {
31 | color: #416bbb;
32 | }
33 |
34 | .type.get {
35 | color: #39bb2f;
36 | }
37 |
38 | .type.put {
39 | color: #bb7220;
40 | }
41 |
42 | .type.delete {
43 | color: #bb221b;
44 | }
45 |
46 | /*=======页面颜色==========*/
47 |
48 | .el-table .put {
49 | color: put;
50 | }
51 |
52 | .el-table .head {
53 | color: head;
54 | }
55 |
56 | .el-table .delete {
57 | color: delete;
58 | }
59 |
60 | .el-table .post {
61 | color: post;
62 | }
63 |
64 | .el-table .patch {
65 | color: patch;
66 | }
67 |
68 | .el-table .get {
69 | color: get;
70 | }
71 |
72 | .el-table .options {
73 | color: options;
74 | }
75 |
76 | /*=========类型 列表展示样式========*/
77 | .ia-splitter-handle {
78 | height: 100%;
79 | position: absolute;
80 | top: 0;
81 | right: -6px;
82 | width: 11px;
83 | z-index: 11;
84 | cursor: col-resize;
85 | }
86 |
87 | .ia-splitter-handle-highlight {
88 | background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAAMCAYAAABIvGxUAAADHmlDQ1BJQ0MgUHJvZmlsZQAAeAGFVN9r01AU/tplnbDhizpnEQk+aJFuZFN0Q5y2a1e6zVrqNrchSJumbVyaxiTtfrAH2YtvOsV38Qc++QcM2YNve5INxhRh+KyIIkz2IrOemzRNJ1MDufe73/nuOSfn5F6g+XFa0xQvDxRVU0/FwvzE5BTf8gFeHEMr/GhNi4YWSiZHQA/Tsnnvs/MOHsZsdO5v36v+Y9WalQwR8BwgvpQ1xCLhWaBpXNR0E+DWie+dMTXCzUxzWKcECR9nOG9jgeGMjSOWZjQ1QJoJwgfFQjpLuEA4mGng8w3YzoEU5CcmqZIuizyrRVIv5WRFsgz28B9zg/JfsKiU6Zut5xCNbZoZTtF8it4fOX1wjOYA1cE/Xxi9QbidcFg246M1fkLNJK4RJr3n7nRpmO1lmpdZKRIlHCS8YlSuM2xp5gsDiZrm0+30UJKwnzS/NDNZ8+PtUJUE6zHF9fZLRvS6vdfbkZMH4zU+pynWf0D+vff1corleZLw67QejdX0W5I6Vtvb5M2mI8PEd1E/A0hCgo4cZCjgkUIMYZpjxKr4TBYZIkqk0ml0VHmyONY7KJOW7RxHeMlfDrheFvVbsrj24Pue3SXXjrwVhcW3o9hR7bWB6bqyE5obf3VhpaNu4Te55ZsbbasLCFH+iuWxSF5lyk+CUdd1NuaQU5f8dQvPMpTuJXYSWAy6rPBe+CpsCk+FF8KXv9TIzt6tEcuAcSw+q55TzcbsJdJM0utkuL+K9ULGGPmQMUNanb4kTZyKOfLaUAsnBneC6+biXC/XB567zF3h+rkIrS5yI47CF/VFfCHwvjO+Pl+3b4hhp9u+02TrozFa67vTkbqisXqUj9sn9j2OqhMZsrG+sX5WCCu0omNqSrN0TwADJW1Ol/MFk+8RhAt8iK4tiY+rYleQTysKb5kMXpcMSa9I2S6wO4/tA7ZT1l3maV9zOfMqcOkb/cPrLjdVBl4ZwNFzLhegM3XkCbB8XizrFdsfPJ63gJE722OtPW1huos+VqvbdC5bHgG7D6vVn8+q1d3n5H8LeKP8BqkjCtbCoV8yAAAACXBIWXMAAAsSAAALEgHS3X78AAABZ2lUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNC40LjAiPgogICA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iPgogICAgICAgICA8eG1wOkNyZWF0b3JUb29sPkFkb2JlIEZpcmV3b3JrcyBDUzY8L3htcDpDcmVhdG9yVG9vbD4KICAgICAgPC9yZGY6RGVzY3JpcHRpb24+CiAgIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+CsO3s+UAAAAsSURBVAgdY7x69ep/BgaGRpZNmzYBaQYGxv//QQIMDExgEpnBcu3aNQoUAwChKRhfrNwRnQAAAABJRU5ErkJggg==");
89 | background-position: right center;
90 | background-repeat: no-repeat
91 | position: absolute;
92 | top: 0;
93 | left: 4px;
94 | bottom: 0;
95 | width: 6px;
96 | border-left: 1px solid #ccc;
97 | }
98 |
99 | .el-radio-button__orig-radio:checked + .el-radio-button__inner {
100 | color: #fff;
101 | background-color: #1970a9;
102 | border-color: #1970a9;
103 | }
104 |
105 | .noborder input, .div-table li .noborder textarea {
106 | border none;
107 | }
108 | .el-tabs__nav-wrap::after{
109 | background-color: rgba(228, 231, 237, 0)
110 | }
111 |
112 | .my-autocomplete {
113 | li {
114 | line-height: normal;
115 | padding: 7px;
116 |
117 | .name {
118 | text-overflow: ellipsis;
119 | overflow: hidden;
120 | }
121 | .addr {
122 | font-size: 12px;
123 | color: #b4b4b4;
124 | }
125 |
126 | .highlighted .addr {
127 | color: #ddd;
128 | }
129 | }
130 | }
131 |
132 | .el-tabs--border-card {
133 | background: #fff;
134 | border: 1px solid #d1dbe5;
135 | box-shadow: 0 2px 4px 0 rgba(0, 0, 0, .12), 0 0 6px 0 rgba(0, 0, 0, .04)
136 | }
137 |
138 | .el-tabs--border-card > .el-tabs__content {
139 | padding: 15px
140 | }
141 |
142 | .el-tabs--border-card > .el-tabs__header {
143 | background-color: #eef1f6;
144 | margin: 0
145 | }
146 |
147 | .el-tabs--border-card > .el-tabs__header .el-tabs__item {
148 | transition: all .3s cubic-bezier(.645, .045, .355, 1);
149 | border: 1px solid transparent;
150 | border-top: 0;
151 | margin-right: -1px;
152 | margin-left: -1px
153 | }
154 |
155 | .el-tabs--border-card > .el-tabs__header .el-tabs__item.is-active {
156 | background-color: #fff;
157 | border-right-color: #d1dbe5;
158 | border-left-color: #d1dbe5
159 | }
160 |
161 | .el-tabs--border-card > .el-tabs__header .el-tabs__item.is-active:first-child {
162 | border-left-color: #d1dbe5
163 | }
164 |
165 | .el-tabs--border-card > .el-tabs__header .el-tabs__item.is-active:last-child {
166 | border-right-color: #d1dbe5
167 | }
168 | .deprecated {
169 | text-decoration: line-through;
170 | }
171 | /*==============提示==============*/
172 | .tipWarp {
173 | margin 5px
174 | }
175 |
176 | .el-dialog__headerbtn, .el-message-box__headerbtn {
177 | float: right;
178 | background: transparent;
179 | border: none;
180 | outline: none;
181 | padding: 0;
182 | cursor: pointer;
183 | }
--------------------------------------------------------------------------------
/src/dialog/DAddPage.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
基础信息
7 |
8 |
9 |
10 | {{ item.groupName+'/'+item.projectName }}
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
34 |
35 |
36 |
37 |
38 |
39 | 否
40 | 是
41 |
42 |
43 |
44 |
45 |
46 |
50 |
51 |
52 |
78 |
169 |
170 |
--------------------------------------------------------------------------------
/src/pages/component/editer.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
37 |
38 |
39 |
40 |
41 | 否
42 | 是
43 |
44 |
45 |
46 | 提交
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
81 |
82 |
178 |
--------------------------------------------------------------------------------
/src/pages/completePage.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | 添加页面
14 |
15 |
16 |
17 |
18 |
19 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 | 基本设置
41 |
42 |
43 |
44 |
45 |
46 |
47 |
删除项目
48 |
49 |
50 | 删除项目是不可逆的,确认
51 |
52 |
53 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
118 |
119 |
197 |
--------------------------------------------------------------------------------
/src/dialog/DCopyPage.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
基础信息
7 |
8 |
9 |
10 | {{ item.groupName+'/'+item.projectName }}
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 | 否
30 | 是
31 |
32 |
33 |
34 |
35 |
36 |
40 |
41 |
42 |
68 |
175 |
176 |
--------------------------------------------------------------------------------
/src/components/Header.vue:
--------------------------------------------------------------------------------
1 |
2 |
60 |
61 |
77 |
169 |
170 |
--------------------------------------------------------------------------------
/src/pages/project.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 | 添加页面
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | 你无权访问该项目信息
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 | 基本设置
45 |
46 |
47 |
48 |
49 |
50 |
51 |
删除项目
52 |
53 |
54 | 删除项目是不可逆的,确认
55 |
56 |
57 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
122 |
123 |
200 |
--------------------------------------------------------------------------------
/src/pages/page.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | 页面列表
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 | 你无权访问该项目信息
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 | 基本设置
41 |
42 |
43 |
44 |
45 |
46 |
47 |
删除页面
48 |
49 |
50 | 删除页面是不可逆的,确认
51 |
52 |
53 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
124 |
125 |
235 |
--------------------------------------------------------------------------------
/src/pages/pages/CNew.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 | {{ item.groupName+'/'+item.projectName }}
39 |
40 |
41 |
42 |
46 |
47 |
48 |
49 |
52 |
53 |
54 |
55 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
69 |
70 |
71 |
72 |
73 |
74 | 否
75 | 是
76 |
77 |
78 |
79 | 提交
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
123 |
124 |
241 |
--------------------------------------------------------------------------------
/src/pages/projects/data.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | 数据
8 |
9 |
10 |
11 |
12 |
13 |
14 |
22 |
23 |
24 |
25 |
26 | {{item.label||item.id}}
27 |
28 |
29 |
30 | 查询
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 | 共计 {{sumData.pageCount}} 个页面, 累计访客 {{sumData.user}} 位
39 |
40 |
41 |
42 |
43 |
44 |
45 | PU / UV 点击图例可显示/隐藏对应指标
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 | {{h}}
54 |
55 |
56 |
57 | {{val}}
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
93 |
94 |
234 |
--------------------------------------------------------------------------------