added ESlint 语法检测

This commit is contained in:
何秀钢
2021-06-02 14:11:45 +08:00
parent 3932a8fbf3
commit 2f0465a1a1
94 changed files with 5031 additions and 4790 deletions

4
web/.eslintignore Normal file
View File

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

269
web/.eslintrc.js Normal file
View File

@@ -0,0 +1,269 @@
//@author: [bstdn](https://github.com/bstdn)
//@description: ESlint 语法检测
module.exports = {
root: true,
parserOptions: {
parser: 'babel-eslint',
sourceType: 'module'
},
env: {
browser: true,
node: true,
es6: true
},
extends: ['plugin:vue/recommended', 'eslint:recommended'],
// add your custom rules here
// it is base on https://github.com/vuejs/eslint-config-vue
rules: {
'vue/max-attributes-per-line': [
2,
{
singleline: 10,
multiline: {
max: 1,
allowFirstLine: false
}
}
],
'vue/singleline-html-element-content-newline': 'off',
'vue/multiline-html-element-content-newline': 'off',
'vue/name-property-casing': ['error', 'PascalCase'],
'vue/no-v-html': 'off',
'accessor-pairs': 2,
'arrow-spacing': [
2,
{
before: true,
after: true
}
],
'block-spacing': [2, 'always'],
'brace-style': [
2,
'1tbs',
{
allowSingleLine: true
}
],
camelcase: [
0,
{
properties: 'always'
}
],
'comma-dangle': [2, 'never'],
'comma-spacing': [
2,
{
before: false,
after: true
}
],
'comma-style': [2, 'last'],
'constructor-super': 2,
curly: [2, 'multi-line'],
'dot-location': [2, 'property'],
'eol-last': 2,
eqeqeq: ['error', 'always', { null: 'ignore' }],
'generator-star-spacing': [
2,
{
before: true,
after: true
}
],
'handle-callback-err': [2, '^(err|error)$'],
indent: [
2,
2,
{
SwitchCase: 1
}
],
'jsx-quotes': [2, 'prefer-single'],
'key-spacing': [
2,
{
beforeColon: false,
afterColon: true
}
],
'keyword-spacing': [
2,
{
before: true,
after: true
}
],
'new-cap': [
2,
{
newIsCap: true,
capIsNew: false
}
],
'new-parens': 2,
'no-array-constructor': 2,
'no-caller': 2,
'no-console': 'off',
'no-class-assign': 2,
'no-cond-assign': 2,
'no-const-assign': 2,
'no-control-regex': 0,
'no-delete-var': 2,
'no-dupe-args': 2,
'no-dupe-class-members': 2,
'no-dupe-keys': 2,
'no-duplicate-case': 2,
'no-empty-character-class': 2,
'no-empty-pattern': 2,
'no-eval': 2,
'no-ex-assign': 2,
'no-extend-native': 2,
'no-extra-bind': 2,
'no-extra-boolean-cast': 2,
'no-extra-parens': [2, 'functions'],
'no-fallthrough': 2,
'no-floating-decimal': 2,
'no-func-assign': 2,
'no-implied-eval': 2,
'no-inner-declarations': [2, 'functions'],
'no-invalid-regexp': 2,
'no-irregular-whitespace': 2,
'no-iterator': 2,
'no-label-var': 2,
'no-labels': [
2,
{
allowLoop: false,
allowSwitch: false
}
],
'no-lone-blocks': 2,
'no-mixed-spaces-and-tabs': 2,
'no-multi-spaces': 2,
'no-multi-str': 2,
'no-multiple-empty-lines': [
2,
{
max: 1
}
],
'no-native-reassign': 2,
'no-negated-in-lhs': 2,
'no-new-object': 2,
'no-new-require': 2,
'no-new-symbol': 2,
'no-new-wrappers': 2,
'no-obj-calls': 2,
'no-octal': 2,
'no-octal-escape': 2,
'no-path-concat': 2,
'no-proto': 2,
'no-redeclare': 2,
'no-regex-spaces': 2,
'no-return-assign': [2, 'except-parens'],
'no-self-assign': 2,
'no-self-compare': 2,
'no-sequences': 2,
'no-shadow-restricted-names': 2,
'no-spaced-func': 2,
'no-sparse-arrays': 2,
'no-this-before-super': 2,
'no-throw-literal': 2,
'no-trailing-spaces': 2,
'no-undef': 2,
'no-undef-init': 2,
'no-unexpected-multiline': 2,
'no-unmodified-loop-condition': 2,
'no-unneeded-ternary': [
2,
{
defaultAssignment: false
}
],
'no-unreachable': 2,
'no-unsafe-finally': 2,
'no-unused-vars': [
2,
{
vars: 'all',
args: 'none'
}
],
'no-useless-call': 2,
'no-useless-computed-key': 2,
'no-useless-constructor': 2,
'no-useless-escape': 0,
'no-whitespace-before-property': 2,
'no-with': 2,
'one-var': [
2,
{
initialized: 'never'
}
],
'operator-linebreak': [
2,
'after',
{
overrides: {
'?': 'before',
':': 'before'
}
}
],
'padded-blocks': [2, 'never'],
quotes: [
2,
'single',
{
avoidEscape: true,
allowTemplateLiterals: true
}
],
semi: [2, 'never'],
'semi-spacing': [
2,
{
before: false,
after: true
}
],
'space-before-blocks': [2, 'always'],
'space-before-function-paren': [2, 'never'],
'space-in-parens': [2, 'never'],
'space-infix-ops': 2,
'space-unary-ops': [
2,
{
words: true,
nonwords: false
}
],
'spaced-comment': [
2,
'always',
{
markers: ['global', 'globals', 'eslint', 'eslint-disable', '*package', '!', ',']
}
],
'template-curly-spacing': [2, 'never'],
'use-isnan': 2,
'valid-typeof': 2,
'wrap-iife': [2, 'any'],
'yield-star-spacing': [2, 'both'],
yoda: [2, 'never'],
'prefer-const': 2,
'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0,
'object-curly-spacing': [
2,
'always',
{
objectsInObjects: false
}
],
'array-bracket-spacing': [2, 'never']
}
}

View File

@@ -2,12 +2,12 @@ module.exports = {
presets: [
'@vue/cli-plugin-babel/preset'
],
"plugins": [
'plugins': [
[
"component",
'component',
{
"libraryName": "element-ui",
"styleLibraryName": "theme-chalk"
'libraryName': 'element-ui',
'styleLibraryName': 'theme-chalk'
}
]
]

View File

@@ -1,19 +1,17 @@
'use strict'
module.exports = {
title: 'GIN-VUE-ADMIN1',
vueClientPort: 8080,
goServerPort: 8888,
baseCdnUrl: '//cdn.staticfile.org',
cdns: [
/**
* 如果设置path属性, { name: 'vue', scope: 'Vue', path: '/vue/2.6.9/vue.min.js' } 即编译出来以[baseCdnUrl][path]
* 否则自动拼写 [baseCdnUrl]/[name]/[version]/[name].min.js
* */
{ name: 'vue', scope: 'Vue' },
{ name: 'vue-router', scope: 'VueRouter' },
{ name: 'vuex', scope: 'Vuex' },
{ name: 'axios', scope: 'axios' },
{ name: 'element-ui', scope: 'ELEMENT', path: '/element-ui/2.12.0/index.js'},
]
};
title: 'GIN-VUE-ADMIN',
baseCdnUrl: '//cdn.staticfile.org',
cdns: [
/**
* 如果设置path属性, { name: 'vue', scope: 'Vue', path: '/vue/2.6.9/vue.min.js' } 即编译出来以[baseCdnUrl][path]
* 否则自动拼写 [baseCdnUrl]/[name]/[version]/[name].min.js
* */
{ name: 'vue', scope: 'Vue' },
{ name: 'vue-router', scope: 'VueRouter' },
{ name: 'vuex', scope: 'Vuex' },
{ name: 'axios', scope: 'axios' },
{ name: 'element-ui', scope: 'ELEMENT', path: '/element-ui/2.12.0/index.js' }
]
}

View File

@@ -5,19 +5,19 @@
否则将依法维权
*/
var child_process = require("child_process");
var child_process = require('child_process')
var url = "https://www.gin-vue-admin.com",
cmd = '';
var url = 'https://www.gin-vue-admin.com'
var cmd = ''
console.log(process.platform)
switch (process.platform) {
case 'win32':
cmd = 'start';
child_process.exec(cmd + ' ' + url);
break;
case 'win32':
cmd = 'start'
child_process.exec(cmd + ' ' + url)
break
case 'darwin':
cmd = 'open';
child_process.exec(cmd + ' ' + url);
break;
}
case 'darwin':
cmd = 'open'
child_process.exec(cmd + ' ' + url)
break
}

View File

@@ -1,16 +1,16 @@
<template>
<div id="app">
<router-view></router-view>
<router-view />
</div>
</template>
<script>
import { checkDB } from "@/api/initdb"
import { checkDB } from '@/api/initdb'
export default {
name: 'app',
async created(){
name: 'App',
async created() {
await checkDB()
}
}
}
</script>

View File

@@ -1,4 +1,5 @@
import service from '@/utils/request'
// @Tags api
// @Summary 分页获取角色列表
// @Security ApiKeyAuth
@@ -12,14 +13,13 @@ import service from '@/utils/request'
// pageSize int
// }
export const getApiList = (data) => {
return service({
url: "/api/getApiList",
method: 'post',
data
})
return service({
url: '/api/getApiList',
method: 'post',
data
})
}
// @Tags Api
// @Summary 创建基础api
// @Security ApiKeyAuth
@@ -29,11 +29,11 @@ export const getApiList = (data) => {
// @Success 200 {string} json "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /api/createApi [post]
export const createApi = (data) => {
return service({
url: "/api/createApi",
method: 'post',
data
})
return service({
url: '/api/createApi',
method: 'post',
data
})
}
// @Tags menu
@@ -45,15 +45,13 @@ export const createApi = (data) => {
// @Success 200 {string} json "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /menu/getApiById [post]
export const getApiById = (data) => {
return service({
url: "/api/getApiById",
method: 'post',
data
})
return service({
url: '/api/getApiById',
method: 'post',
data
})
}
// @Tags Api
// @Summary 更新api
// @Security ApiKeyAuth
@@ -63,11 +61,11 @@ export const getApiById = (data) => {
// @Success 200 {string} json "{"success":true,"data":{},"msg":"更新成功"}"
// @Router /api/updateApi [post]
export const updateApi = (data) => {
return service({
url: "/api/updateApi",
method: 'post',
data
})
return service({
url: '/api/updateApi',
method: 'post',
data
})
}
// @Tags Api
@@ -79,11 +77,11 @@ export const updateApi = (data) => {
// @Success 200 {string} json "{"success":true,"data":{},"msg":"更新成功"}"
// @Router /api/setAuthApi [post]
export const setAuthApi = (data) => {
return service({
url: "/api/setAuthApi",
method: 'post',
data
})
return service({
url: '/api/setAuthApi',
method: 'post',
data
})
}
// @Tags Api
@@ -94,11 +92,11 @@ export const setAuthApi = (data) => {
// @Success 200 {string} json "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /api/getAllApis [post]
export const getAllApis = (data) => {
return service({
url: "/api/getAllApis",
method: 'post',
data
})
return service({
url: '/api/getAllApis',
method: 'post',
data
})
}
// @Tags Api
@@ -110,11 +108,11 @@ export const getAllApis = (data) => {
// @Success 200 {string} json "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /api/deleteApi [post]
export const deleteApi = (data) => {
return service({
url: "/api/deleteApi",
method: 'post',
data
})
return service({
url: '/api/deleteApi',
method: 'post',
data
})
}
// @Tags SysApi
@@ -126,9 +124,9 @@ export const deleteApi = (data) => {
// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
// @Router /api/deleteApisByIds [delete]
export const deleteApisByIds = (data) => {
return service({
url: "/api/deleteApisByIds",
method: 'delete',
data
})
}
return service({
url: '/api/deleteApisByIds',
method: 'delete',
data
})
}

View File

@@ -1,16 +1,14 @@
import service from '@/utils/request'
// @Router /authority/getAuthorityList [post]
export const getAuthorityList = (data) => {
return service({
url: "/authority/getAuthorityList",
method: 'post',
data
})
return service({
url: '/authority/getAuthorityList',
method: 'post',
data
})
}
// @Summary 删除角色
// @Security ApiKeyAuth
// @accept application/json
@@ -19,11 +17,11 @@ export const getAuthorityList = (data) => {
// @Success 200 {string} json "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /authority/deleteAuthority [post]
export const deleteAuthority = (data) => {
return service({
url: "/authority/deleteAuthority",
method: 'post',
data
})
return service({
url: '/authority/deleteAuthority',
method: 'post',
data
})
}
// @Summary 创建角色
@@ -34,11 +32,11 @@ export const deleteAuthority = (data) => {
// @Success 200 {string} json "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /authority/createAuthority [post]
export const createAuthority = (data) => {
return service({
url: "/authority/createAuthority",
method: 'post',
data
})
return service({
url: '/authority/createAuthority',
method: 'post',
data
})
}
// @Tags authority
@@ -50,11 +48,11 @@ export const createAuthority = (data) => {
// @Success 200 {string} json "{"success":true,"data":{},"msg":"拷贝成功"}"
// @Router /authority/copyAuthority [post]
export const copyAuthority = (data) => {
return service({
url: "/authority/copyAuthority",
method: 'post',
data
})
return service({
url: '/authority/copyAuthority',
method: 'post',
data
})
}
// @Summary 设置角色资源权限
@@ -65,11 +63,11 @@ export const copyAuthority = (data) => {
// @Success 200 {string} string "{"success":true,"data":{},"msg":"设置成功"}"
// @Router /authority/setDataAuthority [post]
export const setDataAuthority = (data) => {
return service({
url: "/authority/setDataAuthority",
method: 'post',
data
})
return service({
url: '/authority/setDataAuthority',
method: 'post',
data
})
}
// @Summary 修改角色
@@ -80,9 +78,9 @@ export const setDataAuthority = (data) => {
// @Success 200 {string} string "{"success":true,"data":{},"msg":"设置成功"}"
// @Router /authority/setDataAuthority [post]
export const updateAuthority = (data) => {
return service({
url: "/authority/updateAuthority",
method: 'put',
data
})
}
return service({
url: '/authority/updateAuthority',
method: 'put',
data
})
}

View File

@@ -1,20 +1,20 @@
import service from '@/utils/request'
export const preview = (data) => {
return service({
url: "/autoCode/preview",
method: 'post',
data,
})
return service({
url: '/autoCode/preview',
method: 'post',
data
})
}
export const createTemp = (data) => {
return service({
url: "/autoCode/createTemp",
method: 'post',
data,
responseType: 'blob'
})
return service({
url: '/autoCode/createTemp',
method: 'post',
data,
responseType: 'blob'
})
}
// @Tags SysApi
@@ -25,14 +25,12 @@ export const createTemp = (data) => {
// @Success 200 {string} string "{"success":true,"data":{},"msg":"创建成功"}"
// @Router /autoCode/getDatabase [get]
export const getDB = () => {
return service({
url: "/autoCode/getDB",
method: 'get',
})
return service({
url: '/autoCode/getDB',
method: 'get'
})
}
// @Tags SysApi
// @Summary 获取当前数据库所有表
// @Security ApiKeyAuth
@@ -41,11 +39,11 @@ export const getDB = () => {
// @Success 200 {string} string "{"success":true,"data":{},"msg":"创建成功"}"
// @Router /autoCode/getTables [get]
export const getTable = (params) => {
return service({
url: "/autoCode/getTables",
method: 'get',
params,
})
return service({
url: '/autoCode/getTables',
method: 'get',
params
})
}
// @Tags SysApi
@@ -56,9 +54,9 @@ export const getTable = (params) => {
// @Success 200 {string} string "{"success":true,"data":{},"msg":"创建成功"}"
// @Router /autoCode/getColumn [get]
export const getColumn = (params) => {
return service({
url: "/autoCode/getColumn",
method: 'get',
params,
})
}
return service({
url: '/autoCode/getColumn',
method: 'get',
params
})
}

View File

@@ -9,28 +9,26 @@ import service from '@/utils/request'
// @Router /authority/setDataAuthority [post]
export const findFile = (params) => {
return service({
url: "/fileUploadAndDownload/findFile",
method: 'get',
params
})
return service({
url: '/fileUploadAndDownload/findFile',
method: 'get',
params
})
}
export const breakpointContinueFinish = (params) => {
return service({
url: "/fileUploadAndDownload/breakpointContinueFinish",
method: 'post',
params
})
return service({
url: '/fileUploadAndDownload/breakpointContinueFinish',
method: 'post',
params
})
}
export const removeChunk = (data, params) => {
return service({
url: "/fileUploadAndDownload/removeChunk",
method: 'post',
data,
params
})
}
return service({
url: '/fileUploadAndDownload/removeChunk',
method: 'post',
data,
params
})
}

View File

@@ -8,16 +8,14 @@ import service from '@/utils/request'
// @Param data body api.CreateAuthorityPatams true "更改角色api权限"
// @Success 200 {string} json "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /casbin/UpdateCasbin [post]
export const UpdateCasbin = (data) => {
return service({
url: "/casbin/updateCasbin",
method: 'post',
data
})
return service({
url: '/casbin/updateCasbin',
method: 'post',
data
})
}
// @Tags casbin
// @Summary 获取权限列表
// @Security ApiKeyAuth
@@ -27,9 +25,9 @@ export const UpdateCasbin = (data) => {
// @Success 200 {string} json "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /casbin/getPolicyPathByAuthorityId [post]
export const getPolicyPathByAuthorityId = (data) => {
return service({
url: "/casbin/getPolicyPathByAuthorityId",
method: 'post',
data
})
}
return service({
url: '/casbin/getPolicyPathByAuthorityId',
method: 'post',
data
})
}

View File

@@ -9,15 +9,13 @@ import service from '@/utils/request'
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /customer/customer [post]
export const createExaCustomer = (data) => {
return service({
url: "/customer/customer",
method: 'post',
data
})
return service({
url: '/customer/customer',
method: 'post',
data
})
}
// @Tags SysApi
// @Summary 更新客户信息
// @Security ApiKeyAuth
@@ -27,14 +25,13 @@ export const createExaCustomer = (data) => {
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /customer/customer [put]
export const updateExaCustomer = (data) => {
return service({
url: "/customer/customer",
method: 'put',
data
})
return service({
url: '/customer/customer',
method: 'put',
data
})
}
// @Tags SysApi
// @Summary 创建客户
// @Security ApiKeyAuth
@@ -44,14 +41,13 @@ export const updateExaCustomer = (data) => {
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /customer/customer [delete]
export const deleteExaCustomer = (data) => {
return service({
url: "/customer/customer",
method: 'delete',
data
})
return service({
url: '/customer/customer',
method: 'delete',
data
})
}
// @Tags SysApi
// @Summary 获取单一客户信息
// @Security ApiKeyAuth
@@ -61,14 +57,13 @@ export const deleteExaCustomer = (data) => {
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /customer/customer [get]
export const getExaCustomer = (params) => {
return service({
url: "/customer/customer",
method: 'get',
params
})
return service({
url: '/customer/customer',
method: 'get',
params
})
}
// @Tags SysApi
// @Summary 获取权限客户列表
// @Security ApiKeyAuth
@@ -78,9 +73,9 @@ export const getExaCustomer = (params) => {
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /customer/customerList [get]
export const getExaCustomerList = (params) => {
return service({
url: "/customer/customerList",
method: 'get',
params
})
}
return service({
url: '/customer/customerList',
method: 'get',
params
})
}

View File

@@ -7,9 +7,9 @@ import service from '@/utils/request'
// @Success 200 {string} string "{"success":true,"data":{},"msg":"返回成功"}"
// @Router /email/emailTest [post]
export const emailTest = (data) => {
return service({
url: "/email/emailTest",
method: 'post',
data
})
}
return service({
url: '/email/emailTest',
method: 'post',
data
})
}

View File

@@ -1,29 +1,29 @@
import service from '@/utils/request';
import { Message } from 'element-ui';
import service from '@/utils/request'
import { Message } from 'element-ui'
const handleFileError = (res, fileName) => {
if (typeof(res.data) !== "undefined") {
if (res.data.type == "application/json") {
const reader = new FileReader();
reader.onload = function() {
let message = JSON.parse(reader.result).msg;
Message({
showClose: true,
message: message,
type: 'error'
})
};
reader.readAsText(new Blob([res.data]));
}
} else {
var downloadUrl = window.URL.createObjectURL(new Blob([res]));
var a = document.createElement('a');
a.style.display = 'none';
a.href = downloadUrl;
a.download = fileName;
var event = new MouseEvent("click");
a.dispatchEvent(event);
if (typeof (res.data) !== 'undefined') {
if (res.data.type === 'application/json') {
const reader = new FileReader()
reader.onload = function() {
const message = JSON.parse(reader.result).msg
Message({
showClose: true,
message: message,
type: 'error'
})
}
reader.readAsText(new Blob([res.data]))
}
} else {
var downloadUrl = window.URL.createObjectURL(new Blob([res]))
var a = document.createElement('a')
a.style.display = 'none'
a.href = downloadUrl
a.download = fileName
var event = new MouseEvent('click')
a.dispatchEvent(event)
}
}
// @Tags excel
@@ -35,17 +35,17 @@ const handleFileError = (res, fileName) => {
// @Success 200
// @Router /excel/exportExcel [post]
export const exportExcel = (tableData, fileName) => {
service({
url: "/excel/exportExcel",
method: 'post',
data: {
fileName: fileName,
infoList: tableData
},
responseType: 'blob'
}).then((res) => {
handleFileError(res, fileName)
})
service({
url: '/excel/exportExcel',
method: 'post',
data: {
fileName: fileName,
infoList: tableData
},
responseType: 'blob'
}).then((res) => {
handleFileError(res, fileName)
})
}
// @Tags excel
@@ -57,10 +57,10 @@ export const exportExcel = (tableData, fileName) => {
// @Success 200 {string} string "{"success":true,"data":{},"msg":"导入成功"}"
// @Router /excel/importExcel [post]
export const loadExcelData = () => {
return service({
url: "/excel/loadExcel",
method: 'get'
})
return service({
url: '/excel/loadExcel',
method: 'get'
})
}
// @Tags excel
@@ -72,14 +72,14 @@ export const loadExcelData = () => {
// @Success 200
// @Router /excel/downloadTemplate [get]
export const downloadTemplate = (fileName) => {
return service({
url: "/excel/downloadTemplate",
method: 'get',
params: {
fileName: fileName
},
responseType: 'blob'
}).then((res) => {
handleFileError(res, fileName)
})
}
return service({
url: '/excel/downloadTemplate',
method: 'get',
params: {
fileName: fileName
},
responseType: 'blob'
}).then((res) => {
handleFileError(res, fileName)
})
}

View File

@@ -1,4 +1,4 @@
import service from '@/utils/request';
import service from '@/utils/request'
// @Tags FileUploadAndDownload
// @Summary 分页文件列表
@@ -9,11 +9,11 @@ import service from '@/utils/request';
// @Success 200 {string} json "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /fileUploadAndDownload/getFileList [post]
export const getFileList = (data) => {
return service({
url: "/fileUploadAndDownload/getFileList",
method: "post",
data
})
return service({
url: '/fileUploadAndDownload/getFileList',
method: 'post',
data
})
}
// @Tags FileUploadAndDownload
@@ -24,9 +24,9 @@ export const getFileList = (data) => {
// @Success 200 {string} json "{"success":true,"data":{},"msg":"返回成功"}"
// @Router /fileUploadAndDownload/deleteFile [post]
export const deleteFile = (data) => {
return service({
url: "/fileUploadAndDownload/deleteFile",
method: "post",
data
})
}
return service({
url: '/fileUploadAndDownload/deleteFile',
method: 'post',
data
})
}

View File

@@ -1,33 +1,32 @@
import axios from "axios";
import { Loading } from "element-ui";
import axios from 'axios'
import { Loading } from 'element-ui'
let loadingInstance;
let service = axios.create();
let loadingInstance
const service = axios.create()
service.interceptors.request.use((config) => {
loadingInstance = Loading.service({ fullscreen: true });
return config;
});
loadingInstance = Loading.service({ fullscreen: true })
return config
})
service.interceptors.response.use((resp) => {
loadingInstance.close();
return resp;
loadingInstance.close()
return resp
}, (error) => {
loadingInstance.close();
return error;
});
loadingInstance.close()
return error
})
export function Commits(page) {
return service({
url: "https://api.github.com/repos/flipped-aurora/gin-vue-admin/commits?page=" +
page,
method: "get",
});
return service({
url: 'https://api.github.com/repos/flipped-aurora/gin-vue-admin/commits?page=' + page,
method: 'get'
})
}
export function Members() {
return service({
url: "https://api.github.com/orgs/FLIPPED-AURORA/members",
method: "get",
});
}
return service({
url: 'https://api.github.com/orgs/FLIPPED-AURORA/members',
method: 'get'
})
}

View File

@@ -7,23 +7,21 @@ import service from '@/utils/request'
// @Success 200 {string} string "{"code":0,"data":{},"msg":"自动创建数据库成功"}"
// @Router /init/initdb [post]
export const initDB = (data) => {
return service({
url: "/init/initdb",
method: 'post',
data
})
return service({
url: '/init/initdb',
method: 'post',
data
})
}
// @Tags CheckDB
// @Summary 初始化用户数据库
// @Produce application/json
// @Success 200 {string} string "{"code":0,"data":{},"msg":"探测完成"}"
// @Router /init/checkdb [post]
export const checkDB = () => {
return service({
url: "/init/checkdb",
method: 'post',
})
}
return service({
url: '/init/checkdb',
method: 'post'
})
}

View File

@@ -7,10 +7,9 @@ import service from '@/utils/request'
// @Produce application/json
// @Success 200 {string} string "{"success":true,"data":{},"msg":"拉黑成功"}"
// @Router /jwt/jsonInBlacklist [post]
export const jsonInBlacklist = () => {
return service({
url: "/jwt/jsonInBlacklist",
method: 'post',
})
}
return service({
url: '/jwt/jsonInBlacklist',
method: 'post'
})
}

View File

@@ -5,10 +5,10 @@ import service from '@/utils/request'
// @Param 可以什么都不填 调一下即可
// @Router /menu/getMenu [post]
export const asyncMenu = () => {
return service({
url: "/menu/getMenu",
method: 'post',
})
return service({
url: '/menu/getMenu',
method: 'post'
})
}
// @Summary 获取menu列表
@@ -19,24 +19,23 @@ export const asyncMenu = () => {
// }
// @Router /menu/getMenuList [post]
export const getMenuList = (data) => {
return service({
url: "/menu/getMenuList",
method: 'post',
data
})
return service({
url: '/menu/getMenuList',
method: 'post',
data
})
}
// @Summary 新增基础menu
// @Produce application/json
// @Param menu Object
// @Router /menu/getMenuList [post]
export const addBaseMenu = (data) => {
return service({
url: "/menu/addBaseMenu",
method: 'post',
data
})
return service({
url: '/menu/addBaseMenu',
method: 'post',
data
})
}
// @Summary 获取基础路由列表
@@ -44,10 +43,10 @@ export const addBaseMenu = (data) => {
// @Param 可以什么都不填 调一下即可
// @Router /menu/getBaseMenuTree [post]
export const getBaseMenuTree = () => {
return service({
url: "/menu/getBaseMenuTree",
method: 'post',
})
return service({
url: '/menu/getBaseMenuTree',
method: 'post'
})
}
// @Summary 添加用户menu关联关系
@@ -55,11 +54,11 @@ export const getBaseMenuTree = () => {
// @Param menus Object authorityId string
// @Router /menu/getMenuList [post]
export const addMenuAuthority = (data) => {
return service({
url: "/menu/addMenuAuthority",
method: 'post',
data
})
return service({
url: '/menu/addMenuAuthority',
method: 'post',
data
})
}
// @Summary 获取用户menu关联关系
@@ -67,11 +66,11 @@ export const addMenuAuthority = (data) => {
// @Param authorityId string
// @Router /menu/getMenuAuthority [post]
export const getMenuAuthority = (data) => {
return service({
url: "/menu/getMenuAuthority",
method: 'post',
data
})
return service({
url: '/menu/getMenuAuthority',
method: 'post',
data
})
}
// @Summary 获取用户menu关联关系
@@ -79,27 +78,25 @@ export const getMenuAuthority = (data) => {
// @Param ID float64
// @Router /menu/deleteBaseMenu [post]
export const deleteBaseMenu = (data) => {
return service({
url: "/menu/deleteBaseMenu",
method: 'post',
data
})
return service({
url: '/menu/deleteBaseMenu',
method: 'post',
data
})
}
// @Summary 修改menu列表
// @Produce application/json
// @Param menu Object
// @Router /menu/updateBaseMenu [post]
export const updateBaseMenu = (data) => {
return service({
url: "/menu/updateBaseMenu",
method: 'post',
data
})
return service({
url: '/menu/updateBaseMenu',
method: 'post',
data
})
}
// @Tags menu
// @Summary 根据id获取菜单
// @Security ApiKeyAuth
@@ -109,9 +106,9 @@ export const updateBaseMenu = (data) => {
// @Success 200 {string} json "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /menu/getBaseMenuById [post]
export const getBaseMenuById = (data) => {
return service({
url: "/menu/getBaseMenuById",
method: 'post',
data
})
}
return service({
url: '/menu/getBaseMenuById',
method: 'post',
data
})
}

View File

@@ -1,5 +1,4 @@
import service from '@/utils/request'
// @Tags SimpleUploader
@@ -11,14 +10,13 @@ import service from '@/utils/request'
// @Success 200 {string} string "{"success":true,"data":{},"msg":"查询成功"}"
// @Router /simpleUploader/checkFileMd5 [get]
export const checkFileMd5 = (params) => {
return service({
url: "/simpleUploader/checkFileMd5",
method: 'get',
params
})
return service({
url: '/simpleUploader/checkFileMd5',
method: 'get',
params
})
}
// @Tags SimpleUploader
// @Summary 合并文件
// @Security ApiKeyAuth
@@ -27,10 +25,10 @@ export const checkFileMd5 = (params) => {
// @Success 200 {string} string "{"success":true,"data":{},"msg":"合并成功"}"
// @Router /simpleUploader/mergeFileMd5 [get]
export const mergeFileMd5 = (params) => {
return service({
url: "/simpleUploader/mergeFileMd5",
method: 'get',
params
})
return service({
url: '/simpleUploader/mergeFileMd5',
method: 'get',
params
})
}

View File

@@ -9,13 +9,12 @@ import service from '@/utils/request'
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /sysDictionary/createSysDictionary [post]
export const createSysDictionary = (data) => {
return service({
url: "/sysDictionary/createSysDictionary",
method: 'post',
data
})
}
return service({
url: '/sysDictionary/createSysDictionary',
method: 'post',
data
})
}
// @Tags SysDictionary
// @Summary 删除SysDictionary
@@ -25,13 +24,13 @@ export const createSysDictionary = (data) => {
// @Param data body model.SysDictionary true "删除SysDictionary"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
// @Router /sysDictionary/deleteSysDictionary [delete]
export const deleteSysDictionary = (data) => {
return service({
url: "/sysDictionary/deleteSysDictionary",
method: 'delete',
data
})
}
export const deleteSysDictionary = (data) => {
return service({
url: '/sysDictionary/deleteSysDictionary',
method: 'delete',
data
})
}
// @Tags SysDictionary
// @Summary 更新SysDictionary
@@ -41,14 +40,13 @@ export const createSysDictionary = (data) => {
// @Param data body model.SysDictionary true "更新SysDictionary"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"更新成功"}"
// @Router /sysDictionary/updateSysDictionary [put]
export const updateSysDictionary = (data) => {
return service({
url: "/sysDictionary/updateSysDictionary",
method: 'put',
data
})
}
export const updateSysDictionary = (data) => {
return service({
url: '/sysDictionary/updateSysDictionary',
method: 'put',
data
})
}
// @Tags SysDictionary
// @Summary 用id查询SysDictionary
@@ -58,14 +56,13 @@ export const createSysDictionary = (data) => {
// @Param data body model.SysDictionary true "用id查询SysDictionary"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"查询成功"}"
// @Router /sysDictionary/findSysDictionary [get]
export const findSysDictionary = (params) => {
return service({
url: "/sysDictionary/findSysDictionary",
method: 'get',
params
})
}
export const findSysDictionary = (params) => {
return service({
url: '/sysDictionary/findSysDictionary',
method: 'get',
params
})
}
// @Tags SysDictionary
// @Summary 分页获取SysDictionary列表
@@ -75,10 +72,10 @@ export const createSysDictionary = (data) => {
// @Param data body request.PageInfo true "分页获取SysDictionary列表"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /sysDictionary/getSysDictionaryList [get]
export const getSysDictionaryList = (params) => {
return service({
url: "/sysDictionary/getSysDictionaryList",
method: 'get',
params
})
}
export const getSysDictionaryList = (params) => {
return service({
url: '/sysDictionary/getSysDictionaryList',
method: 'get',
params
})
}

View File

@@ -9,13 +9,12 @@ import service from '@/utils/request'
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /sysDictionaryDetail/createSysDictionaryDetail [post]
export const createSysDictionaryDetail = (data) => {
return service({
url: "/sysDictionaryDetail/createSysDictionaryDetail",
method: 'post',
data
})
}
return service({
url: '/sysDictionaryDetail/createSysDictionaryDetail',
method: 'post',
data
})
}
// @Tags SysDictionaryDetail
// @Summary 删除SysDictionaryDetail
@@ -25,13 +24,13 @@ export const createSysDictionaryDetail = (data) => {
// @Param data body model.SysDictionaryDetail true "删除SysDictionaryDetail"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
// @Router /sysDictionaryDetail/deleteSysDictionaryDetail [delete]
export const deleteSysDictionaryDetail = (data) => {
return service({
url: "/sysDictionaryDetail/deleteSysDictionaryDetail",
method: 'delete',
data
})
}
export const deleteSysDictionaryDetail = (data) => {
return service({
url: '/sysDictionaryDetail/deleteSysDictionaryDetail',
method: 'delete',
data
})
}
// @Tags SysDictionaryDetail
// @Summary 更新SysDictionaryDetail
@@ -41,14 +40,13 @@ export const createSysDictionaryDetail = (data) => {
// @Param data body model.SysDictionaryDetail true "更新SysDictionaryDetail"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"更新成功"}"
// @Router /sysDictionaryDetail/updateSysDictionaryDetail [put]
export const updateSysDictionaryDetail = (data) => {
return service({
url: "/sysDictionaryDetail/updateSysDictionaryDetail",
method: 'put',
data
})
}
export const updateSysDictionaryDetail = (data) => {
return service({
url: '/sysDictionaryDetail/updateSysDictionaryDetail',
method: 'put',
data
})
}
// @Tags SysDictionaryDetail
// @Summary 用id查询SysDictionaryDetail
@@ -58,14 +56,13 @@ export const createSysDictionaryDetail = (data) => {
// @Param data body model.SysDictionaryDetail true "用id查询SysDictionaryDetail"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"查询成功"}"
// @Router /sysDictionaryDetail/findSysDictionaryDetail [get]
export const findSysDictionaryDetail = (params) => {
return service({
url: "/sysDictionaryDetail/findSysDictionaryDetail",
method: 'get',
params
})
}
export const findSysDictionaryDetail = (params) => {
return service({
url: '/sysDictionaryDetail/findSysDictionaryDetail',
method: 'get',
params
})
}
// @Tags SysDictionaryDetail
// @Summary 分页获取SysDictionaryDetail列表
@@ -75,10 +72,10 @@ export const createSysDictionaryDetail = (data) => {
// @Param data body request.PageInfo true "分页获取SysDictionaryDetail列表"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /sysDictionaryDetail/getSysDictionaryDetailList [get]
export const getSysDictionaryDetailList = (params) => {
return service({
url: "/sysDictionaryDetail/getSysDictionaryDetailList",
method: 'get',
params
})
}
export const getSysDictionaryDetailList = (params) => {
return service({
url: '/sysDictionaryDetail/getSysDictionaryDetailList',
method: 'get',
params
})
}

View File

@@ -9,11 +9,11 @@ import service from '@/utils/request'
// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
// @Router /sysOperationRecord/deleteSysOperationRecord [delete]
export const deleteSysOperationRecord = (data) => {
return service({
url: "/sysOperationRecord/deleteSysOperationRecord",
method: 'delete',
data
})
return service({
url: '/sysOperationRecord/deleteSysOperationRecord',
method: 'delete',
data
})
}
// @Tags SysOperationRecord
@@ -25,11 +25,11 @@ export const deleteSysOperationRecord = (data) => {
// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
// @Router /sysOperationRecord/deleteSysOperationRecord [delete]
export const deleteSysOperationRecordByIds = (data) => {
return service({
url: "/sysOperationRecord/deleteSysOperationRecordByIds",
method: 'delete',
data
})
return service({
url: '/sysOperationRecord/deleteSysOperationRecordByIds',
method: 'delete',
data
})
}
// @Tags SysOperationRecord
@@ -41,9 +41,9 @@ export const deleteSysOperationRecordByIds = (data) => {
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /sysOperationRecord/getSysOperationRecordList [get]
export const getSysOperationRecordList = (params) => {
return service({
url: "/sysOperationRecord/getSysOperationRecordList",
method: 'get',
params
})
}
return service({
url: '/sysOperationRecord/getSysOperationRecordList',
method: 'get',
params
})
}

View File

@@ -1,4 +1,4 @@
import service from "@/utils/request";
import service from '@/utils/request'
// @Tags systrm
// @Summary 获取配置文件内容
@@ -7,11 +7,11 @@ import service from "@/utils/request";
// @Success 200 {string} string "{"success":true,"data":{},"msg":"返回成功"}"
// @Router /system/getSystemConfig [post]
export const getSystemConfig = () => {
return service({
url: "/system/getSystemConfig",
method: "post",
});
};
return service({
url: '/system/getSystemConfig',
method: 'post'
})
}
// @Tags system
// @Summary 设置配置文件内容
@@ -21,12 +21,12 @@ export const getSystemConfig = () => {
// @Success 200 {string} string "{"success":true,"data":{},"msg":"返回成功"}"
// @Router /system/setSystemConfig [post]
export const setSystemConfig = (data) => {
return service({
url: "/system/setSystemConfig",
method: "post",
data,
});
};
return service({
url: '/system/setSystemConfig',
method: 'post',
data
})
}
// @Tags system
// @Summary 获取服务器运行状态
@@ -35,9 +35,9 @@ export const setSystemConfig = (data) => {
// @Success 200 {string} string "{"success":true,"data":{},"msg":"返回成功"}"
// @Router /system/getServerInfo [post]
export const getSystemState = () => {
return service({
url: "/system/getServerInfo",
method: "post",
donNotShowLoading: true
});
};
return service({
url: '/system/getServerInfo',
method: 'post',
donNotShowLoading: true
})
}

View File

@@ -5,11 +5,11 @@ import service from '@/utils/request'
// @Param data body {username:"string",password:"string"}
// @Router /base/login [post]
export const login = (data) => {
return service({
url: "/base/login",
method: 'post',
data: data
})
return service({
url: '/base/login',
method: 'post',
data: data
})
}
// @Summary 获取验证码
@@ -17,11 +17,11 @@ export const login = (data) => {
// @Param data body {username:"string",password:"string"}
// @Router /base/captcha [post]
export const captcha = (data) => {
return service({
url: "/base/captcha",
method: 'post',
data: data
})
return service({
url: '/base/captcha',
method: 'post',
data: data
})
}
// @Summary 用户注册
@@ -29,39 +29,40 @@ export const captcha = (data) => {
// @Param data body {username:"string",password:"string"}
// @Router /base/resige [post]
export const register = (data) => {
return service({
url: "/user/register",
method: 'post',
data: data
})
}
// @Summary 修改密码
// @Produce application/json
// @Param data body {username:"string",password:"string",newPassword:"string"}
// @Router /user/changePassword [post]
export const changePassword = (data) => {
return service({
url: "/user/changePassword",
method: 'post',
data: data
})
}
// @Tags User
// @Summary 分页获取用户列表
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body modelInterface.PageInfo true "分页获取用户列表"
// @Success 200 {string} json "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /user/getUserList [post]
export const getUserList = (data) => {
return service({
url: "/user/getUserList",
method: 'post',
data: data
})
return service({
url: '/user/register',
method: 'post',
data: data
})
}
// @Summary 修改密码
// @Produce application/json
// @Param data body {username:"string",password:"string",newPassword:"string"}
// @Router /user/changePassword [post]
export const changePassword = (data) => {
return service({
url: '/user/changePassword',
method: 'post',
data: data
})
}
// @Tags User
// @Summary 分页获取用户列表
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body modelInterface.PageInfo true "分页获取用户列表"
// @Success 200 {string} json "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /user/getUserList [post]
export const getUserList = (data) => {
return service({
url: '/user/getUserList',
method: 'post',
data: data
})
}
// @Tags User
// @Summary 设置用户权限
@@ -72,14 +73,13 @@ export const getUserList = (data) => {
// @Success 200 {string} json "{"success":true,"data":{},"msg":"修改成功"}"
// @Router /user/setUserAuthority [post]
export const setUserAuthority = (data) => {
return service({
url: "/user/setUserAuthority",
method: 'post',
data: data
})
return service({
url: '/user/setUserAuthority',
method: 'post',
data: data
})
}
// @Tags SysUser
// @Summary 删除用户
// @Security ApiKeyAuth
@@ -89,11 +89,11 @@ export const setUserAuthority = (data) => {
// @Success 200 {string} string "{"success":true,"data":{},"msg":"修改成功"}"
// @Router /user/deleteUser [delete]
export const deleteUser = (data) => {
return service({
url: "/user/deleteUser",
method: 'delete',
data: data
})
return service({
url: '/user/deleteUser',
method: 'delete',
data: data
})
}
// @Tags SysUser
@@ -105,9 +105,9 @@ export const deleteUser = (data) => {
// @Success 200 {string} string "{"success":true,"data":{},"msg":"修改成功"}"
// @Router /user/setUserInfo [put]
export const setUserInfo = (data) => {
return service({
url: "/user/setUserInfo",
method: 'put',
data: data
})
}
return service({
url: '/user/setUserInfo',
method: 'put',
data: data
})
}

View File

@@ -9,14 +9,13 @@ import service from '@/utils/request'
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /workflowProcess/createWorkflowProcess [post]
export const createWorkflowProcess = (data) => {
return service({
url: "/workflowProcess/createWorkflowProcess",
method: 'post',
data
})
return service({
url: '/workflowProcess/createWorkflowProcess',
method: 'post',
data
})
}
// @Tags WorkflowProcess
// @Summary 删除WorkflowProcess
// @Security ApiKeyAuth
@@ -26,11 +25,11 @@ export const createWorkflowProcess = (data) => {
// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
// @Router /workflowProcess/deleteWorkflowProcess [delete]
export const deleteWorkflowProcess = (data) => {
return service({
url: "/workflowProcess/deleteWorkflowProcess",
method: 'delete',
data
})
return service({
url: '/workflowProcess/deleteWorkflowProcess',
method: 'delete',
data
})
}
// @Tags WorkflowProcess
@@ -42,11 +41,11 @@ export const deleteWorkflowProcess = (data) => {
// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
// @Router /workflowProcess/deleteWorkflowProcess [delete]
export const deleteWorkflowProcessByIds = (data) => {
return service({
url: "/workflowProcess/deleteWorkflowProcessByIds",
method: 'delete',
data
})
return service({
url: '/workflowProcess/deleteWorkflowProcessByIds',
method: 'delete',
data
})
}
// @Tags WorkflowProcess
@@ -58,14 +57,13 @@ export const deleteWorkflowProcessByIds = (data) => {
// @Success 200 {string} string "{"success":true,"data":{},"msg":"更新成功"}"
// @Router /workflowProcess/updateWorkflowProcess [put]
export const updateWorkflowProcess = (data) => {
return service({
url: "/workflowProcess/updateWorkflowProcess",
method: 'put',
data
})
return service({
url: '/workflowProcess/updateWorkflowProcess',
method: 'put',
data
})
}
// @Tags WorkflowProcess
// @Summary 用id查询WorkflowProcess
// @Security ApiKeyAuth
@@ -75,14 +73,13 @@ export const updateWorkflowProcess = (data) => {
// @Success 200 {string} string "{"success":true,"data":{},"msg":"查询成功"}"
// @Router /workflowProcess/findWorkflowProcess [get]
export const findWorkflowProcess = (params) => {
return service({
url: "/workflowProcess/findWorkflowProcess",
method: 'get',
params
})
return service({
url: '/workflowProcess/findWorkflowProcess',
method: 'get',
params
})
}
// @Tags WorkflowProcess
// @Summary 分页获取WorkflowProcess列表
// @Security ApiKeyAuth
@@ -92,11 +89,11 @@ export const findWorkflowProcess = (params) => {
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /workflowProcess/getWorkflowProcessList [get]
export const getWorkflowProcessList = (params) => {
return service({
url: "/workflowProcess/getWorkflowProcessList",
method: 'get',
params
})
return service({
url: '/workflowProcess/getWorkflowProcessList',
method: 'get',
params
})
}
// @Tags WorkflowProcess
@@ -108,14 +105,13 @@ export const getWorkflowProcessList = (params) => {
// @Success 200 {string} string "{"success":true,"data":{},"msg":"查询成功"}"
// @Router /workflowProcess/findWorkflowStep [get]
export const findWorkflowStep = (params) => {
return service({
url: "/workflowProcess/findWorkflowStep",
method: 'get',
params
})
return service({
url: '/workflowProcess/findWorkflowStep',
method: 'get',
params
})
}
// @Tags ExaWfLeave
// @Summary 创建ExaWfLeave
// @Security ApiKeyAuth
@@ -124,15 +120,14 @@ export const findWorkflowStep = (params) => {
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /workflowProcess/startWorkflow [post]
export const startWorkflow = (data, params = { businessType: data.wf.businessType }) => {
return service({
url: "/workflowProcess/startWorkflow",
method: 'post',
data,
params
})
return service({
url: '/workflowProcess/startWorkflow',
method: 'post',
data,
params
})
}
// @Tags ExaWfLeave
// @Summary 创建ExaWfLeave
// @Security ApiKeyAuth
@@ -141,28 +136,27 @@ export const startWorkflow = (data, params = { businessType: data.wf.businessTyp
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /workflowProcess/completeWorkflowMove [post]
export const completeWorkflowMove = (data, params = { businessType: data.wf.businessType }) => {
return service({
url: "/workflowProcess/completeWorkflowMove",
method: 'post',
data,
params
})
}
// @Tags WorkflowProcess
// @Summary 我发起的工作流
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /workflowProcess/getMyStated [get]
export const getMyStated = () => {
return service({
url: "/workflowProcess/getMyStated",
method: 'get',
})
return service({
url: '/workflowProcess/completeWorkflowMove',
method: 'post',
data,
params
})
}
// @Tags WorkflowProcess
// @Summary 我发起的工作流
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /workflowProcess/getMyStated [get]
export const getMyStated = () => {
return service({
url: '/workflowProcess/getMyStated',
method: 'get'
})
}
// @Tags WorkflowProcess
// @Summary 我发起的工作流
@@ -172,10 +166,10 @@ export const getMyStated = () => {
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /workflowProcess/getMyNeed [get]
export const getMyNeed = () => {
return service({
url: "/workflowProcess/getMyNeed",
method: 'get',
})
return service({
url: '/workflowProcess/getMyNeed',
method: 'get'
})
}
// @Tags WorkflowProcess
@@ -187,9 +181,9 @@ export const getMyNeed = () => {
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /workflowProcess/getWorkflowMoveByID [get]
export const getWorkflowMoveByID = (params) => {
return service({
url: "/workflowProcess/getWorkflowMoveByID",
method: 'get',
params
})
}
return service({
url: '/workflowProcess/getWorkflowMoveByID',
method: 'get',
params
})
}

View File

@@ -2,14 +2,14 @@
<el-drawer title="媒体库" :visible.sync="drawer">
<div class="media">
<el-image
class="header-img-box-list"
:src="(item.url && item.url.slice(0, 4) !== 'http')?path+item.url:item.url"
v-for="(item,key) in picList"
:key="key"
class="header-img-box-list"
:src="(item.url && item.url.slice(0, 4) !== 'http')?path+item.url:item.url"
@click.native="chooseImg(item.url,target,targetKey)"
>
<div slot="error" class="header-img-box-list">
<i class="el-icon-picture-outline"></i>
<i class="el-icon-picture-outline" />
</div>
</el-image>
</div>
@@ -18,34 +18,40 @@
<script>
const path = process.env.VUE_APP_BASE_API
import { getFileList } from "@/api/fileUploadAndDownload";
import { getFileList } from '@/api/fileUploadAndDownload'
export default {
props: {
target: [Object],
targetKey: [String]
target: {
type: Object,
default: null
},
targetKey: {
type: String,
default: ''
}
},
data() {
return {
drawer: false,
picList: [],
path:path
};
path: path
}
},
methods: {
chooseImg(url, target, targetKey) {
if(target&&targetKey){
target[targetKey] = url;
if (target && targetKey) {
target[targetKey] = url
}
this.$emit("enter-img", url);
this.drawer = false;
this.$emit('enter-img', url)
this.drawer = false
},
async open() {
const res = await getFileList({ page: 1, pageSize: 9999 });
this.picList = res.data.list;
this.drawer = true;
const res = await getFileList({ page: 1, pageSize: 9999 })
this.picList = res.data.list
this.drawer = true
}
}
};
}
</script>
<style lang="scss">
@@ -65,4 +71,4 @@ export default {
}
}
</style>
</style>

View File

@@ -1,63 +1,63 @@
<template>
<span class="headerAvatar">
<template v-if="picType === 'avatar'">
<el-avatar :size="30" :src="avatar" v-if="userInfo.headerImg"></el-avatar>
<el-avatar :size="30" :src="require('@/assets/noBody.png')" v-else></el-avatar>
</template>
<template v-if="picType === 'img'">
<img :src="avatar" class="avatar" v-if="userInfo.headerImg" />
<img :src="require('@/assets/noBody.png')" class="avatar" v-else/>
</template>
<template v-if="picType === 'file'">
<img :src="file" class="file"/>
</template>
</span>
<span class="headerAvatar">
<template v-if="picType === 'avatar'">
<el-avatar v-if="userInfo.headerImg" :size="30" :src="avatar" />
<el-avatar v-else :size="30" :src="require('@/assets/noBody.png')" />
</template>
<template v-if="picType === 'img'">
<img v-if="userInfo.headerImg" :src="avatar" class="avatar">
<img v-else :src="require('@/assets/noBody.png')" class="avatar">
</template>
<template v-if="picType === 'file'">
<img :src="file" class="file">
</template>
</span>
</template>
<script>
import { mapGetters } from 'vuex'
const path = process.env.VUE_APP_BASE_API
export default {
name: "customPic",
props: {
picType: {
type: String,
required: false,
default: "avatar"
},
picSrc: {
type: String,
required: false,
default: ""
}
name: 'CustomPic',
props: {
picType: {
type: String,
required: false,
default: 'avatar'
},
data(){
return{
path: path + '/',
}
},
computed:{
...mapGetters('user', ['userInfo']),
avatar(){
if(this.picSrc === ''){
if(this.userInfo.headerImg !== '' && this.userInfo.headerImg.slice(0, 4) === "http"){
return this.userInfo.headerImg
}
return this.path + this.userInfo.headerImg
}else{
if(this.picSrc !== '' && this.picSrc.slice(0, 4) === "http"){
return this.picSrc
}
return this.path + this.picSrc
}
},
file(){
if(this.picSrc && this.picSrc.slice(0, 4) !== "http"){
return this.path + this.picSrc
}
return this.picSrc
}
picSrc: {
type: String,
required: false,
default: ''
}
},
data() {
return {
path: path + '/'
}
},
computed: {
...mapGetters('user', ['userInfo']),
avatar() {
if (this.picSrc === '') {
if (this.userInfo.headerImg !== '' && this.userInfo.headerImg.slice(0, 4) === 'http') {
return this.userInfo.headerImg
}
return this.path + this.userInfo.headerImg
} else {
if (this.picSrc !== '' && this.picSrc.slice(0, 4) === 'http') {
return this.picSrc
}
return this.path + this.picSrc
}
},
file() {
if (this.picSrc && this.picSrc.slice(0, 4) !== 'http') {
return this.path + this.picSrc
}
return this.picSrc
}
}
}
</script>

View File

@@ -4,8 +4,6 @@
<upload-image v-model="imageUrl" :fileSize="512" />
已上传文件 {{ imageUrl }}
</div>
-->
<template>
@@ -19,62 +17,63 @@
:before-upload="beforeImageUpload"
:multiple="false"
>
<img v-if="imageUrl" :src="path + imageUrl" class="image" />
<i v-else class="el-icon-plus image-uploader-icon"></i>
<img v-if="imageUrl" :src="path + imageUrl" class="image">
<i v-else class="el-icon-plus image-uploader-icon" />
</el-upload>
</div>
</template>
<script>
const path = process.env.VUE_APP_BASE_API;
import { mapGetters } from "vuex";
import ImageCompress from "@/utils/image.js";
const path = process.env.VUE_APP_BASE_API
import { mapGetters } from 'vuex'
import ImageCompress from '@/utils/image'
export default {
name: "upload-image",
name: 'UploadImage',
model: {
prop: "imageUrl",
event: "change",
prop: 'imageUrl',
event: 'change'
},
props: {
imageUrl: {
type: String,
default: "",
default: ''
},
fileSize: {
type: Number,
default: 2048, // 2M 超出后执行压缩
default: 2048 // 2M 超出后执行压缩
},
maxWH: {
type: Number,
default: 1920, // 图片长宽上限
},
default: 1920 // 图片长宽上限
}
},
data() {
return {
path: path,
};
path: path
}
},
computed: {
...mapGetters("user", ["userInfo", "token"]),
...mapGetters('user', ['userInfo', 'token'])
},
methods: {
beforeImageUpload(file) {
let isRightSize = file.size / 1024 < this.fileSize;
const isRightSize = file.size / 1024 < this.fileSize
if (!isRightSize) {
// 压缩
let compress = new ImageCompress(file, this.fileSize, this.maxWH);
return compress.compress();
const compress = new ImageCompress(file, this.fileSize, this.maxWH)
return compress.compress()
}
return isRightSize;
return isRightSize
},
handleImageSuccess(res) {
// this.imageUrl = URL.createObjectURL(file.raw);
const { data } = res;
const { data } = res
if (data.file) {
this.$emit("change", data.file.url);
this.$emit('change', data.file.url)
}
},
},
};
}
}
}
</script>
<style lang="scss" scoped>

View File

@@ -1,39 +1,39 @@
// 权限按钮展示指令
import { store } from '@/store/index'
import { store } from '@/store'
export const auth = (Vue) => {
Vue.directive('auth', {
// 当被绑定的元素插入到 DOM 中时……
bind: function (el, binding) {
const userInfo = store.getters['user/userInfo']
let type = ""
switch (Object.prototype.toString.call(binding.value)) {
case "[object Array]":
type = "Array"
break;
case "[object String]":
type = "String"
break;
case "[object Number]":
type = "Number"
break;
default:
type = ""
break;
}
if (type === "") {
/* eslint-disable */
Vue.directive('auth', {
// 当被绑定的元素插入到 DOM 中时……
bind: function(el, binding) {
const userInfo = store.getters['user/userInfo']
let type = ''
switch (Object.prototype.toString.call(binding.value)) {
case '[object Array]':
type = 'Array'
break
case '[object String]':
type = 'String'
break
case '[object Number]':
type = 'Number'
break
default:
type = ''
break
}
if (type === '') {
/* eslint-disable */
console.error("v-auth必须是Array,Number,String属性,暂不支持其他属性")
/* eslint-enable */
return
}
const waitUse = binding.value.toString().split(",")
let flag = waitUse.some(item=>item==userInfo.authorityId)
if (binding.modifiers.not) {
flag = !flag
}
if(!flag){
el.style.display = 'none'
}
}
})
return
}
const waitUse = binding.value.toString().split(',')
let flag = waitUse.some(item => item === userInfo.authorityId)
if (binding.modifiers.not) {
flag = !flag
}
if (!flag) {
el.style.display = 'none'
}
}
})
}

View File

@@ -3,112 +3,112 @@ import App from './App.vue'
// 按需引入element
import {
Button,
Select,
Dialog,
Form,
Input,
FormItem,
Option,
Loading,
Message,
Container,
Card,
Dropdown,
DropdownMenu,
DropdownItem,
Row,
Col,
Menu,
Submenu,
MenuItem,
Aside,
Main,
Badge,
Header,
Tabs,
Breadcrumb,
BreadcrumbItem,
Scrollbar,
Avatar,
TabPane,
Divider,
Table,
TableColumn,
Cascader,
Checkbox,
CheckboxGroup,
Pagination,
Tag,
Drawer,
Tree,
Popover,
Switch,
Collapse,
CollapseItem,
Tooltip,
DatePicker,
InputNumber,
Steps,
Upload,
Progress,
MessageBox,
Image
} from 'element-ui';
Button,
Select,
Dialog,
Form,
Input,
FormItem,
Option,
Loading,
Message,
Container,
Card,
Dropdown,
DropdownMenu,
DropdownItem,
Row,
Col,
Menu,
Submenu,
MenuItem,
Aside,
Main,
Badge,
Header,
Tabs,
Breadcrumb,
BreadcrumbItem,
Scrollbar,
Avatar,
TabPane,
Divider,
Table,
TableColumn,
Cascader,
Checkbox,
CheckboxGroup,
Pagination,
Tag,
Drawer,
Tree,
Popover,
Switch,
Collapse,
CollapseItem,
Tooltip,
DatePicker,
InputNumber,
Steps,
Upload,
Progress,
MessageBox,
Image
} from 'element-ui'
Vue.use(Button);
Vue.use(Select);
Vue.use(Dialog);
Vue.use(Form);
Vue.use(FormItem);
Vue.use(Input);
Vue.use(Option);
Vue.use(Container);
Vue.use(Card);
Vue.use(Dropdown);
Vue.use(DropdownMenu);
Vue.use(DropdownItem);
Vue.use(Row);
Vue.use(Col);
Vue.use(Menu);
Vue.use(Submenu);
Vue.use(MenuItem);
Vue.use(Aside);
Vue.use(Main);
Vue.use(Badge);
Vue.use(Header);
Vue.use(Tabs);
Vue.use(Breadcrumb);
Vue.use(BreadcrumbItem);
Vue.use(Avatar);
Vue.use(TabPane);
Vue.use(Divider);
Vue.use(Table);
Vue.use(TableColumn);
Vue.use(Checkbox);
Vue.use(Cascader);
Vue.use(Tag);
Vue.use(Pagination);
Vue.use(Drawer);
Vue.use(Tree);
Vue.use(CheckboxGroup);
Vue.use(Popover);
Vue.use(InputNumber);
Vue.use(Switch);
Vue.use(Collapse);
Vue.use(CollapseItem);
Vue.use(Tooltip);
Vue.use(DatePicker);
Vue.use(Steps);
Vue.use(Upload);
Vue.use(Progress);
Vue.use(Scrollbar);
Vue.use(Loading.directive);
Vue.use(Button)
Vue.use(Select)
Vue.use(Dialog)
Vue.use(Form)
Vue.use(FormItem)
Vue.use(Input)
Vue.use(Option)
Vue.use(Container)
Vue.use(Card)
Vue.use(Dropdown)
Vue.use(DropdownMenu)
Vue.use(DropdownItem)
Vue.use(Row)
Vue.use(Col)
Vue.use(Menu)
Vue.use(Submenu)
Vue.use(MenuItem)
Vue.use(Aside)
Vue.use(Main)
Vue.use(Badge)
Vue.use(Header)
Vue.use(Tabs)
Vue.use(Breadcrumb)
Vue.use(BreadcrumbItem)
Vue.use(Avatar)
Vue.use(TabPane)
Vue.use(Divider)
Vue.use(Table)
Vue.use(TableColumn)
Vue.use(Checkbox)
Vue.use(Cascader)
Vue.use(Tag)
Vue.use(Pagination)
Vue.use(Drawer)
Vue.use(Tree)
Vue.use(CheckboxGroup)
Vue.use(Popover)
Vue.use(InputNumber)
Vue.use(Switch)
Vue.use(Collapse)
Vue.use(CollapseItem)
Vue.use(Tooltip)
Vue.use(DatePicker)
Vue.use(Steps)
Vue.use(Upload)
Vue.use(Progress)
Vue.use(Scrollbar)
Vue.use(Loading.directive)
Vue.use(Image)
Vue.prototype.$loading = Loading.service;
Vue.prototype.$message = Message;
Vue.prototype.$confirm = MessageBox.confirm;
Vue.prototype.$loading = Loading.service
Vue.prototype.$message = Message
Vue.prototype.$confirm = MessageBox.confirm
Dialog.props.closeOnClickModal.default = false
// 引入封装的router
@@ -118,20 +118,19 @@ import router from '@/router/index'
import '../node_modules/timeline-vuejs/dist/timeline-vuejs.css'
import '@/permission'
import { store } from '@/store/index'
import { store } from '@/store'
Vue.config.productionTip = false
// 路由守卫
import Bus from '@/utils/bus.js'
import Bus from '@/utils/bus'
Vue.use(Bus)
import APlayer from '@moefe/vue-aplayer';
import APlayer from '@moefe/vue-aplayer'
Vue.use(APlayer, {
defaultCover: 'https://github.com/u3u.png',
productionTip: true,
});
defaultCover: 'https://github.com/u3u.png',
productionTip: true
})
import { auth } from '@/directive/auth'
// 按钮权限指令
@@ -141,12 +140,11 @@ import uploader from 'vue-simple-uploader'
Vue.use(uploader)
export default new Vue({
render: h => h(App),
router,
store
render: h => h(App),
router,
store
}).$mount('#app')
console.log(`
欢迎使用 Gin-Vue-Admin
当前版本:V2.4.2
@@ -154,4 +152,4 @@ console.log(`
默认自动化文档地址:http://127.0.0.1:${process.env.VUE_APP_SERVER_PORT}/swagger/index.html
默认前端文件运行地址:http://127.0.0.1:${process.env.VUE_APP_CLI_PORT}
如果项目让您获得了收益,希望您能请团队喝杯可乐:https://www.gin-vue-admin.com/docs/coffee
`)
`)

View File

@@ -1,40 +1,40 @@
import { getDict } from "@/utils/dictionary";
import { getDict } from '@/utils/dictionary'
export default {
data() {
return {
page: 1,
total: 10,
pageSize: 10,
tableData: [],
searchInfo: {}
}
},
methods: {
filterDict(value, type) {
const rowLabel = this[type + "Options"] && this[type + "Options"].filter(item => item.value == value)
return rowLabel && rowLabel[0] && rowLabel[0].label
},
async getDict(type) {
const dicts = await getDict(type)
this[type + "Options"] = dicts
return dicts
},
handleSizeChange(val) {
this.pageSize = val
this.getTableData()
},
handleCurrentChange(val) {
this.page = val
this.getTableData()
},
async getTableData(page = this.page, pageSize = this.pageSize) {
const table = await this.listApi({ page, pageSize, ...this.searchInfo })
if (table.code == 0) {
this.tableData = table.data.list
this.total = table.data.total
this.page = table.data.page
this.pageSize = table.data.pageSize
}
}
data() {
return {
page: 1,
total: 10,
pageSize: 10,
tableData: [],
searchInfo: {}
}
}
},
methods: {
filterDict(value, type) {
const rowLabel = this[type + 'Options'] && this[type + 'Options'].filter(item => item.value === value)
return rowLabel && rowLabel[0] && rowLabel[0].label
},
async getDict(type) {
const dicts = await getDict(type)
this[type + 'Options'] = dicts
return dicts
},
handleSizeChange(val) {
this.pageSize = val
this.getTableData()
},
handleCurrentChange(val) {
this.page = val
this.getTableData()
},
async getTableData(page = this.page, pageSize = this.pageSize) {
const table = await this.listApi({ page, pageSize, ...this.searchInfo })
if (table.code === 0) {
this.tableData = table.data.list
this.total = table.data.total
this.page = table.data.page
this.pageSize = table.data.pageSize
}
}
}
}

View File

@@ -1,47 +1,47 @@
import router from './router'
import { store } from '@/store/index'
import { store } from '@/store'
import getPageTitle from '@/utils/page'
let asyncRouterFlag = 0
const whiteList = ['login', 'init']
router.beforeEach(async (to, from, next) => {
const token = store.getters['user/token']
// 在白名单中的判断情况
//修改网页标签名称
document.title = getPageTitle(to.meta.title)
if (whiteList.indexOf(to.name) > -1) {
if (token) {
next({ name: store.getters["user/userInfo"].authority.defaultRouter })
} else {
next()
}
const whiteList = ['Login', 'Init']
router.beforeEach(async(to, from, next) => {
const token = store.getters['user/token']
// 在白名单中的判断情况
// 修改网页标签名称
document.title = getPageTitle(to.meta.title)
if (whiteList.indexOf(to.name) > -1) {
if (token) {
next({ name: store.getters['user/userInfo'].authority.defaultRouter })
} else {
// 不在白名单中并且已经登陆的时候
if (token) {
// 添加flag防止多次获取动态路由和栈溢出
if (!asyncRouterFlag && store.getters['router/asyncRouters'].length == 0) {
asyncRouterFlag++
await store.dispatch('router/SetAsyncRouter')
const asyncRouters = store.getters['router/asyncRouters']
router.addRoutes(asyncRouters)
next({ ...to, replace: true })
} else {
if (to.matched.length) {
next()
} else {
next({ path: "/layout/404" })
}
}
}
// 不在白名单中并且未登陆的时候
if (!token) {
next({
name: "login",
query: {
redirect: document.location.hash
}
})
}
next()
}
})
} else {
// 不在白名单中并且已经登陆的时候
if (token) {
// 添加flag防止多次获取动态路由和栈溢出
if (!asyncRouterFlag && store.getters['router/asyncRouters'].length === 0) {
asyncRouterFlag++
await store.dispatch('router/SetAsyncRouter')
const asyncRouters = store.getters['router/asyncRouters']
router.addRoutes(asyncRouters)
next({ ...to, replace: true })
} else {
if (to.matched.length) {
next()
} else {
next({ path: '/layout/404' })
}
}
}
// 不在白名单中并且未登陆的时候
if (!token) {
next({
name: 'Login',
query: {
redirect: document.location.hash
}
})
}
}
})

View File

@@ -3,35 +3,34 @@ import Router from 'vue-router'
Vue.use(Router)
//获取原型对象上的push函数
// 获取原型对象上的push函数
const originalPush = Router.prototype.push
//修改原型对象中的push方法
// 修改原型对象中的push方法
Router.prototype.push = function push(location) {
return originalPush.call(this, location).catch(err => err)
return originalPush.call(this, location).catch(err => err)
}
const baseRouters = [{
const baseRouters = [
{
path: '/',
redirect: '/login'
},
{
path: "/init",
name: 'init',
component: () =>
import('@/view/init/init.vue')
},
{
},
{
path: '/init',
name: 'Init',
component: () => import('@/view/init/init')
},
{
path: '/login',
name: 'login',
component: () =>
import('@/view/login/login.vue')
}
name: 'Login',
component: () => import('@/view/login/login')
}
]
// 需要通过后台数据来生成的组件
const createRouter = () => new Router({
routes: baseRouters
routes: baseRouters
})
const router = createRouter()

View File

@@ -2,22 +2,20 @@ import Vue from 'vue'
import Vuex from 'vuex'
import VuexPersistence from 'vuex-persist'
import { user } from "@/store/module/user"
import { router } from "@/store/module/router"
import { dictionary } from "@/store/module/dictionary"
import { user } from '@/store/module/user'
import { router } from '@/store/module/router'
import { dictionary } from '@/store/module/dictionary'
Vue.use(Vuex)
const vuexLocal = new VuexPersistence({
storage: window.localStorage,
modules: ['user']
storage: window.localStorage,
modules: ['user']
})
export const store = new Vuex.Store({
modules: {
user,
router,
dictionary
},
plugins: [vuexLocal.plugin]
})
modules: {
user,
router,
dictionary
},
plugins: [vuexLocal.plugin]
})

View File

@@ -1,42 +1,42 @@
import { findSysDictionary } from '@/api/sysDictionary'
export const dictionary = {
namespaced: true,
state: {
dictionaryMap: {},
},
mutations: {
setDictionaryMap(state, dictionaryMap) {
state.dictionaryMap = { ...state.dictionaryMap, ...dictionaryMap }
},
},
actions: {
// 从后台获取动态路由
async getDictionary({ commit, state }, type) {
if (state.dictionaryMap[type]) {
return state.dictionaryMap[type]
} else {
const res = await findSysDictionary({ type })
if (res.code == 0) {
const dictionaryMap = {}
const dict = []
res.data.resysDictionary.sysDictionaryDetails && res.data.resysDictionary.sysDictionaryDetails.map(item => {
dict.push({
label: item.label,
value: item.value
})
})
dictionaryMap[res.data.resysDictionary.type] = dict
commit("setDictionaryMap", dictionaryMap)
return state.dictionaryMap[type]
}
}
}
},
getters:{
getDictionary(state){
return state.dictionaryMap
}
namespaced: true,
state: {
dictionaryMap: {}
},
mutations: {
setDictionaryMap(state, dictionaryMap) {
state.dictionaryMap = { ...state.dictionaryMap, ...dictionaryMap }
}
}
},
actions: {
// 从后台获取动态路由
async getDictionary({ commit, state }, type) {
if (state.dictionaryMap[type]) {
return state.dictionaryMap[type]
} else {
const res = await findSysDictionary({ type })
if (res.code === 0) {
const dictionaryMap = {}
const dict = []
res.data.resysDictionary.sysDictionaryDetails && res.data.resysDictionary.sysDictionaryDetails.map(item => {
dict.push({
label: item.label,
value: item.value
})
})
dictionaryMap[res.data.resysDictionary.type] = dict
commit('setDictionaryMap', dictionaryMap)
return state.dictionaryMap[type]
}
}
}
},
getters: {
getDictionary(state) {
return state.dictionaryMap
}
}
}

View File

@@ -1,83 +1,82 @@
import { asyncRouterHandle } from '@/utils/asyncRouter';
import { asyncRouterHandle } from '@/utils/asyncRouter'
import { asyncMenu } from '@/api/menu'
const routerList = []
const formatRouter = (routes) => {
routes && routes.map(item => {
if ((!item.children || item.children.every(ch => ch.hidden)) && item.name != '404') {
routerList.push({ label: item.meta.title, value: item.name })
}
if (item.children && item.children.length > 0) {
formatRouter(item.children)
}
})
routes && routes.map(item => {
if ((!item.children || item.children.every(ch => ch.hidden)) && item.name !== '404') {
routerList.push({ label: item.meta.title, value: item.name })
}
if (item.children && item.children.length > 0) {
formatRouter(item.children)
}
})
}
export const router = {
namespaced: true,
state: {
asyncRouters: [],
routerList: routerList,
namespaced: true,
state: {
asyncRouters: [],
routerList: routerList
},
mutations: {
setRouterList(state, routerList) {
state.routerList = routerList
},
mutations: {
setRouterList(state, routerList) {
state.routerList = routerList
},
// 设置动态路由
setAsyncRouter(state, asyncRouters) {
state.asyncRouters = asyncRouters
},
},
actions: {
// 从后台获取动态路由
async SetAsyncRouter({ commit }) {
const baseRouter = [{
path: '/layout',
name: 'layout',
component: "view/layout/index.vue",
meta: {
title: "底层layout"
},
children: []
}]
const asyncRouterRes = await asyncMenu()
if(asyncRouterRes.code !=0){
return
}
const asyncRouter = asyncRouterRes.data&&asyncRouterRes.data.menus
asyncRouter.push({
path: "404",
name: "404",
hidden: true,
meta: {
title: "迷路了*。*",
},
component: 'view/error/index.vue'
})
formatRouter(asyncRouter)
baseRouter[0].children = asyncRouter
baseRouter.push({
path: '*',
redirect: '/layout/404'
})
asyncRouterHandle(baseRouter)
commit('setAsyncRouter', baseRouter)
commit('setRouterList', routerList)
return true
}
},
getters: {
// 获取动态路由
asyncRouters(state) {
return state.asyncRouters
},
routerList(state) {
return state.routerList
},
defaultRouter(state) {
return state.defaultRouter
}
// 设置动态路由
setAsyncRouter(state, asyncRouters) {
state.asyncRouters = asyncRouters
}
}
},
actions: {
// 从后台获取动态路由
async SetAsyncRouter({ commit }) {
const baseRouter = [{
path: '/layout',
name: 'layout',
component: 'view/layout/index.vue',
meta: {
title: '底层layout'
},
children: []
}]
const asyncRouterRes = await asyncMenu()
if (asyncRouterRes.code !== 0) {
return
}
const asyncRouter = asyncRouterRes.data && asyncRouterRes.data.menus
asyncRouter.push({
path: '404',
name: '404',
hidden: true,
meta: {
title: '迷路了*。*'
},
component: 'view/error/index.vue'
})
formatRouter(asyncRouter)
baseRouter[0].children = asyncRouter
baseRouter.push({
path: '*',
redirect: '/layout/404'
})
asyncRouterHandle(baseRouter)
commit('setAsyncRouter', baseRouter)
commit('setRouterList', routerList)
return true
}
},
getters: {
// 获取动态路由
asyncRouters(state) {
return state.asyncRouters
},
routerList(state) {
return state.routerList
},
defaultRouter(state) {
return state.defaultRouter
}
}
}

View File

@@ -2,78 +2,77 @@ import { login } from '@/api/user'
import { jsonInBlacklist } from '@/api/jwt'
import router from '@/router/index'
export const user = {
namespaced: true,
state: {
userInfo: {
uuid: "",
nickName: "",
headerImg: "",
authority: "",
},
token: "",
namespaced: true,
state: {
userInfo: {
uuid: '',
nickName: '',
headerImg: '',
authority: ''
},
mutations: {
setUserInfo(state, userInfo) {
// 这里的 `state` 对象是模块的局部状态
state.userInfo = userInfo
},
setToken(state, token) {
// 这里的 `state` 对象是模块的局部状态
state.token = token
},
NeedInit(state){
state.userInfo = {}
state.token = ""
sessionStorage.clear()
router.push({ name: 'init', replace: true })
},
LoginOut(state) {
state.userInfo = {}
state.token = ""
sessionStorage.clear()
router.push({ name: 'login', replace: true })
window.location.reload()
},
ResetUserInfo(state, userInfo = {}) {
state.userInfo = {...state.userInfo,
...userInfo
}
}
token: ''
},
mutations: {
setUserInfo(state, userInfo) {
// 这里的 `state` 对象是模块的局部状态
state.userInfo = userInfo
},
actions: {
async LoginIn({ commit, dispatch, rootGetters, getters }, loginInfo) {
const res = await login(loginInfo)
if (res.code == 0) {
commit('setUserInfo', res.data.user)
commit('setToken', res.data.token)
await dispatch('router/SetAsyncRouter', {}, { root: true })
const asyncRouters = rootGetters['router/asyncRouters']
router.addRoutes(asyncRouters)
// const redirect = router.history.current.query.redirect
// console.log(redirect)
// if (redirect) {
// router.push({ path: redirect })
// } else {
router.push({ name: getters["userInfo"].authority.defaultRouter })
// }
return true
}
},
async LoginOut({ commit }) {
const res = await jsonInBlacklist()
if (res.code == 0) {
commit("LoginOut")
}
}
setToken(state, token) {
// 这里的 `state` 对象是模块的局部状态
state.token = token
},
getters: {
userInfo(state) {
return state.userInfo
},
token(state) {
return state.token
},
NeedInit(state) {
state.userInfo = {}
state.token = ''
sessionStorage.clear()
router.push({ name: 'Init', replace: true })
},
LoginOut(state) {
state.userInfo = {}
state.token = ''
sessionStorage.clear()
router.push({ name: 'Login', replace: true })
window.location.reload()
},
ResetUserInfo(state, userInfo = {}) {
state.userInfo = { ...state.userInfo,
...userInfo
}
}
}
},
actions: {
async LoginIn({ commit, dispatch, rootGetters, getters }, loginInfo) {
const res = await login(loginInfo)
if (res.code === 0) {
commit('setUserInfo', res.data.user)
commit('setToken', res.data.token)
await dispatch('router/SetAsyncRouter', {}, { root: true })
const asyncRouters = rootGetters['router/asyncRouters']
router.addRoutes(asyncRouters)
// const redirect = router.history.current.query.redirect
// console.log(redirect)
// if (redirect) {
// router.push({ path: redirect })
// } else {
router.push({ name: getters['userInfo'].authority.defaultRouter })
// }
return true
}
},
async LoginOut({ commit }) {
const res = await jsonInBlacklist()
if (res.code === 0) {
commit('LoginOut')
}
}
},
getters: {
userInfo(state) {
return state.userInfo
},
token(state) {
return state.token
}
}
}

View File

@@ -1,3 +1,3 @@
module.exports = file => () => {
return import ('@/' + file)
}
return import ('@/' + file)
}

View File

@@ -1,13 +1,13 @@
const _import = require('./_import') //获取组件的方法
const _import = require('./_import') // 获取组件的方法
export const asyncRouterHandle = (asyncRouter) => {
asyncRouter.map(item => {
if (item.component) {
item.component = _import(item.component)
} else {
delete item['component']
}
if (item.children) {
asyncRouterHandle(item.children)
}
})
}
asyncRouter.map(item => {
if (item.component) {
item.component = _import(item.component)
} else {
delete item['component']
}
if (item.children) {
asyncRouterHandle(item.children)
}
})
}

View File

@@ -1,18 +1,18 @@
const install = (Vue) => {
const Bus = new Vue({
methods: {
emit(event, ...args) {
this.$emit(event, ...args)
},
on(event, cb) {
this.$on(event, cb)
},
off(event, cb) {
this.$off(event, cb)
}
},
})
Vue.prototype.$bus = Bus
const Bus = new Vue({
methods: {
emit(event, ...args) {
this.$emit(event, ...args)
},
on(event, cb) {
this.$on(event, cb)
},
off(event, cb) {
this.$off(event, cb)
}
}
})
Vue.prototype.$bus = Bus
}
export default install
export default install

View File

@@ -3,28 +3,28 @@
// 年(y)可以用 1-4 个占位符,毫秒(S)只能用 1 个占位符(是 1-3 位的数字)
// (new Date()).Format("yyyy-MM-dd hh:mm:ss.S") ==> 2006-07-02 08:09:04.423
// (new Date()).Format("yyyy-M-d h:m:s.S") ==> 2006-7-2 8:9:4.18
// eslint-disable-next-line no-extend-native
Date.prototype.Format = function(fmt) {
var o = {
"M+": this.getMonth() + 1, //月份
"d+": this.getDate(), //日
"h+": this.getHours(), //小时
"m+": this.getMinutes(), //分
"s+": this.getSeconds(), //秒
"q+": Math.floor((this.getMonth() + 3) / 3), //季度
"S": this.getMilliseconds() //毫秒
};
if (/(y+)/.test(fmt))
fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
for (var k in o)
if (new RegExp("(" + k + ")").test(fmt))
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
return fmt;
var o = {
'M+': this.getMonth() + 1, // 月份
'd+': this.getDate(), //
'h+': this.getHours(), // 小时
'm+': this.getMinutes(), //
's+': this.getSeconds(), //
'q+': Math.floor((this.getMonth() + 3) / 3), // 季度
'S': this.getMilliseconds() // 毫秒
}
if (/(y+)/.test(fmt)) { fmt = fmt.replace(RegExp.$1, (this.getFullYear() + '').substr(4 - RegExp.$1.length)) }
for (var k in o) {
if (new RegExp('(' + k + ')').test(fmt)) { fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1) ? (o[k]) : (('00' + o[k]).substr(('' + o[k]).length))) }
}
return fmt
}
export function formatTimeToStr(times, pattern) {
var d = new Date(times).Format("yyyy-MM-dd hh:mm:ss");
if (pattern) {
d = new Date(times).Format(pattern);
}
return d.toLocaleString();
}
var d = new Date(times).Format('yyyy-MM-dd hh:mm:ss')
if (pattern) {
d = new Date(times).Format(pattern)
}
return d.toLocaleString()
}

View File

@@ -1,6 +1,6 @@
import { store } from '@/store/index'
import { store } from '@/store'
// 获取字典方法 使用示例 getDict('sex').then(res) 或者 async函数下 const res = await getDict('sex')
export const getDict = async (type) => {
await store.dispatch("dictionary/getDictionary", type)
return store.getters["dictionary/getDictionary"][type]
}
export const getDict = async(type) => {
await store.dispatch('dictionary/getDictionary', type)
return store.getters['dictionary/getDictionary'][type]
}

View File

@@ -1,19 +1,19 @@
export const downloadImage = (imgsrc, name) => { //下载图片地址和图片名
var image = new Image();
image.setAttribute("crossOrigin", "anonymous");
image.onload = function() {
var canvas = document.createElement("canvas");
canvas.width = image.width;
canvas.height = image.height;
var context = canvas.getContext("2d");
context.drawImage(image, 0, 0, image.width, image.height);
var url = canvas.toDataURL("image/png"); //得到图片的base64编码数据
export const downloadImage = (imgsrc, name) => { // 下载图片地址和图片名
var image = new Image()
image.setAttribute('crossOrigin', 'anonymous')
image.onload = function() {
var canvas = document.createElement('canvas')
canvas.width = image.width
canvas.height = image.height
var context = canvas.getContext('2d')
context.drawImage(image, 0, 0, image.width, image.height)
var url = canvas.toDataURL('image/png') // 得到图片的base64编码数据
var a = document.createElement("a"); // 生成一个a元素
var event = new MouseEvent("click"); // 创建一个单击事件
a.download = name || "photo"; // 设置图片名称
a.href = url; // 将生成的URL设置为a.href属性
a.dispatchEvent(event); // 触发a的单击事件
};
image.src = imgsrc;
}
var a = document.createElement('a') // 生成一个a元素
var event = new MouseEvent('click') // 创建一个单击事件
a.download = name || 'photo' // 设置图片名称
a.href = url // 将生成的URL设置为a.href属性
a.dispatchEvent(event) // 触发a的单击事件
}
image.src = imgsrc
}

View File

@@ -1,94 +1,92 @@
export default class ImageCompress {
constructor(file, fileSize, maxWH = 1920) {
this.file = file
this.fileSize = fileSize
this.maxWH = maxWH // 最大长宽
}
constructor(file, fileSize, maxWH = 1920) {
this.file = file
this.fileSize = fileSize
this.maxWH = maxWH // 最大长宽
}
compress() {
// 压缩
const fileType = this.file.type
const fileSize = this.file.size / 1024
return new Promise(resolve => {
const reader = new FileReader();
reader.readAsDataURL(this.file);
reader.onload = () => {
const canvas = document.createElement('canvas');
const img = document.createElement('img');
img.src = reader.result;
img.onload = () => {
const ctx = canvas.getContext('2d');
let _dWH = this.dWH(img.width, img.height, this.maxWH)
canvas.width = _dWH.width
canvas.height = _dWH.height
compress() {
// 压缩
const fileType = this.file.type
const fileSize = this.file.size / 1024
return new Promise(resolve => {
const reader = new FileReader()
reader.readAsDataURL(this.file)
reader.onload = () => {
const canvas = document.createElement('canvas')
const img = document.createElement('img')
img.src = reader.result
img.onload = () => {
const ctx = canvas.getContext('2d')
const _dWH = this.dWH(img.width, img.height, this.maxWH)
canvas.width = _dWH.width
canvas.height = _dWH.height
// 清空后, 重写画布
ctx.clearRect(0, 0, canvas.width, canvas.height)
ctx.drawImage(img, 0, 0, canvas.width, canvas.height)
// 清空后, 重写画布
ctx.clearRect(0, 0, canvas.width, canvas.height)
ctx.drawImage(img, 0, 0, canvas.width, canvas.height)
let newImgData = canvas.toDataURL(fileType, 0.90)
const newImgData = canvas.toDataURL(fileType, 0.90)
// 压缩宽高后的图像大小
let newImgSize = this.fileSizeKB(newImgData)
// 压缩宽高后的图像大小
const newImgSize = this.fileSizeKB(newImgData)
if (newImgSize > this.fileSize) {
console.log('图片尺寸太大!' + fileSize + " >> " + newImgSize)
}
if (newImgSize > this.fileSize) {
console.log('图片尺寸太大!' + fileSize + ' >> ' + newImgSize)
}
let blob = this.dataURLtoBlob(newImgData, fileType)
let nfile = new File([blob], this.file.name);
resolve(nfile)
};
};
});
}
/*
* 长宽等比缩小
* 图像的一边(长或宽)为最大目标值
* */
dWH(srcW, srcH, dMax) {
let defaults = {
width: srcW,
height: srcH
const blob = this.dataURLtoBlob(newImgData, fileType)
const nfile = new File([blob], this.file.name)
resolve(nfile)
}
if (Math.max(srcW, srcH) > dMax) {
if (srcW > srcH) {
defaults.width = dMax
defaults.height = Math.round(srcH * (dMax / srcW))
return defaults
} else {
defaults.height = dMax
defaults.width = Math.round(srcW * (dMax / srcH))
return defaults
}
} else {
return defaults
}
}
}
})
}
fileSizeKB(dataURL) {
let sizeKB = 0
sizeKB = Math.round((dataURL.split(',')[1].length * 3 / 4) / 1024)
return sizeKB
/**
* 长宽等比缩小
* 图像的一边(长或宽)为最大目标值
*/
dWH(srcW, srcH, dMax) {
const defaults = {
width: srcW,
height: srcH
}
/*
* 转为Blob
* */
dataURLtoBlob(dataURL, fileType) {
let byteString = atob(dataURL.split(',')[1])
let mimeString = dataURL.split(',')[0].split(':')[1].split(';')[0]
let ab = new ArrayBuffer(byteString.length)
let ia = new Uint8Array(ab)
for (let i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i)
}
if (fileType) {
mimeString = fileType
}
return new Blob([ab], { type: mimeString, lastModifiedDate: new Date() })
if (Math.max(srcW, srcH) > dMax) {
if (srcW > srcH) {
defaults.width = dMax
defaults.height = Math.round(srcH * (dMax / srcW))
return defaults
} else {
defaults.height = dMax
defaults.width = Math.round(srcW * (dMax / srcH))
return defaults
}
} else {
return defaults
}
}
}
fileSizeKB(dataURL) {
let sizeKB = 0
sizeKB = Math.round((dataURL.split(',')[1].length * 3 / 4) / 1024)
return sizeKB
}
/**
* 转为Blob
*/
dataURLtoBlob(dataURL, fileType) {
const byteString = atob(dataURL.split(',')[1])
let mimeString = dataURL.split(',')[0].split(':')[1].split(';')[0]
const ab = new ArrayBuffer(byteString.length)
const ia = new Uint8Array(ab)
for (let i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i)
}
if (fileType) {
mimeString = fileType
}
return new Blob([ab], { type: mimeString, lastModifiedDate: new Date() })
}
}

View File

@@ -1,8 +1,8 @@
const title = 'GIN-VUE-ADMIN'
export default function getPageTitle(pageTitle) {
if (pageTitle) {
return `${pageTitle} - ${title}`
}
return `${title}`
}
if (pageTitle) {
return `${pageTitle} - ${title}`
}
return `${title}`
}

View File

@@ -1,103 +1,102 @@
import axios from 'axios'; // 引入axios
import { Message } from 'element-ui';
import { store } from '@/store/index'
import context from '@/main.js'
import axios from 'axios' // 引入axios
import { Message } from 'element-ui'
import { store } from '@/store'
import context from '@/main'
import router from '@/router/index'
const service = axios.create({
baseURL: process.env.VUE_APP_BASE_API,
timeout: 99999
baseURL: process.env.VUE_APP_BASE_API,
timeout: 99999
})
let acitveAxios = 0
let timer
const showLoading = () => {
acitveAxios++
if (timer) {
clearTimeout(timer)
acitveAxios++
if (timer) {
clearTimeout(timer)
}
timer = setTimeout(() => {
if (acitveAxios > 0) {
context.$bus.emit('showLoading')
}
timer = setTimeout(() => {
if (acitveAxios > 0) {
context.$bus.emit("showLoading")
}
}, 400);
}, 400)
}
const closeLoading = () => {
acitveAxios--
if (acitveAxios <= 0) {
clearTimeout(timer)
context.$bus.emit("closeLoading")
}
}
//http request 拦截器
acitveAxios--
if (acitveAxios <= 0) {
clearTimeout(timer)
context.$bus.emit('closeLoading')
}
}
// http request 拦截器
service.interceptors.request.use(
config => {
if (!config.donNotShowLoading) {
showLoading()
}
const token = store.getters['user/token']
const user = store.getters['user/userInfo']
config.data = JSON.stringify(config.data);
config.headers = {
'Content-Type': 'application/json',
'x-token': token,
'x-user-id': user.ID
}
return config;
},
error => {
closeLoading()
Message({
showClose: true,
message: error,
type: 'error'
})
return error;
config => {
if (!config.donNotShowLoading) {
showLoading()
}
);
//http response 拦截器
service.interceptors.response.use(
response => {
closeLoading()
if (response.headers["new-token"]) {
store.commit('user/setToken', response.headers["new-token"])
}
if(response.data.code == 0){
if(response.data.data?.needInit){
Message({
type:"info",
message:"您是第一次使用,请初始化"
})
store.commit("user/NeedInit")
router.push({name:"init"})
}
}
if (response.data.code == 0 || response.headers.success === "true") {
return response.data
} else {
Message({
showClose: true,
message: response.data.msg || decodeURI(response.headers.msg),
type: response.headers.msgtype||'error',
})
if (response.data.data && response.data.data.reload) {
store.commit('user/LoginOut')
}
return response.data.msg ? response.data : response
}
},
error => {
closeLoading()
Message({
showClose: true,
message: error,
type: 'error'
})
return error
const token = store.getters['user/token']
const user = store.getters['user/userInfo']
config.data = JSON.stringify(config.data)
config.headers = {
'Content-Type': 'application/json',
'x-token': token,
'x-user-id': user.ID
}
return config
},
error => {
closeLoading()
Message({
showClose: true,
message: error,
type: 'error'
})
return error
}
)
export default service
// http response 拦截器
service.interceptors.response.use(
response => {
closeLoading()
if (response.headers['new-token']) {
store.commit('user/setToken', response.headers['new-token'])
}
if (response.data.code === 0) {
if (response.data.data?.needInit) {
Message({
type: 'info',
message: '您是第一次使用,请初始化'
})
store.commit('user/NeedInit')
router.push({ name: 'Init' })
}
}
if (response.data.code === 0 || response.headers.success === 'true') {
return response.data
} else {
Message({
showClose: true,
message: response.data.msg || decodeURI(response.headers.msg),
type: response.headers.msgtype || 'error'
})
if (response.data.data && response.data.data.reload) {
store.commit('user/LoginOut')
}
return response.data.msg ? response.data : response
}
},
error => {
closeLoading()
Message({
showClose: true,
message: error,
type: 'error'
})
return error
}
)
export default service

View File

@@ -3,7 +3,7 @@ export const toUpperCase = (str) => {
if (str[0]) {
return str.replace(str[0], str[0].toUpperCase())
} else {
return ""
return ''
}
}
@@ -11,13 +11,13 @@ export const toLowerCase = (str) => {
if (str[0]) {
return str.replace(str[0], str[0].toLowerCase())
} else {
return ""
return ''
}
}
// 驼峰转换下划线
export const toSQLLine = (str) => {
if (str == "ID") return "ID"
if (str === 'ID') return 'ID'
return str.replace(/([A-Z])/g, "_$1").toLowerCase();
}

View File

@@ -12,7 +12,7 @@
class="org-img dom-center"
src="@/assets/logo.png"
alt="gin-vue-admin"
/>
>
</a>
</el-col>
</el-row>
@@ -23,7 +23,7 @@
class="dom-center"
src="https://img.shields.io/github/watchers/flipped-aurora/gin-vue-admin.svg?label=Watch"
alt=""
/>
>
</a>
</el-col>
<el-col :span="8">
@@ -31,15 +31,19 @@
<img
class="dom-center"
src="https://img.shields.io/github/stars/flipped-aurora/gin-vue-admin.svg?style=social"
alt=""/></a
></el-col>
alt=""
>
</a>
</el-col>
<el-col :span="8">
<a href="https://github.com/flipped-aurora/gin-vue-admin">
<img
class="dom-center"
src="https://img.shields.io/github/forks/flipped-aurora/gin-vue-admin.svg?label=Fork"
alt=""/></a
></el-col>
alt=""
>
</a>
</el-col>
</el-row>
</div>
</el-card>
@@ -53,15 +57,15 @@
class="org-img dom-center"
src="@/assets/flipped-aurora.png"
alt="flipped-aurora"
/>
>
</a>
</el-col>
</el-row>
<el-row style="margin-left: 40px" :gutter="20">
<template v-for="(item, index) in members">
<el-col :span="8" :key="index">
<el-col :key="index" :span="8">
<a :href="item.html_url">
<img class="avatar-img" :src="item.avatar_url" />
<img class="avatar-img" :src="item.avatar_url">
<a class="author-name" style="">{{ item.login }}</a>
</a>
</el-col>
@@ -79,16 +83,18 @@
<Timeline
:timeline-items="dataTimeline"
:message-when-no-items="messageWhenNoItems"
:uniqueTimeline="true"
:unique-timeline="true"
:unique-year="true"
:show-day-and-month="true"
order="desc"
dateLocale="zh-CN"
date-locale="zh-CN"
/>
</div>
<el-button class="load-more" @click="loadMore" type="text"
>Load more</el-button
>
<el-button
class="load-more"
type="text"
@click="loadMore"
>Load more</el-button>
</el-card>
</el-col>
</el-row>
@@ -96,29 +102,29 @@
</template>
<script>
import { Commits, Members } from "@/api/github";
import Timeline from "timeline-vuejs";
import { Commits, Members } from '@/api/github'
import Timeline from 'timeline-vuejs'
export default {
name: "Test",
name: 'About',
components: {
Timeline,
Timeline
},
data() {
return {
messageWhenNoItems: "There arent commits",
messageWhenNoItems: 'There arent commits',
members: [],
dataTimeline: [],
page: 0,
};
page: 0
}
},
created() {
this.loadCommits();
this.loadMembers();
this.loadCommits()
this.loadMembers()
},
methods: {
loadMore() {
this.page++;
this.loadCommits();
this.page++
this.loadCommits()
},
loadCommits() {
Commits(this.page).then(({ data }) => {
@@ -128,20 +134,20 @@ export default {
from: new Date(element.commit.author.date),
title: element.commit.author.name,
showDayAndMonth: true,
description: `<a style="color: #26191b" href="${element.html_url}">${element.commit.message}</a>`,
});
description: `<a style="color: #26191b" href="${element.html_url}">${element.commit.message}</a>`
})
}
});
});
})
})
},
loadMembers() {
Members().then(({ data }) => {
this.members = data;
this.members.sort();
});
},
},
};
this.members = data
this.members.sort()
})
}
}
}
</script>
<style scoped>

View File

@@ -1,48 +1,44 @@
<template>
<div>
<div style="width: 100%">
<APlayer :audio="audio"></APlayer>
</div>
<div>
<div style="width: 100%">
<APlayer :audio="audio" />
</div>
</div>
</template>
<script>
import { APlayer } from '@moefe/vue-aplayer';
export default {
name: "musicPlayer",
components:{
APlayer
import { APlayer } from '@moefe/vue-aplayer'
export default {
name: 'MusicPlayer',
components: {
APlayer
},
data() {
return {
audio: [
{
name: '东西Cover林俊呈',
artist: '纳豆',
url: 'http://music.163.com/song/media/outer/url?id=1321594530.mp3',
cover: 'https://p1.music.126.net/5zs7IvmLv7KahY3BFzUmrg==/109951163635241613.jpg?param=300y300', // prettier-ignore
lrc: 'https://cdn.moefe.org/music/lrc/thing.lrc'
},
data(){
return {
audio :[
{
name: '东西Cover林俊呈',
artist: '纳豆',
url: 'http://music.163.com/song/media/outer/url?id=1321594530.mp3',
cover: 'https://p1.music.126.net/5zs7IvmLv7KahY3BFzUmrg==/109951163635241613.jpg?param=300y300', // prettier-ignore
lrc: 'https://cdn.moefe.org/music/lrc/thing.lrc',
},
{
name: '响喜乱舞CoverMARiA',
artist: '泠鸢yousa',
url: 'http://music.163.com/song/media/outer/url?id=1318962459.mp3',
cover: 'https://p1.music.126.net/AUGVPQ_rVrngDH9ocQrn3Q==/109951163613037822.jpg?param=300y300', // prettier-ignore
lrc: 'https://cdn.moefe.org/music/lrc/kyoukiranbu.lrc',
},
{
name: '啵唧',
artist: 'Hanser',
url: 'http://music.163.com/song/media/outer/url?id=1321424246.mp3',
cover: 'https://p1.music.126.net/K0-IPcIQ9QFvA0jXTBqoWQ==/109951163636756693.jpg?param=300y300', // prettier-ignore
lrc: 'https://cdn.moefe.org/music/lrc/kiss.lrc',
},
]
}
{
name: '响喜乱舞CoverMARiA',
artist: '泠鸢yousa',
url: 'http://music.163.com/song/media/outer/url?id=1318962459.mp3',
cover: 'https://p1.music.126.net/AUGVPQ_rVrngDH9ocQrn3Q==/109951163613037822.jpg?param=300y300', // prettier-ignore
lrc: 'https://cdn.moefe.org/music/lrc/kyoukiranbu.lrc'
},
{
name: '啵唧',
artist: 'Hanser',
url: 'http://music.163.com/song/media/outer/url?id=1321424246.mp3',
cover: 'https://p1.music.126.net/K0-IPcIQ9QFvA0jXTBqoWQ==/109951163636756693.jpg?param=300y300', // prettier-ignore
lrc: 'https://cdn.moefe.org/music/lrc/kiss.lrc'
}
]
}
}
}
</script>
<style scoped>
</style>

View File

@@ -1,81 +1,81 @@
<template>
<li :class="{ completed: todo.done, editing: editing }" class="todo">
<div class="view">
<input
:checked="todo.done"
class="toggle"
type="checkbox"
@change="toggleTodo( todo)"
>
<label @dblclick="editing = true" v-text="todo.text" />
<button class="destroy" @click="deleteTodo( todo )" />
</div>
<input
v-show="editing"
v-focus="editing"
:value="todo.text"
class="edit"
@keyup.enter="doneEdit"
@keyup.esc="cancelEdit"
@blur="doneEdit"
>
</li>
<li :class="{ completed: todo.done, editing: editing }" class="todo">
<div class="view">
<input
:checked="todo.done"
class="toggle"
type="checkbox"
@change="toggleTodo( todo)"
>
<label @dblclick="editing = true" v-text="todo.text" />
<button class="destroy" @click="deleteTodo( todo )" />
</div>
<input
v-show="editing"
v-focus="editing"
:value="todo.text"
class="edit"
@keyup.enter="doneEdit"
@keyup.esc="cancelEdit"
@blur="doneEdit"
>
</li>
</template>
<script>
export default {
name: 'Todo',
directives: {
focus(el, { value }, { context }) {
if (value) {
context.$nextTick(() => {
el.focus()
})
}
}
},
props: {
todo: {
type: Object,
default: function() {
return {}
}
}
},
data() {
return {
editing: false
}
},
methods: {
deleteTodo(todo) {
this.$emit('deleteTodo', todo)
},
editTodo({ todo, value }) {
this.$emit('editTodo', { todo, value })
},
toggleTodo(todo) {
this.$emit('toggleTodo', todo)
},
doneEdit(e) {
const value = e.target.value.trim()
const { todo } = this
if (!value) {
this.deleteTodo({
todo
})
} else if (this.editing) {
this.editTodo({
todo,
value
})
this.editing = false
}
},
cancelEdit(e) {
e.target.value = this.todo.text
this.editing = false
}
}
export default {
name: 'Todo',
directives: {
focus(el, { value }, { context }) {
if (value) {
context.$nextTick(() => {
el.focus()
})
}
}
},
props: {
todo: {
type: Object,
default: function() {
return {}
}
}
},
data() {
return {
editing: false
}
},
methods: {
deleteTodo(todo) {
this.$emit('deleteTodo', todo)
},
editTodo({ todo, value }) {
this.$emit('editTodo', { todo, value })
},
toggleTodo(todo) {
this.$emit('toggleTodo', todo)
},
doneEdit(e) {
const value = e.target.value.trim()
const { todo } = this
if (!value) {
this.deleteTodo({
todo
})
} else if (this.editing) {
this.editTodo({
todo,
value
})
this.editing = false
}
},
cancelEdit(e) {
e.target.value = this.todo.text
this.editing = false
}
}
}
</script>

View File

@@ -1,120 +1,120 @@
<template>
<section class="todoapp">
<!-- header -->
<header class="header">
<input class="new-todo" autocomplete="off" placeholder="Todo List" @keyup.enter="addTodo">
</header>
<!-- main section -->
<section v-show="todos.length" class="main">
<input id="toggle-all" :checked="allChecked" class="toggle-all" type="checkbox" @change="toggleAll({ done: !allChecked })">
<label for="toggle-all" />
<ul class="todo-list">
<todo
v-for="(todo, index) in filteredTodos"
:key="index"
:todo="todo"
@toggleTodo="toggleTodo"
@editTodo="editTodo"
@deleteTodo="deleteTodo"
/>
</ul>
</section>
<!-- footer -->
<footer v-show="todos.length" class="footer">
<section class="todoapp">
<!-- header -->
<header class="header">
<input class="new-todo" autocomplete="off" placeholder="Todo List" @keyup.enter="addTodo">
</header>
<!-- main section -->
<section v-show="todos.length" class="main">
<input id="toggle-all" :checked="allChecked" class="toggle-all" type="checkbox" @change="toggleAll({ done: !allChecked })">
<label for="toggle-all" />
<ul class="todo-list">
<todo
v-for="(todo, index) in filteredTodos"
:key="index"
:todo="todo"
@toggleTodo="toggleTodo"
@editTodo="editTodo"
@deleteTodo="deleteTodo"
/>
</ul>
</section>
<!-- footer -->
<footer v-show="todos.length" class="footer">
<span class="todo-count">
<strong>{{ remaining }}</strong>
{{ remaining | pluralize('item') }} left
</span>
<ul class="filters">
<li v-for="(val, key) in filters" :key="key">
<a :class="{ selected: visibility === key }" @click.prevent="visibility = key">{{ key | capitalize }}</a>
</li>
</ul>
<!-- <button class="clear-completed" v-show="todos.length > remaining" @click="clearCompleted">
Clear completed
</button> -->
</footer>
</section>
<ul class="filters">
<li v-for="(val, key) in filters" :key="key">
<a :class="{ selected: visibility === key }" @click.prevent="visibility = key">{{ key | capitalize }}</a>
</li>
</ul>
<!-- <button class="clear-completed" v-show="todos.length > remaining" @click="clearCompleted">
Clear completed
</button> -->
</footer>
</section>
</template>
<script>
import Todo from './Todo.vue'
import Todo from './Todo.vue'
const STORAGE_KEY = 'todos'
const filters = {
all: todos => todos,
active: todos => todos.filter(todo => !todo.done),
completed: todos => todos.filter(todo => todo.done)
const STORAGE_KEY = 'todos'
const filters = {
all: todos => todos,
active: todos => todos.filter(todo => !todo.done),
completed: todos => todos.filter(todo => todo.done)
}
const defaultList = [
{ text: '工作流功能绘制工具', done: false },
{ text: '工作流流转方法', done: false },
{ text: '自动化代码优化', done: false }
]
export default {
components: { Todo },
filters: {
pluralize: (n, w) => n === 1 ? w : w + 's',
capitalize: s => s.charAt(0).toUpperCase() + s.slice(1)
},
data() {
return {
visibility: 'all',
filters,
// todos: JSON.parse(window.localStorage.getItem(STORAGE_KEY)) || defaultList
todos: defaultList
}
const defalutList = [
{ text: '工作流功能绘制工具', done: false },
{ text: '工作流流转方法', done: false },
{ text: '自动化代码优化', done: false }
]
export default {
components: { Todo },
filters: {
pluralize: (n, w) => n === 1 ? w : w + 's',
capitalize: s => s.charAt(0).toUpperCase() + s.slice(1)
},
data() {
return {
visibility: 'all',
filters,
// todos: JSON.parse(window.localStorage.getItem(STORAGE_KEY)) || defalutList
todos: defalutList
}
},
computed: {
allChecked() {
return this.todos.every(todo => todo.done)
},
filteredTodos() {
return filters[this.visibility](this.todos)
},
remaining() {
return this.todos.filter(todo => !todo.done).length
}
},
methods: {
setLocalStorage() {
window.localStorage.setItem(STORAGE_KEY, JSON.stringify(this.todos))
},
addTodo(e) {
const text = e.target.value
if (text.trim()) {
this.todos.push({
text,
done: false
})
this.setLocalStorage()
}
e.target.value = ''
},
toggleTodo(val) {
val.done = !val.done
this.setLocalStorage()
},
deleteTodo(todo) {
this.todos.splice(this.todos.indexOf(todo), 1)
this.setLocalStorage()
},
editTodo({ todo, value }) {
todo.text = value
this.setLocalStorage()
},
clearCompleted() {
this.todos = this.todos.filter(todo => !todo.done)
this.setLocalStorage()
},
toggleAll({ done }) {
this.todos.forEach(todo => {
todo.done = done
this.setLocalStorage()
})
}
}
},
computed: {
allChecked() {
return this.todos.every(todo => todo.done)
},
filteredTodos() {
return filters[this.visibility](this.todos)
},
remaining() {
return this.todos.filter(todo => !todo.done).length
}
},
methods: {
setLocalStorage() {
window.localStorage.setItem(STORAGE_KEY, JSON.stringify(this.todos))
},
addTodo(e) {
const text = e.target.value
if (text.trim()) {
this.todos.push({
text,
done: false
})
this.setLocalStorage()
}
e.target.value = ''
},
toggleTodo(val) {
val.done = !val.done
this.setLocalStorage()
},
deleteTodo(todo) {
this.todos.splice(this.todos.indexOf(todo), 1)
this.setLocalStorage()
},
editTodo({ todo, value }) {
todo.text = value
this.setLocalStorage()
},
clearCompleted() {
this.todos = this.todos.filter(todo => !todo.done)
this.setLocalStorage()
},
toggleAll({ done }) {
this.todos.forEach(todo => {
todo.done = done
this.setLocalStorage()
})
}
}
}
</script>
<style lang="scss">

View File

@@ -2,20 +2,20 @@
<div class="big">
<el-row>
<div class="card">
<el-col :xs="24" :lg="16" :md="16" >
<el-col :xs="24" :lg="16" :md="16">
<div class="car-left">
<el-row>
<div>
<el-col :xs="4" :md="3" :lg="3">
<span class="card-img">
<img :src="userInfo.headerImg" alt="" />
<img :src="userInfo.headerImg" alt="">
</span>
</el-col>
<el-col :xs="20" :lg="12" :md="12">
<div class="text">
<h4>早安管理员 请开始您一天的工作吧</h4>
<p class="tips-text">
<i class="el-icon-sunny el-icon"></i>
<i class="el-icon-sunny el-icon" />
<span>今日晴0 - 10天气寒冷注意添加衣物</span>
</p>
</div>
@@ -24,34 +24,34 @@
</el-row>
</div>
</el-col>
<el-col :xs="24" :lg='8' :md="8">
<el-col :xs="24" :lg="8" :md="8">
<div class="car-right">
<el-row>
<el-col :span="8"
><div class="car-item">
<span class="flow"><i class="el-icon-s-grid"></i></span>
<el-col :span="8">
<div class="car-item">
<span class="flow"><i class="el-icon-s-grid" /></span>
<span>今日流量 </span>
<b>13260</b>
</div></el-col
>
<el-col :span="8"
><div class="car-item">
</div>
</el-col>
<el-col :span="8">
<div class="car-item">
<span class="user-number">
<i class="el-icon-s-custom"></i>
<i class="el-icon-s-custom" />
</span>
<span>总用户 </span>
<b>48286</b>
</div></el-col
>
<el-col :span="8"
><div class="car-item">
</div>
</el-col>
<el-col :span="8">
<div class="car-item">
<span class="feedback">
<i class="el-icon-star-on"></i>
<i class="el-icon-star-on" />
</span>
<span>好评率 </span>
<b>98%</b>
</div></el-col
>
</div>
</el-col>
</el-row>
</div>
</el-col>
@@ -59,27 +59,27 @@
</el-row>
<el-row>
<el-card shadow="hover">
<h2>
使用教学<a style="color:#409EFF" target="view_window" href="https://www.bilibili.com/video/BV1fV411y7dT/">https://www.bilibili.com/video/BV1fV411y7dT/</a>
</h2>
<br>
<h2>
工作流教学<a style="color:#409EFF" target="view_window" href="https://www.bilibili.com/video/BV1Ka411F7Ji/">https://www.bilibili.com/video/BV1Ka411F7Ji/</a>
</h2>
<div></div>
<h2>
使用教学<a style="color:#409EFF" target="view_window" href="https://www.bilibili.com/video/BV1fV411y7dT/">https://www.bilibili.com/video/BV1fV411y7dT/</a>
</h2>
<br>
<h2>
工作流教学<a style="color:#409EFF" target="view_window" href="https://www.bilibili.com/video/BV1Ka411F7Ji/">https://www.bilibili.com/video/BV1Ka411F7Ji/</a>
</h2>
<div />
</el-card>
</el-row>
<div class="shadow">
<el-row :gutter="20">
<el-col
:span="4"
v-for="(card, key) in toolCards"
:key="key"
@click.native="toTarget(card.name)"
:span="4"
:xs="8"
@click.native="toTarget(card.name)"
>
<el-card shadow="hover" class="grid-content">
<i :class="card.icon" :style="{ color: card.color }"></i>
<i :class="card.icon" :style="{ color: card.color }" />
<p>{{ card.label }}</p>
</el-card>
</el-col>
@@ -89,7 +89,7 @@
<el-row :gutter="32">
<el-col :xs="24" :sm="24" :lg="12">
<div class="chart-player">
<musicPlayer />
<music-player />
</div>
</el-col>
<el-col :xs="24" :sm="24" :lg="12">
@@ -103,69 +103,69 @@
</template>
<script>
import musicPlayer from "./component/musicPlayer";
import TodoList from "./component/todoList";
import { mapGetters } from "vuex";
import musicPlayer from './component/musicPlayer'
import TodoList from './component/todoList'
import { mapGetters } from 'vuex'
export default {
name: "Dashboard",
data() {
return {
toolCards: [
{
label: "用户管理",
icon: "el-icon el-icon-monitor",
name: "user",
color: "#ff9c6e",
},
{
label: "角色管理",
icon: "el-icon el-icon-setting",
name: "authority",
color: "#69c0ff",
},
{
label: "菜单管理",
icon: "el-icon el-icon-menu",
name: "menu",
color: "#b37feb",
},
{
label: "代码生成器",
icon: "el-icon el-icon-cpu",
name: "autoCode",
color: "#ffd666",
},
{
label: "表单生成器",
icon: "el-icon el-icon-document-checked",
name: "formCreate",
color: "#ff85c0",
},
{
label: "关于我们",
icon: "el-icon el-icon-user",
name: "about",
color: "#5cdbd3",
},
],
};
},
computed: {
...mapGetters("user", ["userInfo"]),
},
name: 'Dashboard',
components: {
musicPlayer, //音乐播放器
TodoList, //TodoList
musicPlayer, // 音乐播放器
TodoList // TodoList
// RaddarChart, //雷达图
// stackMap, //堆叠图
// Sunburst, //旭日图
},
data() {
return {
toolCards: [
{
label: '用户管理',
icon: 'el-icon el-icon-monitor',
name: 'user',
color: '#ff9c6e'
},
{
label: '角色管理',
icon: 'el-icon el-icon-setting',
name: 'authority',
color: '#69c0ff'
},
{
label: '菜单管理',
icon: 'el-icon el-icon-menu',
name: 'menu',
color: '#b37feb'
},
{
label: '代码生成器',
icon: 'el-icon el-icon-cpu',
name: 'autoCode',
color: '#ffd666'
},
{
label: '表单生成器',
icon: 'el-icon el-icon-document-checked',
name: 'formCreate',
color: '#ff85c0'
},
{
label: '关于我们',
icon: 'el-icon el-icon-user',
name: 'about',
color: '#5cdbd3'
}
]
}
},
computed: {
...mapGetters('user', ['userInfo'])
},
methods: {
toTarget(name) {
this.$router.push({ name });
},
},
};
this.$router.push({ name })
}
}
}
</script>
<style lang="scss" scoped>

View File

@@ -1,21 +1,21 @@
<template>
<div>
<div class="big">
<div class="inner">
<img src="../../assets/notFound.png">
<p>页面被神秘力量吸走了请联系我们修复</p>
<p style="font-size:18px;line-height:40px;">常见问题为菜单未分配仪表盘可自行分配仪表盘或修改默认路由</p>
<p></p>
<img src="../../assets/qm.png" class="leftPic">
</div>
</div>
<div>
<div class="big">
<div class="inner">
<img src="../../assets/notFound.png">
<p>页面被神秘力量吸走了请联系我们修复</p>
<p style="font-size:18px;line-height:40px;">常见问题为菜单未分配仪表盘可自行分配仪表盘或修改默认路由</p>
<p></p>
<img src="../../assets/qm.png" class="leftPic">
</div>
</div>
</div>
</template>
<script>
export default {
name:"Login"
name: 'Error'
}
</script>
@@ -42,4 +42,4 @@ export default {
margin-left: 44%;
margin-top: 20px;
}
</style>
</style>

View File

@@ -1,30 +1,31 @@
<template>
<div class="hello">
<el-divider content-position="left">大文件上传</el-divider>
<form id="fromCont" method="post" >
<el-divider content-position="left">大文件上传</el-divider>
<form id="fromCont" method="post">
<div class="fileUpload" @click="inputChange">
选择文件
<input v-show="false" @change="choseFile" id="file" multiple="multiple" type="file" ref="Input" />
<input v-show="false" id="file" ref="Input" multiple="multiple" type="file" @change="choseFile">
</div>
</form>
<el-button @click="getFile" :disabled="limitFileSize" type="primary" size="medium" class="uploadBtn">上传文件</el-button>
<el-button :disabled="limitFileSize" type="primary" size="medium" class="uploadBtn" @click="getFile">上传文件</el-button>
<div class="el-upload__tip">请上传不超过5MB的文件</div>
<div class="list">
<transition name="list" tag="p">
<div class="list-item" v-if="file" >
<i class="el-icon-document"></i>
<transition name="list" tag="p">
<div v-if="file" class="list-item">
<i class="el-icon-document" />
<span>{{ file.name }}</span>
<span class="percentage" >{{percentage}}%</span>
<el-progress :show-text='false' :text-inside="false" :stroke-width="2" :percentage="percentage"></el-progress>
</div>
<span class="percentage">{{ percentage }}%</span>
<el-progress :show-text="false" :text-inside="false" :stroke-width="2" :percentage="percentage" />
</div>
</transition>
</div>
<!-- <span
</div>
<!-- <span
v-if="this.file"
>{{Math.floor(((this.formDataList.length-this.waitNum)/this.formDataList.length)*100)}}%</span> -->
<div class="tips">此版本为先行体验功能测试版样式美化和性能优化正在进行中上传切片文件和合成的完整文件分别再QMPlusserver目录的breakpointDir文件夹和fileDir文件夹</div>
</div>
</template>
<script>
import SparkMD5 from 'spark-md5'
import axios from 'axios'
@@ -43,83 +44,80 @@ export default {
waitUpLoad: [],
waitNum: 0,
limitFileSize: false,
percentage:0,
percentage: 0,
percentageFlage: true,
customColor: '#409eff'
}
},
created(){
},
methods: {
// 选中文件的函数
async choseFile(e) {
const fileR = new FileReader() // 创建一个reader用来读取文件流
const file = e.target.files[0] // 获取当前文件
const maxSize = 5*1024*1024
const maxSize = 5 * 1024 * 1024
this.file = file // file 丢全局方便后面用 可以改进为func传参形式
this.percentage = 0
if(file.size<maxSize){
fileR.readAsArrayBuffer(file) // 把文件读成ArrayBuffer 主要为了保持跟后端的流一致
fileR.onload = async e => {
// 读成arrayBuffer的回调 e 为方法自带参数 相当于 dom的e 流存在e.target.result 中
const blob = e.target.result
let spark = new SparkMD5.ArrayBuffer() // 创建md5制造工具 md5用于检测文件一致性 这里不懂就打电话问我)
spark.append(blob) // 文件流丢进工具
this.fileMd5 = spark.end() // 工具结束 产生一个a 总文件的md5
const FileSliceCap = 1 * 1024 * 1024 // 分片字节数
let start = 0 // 定义分片开始切的地方
let end = 0 // 每片结束切的地方a
let i = 0 // 第几片
this.formDataList = [] // 分片存储的一个池子 丢全局
while (end < file.size) {
// 当结尾数字大于文件总size的时候 结束切片
start = i * FileSliceCap // 计算每片开始位置
end = (i + 1) * FileSliceCap // 计算每片结束位置
var fileSlice = this.file.slice(start, end) // 开始切 file.slice 为 h5方法 对文件切片 参数为 起止字节数
const formData = new window.FormData() // 创建FormData用于存储传给后端的信息
formData.append('fileMd5', this.fileMd5) // 存储总文件的Md5 让后端知道自己是谁的切片
formData.append('file', fileSlice) //当前的切片
formData.append('chunkNumber', i) // 当前是第几片
formData.append('fileName', this.file.name) //当前文件的文件名 用于后端文件切片的命名 formData.appen 为 formData对象添加参数的方法
this.formDataList.push({ key: i, formData }) // 把当前切片信息 自己是第几片 存入我们方才准备好的池子
i++
}
const params = {
fileName: this.file.name,
fileMd5: this.fileMd5,
chunkTotal: this.formDataList.length
}
const res = await findFile(params)
// 全部切完以后 发一个请求给后端 拉当前文件后台存储的切片信息 用于检测有多少上传成功的切片
const finishList = res.data.file.ExaFileChunk // 上传成功的切片
const IsFinish = res.data.file.IsFinish // 是否是同文件不同命 文件md5相同 文件名不同 则默认是同一个文件但是不同文件名 此时后台数据库只需要拷贝一下数据库文件即可 不需要上传文件 即秒传功能)
if (!IsFinish) {
// 当是断点续传时候
this.waitUpLoad = this.formDataList.filter(all => {
return !(
finishList &&
if (file.size < maxSize) {
fileR.readAsArrayBuffer(file) // 把文件读成ArrayBuffer 主要为了保持跟后端的流一致
fileR.onload = async e => {
// 读成arrayBuffer的回调 e 为方法自带参数 相当于 dom的e 流存在e.target.result 中
const blob = e.target.result
const spark = new SparkMD5.ArrayBuffer() // 创建md5制造工具 md5用于检测文件一致性 这里不懂就打电话问我)
spark.append(blob) // 文件流丢进工具
this.fileMd5 = spark.end() // 工具结束 产生一个a 总文件的md5
const FileSliceCap = 1 * 1024 * 1024 // 分片字节数
let start = 0 // 定义分片开始切的地方
let end = 0 // 每片结束切的地方a
let i = 0 // 第几片
this.formDataList = [] // 分片存储的一个池子 丢全局
while (end < file.size) {
// 当结尾数字大于文件总size的时候 结束切片
start = i * FileSliceCap // 计算每片开始位置
end = (i + 1) * FileSliceCap // 计算每片结束位置
var fileSlice = this.file.slice(start, end) // 开始切 file.slice 为 h5方法 对文件切片 参数为 起止字节数
const formData = new window.FormData() // 创建FormData用于存储传给后端的信息
formData.append('fileMd5', this.fileMd5) // 存储总文件的Md5 让后端知道自己是谁的切片
formData.append('file', fileSlice) // 当前的切片
formData.append('chunkNumber', i) // 当前是第几片
formData.append('fileName', this.file.name) // 当前文件的文件名 用于后端文件切片的命名 formData.appen 为 formData对象添加参数的方法
this.formDataList.push({ key: i, formData }) // 把当前切片信息 自己是第几片 存入我们方才准备好的池子
i++
}
const params = {
fileName: this.file.name,
fileMd5: this.fileMd5,
chunkTotal: this.formDataList.length
}
const res = await findFile(params)
// 全部切完以后 发一个请求给后端 拉当前文件后台存储的切片信息 用于检测有多少上传成功的切片
const finishList = res.data.file.ExaFileChunk // 上传成功的切片
const IsFinish = res.data.file.IsFinish // 是否是同文件不同命 文件md5相同 文件名不同 则默认是同一个文件但是不同文件名 此时后台数据库只需要拷贝一下数据库文件即可 不需要上传文件 即秒传功能)
if (!IsFinish) {
// 当是断点续传时候
this.waitUpLoad = this.formDataList.filter(all => {
return !(
finishList &&
finishList.some(fi => fi.FileChunkNumber === all.key)
) // 找出需要上传的切片
})
} else {
this.waitUpLoad = [] // 秒传则没有需要上传的切片
) // 找出需要上传的切片
})
} else {
this.waitUpLoad = [] // 秒传则没有需要上传的切片
}
this.waitNum = this.waitUpLoad.length // 记录长度用于百分比展示
}
this.waitNum = this.waitUpLoad.length // 记录长度用于百分比展示
}
} else {
this.limitFileSize = true
this.$message('请上传小于5M文件')
this.limitFileSize = true
this.$message('请上传小于5M文件')
}
},
getFile() {
// 确定按钮
if (this.file == null) {
if (this.file === null) {
this.$message('请先上传文件')
return
}
this.percentage = Math.floor(((this.formDataList.length-this.waitNum)/this.formDataList.length)*100)
if(this.percentage == 100){
this.percentage = Math.floor(((this.formDataList.length - this.waitNum) / this.formDataList.length) * 100)
if (this.percentage === 100) {
this.percentageFlage = false
}
this.sliceFile() // 上传切片
@@ -127,13 +125,13 @@ export default {
sliceFile() {
this.waitUpLoad &&
this.waitUpLoad.map(item => {
//需要上传的切片
// 需要上传的切片
item.formData.append('chunkTotal', this.formDataList.length) // 切片总数携带给后台 总有用的
const fileR = new FileReader() // 功能同上
const file = item.formData.get('file')
fileR.readAsArrayBuffer(file)
fileR.onload = e => {
let spark = new SparkMD5.ArrayBuffer()
const spark = new SparkMD5.ArrayBuffer()
spark.append(e.target.result)
item.formData.append('chunkMd5', spark.end()) // 获取当前切片md5 后端用于验证切片完整性
this.upLoadFileSlice(item)
@@ -142,9 +140,9 @@ export default {
},
async upLoadFileSlice(item) {
// 切片上传
await axios.post(process.env.VUE_APP_BASE_API+"/fileUploadAndDownload/breakpointContinue",item.formData)
await axios.post(process.env.VUE_APP_BASE_API + '/fileUploadAndDownload/breakpointContinue', item.formData)
this.waitNum-- // 百分数增加
if (this.waitNum == 0) {
if (this.waitNum === 0) {
// 切片传完以后 合成文件
const params = {
fileName: this.file.name,
@@ -162,7 +160,7 @@ export default {
}
}
},
inputChange(){
inputChange() {
this.$refs.Input.dispatchEvent(new MouseEvent('click'))
}
}
@@ -226,7 +224,7 @@ a {
.el-divider{
margin: 0 0 30px 0;
}
.list{
margin-top:15px;
}
@@ -249,4 +247,4 @@ a {
opacity: 0;
transform: translateY(-30px);
}
</style>
</style>

View File

@@ -3,35 +3,35 @@
<div class="search-term">
<el-form :inline="true" :model="searchInfo" class="demo-form-inline">
<el-form-item>
<el-button @click="openDialog" type="primary">新增客户</el-button>
<el-button type="primary" @click="openDialog">新增客户</el-button>
</el-form-item>
</el-form>
</div>
<el-table
ref="multipleTable"
:data="tableData"
border
ref="multipleTable"
stripe
style="width: 100%"
tooltip-effect="dark"
>
<el-table-column type="selection" width="55"></el-table-column>
<el-table-column type="selection" width="55" />
<el-table-column label="接入日期" width="180">
<template slot-scope="scope">{{ scope.row.CreatedAt|formatDate }}</template>
</el-table-column>
<el-table-column label="姓名" prop="customerName" width="120"></el-table-column>
<el-table-column label="电话" prop="customerPhoneData" width="120"></el-table-column>
<el-table-column label="接入人ID" prop="sysUserId" width="120"></el-table-column>
<el-table-column label="姓名" prop="customerName" width="120" />
<el-table-column label="电话" prop="customerPhoneData" width="120" />
<el-table-column label="接入人ID" prop="sysUserId" width="120" />
<el-table-column label="按钮组" min-width="160">
<template slot-scope="scope">
<el-button @click="updateCustomer(scope.row)" size="small" type="text">变更</el-button>
<el-popover placement="top" width="160" v-model="scope.row.visible">
<el-button size="small" type="text" @click="updateCustomer(scope.row)">变更</el-button>
<el-popover v-model="scope.row.visible" placement="top" width="160">
<p>确定要删除吗</p>
<div style="text-align: right; margin: 0">
<el-button size="mini" type="text" @click="scope.row.visible = false">取消</el-button>
<el-button type="primary" size="mini" @click="deleteCustomer(scope.row)">确定</el-button>
</div>
<el-button type="danger" icon="el-icon-delete" size="mini" slot="reference">删除</el-button>
<el-button slot="reference" type="danger" icon="el-icon-delete" size="mini">删除</el-button>
</el-popover>
</template>
</el-table-column>
@@ -43,23 +43,23 @@
:page-sizes="[10, 30, 50, 100]"
:style="{float:'right',padding:'20px'}"
:total="total"
layout="total, sizes, prev, pager, next, jumper"
@current-change="handleCurrentChange"
@size-change="handleSizeChange"
layout="total, sizes, prev, pager, next, jumper"
></el-pagination>
/>
<el-dialog :before-close="closeDialog" :visible.sync="dialogFormVisible" title="客户">
<el-form :inline="true" :model="form" label-width="80px">
<el-form-item label="客户名">
<el-input autocomplete="off" v-model="form.customerName"></el-input>
<el-input v-model="form.customerName" autocomplete="off" />
</el-form-item>
<el-form-item label="客户电话">
<el-input autocomplete="off" v-model="form.customerPhoneData"></el-input>
<el-input v-model="form.customerPhoneData" autocomplete="off" />
</el-form-item>
</el-form>
<div class="dialog-footer" slot="footer">
<div slot="footer" class="dialog-footer">
<el-button @click="closeDialog"> </el-button>
<el-button @click="enterDialog" type="primary"> </el-button>
<el-button type="primary" @click="enterDialog"> </el-button>
</div>
</el-dialog>
<div class="tips">在资源权限中将此角色的资源权限清空 或者不包含创建者的角色 即可屏蔽此客户资源的显示</div>
@@ -73,93 +73,93 @@ import {
deleteExaCustomer,
getExaCustomer,
getExaCustomerList
} from "@/api/customer";
import { formatTimeToStr } from "@/utils/date";
import infoList from "@/mixins/infoList";
} from '@/api/customer'
import { formatTimeToStr } from '@/utils/date'
import infoList from '@/mixins/infoList'
export default {
name: "Customer",
name: 'Customer',
filters: {
formatDate: function(time) {
if (time !== null && time !== '') {
var date = new Date(time)
return formatTimeToStr(date, 'yyyy-MM-dd hh:mm:ss')
} else {
return ''
}
}
},
mixins: [infoList],
data() {
return {
listApi: getExaCustomerList,
dialogFormVisible: false,
type: "",
type: '',
form: {
customerName: "",
customerPhoneData: ""
customerName: '',
customerPhoneData: ''
}
};
},
filters: {
formatDate: function(time) {
if (time != null && time != "") {
var date = new Date(time);
return formatTimeToStr(date, "yyyy-MM-dd hh:mm:ss");
} else {
return "";
}
}
},
methods: {
async updateCustomer(row) {
const res = await getExaCustomer({ ID: row.ID });
this.type = "update";
if (res.code == 0) {
this.form = res.data.customer;
this.dialogFormVisible = true;
}
},
closeDialog() {
this.dialogFormVisible = false;
this.form = {
customerName: "",
customerPhoneData: ""
};
},
async deleteCustomer(row) {
row.visible = false;
const res = await deleteExaCustomer({ ID: row.ID });
if (res.code == 0) {
this.$message({
type: "success",
message: ""
});
if (this.tableData.length == 1 && this.page > 1 ) {
this.page--;
}
this.getTableData();
}
},
async enterDialog() {
let res;
switch (this.type) {
case "create":
res = await createExaCustomer(this.form);
break;
case "update":
res = await updateExaCustomer(this.form);
break;
default:
res = await createExaCustomer(this.form);
break;
}
if (res.code == 0) {
this.closeDialog();
this.getTableData();
}
},
openDialog() {
this.type = "create";
this.dialogFormVisible = true;
}
},
created() {
this.getTableData();
this.getTableData()
},
methods: {
async updateCustomer(row) {
const res = await getExaCustomer({ ID: row.ID })
this.type = 'update'
if (res.code === 0) {
this.form = res.data.customer
this.dialogFormVisible = true
}
},
closeDialog() {
this.dialogFormVisible = false
this.form = {
customerName: '',
customerPhoneData: ''
}
},
async deleteCustomer(row) {
row.visible = false
const res = await deleteExaCustomer({ ID: row.ID })
if (res.code === 0) {
this.$message({
type: 'success',
message: ''
})
if (this.tableData.length === 1 && this.page > 1) {
this.page--
}
this.getTableData()
}
},
async enterDialog() {
let res
switch (this.type) {
case 'create':
res = await createExaCustomer(this.form)
break
case 'update':
res = await updateExaCustomer(this.form)
break
default:
res = await createExaCustomer(this.form)
break
}
if (res.code === 0) {
this.closeDialog()
this.getTableData()
}
},
openDialog() {
this.type = 'create'
this.dialogFormVisible = true
}
}
};
}
</script>
<style>
</style>
</style>

View File

@@ -19,26 +19,27 @@
</el-col>
</el-row>
<el-table :data="tableData" border row-key="ID" stripe>
<el-table-column label="ID" min-width="100" prop="ID"></el-table-column>
<el-table-column label="路由Name" min-width="160" prop="name"></el-table-column>
<el-table-column label="路由Path" min-width="160" prop="path"></el-table-column>
<el-table-column label="ID" min-width="100" prop="ID" />
<el-table-column label="路由Name" min-width="160" prop="name" />
<el-table-column label="路由Path" min-width="160" prop="path" />
<el-table-column label="是否隐藏" min-width="100" prop="hidden">
<template slot-scope="scope">
<span>{{scope.row.hidden?"隐藏":"显示"}}</span>
<span>{{ scope.row.hidden?"隐藏":"显示" }}</span>
</template>
</el-table-column>
<el-table-column label="父节点" min-width="90" prop="parentId"></el-table-column>
<el-table-column label="排序" min-width="70" prop="sort"></el-table-column>
<el-table-column label="文件路径" min-width="360" prop="component"></el-table-column>
<el-table-column label="父节点" min-width="90" prop="parentId" />
<el-table-column label="排序" min-width="70" prop="sort" />
<el-table-column label="文件路径" min-width="360" prop="component" />
</el-table>
</div>
</template>
<script>
const path = process.env.VUE_APP_BASE_API;
import { mapGetters } from 'vuex';
import infoList from "@/mixins/infoList";
import { exportExcel, loadExcelData, downloadTemplate } from "@/api/excel";
import { getMenuList } from "@/api/menu";
const path = process.env.VUE_APP_BASE_API
import { mapGetters } from 'vuex'
import infoList from '@/mixins/infoList'
import { exportExcel, loadExcelData, downloadTemplate } from '@/api/excel'
import { getMenuList } from '@/api/menu'
export default {
name: 'Excel',
mixins: [infoList],
@@ -51,24 +52,24 @@ export default {
computed: {
...mapGetters('user', ['userInfo', 'token'])
},
created() {
this.pageSize = 999
this.getTableData()
},
methods: {
handleExcelExport(fileName) {
if (!fileName || typeof fileName !== "string") {
fileName = "ExcelExport.xlsx";
if (!fileName || typeof fileName !== 'string') {
fileName = 'ExcelExport.xlsx'
}
exportExcel(this.tableData, fileName);
exportExcel(this.tableData, fileName)
},
loadExcel() {
this.listApi = loadExcelData;
this.getTableData();
this.listApi = loadExcelData
this.getTableData()
},
downloadExcelTemplate() {
downloadTemplate('ExcelTemplate.xlsx')
}
},
created() {
this.pageSize = 999;
this.getTableData();
}
}
</script>
</script>

View File

@@ -1,15 +1,14 @@
<template>
<div>
<keep-alive>
<router-view v-if="$route.meta.keepAlive"></router-view>
<router-view v-if="$route.meta.keepAlive" />
</keep-alive>
<router-view v-if="!$route.meta.keepAlive"></router-view>
<router-view v-if="!$route.meta.keepAlive" />
</div>
</template>
<script>
export default {
name: "Example",
};
name: 'Example'
}
</script>
<style lang="scss"></style>

View File

@@ -2,145 +2,143 @@
<uploader
:options="options"
:file-status-text="statusText"
:autoStart="false"
:auto-start="false"
class="uploader-example"
@file-added="fileAdded"
@file-progress="onFileProgress"
@file-success="onFileSuccess"
@file-error="onFileError"
class="uploader-example"
>
<uploader-unsupport></uploader-unsupport>
<uploader-unsupport />
<uploader-drop>
<p>拖拽文件至此或点击</p>
<uploader-btn>选择文件</uploader-btn>
</uploader-drop>
<uploader-list></uploader-list>
<uploader-list />
</uploader>
</template>
<script>
var notUploadedChunks = []; // 已经上传过的文件chunkNumber数组
var isUploaded = false; // 文件已经上传成功了
import { mapGetters } from "vuex";
import { checkFileMd5,mergeFileMd5 } from "@/api/simpleUploader";
import SparkMD5 from "spark-md5";
const path = process.env.VUE_APP_BASE_API;
var notUploadedChunks = [] // 已经上传过的文件chunkNumber数组
var isUploaded = false // 文件已经上传成功了
import { mapGetters } from 'vuex'
import { checkFileMd5, mergeFileMd5 } from '@/api/simpleUploader'
import SparkMD5 from 'spark-md5'
const path = process.env.VUE_APP_BASE_API
export default {
name: "simpleUploader",
data(){
return{
md5:""
name: 'SimpleUploader',
data() {
return {
md5: ''
}
},
computed: {
...mapGetters("user", ["userInfo", "token"]),
...mapGetters('user', ['userInfo', 'token']),
statusText() {
return {
success: "成功了",
error: "出错了",
uploading: "上传中",
paused: "暂停中",
waiting: "等待中"
};
success: '成功了',
error: '出错了',
uploading: '上传中',
paused: '暂停中',
waiting: '等待中'
}
},
options() {
return {
target: path + "/simpleUploader/upload",
target: path + '/simpleUploader/upload',
testChunks: false,
simultaneousUploads: 5,
chunkSize: 2 * 1024 * 1024,
headers: {
"x-token": this.token,
"x-user-id": this.userInfo.ID
'x-token': this.token,
'x-user-id': this.userInfo.ID
},
checkChunkUploadedByResponse(chunk) {
if (isUploaded) {
return true; // return true 会忽略当前文件,不会再发送给后台
return true // return true 会忽略当前文件,不会再发送给后台
} else {
// 根据已经上传过的切片来进行忽略
return (
notUploadedChunks &&
// 根据已经上传过的切片来进行忽略
return (
notUploadedChunks &&
notUploadedChunks.some(
item => item.chunkNumber == chunk.offset + 1
item => item.chunkNumber === chunk.offset + 1
)
);
)
}
}
};
}
}
},
methods: {
// 上传单个文件
fileAdded(file) {
this.computeMD5(file); // 生成MD5
this.computeMD5(file) // 生成MD5
},
// 计算MD5值
computeMD5(file) {
var that = this;
isUploaded = false; // 这个文件是否已经上传成功过
notUploadedChunks = []; // 未成功的chunkNumber
var fileReader = new FileReader();
var md5 = "";
var that = this
isUploaded = false // 这个文件是否已经上传成功过
notUploadedChunks = [] // 未成功的chunkNumber
var fileReader = new FileReader()
var md5 = ''
file.pause();
file.pause()
fileReader.readAsArrayBuffer(file.file);
fileReader.readAsArrayBuffer(file.file)
fileReader.onload = async function(e) {
if (file.size != e.target.result.byteLength) {
if (file.size !== e.target.result.byteLength) {
this.error(
"Browser reported success but could not read the file until the end."
);
return false;
'Browser reported success but could not read the file until the end.'
)
return false
}
md5 = SparkMD5.ArrayBuffer.hash(e.target.result, false);
md5 = SparkMD5.ArrayBuffer.hash(e.target.result, false)
file.uniqueIdentifier = md5;
if (md5 != "") {
const res = await checkFileMd5({ md5: md5 });
if (res.code == 0) {
file.uniqueIdentifier = md5
if (md5 !== '') {
const res = await checkFileMd5({ md5: md5 })
if (res.code === 0) {
if (res.data.isDone) {
// 上传成功过
isUploaded = true;
isUploaded = true
that.$message({
message: "该文件已经上传成功过了,秒传成功。",
type: "success"
});
message: '该文件已经上传成功过了,秒传成功。',
type: 'success'
})
file.cancel();
file.cancel()
} else {
isUploaded = false;
notUploadedChunks = res.data.chunks;
if(notUploadedChunks.length){
file.resume();
isUploaded = false
notUploadedChunks = res.data.chunks
if (notUploadedChunks.length) {
file.resume()
}
}
}
}
};
}
fileReader.onerror = function() {
this.error(
"generater md5 时FileReader异步读取文件出错了FileReader onerror was triggered, maybe the browser aborted due to high memory usage."
);
return false;
};
'generater md5 时FileReader异步读取文件出错了FileReader onerror was triggered, maybe the browser aborted due to high memory usage.'
)
return false
}
},
// 上传进度
onFileProgress() {},
// 上传成功
async onFileSuccess(rootFile, file) {
await mergeFileMd5({md5:file.uniqueIdentifier,fileName:file.name})
await mergeFileMd5({ md5: file.uniqueIdentifier, fileName: file.name })
},
onFileError(rootFile, file, response) {
this.$message({
message: response,
type: "error"
});
type: 'error'
})
}
}
};
}
</script>
<style>
@@ -160,4 +158,4 @@ export default {
overflow-x: hidden;
overflow-y: auto;
}
</style>
</style>

View File

@@ -12,12 +12,12 @@
:show-file-list="false"
>
<el-button size="small" type="primary">点击上传</el-button>
<div class="el-upload__tip" slot="tip">只能上传jpg/png文件且不超过500kb</div>
<div slot="tip" class="el-upload__tip">只能上传jpg/png文件且不超过500kb</div>
</el-upload>
</el-col>
<el-col :span="12">
带压缩的上传, (512(k)为压缩限制)
<upload-image v-model="imageUrl" :fileSize="512" :maxWH="1080" />
<upload-image v-model="imageUrl" :file-size="512" :max-w-h="1080" />
已上传文件 {{ imageUrl }}
</el-col>
</el-row>
@@ -25,7 +25,7 @@
<el-table :data="tableData" border stripe>
<el-table-column label="预览" width="100">
<template slot-scope="scope">
<CustomPic picType="file" :picSrc="scope.row.url" />
<CustomPic pic-type="file" :pic-src="scope.row.url" />
</template>
</el-table-column>
<el-table-column label="日期" prop="UpdatedAt" width="180">
@@ -33,8 +33,8 @@
<div>{{ scope.row.UpdatedAt | formatDate }}</div>
</template>
</el-table-column>
<el-table-column label="文件名" prop="name" width="180"></el-table-column>
<el-table-column label="链接" prop="url" min-width="300"></el-table-column>
<el-table-column label="文件名" prop="name" width="180" />
<el-table-column label="链接" prop="url" min-width="300" />
<el-table-column label="标签" prop="tag" width="100">
<template slot-scope="scope">
<el-tag
@@ -45,8 +45,8 @@
</el-table-column>
<el-table-column label="操作" width="160">
<template slot-scope="scope">
<el-button @click="downloadFile(scope.row)" size="small" type="text">下载</el-button>
<el-button @click="deleteFile(scope.row)" size="small" type="text">删除</el-button>
<el-button size="small" type="text" @click="downloadFile(scope.row)">下载</el-button>
<el-button size="small" type="text" @click="deleteFile(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
@@ -56,124 +56,124 @@
:page-sizes="[10, 30, 50, 100]"
:style="{ float: 'right', padding: '20px' }"
:total="total"
layout="total, sizes, prev, pager, next, jumper"
@current-change="handleCurrentChange"
@size-change="handleSizeChange"
layout="total, sizes, prev, pager, next, jumper"
></el-pagination>
/>
</div>
</div>
</template>
<script>
const path = process.env.VUE_APP_BASE_API;
import { mapGetters } from "vuex";
import infoList from "@/mixins/infoList";
import { getFileList, deleteFile } from "@/api/fileUploadAndDownload";
import { downloadImage } from "@/utils/downloadImg";
import { formatTimeToStr } from "@/utils/date";
import CustomPic from "@/components/customPic";
import UploadImage from "@/components/upload/image.vue";
const path = process.env.VUE_APP_BASE_API
import { mapGetters } from 'vuex'
import infoList from '@/mixins/infoList'
import { getFileList, deleteFile } from '@/api/fileUploadAndDownload'
import { downloadImage } from '@/utils/downloadImg'
import { formatTimeToStr } from '@/utils/date'
import CustomPic from '@/components/customPic'
import UploadImage from '@/components/upload/image.vue'
export default {
name: "Upload",
mixins: [infoList],
name: 'Upload',
components: {
CustomPic,
UploadImage
},
filters: {
formatDate: function(time) {
if (time !== null && time !== '') {
var date = new Date(time)
return formatTimeToStr(date, 'yyyy-MM-dd hh:mm:ss')
} else {
return ''
}
}
},
mixins: [infoList],
data() {
return {
fullscreenLoading: false,
listApi: getFileList,
path: path,
tableData: [],
imageUrl: ""
};
imageUrl: ''
}
},
computed: {
...mapGetters("user", ["userInfo", "token"])
...mapGetters('user', ['userInfo', 'token'])
},
filters: {
formatDate: function(time) {
if (time != null && time != "") {
var date = new Date(time);
return formatTimeToStr(date, "yyyy-MM-dd hh:mm:ss");
} else {
return "";
}
}
created() {
this.getTableData()
},
methods: {
async deleteFile(row) {
this.$confirm("此操作将永久文件, 是否继续?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
this.$confirm('此操作将永久文件, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
.then(async () => {
const res = await deleteFile(row);
if (res.code == 0) {
.then(async() => {
const res = await deleteFile(row)
if (res.code === 0) {
this.$message({
type: "success",
message: "删除成功!"
});
if (this.tableData.length == 1 && this.page > 1 ) {
this.page--;
type: 'success',
message: '删除成功!'
})
if (this.tableData.length === 1 && this.page > 1) {
this.page--
}
this.getTableData();
this.getTableData()
}
})
.catch(() => {
this.$message({
type: "info",
message: "已取消删除"
});
});
type: 'info',
message: '已取消删除'
})
})
},
checkFile(file) {
this.fullscreenLoading = true;
const isJPG = file.type === "image/jpeg";
const isPng = file.type === "image/png";
const isLt2M = file.size / 1024 / 1024 < 2;
this.fullscreenLoading = true
const isJPG = file.type === 'image/jpeg'
const isPng = file.type === 'image/png'
const isLt2M = file.size / 1024 / 1024 < 2
if (!isJPG && !isPng) {
this.$message.error("上传头像图片只能是 JPG或png 格式!");
this.fullscreenLoading = false;
this.$message.error('上传头像图片只能是 JPG或png 格式!')
this.fullscreenLoading = false
}
if (!isLt2M) {
this.$message.error("上传头像图片大小不能超过 2MB!");
this.fullscreenLoading = false;
this.$message.error('上传头像图片大小不能超过 2MB!')
this.fullscreenLoading = false
}
return (isPng || isJPG) && isLt2M;
return (isPng || isJPG) && isLt2M
},
uploadSuccess(res) {
this.fullscreenLoading = false;
if (res.code == 0) {
this.fullscreenLoading = false
if (res.code === 0) {
this.$message({
type: "success",
message: "上传成功"
});
if (res.code == 0) {
this.getTableData();
type: 'success',
message: '上传成功'
})
if (res.code === 0) {
this.getTableData()
}
} else {
this.$message({
type: "warning",
type: 'warning',
message: res.msg
});
})
}
},
uploadError() {
this.$message({
type: "error",
message: "上传失败"
});
this.fullscreenLoading = false;
type: 'error',
message: '上传失败'
})
this.fullscreenLoading = false
},
downloadFile(row) {
downloadImage(row.url, row.name);
downloadImage(row.url, row.name)
}
},
created() {
this.getTableData();
}
};
}
</script>

View File

@@ -1,305 +1,304 @@
<template>
<ul class="icon-list clearfix">
<li v-for="item in iconList" :key="item">
<span>
<i :class="item"></i>
<span class="icon-name">{{item}}</span>
</span>
</li>
</ul>
<ul class="icon-list clearfix">
<li v-for="item in iconList" :key="item">
<span>
<i :class="item" />
<span class="icon-name">{{ item }}</span>
</span>
</li>
</ul>
</template>
<script>
export default {
name: 'IconList',
data() {
return {
iconList : [
"el-icon-platform-eleme",
"el-icon-eleme",
"el-icon-delete-solid",
"el-icon-delete",
"el-icon-s-tools",
"el-icon-setting",
"el-icon-user-solid",
"el-icon-user",
"el-icon-phone",
"el-icon-phone-outline",
"el-icon-more",
"el-icon-more-outline",
"el-icon-star-on",
"el-icon-star-off",
"el-icon-s-goods",
"el-icon-goods",
"el-icon-warning",
"el-icon-warning-outline",
"el-icon-question",
"el-icon-info",
"el-icon-remove",
"el-icon-circle-plus",
"el-icon-success",
"el-icon-error",
"el-icon-zoom-in",
"el-icon-zoom-out",
"el-icon-remove-outline",
"el-icon-circle-plus-outline",
"el-icon-circle-check",
"el-icon-circle-close",
"el-icon-s-help",
"el-icon-help",
"el-icon-minus",
"el-icon-plus",
"el-icon-check",
"el-icon-close",
"el-icon-picture",
"el-icon-picture-outline",
"el-icon-picture-outline-round",
"el-icon-upload",
"el-icon-upload2",
"el-icon-download",
"el-icon-camera-solid",
"el-icon-camera",
"el-icon-video-camera-solid",
"el-icon-video-camera",
"el-icon-message-solid",
"el-icon-bell",
"el-icon-s-cooperation",
"el-icon-s-order",
"el-icon-s-platform",
"el-icon-s-fold",
"el-icon-s-unfold",
"el-icon-s-operation",
"el-icon-s-promotion",
"el-icon-s-home",
"el-icon-s-release",
"el-icon-s-ticket",
"el-icon-s-management",
"el-icon-s-open",
"el-icon-s-shop",
"el-icon-s-marketing",
"el-icon-s-flag",
"el-icon-s-comment",
"el-icon-s-finance",
"el-icon-s-claim",
"el-icon-s-custom",
"el-icon-s-opportunity",
"el-icon-s-data",
"el-icon-s-check",
"el-icon-s-grid",
"el-icon-menu",
"el-icon-share",
"el-icon-d-caret",
"el-icon-caret-left",
"el-icon-caret-right",
"el-icon-caret-bottom",
"el-icon-caret-top",
"el-icon-bottom-left",
"el-icon-bottom-right",
"el-icon-back",
"el-icon-right",
"el-icon-bottom",
"el-icon-top",
"el-icon-top-left",
"el-icon-top-right",
"el-icon-arrow-left",
"el-icon-arrow-right",
"el-icon-arrow-down",
"el-icon-arrow-up",
"el-icon-d-arrow-left",
"el-icon-d-arrow-right",
"el-icon-video-pause",
"el-icon-video-play",
"el-icon-refresh",
"el-icon-refresh-right",
"el-icon-refresh-left",
"el-icon-finished",
"el-icon-sort",
"el-icon-sort-up",
"el-icon-sort-down",
"el-icon-rank",
"el-icon-loading",
"el-icon-view",
"el-icon-c-scale-to-original",
"el-icon-date",
"el-icon-edit",
"el-icon-edit-outline",
"el-icon-folder",
"el-icon-folder-opened",
"el-icon-folder-add",
"el-icon-folder-remove",
"el-icon-folder-delete",
"el-icon-folder-checked",
"el-icon-tickets",
"el-icon-document-remove",
"el-icon-document-delete",
"el-icon-document-copy",
"el-icon-document-checked",
"el-icon-document",
"el-icon-document-add",
"el-icon-printer",
"el-icon-paperclip",
"el-icon-takeaway-box",
"el-icon-search",
"el-icon-monitor",
"el-icon-attract",
"el-icon-mobile",
"el-icon-scissors",
"el-icon-umbrella",
"el-icon-headset",
"el-icon-brush",
"el-icon-mouse",
"el-icon-coordinate",
"el-icon-magic-stick",
"el-icon-reading",
"el-icon-data-line",
"el-icon-data-board",
"el-icon-pie-chart",
"el-icon-data-analysis",
"el-icon-collection-tag",
"el-icon-film",
"el-icon-suitcase",
"el-icon-suitcase-1",
"el-icon-receiving",
"el-icon-collection",
"el-icon-files",
"el-icon-notebook-1",
"el-icon-notebook-2",
"el-icon-toilet-paper",
"el-icon-office-building",
"el-icon-school",
"el-icon-table-lamp",
"el-icon-house",
"el-icon-no-smoking",
"el-icon-smoking",
"el-icon-shopping-cart-full",
"el-icon-shopping-cart-1",
"el-icon-shopping-cart-2",
"el-icon-shopping-bag-1",
"el-icon-shopping-bag-2",
"el-icon-sold-out",
"el-icon-sell",
"el-icon-present",
"el-icon-box",
"el-icon-bank-card",
"el-icon-money",
"el-icon-coin",
"el-icon-wallet",
"el-icon-discount",
"el-icon-price-tag",
"el-icon-news",
"el-icon-guide",
"el-icon-male",
"el-icon-female",
"el-icon-thumb",
"el-icon-cpu",
"el-icon-link",
"el-icon-connection",
"el-icon-open",
"el-icon-turn-off",
"el-icon-set-up",
"el-icon-chat-round",
"el-icon-chat-line-round",
"el-icon-chat-square",
"el-icon-chat-dot-round",
"el-icon-chat-dot-square",
"el-icon-chat-line-square",
"el-icon-message",
"el-icon-postcard",
"el-icon-position",
"el-icon-turn-off-microphone",
"el-icon-microphone",
"el-icon-close-notification",
"el-icon-bangzhu",
"el-icon-time",
"el-icon-odometer",
"el-icon-crop",
"el-icon-aim",
"el-icon-switch-button",
"el-icon-full-screen",
"el-icon-copy-document",
"el-icon-mic",
"el-icon-stopwatch",
"el-icon-medal-1",
"el-icon-medal",
"el-icon-trophy",
"el-icon-trophy-1",
"el-icon-first-aid-kit",
"el-icon-discover",
"el-icon-place",
"el-icon-location",
"el-icon-location-outline",
"el-icon-location-information",
"el-icon-add-location",
"el-icon-delete-location",
"el-icon-map-location",
"el-icon-alarm-clock",
"el-icon-timer",
"el-icon-watch-1",
"el-icon-watch",
"el-icon-lock",
"el-icon-unlock",
"el-icon-key",
"el-icon-service",
"el-icon-mobile-phone",
"el-icon-bicycle",
"el-icon-truck",
"el-icon-ship",
"el-icon-basketball",
"el-icon-football",
"el-icon-soccer",
"el-icon-baseball",
"el-icon-wind-power",
"el-icon-light-rain",
"el-icon-lightning",
"el-icon-heavy-rain",
"el-icon-sunrise",
"el-icon-sunrise-1",
"el-icon-sunset",
"el-icon-sunny",
"el-icon-cloudy",
"el-icon-partly-cloudy",
"el-icon-cloudy-and-sunny",
"el-icon-moon",
"el-icon-moon-night",
"el-icon-dish",
"el-icon-dish-1",
"el-icon-food",
"el-icon-chicken",
"el-icon-fork-spoon",
"el-icon-knife-fork",
"el-icon-burger",
"el-icon-tableware",
"el-icon-sugar",
"el-icon-dessert",
"el-icon-ice-cream",
"el-icon-hot-water",
"el-icon-water-cup",
"el-icon-coffee-cup",
"el-icon-cold-drink",
"el-icon-goblet",
"el-icon-goblet-full",
"el-icon-goblet-square",
"el-icon-goblet-square-full",
"el-icon-refrigerator",
"el-icon-grape",
"el-icon-watermelon",
"el-icon-cherry",
"el-icon-apple",
"el-icon-pear",
"el-icon-orange",
"el-icon-coffee",
"el-icon-ice-tea",
"el-icon-ice-drink",
"el-icon-milk-tea",
"el-icon-potato-strips",
"el-icon-lollipop",
"el-icon-ice-cream-square",
"el-icon-ice-cream-round",
]
}
},
export default {
name: 'IconList',
data() {
return {
iconList: [
'el-icon-platform-eleme',
'el-icon-eleme',
'el-icon-delete-solid',
'el-icon-delete',
'el-icon-s-tools',
'el-icon-setting',
'el-icon-user-solid',
'el-icon-user',
'el-icon-phone',
'el-icon-phone-outline',
'el-icon-more',
'el-icon-more-outline',
'el-icon-star-on',
'el-icon-star-off',
'el-icon-s-goods',
'el-icon-goods',
'el-icon-warning',
'el-icon-warning-outline',
'el-icon-question',
'el-icon-info',
'el-icon-remove',
'el-icon-circle-plus',
'el-icon-success',
'el-icon-error',
'el-icon-zoom-in',
'el-icon-zoom-out',
'el-icon-remove-outline',
'el-icon-circle-plus-outline',
'el-icon-circle-check',
'el-icon-circle-close',
'el-icon-s-help',
'el-icon-help',
'el-icon-minus',
'el-icon-plus',
'el-icon-check',
'el-icon-close',
'el-icon-picture',
'el-icon-picture-outline',
'el-icon-picture-outline-round',
'el-icon-upload',
'el-icon-upload2',
'el-icon-download',
'el-icon-camera-solid',
'el-icon-camera',
'el-icon-video-camera-solid',
'el-icon-video-camera',
'el-icon-message-solid',
'el-icon-bell',
'el-icon-s-cooperation',
'el-icon-s-order',
'el-icon-s-platform',
'el-icon-s-fold',
'el-icon-s-unfold',
'el-icon-s-operation',
'el-icon-s-promotion',
'el-icon-s-home',
'el-icon-s-release',
'el-icon-s-ticket',
'el-icon-s-management',
'el-icon-s-open',
'el-icon-s-shop',
'el-icon-s-marketing',
'el-icon-s-flag',
'el-icon-s-comment',
'el-icon-s-finance',
'el-icon-s-claim',
'el-icon-s-custom',
'el-icon-s-opportunity',
'el-icon-s-data',
'el-icon-s-check',
'el-icon-s-grid',
'el-icon-menu',
'el-icon-share',
'el-icon-d-caret',
'el-icon-caret-left',
'el-icon-caret-right',
'el-icon-caret-bottom',
'el-icon-caret-top',
'el-icon-bottom-left',
'el-icon-bottom-right',
'el-icon-back',
'el-icon-right',
'el-icon-bottom',
'el-icon-top',
'el-icon-top-left',
'el-icon-top-right',
'el-icon-arrow-left',
'el-icon-arrow-right',
'el-icon-arrow-down',
'el-icon-arrow-up',
'el-icon-d-arrow-left',
'el-icon-d-arrow-right',
'el-icon-video-pause',
'el-icon-video-play',
'el-icon-refresh',
'el-icon-refresh-right',
'el-icon-refresh-left',
'el-icon-finished',
'el-icon-sort',
'el-icon-sort-up',
'el-icon-sort-down',
'el-icon-rank',
'el-icon-loading',
'el-icon-view',
'el-icon-c-scale-to-original',
'el-icon-date',
'el-icon-edit',
'el-icon-edit-outline',
'el-icon-folder',
'el-icon-folder-opened',
'el-icon-folder-add',
'el-icon-folder-remove',
'el-icon-folder-delete',
'el-icon-folder-checked',
'el-icon-tickets',
'el-icon-document-remove',
'el-icon-document-delete',
'el-icon-document-copy',
'el-icon-document-checked',
'el-icon-document',
'el-icon-document-add',
'el-icon-printer',
'el-icon-paperclip',
'el-icon-takeaway-box',
'el-icon-search',
'el-icon-monitor',
'el-icon-attract',
'el-icon-mobile',
'el-icon-scissors',
'el-icon-umbrella',
'el-icon-headset',
'el-icon-brush',
'el-icon-mouse',
'el-icon-coordinate',
'el-icon-magic-stick',
'el-icon-reading',
'el-icon-data-line',
'el-icon-data-board',
'el-icon-pie-chart',
'el-icon-data-analysis',
'el-icon-collection-tag',
'el-icon-film',
'el-icon-suitcase',
'el-icon-suitcase-1',
'el-icon-receiving',
'el-icon-collection',
'el-icon-files',
'el-icon-notebook-1',
'el-icon-notebook-2',
'el-icon-toilet-paper',
'el-icon-office-building',
'el-icon-school',
'el-icon-table-lamp',
'el-icon-house',
'el-icon-no-smoking',
'el-icon-smoking',
'el-icon-shopping-cart-full',
'el-icon-shopping-cart-1',
'el-icon-shopping-cart-2',
'el-icon-shopping-bag-1',
'el-icon-shopping-bag-2',
'el-icon-sold-out',
'el-icon-sell',
'el-icon-present',
'el-icon-box',
'el-icon-bank-card',
'el-icon-money',
'el-icon-coin',
'el-icon-wallet',
'el-icon-discount',
'el-icon-price-tag',
'el-icon-news',
'el-icon-guide',
'el-icon-male',
'el-icon-female',
'el-icon-thumb',
'el-icon-cpu',
'el-icon-link',
'el-icon-connection',
'el-icon-open',
'el-icon-turn-off',
'el-icon-set-up',
'el-icon-chat-round',
'el-icon-chat-line-round',
'el-icon-chat-square',
'el-icon-chat-dot-round',
'el-icon-chat-dot-square',
'el-icon-chat-line-square',
'el-icon-message',
'el-icon-postcard',
'el-icon-position',
'el-icon-turn-off-microphone',
'el-icon-microphone',
'el-icon-close-notification',
'el-icon-bangzhu',
'el-icon-time',
'el-icon-odometer',
'el-icon-crop',
'el-icon-aim',
'el-icon-switch-button',
'el-icon-full-screen',
'el-icon-copy-document',
'el-icon-mic',
'el-icon-stopwatch',
'el-icon-medal-1',
'el-icon-medal',
'el-icon-trophy',
'el-icon-trophy-1',
'el-icon-first-aid-kit',
'el-icon-discover',
'el-icon-place',
'el-icon-location',
'el-icon-location-outline',
'el-icon-location-information',
'el-icon-add-location',
'el-icon-delete-location',
'el-icon-map-location',
'el-icon-alarm-clock',
'el-icon-timer',
'el-icon-watch-1',
'el-icon-watch',
'el-icon-lock',
'el-icon-unlock',
'el-icon-key',
'el-icon-service',
'el-icon-mobile-phone',
'el-icon-bicycle',
'el-icon-truck',
'el-icon-ship',
'el-icon-basketball',
'el-icon-football',
'el-icon-soccer',
'el-icon-baseball',
'el-icon-wind-power',
'el-icon-light-rain',
'el-icon-lightning',
'el-icon-heavy-rain',
'el-icon-sunrise',
'el-icon-sunrise-1',
'el-icon-sunset',
'el-icon-sunny',
'el-icon-cloudy',
'el-icon-partly-cloudy',
'el-icon-cloudy-and-sunny',
'el-icon-moon',
'el-icon-moon-night',
'el-icon-dish',
'el-icon-dish-1',
'el-icon-food',
'el-icon-chicken',
'el-icon-fork-spoon',
'el-icon-knife-fork',
'el-icon-burger',
'el-icon-tableware',
'el-icon-sugar',
'el-icon-dessert',
'el-icon-ice-cream',
'el-icon-hot-water',
'el-icon-water-cup',
'el-icon-coffee-cup',
'el-icon-cold-drink',
'el-icon-goblet',
'el-icon-goblet-full',
'el-icon-goblet-square',
'el-icon-goblet-square-full',
'el-icon-refrigerator',
'el-icon-grape',
'el-icon-watermelon',
'el-icon-cherry',
'el-icon-apple',
'el-icon-pear',
'el-icon-orange',
'el-icon-coffee',
'el-icon-ice-tea',
'el-icon-ice-drink',
'el-icon-milk-tea',
'el-icon-potato-strips',
'el-icon-lollipop',
'el-icon-ice-cream-square',
'el-icon-ice-cream-round'
]
}
}
}
</script>
<style lang="scss" scoped>

View File

@@ -5,28 +5,27 @@
<div class="form-card in-three a-fadeinB">
<el-form ref="form" :model="form" label-width="100px">
<el-form-item label="数据库类型">
<el-select disabled v-model="form.sqlType" placeholder="请选择">
<el-option key="mysql" label="mysql(目前只支持mysql)" value="mysql">
</el-option>
<el-select v-model="form.sqlType" disabled placeholder="请选择">
<el-option key="mysql" label="mysql(目前只支持mysql)" value="mysql" />
</el-select>
</el-form-item>
<el-form-item label="host">
<el-input v-model="form.host" placeholder="请输入数据库链接"></el-input>
<el-input v-model="form.host" placeholder="请输入数据库链接" />
</el-form-item>
<el-form-item label="port">
<el-input v-model="form.port" placeholder="请输入数据库端口"></el-input>
<el-input v-model="form.port" placeholder="请输入数据库端口" />
</el-form-item>
<el-form-item label="userName">
<el-input v-model="form.userName" placeholder="请输入数据库用户名"></el-input>
<el-input v-model="form.userName" placeholder="请输入数据库用户名" />
</el-form-item>
<el-form-item label="password">
<el-input
v-model="form.password"
placeholder="请输入数据库密码(没有则为空)"
></el-input>
/>
</el-form-item>
<el-form-item label="dbName">
<el-input v-model="form.dbName" placeholder="请输入数据库名称"></el-input>
<el-input v-model="form.dbName" placeholder="请输入数据库名称" />
</el-form-item>
<el-form-item>
<div style="text-align: right">
@@ -39,46 +38,47 @@
</template>
<script>
import { initDB } from "@/api/initdb";
import { initDB } from '@/api/initdb'
export default {
name: "Init",
name: 'Init',
data() {
return {
form: {
sqlType: "mysql",
host: "127.0.0.1",
port: "3306",
userName: "root",
password: "",
dbName: "gva",
},
};
sqlType: 'mysql',
host: '127.0.0.1',
port: '3306',
userName: 'root',
password: '',
dbName: 'gva'
}
}
},
methods: {
async onSubmit() {
const loading = this.$loading({
lock: true,
text: "正在初始化数据库,请稍候",
spinner: "el-icon-loading",
background: "rgba(0, 0, 0, 0.7)",
});
text: '正在初始化数据库,请稍候',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
})
try {
const res = await initDB(this.form);
if (res.code == 0) {
const res = await initDB(this.form)
if (res.code === 0) {
this.$message({
type: "success",
message: res.msg,
});
this.$router.push({name:"login"})
type: 'success',
message: res.msg
})
this.$router.push({ name: 'Login' })
}
loading.close();
loading.close()
} catch (err) {
loading.close();
loading.close()
}
},
},
};
}
}
}
</script>
<style lang="scss">
.init {
height: 100vh;

View File

@@ -1,10 +1,10 @@
<template>
<el-submenu :popper-append-to-body="false" ref="subMenu" :index="routerInfo.name">
<el-submenu ref="subMenu" :popper-append-to-body="false" :index="routerInfo.name">
<template slot="title">
<i :class="'el-icon-'+routerInfo.meta.icon"></i>
<span slot="title">{{routerInfo.meta.title}}</span>
<i :class="'el-icon-'+routerInfo.meta.icon" />
<span slot="title">{{ routerInfo.meta.title }}</span>
</template>
<slot></slot>
<slot />
</el-submenu>
</template>
@@ -21,5 +21,3 @@ export default {
}
}
</script>
<style lang="scss">
</style>

View File

@@ -1,7 +1,7 @@
<template>
<component :is="menuComponent" :routerInfo="routerInfo" v-if="!routerInfo.hidden">
<component :is="menuComponent" v-if="!routerInfo.hidden" :router-info="routerInfo">
<template v-if="routerInfo.children&&routerInfo.children.length">
<AsideComponent :key="item.name" :routerInfo="item" v-for="item in routerInfo.children" />
<AsideComponent v-for="item in routerInfo.children" :key="item.name" :router-info="item" />
</template>
</component>
</template>
@@ -12,14 +12,9 @@ import AsyncSubmenu from './asyncSubmenu'
export default {
name: 'AsideComponent',
computed: {
menuComponent() {
if (this.routerInfo.children&&this.routerInfo.children.filter(item=>!item.hidden).length) {
return 'AsyncSubmenu'
} else {
return 'MenuItem'
}
}
components: {
MenuItem,
AsyncSubmenu
},
props: {
routerInfo: {
@@ -29,11 +24,14 @@ export default {
type: Object
}
},
components: {
MenuItem,
AsyncSubmenu
computed: {
menuComponent() {
if (this.routerInfo.children && this.routerInfo.children.filter(item => !item.hidden).length) {
return 'AsyncSubmenu'
} else {
return 'MenuItem'
}
}
}
}
</script>
<style lang="scss">
</style>

View File

@@ -1,7 +1,7 @@
<template>
<el-menu-item :index="routerInfo.name" :route="{parameters:routerInfo.parameters}">
<i :class="'el-icon-'+routerInfo.meta.icon"></i>
<span slot="title">{{routerInfo.meta.title}}</span>
<i :class="'el-icon-'+routerInfo.meta.icon" />
<span slot="title">{{ routerInfo.meta.title }}</span>
</el-menu-item>
</template>
@@ -18,5 +18,3 @@ export default {
}
}
</script>
<style lang="scss">
</style>

View File

@@ -1,24 +1,24 @@
<template>
<div class="router-history">
<el-tabs
:closable="!(historys.length==1&&this.$route.name==defaultRouter)"
v-model="activeValue"
:closable="!(historys.length===1&&this.$route.name===defaultRouter)"
type="card"
@contextmenu.prevent.native="openContextMenu($event)"
@tab-click="changeTab"
@tab-remove="removeTab"
type="card"
v-model="activeValue"
>
<el-tab-pane
v-for="item in historys"
:key="item.name + JSON.stringify(item.query)+JSON.stringify(item.params)"
:label="item.meta.title"
:name="item.name + JSON.stringify(item.query)+JSON.stringify(item.params)"
:tab="item"
v-for="item in historys"
></el-tab-pane>
/>
</el-tabs>
<!--自定义右键菜单html代码-->
<ul :style="{left:left+'px',top:top+'px'}" class="contextmenu" v-show="contextMenuVisible">
<ul v-show="contextMenuVisible" :style="{left:left+'px',top:top+'px'}" class="contextmenu">
<li @click="closeAll">关闭所有</li>
<li @click="closeLeft">关闭左侧</li>
<li @click="closeRight">关闭右侧</li>
@@ -26,84 +26,107 @@
</ul>
</div>
</template>
<script>
import { mapGetters } from "vuex";
const getFmtString = (item)=>{
return item.name +
JSON.stringify(item.query) +
JSON.stringify(item.params)
}
import { mapGetters } from 'vuex'
const getFmtString = (item) => {
return item.name +
JSON.stringify(item.query) +
JSON.stringify(item.params)
}
export default {
name: "HistoryComponent",
name: 'HistoryComponent',
data() {
return {
historys: [],
activeValue: "",
activeValue: '',
contextMenuVisible: false,
left: 0,
top: 0,
isCollapse: false,
isMobile: false,
rightActive: ""
};
rightActive: ''
}
},
computed: {
...mapGetters("user", ["userInfo"]),
...mapGetters('user', ['userInfo']),
defaultRouter() {
return this.userInfo.authority.defaultRouter;
return this.userInfo.authority.defaultRouter
}
},
watch: {
contextMenuVisible() {
if (this.contextMenuVisible) {
document.body.addEventListener('click', () => {
this.contextMenuVisible = false
})
} else {
document.body.removeEventListener('click', () => {
this.contextMenuVisible = false
})
}
},
$route(to, now) {
this.historys = this.historys.filter(item => !item.meta.closeTab)
this.setTab(to)
sessionStorage.setItem('historys', JSON.stringify(this.historys))
this.activeValue = window.sessionStorage.getItem('activeValue')
if (now && to && now.name === to.name) {
this.$bus.$emit('reload')
}
}
},
created() {
this.$bus.on("mobile", isMobile => {
this.isMobile = isMobile;
});
this.$bus.on("collapse", isCollapse => {
this.isCollapse = isCollapse;
});
this.$bus.on('mobile', isMobile => {
this.isMobile = isMobile
})
this.$bus.on('collapse', isCollapse => {
this.isCollapse = isCollapse
})
const initHistorys = [
{
name: this.defaultRouter,
meta: {
title: "首页"
title: '首页'
},
query: {},
params: {}
}
];
]
this.historys =
JSON.parse(sessionStorage.getItem("historys")) || initHistorys;
if(!window.sessionStorage.getItem("activeValue")){
this.activeValue = getFmtString(this.$route)
}else{
this.activeValue = window.sessionStorage.getItem("activeValue");
}
this.setTab(this.$route);
JSON.parse(sessionStorage.getItem('historys')) || initHistorys
if (!window.sessionStorage.getItem('activeValue')) {
this.activeValue = getFmtString(this.$route)
} else {
this.activeValue = window.sessionStorage.getItem('activeValue')
}
this.setTab(this.$route)
},
beforeDestroy() {
this.$bus.off("collapse");
this.$bus.off("mobile");
this.$bus.off('collapse')
this.$bus.off('mobile')
},
methods: {
openContextMenu(e) {
if (this.historys.length == 1 && this.$route.name == this.defaultRouter) {
return false;
if (this.historys.length === 1 && this.$route.name === this.defaultRouter) {
return false
}
if (e.srcElement.id) {
this.contextMenuVisible = true;
let width;
this.contextMenuVisible = true
let width
if (this.isCollapse) {
width = 54;
width = 54
} else {
width = 220;
width = 220
}
if (this.isMobile) {
width = 0;
width = 0
}
this.left = e.clientX - width;
this.top = e.clientY + 10;
this.rightActive = e.srcElement.id.split("-")[1];
this.left = e.clientX - width
this.top = e.clientY + 10
this.rightActive = e.srcElement.id.split('-')[1]
}
},
closeAll() {
@@ -111,155 +134,134 @@ export default {
{
name: this.defaultRouter,
meta: {
title: "首页"
title: '首页'
},
query: {},
params: {}
}
];
this.$router.push({ name: this.defaultRouter });
this.contextMenuVisible = false;
sessionStorage.setItem("historys", JSON.stringify(this.historys));
]
this.$router.push({ name: this.defaultRouter })
this.contextMenuVisible = false
sessionStorage.setItem('historys', JSON.stringify(this.historys))
},
closeLeft() {
let right;
let right
const rightIndex = this.historys.findIndex(item => {
if (getFmtString(item) == this.rightActive) {
right = item;
if (getFmtString(item) === this.rightActive) {
right = item
}
return (
getFmtString(item) == this.rightActive
);
});
getFmtString(item) === this.rightActive
)
})
const activeIndex = this.historys.findIndex(
item => getFmtString(item) == this.activeValue
);
this.historys.splice(0, rightIndex);
item => getFmtString(item) === this.activeValue
)
this.historys.splice(0, rightIndex)
if (rightIndex > activeIndex) {
this.$router.push(right);
this.$router.push(right)
}
sessionStorage.setItem("historys", JSON.stringify(this.historys));
sessionStorage.setItem('historys', JSON.stringify(this.historys))
},
closeRight() {
let right;
let right
const leftIndex = this.historys.findIndex(item => {
if ( getFmtString(item) == this.rightActive ) {
right = item;
if (getFmtString(item) === this.rightActive) {
right = item
}
return ( getFmtString(item) == this.rightActive );
});
return (getFmtString(item) === this.rightActive)
})
const activeIndex = this.historys.findIndex(
item => getFmtString(item) == this.activeValue
);
this.historys.splice(leftIndex + 1, this.historys.length);
item => getFmtString(item) === this.activeValue
)
this.historys.splice(leftIndex + 1, this.historys.length)
if (leftIndex < activeIndex) {
this.$router.push(right);
this.$router.push(right)
}
sessionStorage.setItem("historys", JSON.stringify(this.historys));
sessionStorage.setItem('historys', JSON.stringify(this.historys))
},
closeOther() {
let right;
let right
this.historys = this.historys.filter(item => {
if ( getFmtString(item) == this.rightActive
if (getFmtString(item) === this.rightActive
) {
right = item;
right = item
}
return ( getFmtString(item) == this.rightActive
);
});
this.$router.push(right);
sessionStorage.setItem("historys", JSON.stringify(this.historys));
return (getFmtString(item) === this.rightActive
)
})
this.$router.push(right)
sessionStorage.setItem('historys', JSON.stringify(this.historys))
},
isSame(route1, route2) {
if (route1.name != route2.name) {
return false;
if (route1.name !== route2.name) {
return false
}
for (let key in route1.query) {
if (route1.query[key] != route2.query[key]) {
return false;
for (const key in route1.query) {
if (route1.query[key] !== route2.query[key]) {
return false
}
}
for (let key in route1.params) {
if (route1.params[key] != route2.params[key]) {
return false;
for (const key in route1.params) {
if (route1.params[key] !== route2.params[key]) {
return false
}
}
return true;
return true
},
setTab(route) {
if (!this.historys.some(item => this.isSame(item, route))) {
const obj = {};
obj.name = route.name;
obj.meta = route.meta;
obj.query = route.query;
obj.params = route.params;
this.historys.push(obj);
const obj = {}
obj.name = route.name
obj.meta = route.meta
obj.query = route.query
obj.params = route.params
this.historys.push(obj)
}
window.sessionStorage.setItem(
"activeValue",
'activeValue',
getFmtString(this.$route)
);
)
},
changeTab(component) {
const tab = component.$attrs.tab;
const tab = component.$attrs.tab
this.$router.push({
name: tab.name,
query: tab.query,
params: tab.params
});
})
},
removeTab(tab) {
const index = this.historys.findIndex(
item => getFmtString(item) == tab
);
item => getFmtString(item) === tab
)
if (
getFmtString(this.$route) == tab
getFmtString(this.$route) === tab
) {
if (this.historys.length == 1) {
this.$router.push({ name: this.defaultRouter });
if (this.historys.length === 1) {
this.$router.push({ name: this.defaultRouter })
} else {
if (index < this.historys.length - 1) {
this.$router.push({
name: this.historys[index + 1].name,
query: this.historys[index + 1].query,
params: this.historys[index + 1].params
});
})
} else {
this.$router.push({
name: this.historys[index - 1].name,
query: this.historys[index - 1].query,
params: this.historys[index - 1].params
});
})
}
}
}
this.historys.splice(index, 1);
}
},
watch: {
contextMenuVisible() {
if (this.contextMenuVisible) {
document.body.addEventListener("click", () => {
this.contextMenuVisible = false;
});
} else {
document.body.removeEventListener("click", () => {
this.contextMenuVisible = false;
});
}
},
$route(to, now) {
this.historys = this.historys.filter(item => !item.meta.closeTab);
this.setTab(to);
sessionStorage.setItem("historys", JSON.stringify(this.historys));
this.activeValue = window.sessionStorage.getItem("activeValue");
if (now && to && now.name == to.name) {
this.$bus.$emit("reload");
}
this.historys.splice(index, 1)
}
}
};
}
</script>
<style lang="scss">
.contextmenu {
width: 100px;
@@ -283,4 +285,4 @@ export default {
background: #f2f2f2;
cursor: pointer;
}
</style>
</style>

View File

@@ -6,14 +6,14 @@
:collapse="isCollapse"
:collapse-transition="true"
:default-active="active"
@select="selectMenuItem"
active-text-color="#fff"
class="el-menu-vertical"
text-color="rgb(191, 203, 217)"
unique-opened
@select="selectMenuItem"
>
<template v-for="item in asyncRouters[0].children">
<aside-component :key="item.name" :routerInfo="item" v-if="!item.hidden" />
<aside-component v-if="!item.hidden" :key="item.name" :router-info="item" />
</template>
</el-menu>
</transition>
@@ -22,63 +22,63 @@
</template>
<script>
import { mapGetters, mapMutations } from "vuex";
import AsideComponent from "@/view/layout/aside/asideComponent";
import { mapGetters, mapMutations } from 'vuex'
import AsideComponent from '@/view/layout/aside/asideComponent'
export default {
name: "Aside",
data() {
return {
active: "",
isCollapse: false
};
},
methods: {
...mapMutations("history", ["addHistory"]),
selectMenuItem(index, _, ele) {
const query = {};
const params = {};
ele.route.parameters &&
ele.route.parameters.map(item => {
if (item.type == "query") {
query[item.key] = item.value;
} else {
params[item.key] = item.value;
}
});
if (index === this.$route.name) return;
if (index.indexOf("http://") > -1 || index.indexOf("https://") > -1) {
window.open(index);
} else {
this.$router.push({ name: index, query, params });
}
}
},
computed: {
...mapGetters("router", ["asyncRouters"])
},
name: 'Aside',
components: {
AsideComponent
},
created() {
this.active = this.$route.name;
let screenWidth = document.body.clientWidth;
if (screenWidth < 1000) {
this.isCollapse = !this.isCollapse;
data() {
return {
active: '',
isCollapse: false
}
this.$bus.on("collapse", item => {
this.isCollapse = item;
});
},
computed: {
...mapGetters('router', ['asyncRouters'])
},
watch: {
$route() {
this.active = this.$route.name;
this.active = this.$route.name
}
},
created() {
this.active = this.$route.name
const screenWidth = document.body.clientWidth
if (screenWidth < 1000) {
this.isCollapse = !this.isCollapse
}
this.$bus.on('collapse', item => {
this.isCollapse = item
})
},
beforeDestroy() {
this.$bus.off("collapse");
this.$bus.off('collapse')
},
methods: {
...mapMutations('history', ['addHistory']),
selectMenuItem(index, _, ele) {
const query = {}
const params = {}
ele.route.parameters &&
ele.route.parameters.map(item => {
if (item.type === 'query') {
query[item.key] = item.value
} else {
params[item.key] = item.value
}
})
if (index === this.$route.name) return
if (index.indexOf('http://') > -1 || index.indexOf('https://') > -1) {
window.open(index)
} else {
this.$router.push({ name: index, query, params })
}
}
}
};
}
</script>
<style lang="scss">
@@ -95,4 +95,4 @@ export default {
vertical-align: middle;
}
}
</style>
</style>

View File

@@ -3,21 +3,23 @@
<div>
<span>Powered by</span>
<span>
<a href="https://github.com/flipped-aurora/gin-vue-admin">gin-vue-admin</a>
<a href="https://github.com/flipped-aurora/gin-vue-admin">gin-vue-admin</a>
</span>
<el-divider direction="vertical"></el-divider>
<el-divider direction="vertical" />
<span>Copyright</span>
<span>
<a href="https://github.com/flipped-aurora">flipped-aurora团队</a>
<a href="https://github.com/flipped-aurora">flipped-aurora团队</a>
</span>
</div>
</div>
</template>
<script>
export default {
name:"BottomInfo"
name: 'BottomInfo'
}
</script>
<style lang="scss">
.bottom-info {
color: #888;

View File

@@ -1,11 +1,11 @@
<template>
<el-container class="layout-cont">
<el-container :class="[isSider?'openside':'hideside',isMobile ? 'mobile': '']">
<el-row :class="[isShadowBg?'shadowBg':'']" @click.native="changeShadow()"></el-row>
<el-row :class="[isShadowBg?'shadowBg':'']" @click.native="changeShadow()" />
<el-aside class="main-cont main-left">
<div class="tilte">
<img alt class="logoimg" src="~@/assets/nav_logo.png" />
<h2 class="tit-text" v-if="isSider">Gin-Vue-Admin</h2>
<img alt class="logoimg" src="~@/assets/nav_logo.png">
<h2 v-if="isSider" class="tit-text">Gin-Vue-Admin</h2>
</div>
<Aside class="aside" />
</el-aside>
@@ -16,49 +16,49 @@
:style="{width: `calc(100% - ${isMobile?'0px':isCollapse?'54px':'220px'})`}"
class="topfix"
>
<el-row>
<!-- :xs="8" :sm="6" :md="4" :lg="3" :xl="1" -->
<el-header class="header-cont">
<el-col :xs="2" :lg="1" :md="1" :sm="1" :xl="1">
<div @click="totalCollapse" class="menu-total">
<i class="el-icon-s-unfold" v-if="isCollapse"></i>
<i class="el-icon-s-fold" v-else></i>
<el-row>
<!-- :xs="8" :sm="6" :md="4" :lg="3" :xl="1" -->
<el-header class="header-cont">
<el-col :xs="2" :lg="1" :md="1" :sm="1" :xl="1">
<div class="menu-total" @click="totalCollapse">
<i v-if="isCollapse" class="el-icon-s-unfold" />
<i v-else class="el-icon-s-fold" />
</div>
</el-col>
<el-col :xs="10" :lg="14" :md='14' :sm="9" :xl="14">
<el-breadcrumb class="breadcrumb" separator-class="el-icon-arrow-right">
<el-breadcrumb-item
:key="item.path"
v-for="item in matched.slice(1,matched.length)"
>{{item.meta.title}}</el-breadcrumb-item>
</el-breadcrumb>
</el-col>
<el-col :xs="12" :lg="9" :md="9" :sm="14" :xl="9">
<div class="fl-right right-box">
<Search />
<Screenfull class="screenfull" :style="{cursor:'pointer'}"></Screenfull>
<el-dropdown>
<span class="header-avatar">
<CustomPic/>
<span style="margin-left: 5px">{{userInfo.nickName}}</span>
<i class="el-icon-arrow-down"></i>
</span>
<el-dropdown-menu class="dropdown-group" slot="dropdown">
<el-dropdown-item>
<span>
更多信息
<el-badge is-dot />
<el-col :xs="10" :lg="14" :md="14" :sm="9" :xl="14">
<el-breadcrumb class="breadcrumb" separator-class="el-icon-arrow-right">
<el-breadcrumb-item
v-for="item in matched.slice(1,matched.length)"
:key="item.path"
>{{ item.meta.title }}</el-breadcrumb-item>
</el-breadcrumb>
</el-col>
<el-col :xs="12" :lg="9" :md="9" :sm="14" :xl="9">
<div class="fl-right right-box">
<Search />
<Screenfull class="screenfull" :style="{cursor:'pointer'}" />
<el-dropdown>
<span class="header-avatar">
<CustomPic />
<span style="margin-left: 5px">{{ userInfo.nickName }}</span>
<i class="el-icon-arrow-down" />
</span>
</el-dropdown-item>
<el-dropdown-item @click.native="toPerson" icon="el-icon-s-custom">个人信息</el-dropdown-item>
<el-dropdown-item @click.native="LoginOut" icon="el-icon-table-lamp"> </el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
</el-col>
<el-dropdown-menu slot="dropdown" class="dropdown-group">
<el-dropdown-item>
<span>
更多信息
<el-badge is-dot />
</span>
</el-dropdown-item>
<el-dropdown-item icon="el-icon-s-custom" @click.native="toPerson">个人信息</el-dropdown-item>
<el-dropdown-item icon="el-icon-table-lamp" @click.native="LoginOut"> </el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
</el-col>
</el-header>
</el-row>
</el-header>
</el-row>
<!-- 当前面包屑用路由自动生成可根据需求修改 -->
<!--
:to="{ path: item.path }" 暂时注释不用-->
@@ -67,16 +67,16 @@
</transition>
<transition mode="out-in" name="el-fade-in-linear">
<keep-alive>
<router-view v-loading="loadingFlag" element-loading-text="正在加载中" class="admin-box" v-if="$route.meta.keepAlive && reloadFlag"></router-view>
<router-view v-if="$route.meta.keepAlive && reloadFlag" v-loading="loadingFlag" element-loading-text="正在加载中" class="admin-box" />
</keep-alive>
</transition>
<transition mode="out-in" name="el-fade-in-linear">
<router-view v-loading="loadingFlag" element-loading-text="正在加载中" class="admin-box" v-if="!$route.meta.keepAlive && reloadFlag"></router-view>
<router-view v-if="!$route.meta.keepAlive && reloadFlag" v-loading="loadingFlag" element-loading-text="正在加载中" class="admin-box" />
</transition>
<BottomInfo />
<BottomInfo />
</el-main>
</el-container>
</el-container>
</template>
@@ -90,18 +90,6 @@ import { mapGetters, mapActions } from 'vuex'
import CustomPic from '@/components/customPic'
export default {
name: 'Layout',
data() {
return {
show: false,
isCollapse: false,
isSider: true,
isMobile: false,
isShadowBg: false,
loadingFlag:false,
reloadFlag:true,
value: ''
}
},
components: {
Aside,
HistoryComponent,
@@ -110,28 +98,17 @@ export default {
BottomInfo,
CustomPic
},
methods: {
...mapActions('user', ['LoginOut']),
reload(){
this.reloadFlag = false
this.$nextTick(()=>{
this.reloadFlag = true
})
},
totalCollapse() {
this.isCollapse = !this.isCollapse
this.isSider = !this.isCollapse
this.isShadowBg = !this.isCollapse
this.$bus.emit('collapse', this.isCollapse)
},
toPerson() {
this.$router.push({ name: 'person' })
},
changeShadow() {
this.isShadowBg = !this.isShadowBg
this.isSider = !!this.isCollapse
this.totalCollapse()
},
data() {
return {
show: false,
isCollapse: false,
isSider: true,
isMobile: false,
isShadowBg: false,
loadingFlag: false,
reloadFlag: true,
value: ''
}
},
computed: {
...mapGetters('user', ['userInfo']),
@@ -143,7 +120,7 @@ export default {
}
},
mounted() {
let screenWidth = document.body.clientWidth
const screenWidth = document.body.clientWidth
if (screenWidth < 1000) {
this.isMobile = true
this.isSider = false
@@ -159,16 +136,16 @@ export default {
}
this.$bus.emit('collapse', this.isCollapse)
this.$bus.emit('mobile', this.isMobile)
this.$bus.on("reload",this.reload)
this.$bus.on("showLoading",()=>{
this.$bus.on('reload', this.reload)
this.$bus.on('showLoading', () => {
this.loadingFlag = true
})
this.$bus.on("closeLoading",()=>{
this.$bus.on('closeLoading', () => {
this.loadingFlag = false
})
window.onresize = () => {
return (() => {
let screenWidth = document.body.clientWidth
const screenWidth = document.body.clientWidth
if (screenWidth < 1000) {
this.isMobile = true
this.isSider = false
@@ -186,9 +163,33 @@ export default {
this.$bus.emit('mobile', this.isMobile)
})()
}
},
methods: {
...mapActions('user', ['LoginOut']),
reload() {
this.reloadFlag = false
this.$nextTick(() => {
this.reloadFlag = true
})
},
totalCollapse() {
this.isCollapse = !this.isCollapse
this.isSider = !this.isCollapse
this.isShadowBg = !this.isCollapse
this.$bus.emit('collapse', this.isCollapse)
},
toPerson() {
this.$router.push({ name: 'person' })
},
changeShadow() {
this.isShadowBg = !this.isShadowBg
this.isSider = !!this.isCollapse
this.totalCollapse()
}
}
}
</script>
<style lang="scss">
@import '@/style/mobile.scss';
@@ -330,7 +331,6 @@ export default {
// }
// }
// .screenfull {
// display: inline-block;
// }

View File

@@ -25,60 +25,93 @@
d="M333.590658 594.033341 167.8171 759.804852 64.218604 655.67219 64.218604 958.270996 366.342596 958.502263 262.234493 855.071589 428.421466 688.86108Z"
p-id="2073"/>
</svg> -->
<svg t="1590133227479" class="screenfull-svg" viewBox="0 0 1024 1024" version="1.1" width="20" height="20" xmlns="http://www.w3.org/2000/svg"
v-if="isShow">
<svg
v-if="isShow"
t="1590133227479"
class="screenfull-svg"
viewBox="0 0 1024 1024"
version="1.1"
width="20"
height="20"
xmlns="http://www.w3.org/2000/svg"
>
<path id="svg_1" d="m928.512,959.744a32,32 0 0 1 -32,-32l0,-256a32,32 0 0 1 64,0l0,256a32,32 0 0 1 -32,32z" />
<path id="svg_2"
d="m960.512,927.744a32,32 0 0 1 -32,32l-256,0a32,32 0 0 1 0,-64l256,0a32,32 0 0 1 32,32zm-864.768,-863.488a32,32 0 0 1 32,32l0,256a32,32 0 0 1 -64,0l0,-256a32,32 0 0 1 32,-32z" />
<path
id="svg_2"
d="m960.512,927.744a32,32 0 0 1 -32,32l-256,0a32,32 0 0 1 0,-64l256,0a32,32 0 0 1 32,32zm-864.768,-863.488a32,32 0 0 1 32,32l0,256a32,32 0 0 1 -64,0l0,-256a32,32 0 0 1 32,-32z"
/>
<path id="svg_3" d="m63.744,96.256a32,32 0 0 1 32,-32l256,0a32,32 0 0 1 0,64l-256,0a32,32 0 0 1 -32,-32z" />
<path id="svg_4" d="m958.030718,91.777575a32,32 0 0 1 -32,32l-256,0a32,32 0 0 1 0,-64l256,0a32,32 0 0 1 32,32z" />
<path id="svg_5" d="m926.030718,59.777575a32,32 0 0 1 32,32l0,256a32,32 0 0 1 -64,0l0,-256a32,32 0 0 1 32,-32z" />
<path id="svg_6"
d="m940.622718,69.250038a32,32 0 0 1 0,45.248l-247.936,247.936a32,32 0 0 1 -45.248,-45.248l247.936,-247.936a31.936,31.936 0 0 1 45.248,0z" />
<path
id="svg_6"
d="m940.622718,69.250038a32,32 0 0 1 0,45.248l-247.936,247.936a32,32 0 0 1 -45.248,-45.248l247.936,-247.936a31.936,31.936 0 0 1 45.248,0z"
/>
<path id="svg_7" d="m61.649508,930.478492a32,32 0 0 1 32,-32l256,0a32,32 0 0 1 0,64l-256,0a32,32 0 0 1 -32,-32z" />
<path id="svg_8" d="m93.649508,962.478492a32,32 0 0 1 -32,-32l0,-256a32,32 0 0 1 64,0l0,256a32,32 0 0 1 -32,32z" />
<path id="svg_9"
d="m79.121508,945.070492a32,32 0 0 1 0,-45.248l247.936,-247.936a32,32 0 0 1 45.248,45.248l-247.936,247.936a32,32 0 0 1 -45.248,0z" />
<path
id="svg_9"
d="m79.121508,945.070492a32,32 0 0 1 0,-45.248l247.936,-247.936a32,32 0 0 1 45.248,45.248l-247.936,247.936a32,32 0 0 1 -45.248,0z"
/>
</svg>
<svg t="1590133734869" class="screenfull-svg" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1862"
xmlns:xlink="http://www.w3.org/1999/xlink" width="20" height="20" v-else>
<path d="M928.512 959.744a32 32 0 0 1-32-32v-256a32 32 0 0 1 64 0v256a32 32 0 0 1-32 32z" fill="" p-id="1863"></path>
<svg
v-else
t="1590133734869"
class="screenfull-svg"
viewBox="0 0 1024 1024"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
p-id="1862"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="20"
height="20"
>
<path d="M928.512 959.744a32 32 0 0 1-32-32v-256a32 32 0 0 1 64 0v256a32 32 0 0 1-32 32z" fill="" p-id="1863" />
<path
d="M960.512 927.744a32 32 0 0 1-32 32h-256a32 32 0 0 1 0-64h256a32 32 0 0 1 32 32zM95.744 64.256a32 32 0 0 1 32 32v256a32 32 0 0 1-64 0v-256a32 32 0 0 1 32-32z"
fill="" p-id="1864"></path>
<path d="M63.744 96.256a32 32 0 0 1 32-32h256a32 32 0 0 1 0 64h-256a32 32 0 0 1-32-32z" fill="" p-id="1865"></path>
<path d="M384.064 671.744a32 32 0 0 1-32 32h-256a32 32 0 0 1 0-64h256a32 32 0 0 1 32 32z" fill="" p-id="1866"></path>
<path d="M352.064 639.744a32 32 0 0 1 32 32v256a32 32 0 0 1-64 0v-256a32 32 0 0 1 32-32z" fill="" p-id="1867"></path>
<path d="M366.656 657.216a32 32 0 0 1 0 45.248L118.72 950.4a32 32 0 0 1-45.248-45.248l247.936-247.936a31.936 31.936 0 0 1 45.248 0z" fill=""
p-id="1868"></path>
<path d="M639.616 352.512a32 32 0 0 1 32-32h256a32 32 0 0 1 0 64h-256a32 32 0 0 1-32-32z" fill="" p-id="1869"></path>
<path d="M671.616 384.512a32 32 0 0 1-32-32v-256a32 32 0 0 1 64 0v256a32 32 0 0 1-32 32z" fill="" p-id="1870"></path>
<path d="M657.088 367.104a32 32 0 0 1 0-45.248l247.936-247.936a32 32 0 0 1 45.248 45.248l-247.936 247.936a32 32 0 0 1-45.248 0z" fill=""
p-id="1871"></path>
fill=""
p-id="1864"
/>
<path d="M63.744 96.256a32 32 0 0 1 32-32h256a32 32 0 0 1 0 64h-256a32 32 0 0 1-32-32z" fill="" p-id="1865" />
<path d="M384.064 671.744a32 32 0 0 1-32 32h-256a32 32 0 0 1 0-64h256a32 32 0 0 1 32 32z" fill="" p-id="1866" />
<path d="M352.064 639.744a32 32 0 0 1 32 32v256a32 32 0 0 1-64 0v-256a32 32 0 0 1 32-32z" fill="" p-id="1867" />
<path
d="M366.656 657.216a32 32 0 0 1 0 45.248L118.72 950.4a32 32 0 0 1-45.248-45.248l247.936-247.936a31.936 31.936 0 0 1 45.248 0z"
fill=""
p-id="1868"
/>
<path d="M639.616 352.512a32 32 0 0 1 32-32h256a32 32 0 0 1 0 64h-256a32 32 0 0 1-32-32z" fill="" p-id="1869" />
<path d="M671.616 384.512a32 32 0 0 1-32-32v-256a32 32 0 0 1 64 0v256a32 32 0 0 1-32 32z" fill="" p-id="1870" />
<path
d="M657.088 367.104a32 32 0 0 1 0-45.248l247.936-247.936a32 32 0 0 1 45.248 45.248l-247.936 247.936a32 32 0 0 1-45.248 0z"
fill=""
p-id="1871"
/>
</svg>
</div>
</template>
<script>
import screenfull from 'screenfull' //引入screenfull
import screenfull from 'screenfull' // 引入screenfull
export default {
name: 'Screenfull',
props: {
width: {
type: Number,
default: 22,
default: 22
},
height: {
type: Number,
default: 22,
default: 22
},
fill: {
type: String,
default: '#48576a',
},
default: '#48576a'
}
},
data() {
return {
isShow: true,
isShow: true
}
},
mounted() {
@@ -86,6 +119,9 @@ export default {
screenfull.on('change', this.changeFullShow)
}
},
destroyed() {
screenfull.off('change', this.changeFullShow)
},
methods: {
click() {
if (screenfull.isEnabled) {
@@ -94,13 +130,11 @@ export default {
},
changeFullShow() {
this.isShow = !screenfull.isFullscreen
},
},
destroyed() {
screenfull.off('change', this.changeFullShow)
},
}
}
}
</script>
<style scoped>
.screenfull-svg {
width: 17px;

View File

@@ -1,21 +1,21 @@
<template>
<div class="search-component">
<transition name="el-fade-in-linear">
<div class="transition-box" style="display: inline-block; " v-show="show">
<div v-show="show" class="transition-box" style="display: inline-block; ">
<el-select
ref="search-input"
@blur="hiddenSearch"
@change="changeRouter"
v-model="value"
filterable
placeholder="请选择"
v-model="value"
@blur="hiddenSearch"
@change="changeRouter"
>
<el-option
v-for="item in routerList"
:key="item.value"
:label="item.label"
:value="item.value"
v-for="item in routerList"
></el-option>
/>
</el-select>
</div>
</transition>
@@ -23,43 +23,42 @@
:style="{display:'inline-block',float:'right',width:'31px',textAlign:'left',fontSize:'16px',paddingTop:'2px'}"
class="user-box"
>
<i @click="$bus.$emit('reload')" :style="{cursor:'pointer'}" class="el-icon-refresh" />
<i :style="{cursor:'pointer'}" class="el-icon-refresh" @click="$bus.$emit('reload')" />
</div>
<div :style="{display:'inline-block',float:'right'}" class="user-box">
<i :style="{cursor:'pointer'}" @click="showSearch()" class="el-icon-search search-icon"></i>
<i :style="{cursor:'pointer'}" class="el-icon-search search-icon" @click="showSearch()" />
</div>
</div>
</template>
<script>
import { mapGetters } from "vuex";
import { mapGetters } from 'vuex'
export default {
name: "searchComponent",
name: 'SearchComponent',
data() {
return {
value: "",
value: '',
show: false
};
}
},
computed: {
...mapGetters("router", ["routerList"])
...mapGetters('router', ['routerList'])
},
methods: {
changeRouter() {
this.$router.push({ name: this.value });
this.value = "";
this.$router.push({ name: this.value })
this.value = ''
},
hiddenSearch() {
this.show = false;
this.show = false
},
showSearch() {
this.show = true;
this.show = true
this.$nextTick(() => {
this.$refs["search-input"].focus();
});
this.$refs['search-input'].focus()
})
}
}
};
}
</script>
<style lang="scss">
</style>

View File

@@ -3,37 +3,35 @@
<div class="container">
<div class="top">
<div class="desc">
<img class="logo_login" src="@/assets/logo_login.png" alt="" />
<img class="logo_login" src="@/assets/logo_login.png" alt="">
</div>
<div class="header">
<a href="/">
<span class="title">Gin-Vue-Admin</span>
</a>
<a href="/"><span class="title">Gin-Vue-Admin</span></a>
</div>
</div>
<div class="main">
<el-form
ref="loginForm"
:model="loginForm"
:rules="rules"
ref="loginForm"
@keyup.enter.native="submitForm"
>
<el-form-item prop="username">
<el-input placeholder="请输入用户名" v-model="loginForm.username">
<i class="el-input__icon el-icon-user" slot="suffix"></i
></el-input>
<el-input v-model="loginForm.username" placeholder="请输入用户名">
<i slot="suffix" class="el-input__icon el-icon-user" />
</el-input>
</el-form-item>
<el-form-item prop="password">
<el-input
v-model="loginForm.password"
:type="lock === 'lock' ? 'password' : 'text'"
placeholder="请输入密码"
v-model="loginForm.password"
>
<i
slot="suffix"
:class="'el-input__icon el-icon-' + lock"
@click="changeLock"
slot="suffix"
></i>
/>
</el-input>
</el-form-item>
<el-form-item style="position: relative">
@@ -50,32 +48,26 @@
width="100%"
height="100%"
alt="请输入验证码"
@click="loginVefify()"
/>
@click="loginVerify()"
>
</div>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submitForm" style="width: 100%"
> </el-button
>
<el-button
type="primary"
style="width: 100%"
@click="submitForm"
> </el-button>
</el-form-item>
</el-form>
</div>
<div class="footer">
<div class="links">
<a href="http://doc.henrongyi.top/"
><img src="@/assets/docs.png" class="link-icon"
/></a>
<a href="https://www.yuque.com/flipped-aurora/"
><img src="@/assets/yuque.png" class="link-icon"
/></a>
<a href="https://github.com/flipped-aurora/gin-vue-admin"
><img src="@/assets/github.png" class="link-icon"
/></a>
<a href="https://space.bilibili.com/322210472"
><img src="@/assets/video.png" class="link-icon"
/></a>
<a href="http://doc.henrongyi.top/"><img src="@/assets/docs.png" class="link-icon"></a>
<a href="https://www.yuque.com/flipped-aurora/"><img src="@/assets/yuque.png" class="link-icon"></a>
<a href="https://github.com/flipped-aurora/gin-vue-admin"><img src="@/assets/github.png" class="link-icon"></a>
<a href="https://space.bilibili.com/322210472"><img src="@/assets/video.png" class="link-icon"></a>
</div>
<div class="copyright">Copyright &copy; {{ curYear }} 💖flipped-aurora</div>
</div>
@@ -84,80 +76,80 @@
</template>
<script>
import { mapActions } from "vuex";
import { captcha } from "@/api/user";
import { mapActions } from 'vuex'
import { captcha } from '@/api/user'
export default {
name: "Login",
name: 'Login',
data() {
const checkUsername = (rule, value, callback) => {
if (value.length < 5) {
return callback(new Error("请输入正确的用户名"));
return callback(new Error('请输入正确的用户名'))
} else {
callback();
callback()
}
};
}
const checkPassword = (rule, value, callback) => {
if (value.length < 6) {
return callback(new Error("请输入正确的密码"));
return callback(new Error('请输入正确的密码'))
} else {
callback();
callback()
}
};
}
return {
curYear: 0,
lock: "lock",
lock: 'lock',
loginForm: {
username: "admin",
password: "123456",
captcha: "",
captchaId: "",
username: 'admin',
password: '123456',
captcha: '',
captchaId: ''
},
rules: {
username: [{ validator: checkUsername, trigger: "blur" }],
password: [{ validator: checkPassword, trigger: "blur" }],
username: [{ validator: checkUsername, trigger: 'blur' }],
password: [{ validator: checkPassword, trigger: 'blur' }]
},
logVerify: "",
picPath: "",
};
logVerify: '',
picPath: ''
}
},
created() {
this.loginVefify();
this.curYear = new Date().getFullYear();
this.loginVerify()
this.curYear = new Date().getFullYear()
},
methods: {
...mapActions("user", ["LoginIn"]),
...mapActions('user', ['LoginIn']),
async login() {
return await this.LoginIn(this.loginForm);
return await this.LoginIn(this.loginForm)
},
async submitForm() {
this.$refs.loginForm.validate(async (v) => {
this.$refs.loginForm.validate(async(v) => {
if (v) {
const flag = await this.login();
const flag = await this.login()
if (!flag) {
this.loginVefify();
this.loginVerify()
}
} else {
this.$message({
type: "error",
message: "请正确填写登录信息",
showClose: true,
});
this.loginVefify();
return false;
type: 'error',
message: '请正确填写登录信息',
showClose: true
})
this.loginVerify()
return false
}
});
})
},
changeLock() {
this.lock === "lock" ? (this.lock = "unlock") : (this.lock = "lock");
this.lock = this.lock === 'lock' ? 'unlock' : 'lock'
},
loginVefify() {
loginVerify() {
captcha({}).then((ele) => {
this.picPath = ele.data.picPath;
this.loginForm.captchaId = ele.data.captchaId;
});
},
},
};
this.picPath = ele.data.picPath
this.loginForm.captchaId = ele.data.captchaId
})
}
}
}
</script>
<style scoped lang="scss">

View File

@@ -4,28 +4,28 @@
<el-col :span="6">
<div class="fl-left avatar-box">
<div class="user-card">
<div class="user-headpic-update" :style="{ 'background-image': `url(${(userInfo.headerImg && userInfo.headerImg.slice(0, 4) !== 'http')?path+userInfo.headerImg:userInfo.headerImg})`,'background-repeat':'no-repeat','background-size':'cover' }" >
<div class="user-headpic-update" :style="{ 'background-image': `url(${(userInfo.headerImg && userInfo.headerImg.slice(0, 4) !== 'http')?path+userInfo.headerImg:userInfo.headerImg})`,'background-repeat':'no-repeat','background-size':'cover' }">
<span class="update" @click="openChooseImg">
<i class="el-icon-edit"></i>
<i class="el-icon-edit" />
重新上传</span>
</div>
</div>
<div class="user-personality">
<p class="nickname">{{userInfo.nickName}}</p>
<p class="nickname">{{ userInfo.nickName }}</p>
<p class="person-info">这个家伙很懒什么都没有留下</p>
</div>
<div class="user-information">
<ul>
<li>
<i class="el-icon-user"></i>{{userInfo.nickName}}
<i class="el-icon-user" />{{ userInfo.nickName }}
</li>
<li>
<i class="el-icon-data-analysis"></i>北京反转极光科技有限公司-技术部-前端事业群
<i class="el-icon-data-analysis" />北京反转极光科技有限公司-技术部-前端事业群
</li>
<li>
<i class="el-icon-video-camera-solid"></i>中国·北京市·朝阳区
<i class="el-icon-video-camera-solid" />中国·北京市·朝阳区
</li>
<li>
<i class="el-icon-medal-1"></i>goLang/JavaScript/Vue/Gorm
<i class="el-icon-medal-1" />goLang/JavaScript/Vue/Gorm
</li>
</ul>
</div>
@@ -74,73 +74,74 @@
<ChooseImg ref="chooseImg" @enter-img="enterImg" />
<el-dialog :visible.sync="showPassword" @close="clearPassword" title="修改密码" width="360px">
<el-form :model="pwdModify" :rules="rules" label-width="80px" ref="modifyPwdForm">
<el-dialog :visible.sync="showPassword" title="修改密码" width="360px" @close="clearPassword">
<el-form ref="modifyPwdForm" :model="pwdModify" :rules="rules" label-width="80px">
<el-form-item :minlength="6" label="原密码" prop="password">
<el-input show-password v-model="pwdModify.password"></el-input>
<el-input v-model="pwdModify.password" show-password />
</el-form-item>
<el-form-item :minlength="6" label="新密码" prop="newPassword">
<el-input show-password v-model="pwdModify.newPassword"></el-input>
<el-input v-model="pwdModify.newPassword" show-password />
</el-form-item>
<el-form-item :minlength="6" label="确认密码" prop="confirmPassword">
<el-input show-password v-model="pwdModify.confirmPassword"></el-input>
<el-input v-model="pwdModify.confirmPassword" show-password />
</el-form-item>
</el-form>
<div class="dialog-footer" slot="footer">
<div slot="footer" class="dialog-footer">
<el-button @click="showPassword=false"> </el-button>
<el-button @click="savePassword" type="primary"> </el-button>
<el-button type="primary" @click="savePassword"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import ChooseImg from "@/components/chooseImg";
import { setUserInfo,changePassword } from "@/api/user";
import { mapGetters, mapMutations } from "vuex";
const path = process.env.VUE_APP_BASE_API;
<script>
import ChooseImg from '@/components/chooseImg'
import { setUserInfo, changePassword } from '@/api/user'
import { mapGetters, mapMutations } from 'vuex'
const path = process.env.VUE_APP_BASE_API
export default {
name: "Person",
name: 'Person',
components: {
ChooseImg
},
data() {
return {
path: path,
activeName: "second",
activeName: 'second',
showPassword: false,
pwdModify: {},
rules: {
password: [
{ required: true, message: "请输入密码", trigger: "blur" },
{ min: 6, message: "最少6个字符", trigger: "blur" }
{ required: true, message: '请输入密码', trigger: 'blur' },
{ min: 6, message: '最少6个字符', trigger: 'blur' }
],
newPassword: [
{ required: true, message: "请输入新密码", trigger: "blur" },
{ min: 6, message: "最少6个字符", trigger: "blur" }
{ required: true, message: '请输入新密码', trigger: 'blur' },
{ min: 6, message: '最少6个字符', trigger: 'blur' }
],
confirmPassword: [
{ required: true, message: "请输入确认密码", trigger: "blur" },
{ min: 6, message: "最少6个字符", trigger: "blur" },
{ required: true, message: '请输入确认密码', trigger: 'blur' },
{ min: 6, message: '最少6个字符', trigger: 'blur' },
{
validator: (rule, value, callback) => {
if (value !== this.pwdModify.newPassword) {
callback(new Error("两次密码不一致"));
callback(new Error('两次密码不一致'))
} else {
callback();
callback()
}
},
trigger: "blur"
trigger: 'blur'
}
]
}
};
},
components: {
ChooseImg
}
},
computed: {
...mapGetters("user", ["userInfo", "token"])
...mapGetters('user', ['userInfo', 'token'])
},
methods: {
...mapMutations("user", ["ResetUserInfo"]),
...mapMutations('user', ['ResetUserInfo']),
savePassword() {
this.$refs.modifyPwdForm.validate(valid => {
if (valid) {
@@ -149,43 +150,44 @@ export default {
password: this.pwdModify.password,
newPassword: this.pwdModify.newPassword
}).then((res) => {
if(res.code == 0){
this.$message.success("修改密码成功!");
if (res.code === 0) {
this.$message.success('修改密码成功!')
}
this.showPassword = false;
});
this.showPassword = false
})
} else {
return false;
return false
}
});
})
},
clearPassword() {
this.pwdModify = {
password: "",
newPassword: "",
confirmPassword: ""
};
this.$refs.modifyPwdForm.clearValidate();
password: '',
newPassword: '',
confirmPassword: ''
}
this.$refs.modifyPwdForm.clearValidate()
},
openChooseImg() {
this.$refs.chooseImg.open();
this.$refs.chooseImg.open()
},
async enterImg(url) {
const res = await setUserInfo({ headerImg: url, ID: this.userInfo.ID });
if (res.code == 0) {
this.ResetUserInfo({ headerImg: url });
const res = await setUserInfo({ headerImg: url, ID: this.userInfo.ID })
if (res.code === 0) {
this.ResetUserInfo({ headerImg: url })
this.$message({
type: "success",
message: "设置成功"
});
type: 'success',
message: '设置成功'
})
}
},
handleClick(tab, event) {
console.log(tab, event);
console.log(tab, event)
}
}
};
}
</script>
<style lang="scss">
.avatar-uploader .el-upload {
border: 1px dashed #d9d9d9;
@@ -300,4 +302,4 @@ export default {
color:transparent;
}
}
</style>
</style>

View File

@@ -1,16 +1,15 @@
<template>
<!-- 此路由可作为父类路由通用路由页面使用 如需自定义父类路由页面 请参考 @/view/superAdmin/index.vue -->
<!-- 此路由可作为父类路由通用路由页面使用 如需自定义父类路由页面 请参考 @/view/superAdmin/index.vue -->
<div>
<keep-alive>
<router-view v-if="$route.meta.keepAlive"></router-view>
<router-view v-if="$route.meta.keepAlive" />
</keep-alive>
<router-view v-if="!$route.meta.keepAlive"></router-view>
<router-view v-if="!$route.meta.keepAlive" />
</div>
</template>
<script>
export default {
name: "RouterHolder",
};
name: 'RouterHolder'
}
</script>
<style lang="scss"></style>

View File

@@ -3,61 +3,61 @@
<div class="search-term">
<el-form :inline="true" :model="searchInfo" class="demo-form-inline">
<el-form-item label="路径">
<el-input placeholder="路径" v-model="searchInfo.path"></el-input>
<el-input v-model="searchInfo.path" placeholder="路径" />
</el-form-item>
<el-form-item label="描述">
<el-input placeholder="描述" v-model="searchInfo.description"></el-input>
<el-input v-model="searchInfo.description" placeholder="描述" />
</el-form-item>
<el-form-item label="api组">
<el-input placeholder="api组" v-model="searchInfo.apiGroup"></el-input>
<el-input v-model="searchInfo.apiGroup" placeholder="api组" />
</el-form-item>
<el-form-item label="请求">
<el-select clearable placeholder="请选择" v-model="searchInfo.method">
<el-select v-model="searchInfo.method" clearable placeholder="请选择">
<el-option
v-for="item in methodOptions"
:key="item.value"
:label="`${item.label}(${item.value})`"
:value="item.value"
v-for="item in methodOptions"
></el-option>
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button @click="onSubmit" type="primary">查询</el-button>
<el-button type="primary" @click="onSubmit">查询</el-button>
</el-form-item>
<el-form-item>
<el-button @click="openDialog('addApi')" type="primary">新增api</el-button>
<el-button type="primary" @click="openDialog('addApi')">新增api</el-button>
</el-form-item>
<el-form-item>
<el-popover placement="top" v-model="deleteVisible" width="160">
<el-popover v-model="deleteVisible" placement="top" width="160">
<p>确定要删除吗</p>
<div style="text-align: right; margin: 0">
<el-button @click="deleteVisible = false" size="mini" type="text">取消</el-button>
<el-button @click="onDelete" size="mini" type="primary">确定</el-button>
</div>
<el-button icon="el-icon-delete" size="mini" slot="reference" type="danger">批量删除</el-button>
<div style="text-align: right; margin: 0">
<el-button size="mini" type="text" @click="deleteVisible = false">取消</el-button>
<el-button size="mini" type="primary" @click="onDelete">确定</el-button>
</div>
<el-button slot="reference" icon="el-icon-delete" size="mini" type="danger">批量删除</el-button>
</el-popover>
</el-form-item>
</el-form>
</div>
<el-table :data="tableData" @sort-change="sortChange" border stripe @selection-change="handleSelectionChange">
<el-table-column
<el-table :data="tableData" border stripe @sort-change="sortChange" @selection-change="handleSelectionChange">
<el-table-column
type="selection"
width="55">
</el-table-column>
<el-table-column label="id" min-width="60" prop="ID" sortable="custom"></el-table-column>
<el-table-column label="api路径" min-width="150" prop="path" sortable="custom"></el-table-column>
<el-table-column label="api分组" min-width="150" prop="apiGroup" sortable="custom"></el-table-column>
<el-table-column label="api简介" min-width="150" prop="description" sortable="custom"></el-table-column>
width="55"
/>
<el-table-column label="id" min-width="60" prop="ID" sortable="custom" />
<el-table-column label="api路径" min-width="150" prop="path" sortable="custom" />
<el-table-column label="api分组" min-width="150" prop="apiGroup" sortable="custom" />
<el-table-column label="api简介" min-width="150" prop="description" sortable="custom" />
<el-table-column label="请求" min-width="150" prop="method" sortable="custom">
<template slot-scope="scope">
<div>
{{scope.row.method}}
{{ scope.row.method }}
<el-tag
:key="scope.row.methodFiletr"
:type="scope.row.method|tagTypeFiletr"
effect="dark"
size="mini"
>{{scope.row.method|methodFiletr}}</el-tag>
>{{ scope.row.method|methodFiletr }}</el-tag>
<!-- {{scope.row.method|methodFiletr}} -->
</div>
</template>
@@ -65,12 +65,12 @@
<el-table-column fixed="right" label="操作" width="200">
<template slot-scope="scope">
<el-button @click="editApi(scope.row)" size="small" type="primary" icon="el-icon-edit">编辑</el-button>
<el-button size="small" type="primary" icon="el-icon-edit" @click="editApi(scope.row)">编辑</el-button>
<el-button
@click="deleteApi(scope.row)"
size="small"
type="danger"
icon="el-icon-delete"
@click="deleteApi(scope.row)"
>删除</el-button>
</template>
</el-table-column>
@@ -81,43 +81,42 @@
:page-sizes="[10, 30, 50, 100]"
:style="{float:'right',padding:'20px'}"
:total="total"
layout="total, sizes, prev, pager, next, jumper"
@current-change="handleCurrentChange"
@size-change="handleSizeChange"
layout="total, sizes, prev, pager, next, jumper"
></el-pagination>
/>
<el-dialog :before-close="closeDialog" :title="dialogTitle" :visible.sync="dialogFormVisible">
<el-form :inline="true" :model="form" :rules="rules" label-width="80px" ref="apiForm">
<el-form ref="apiForm" :inline="true" :model="form" :rules="rules" label-width="80px">
<el-form-item label="路径" prop="path">
<el-input autocomplete="off" v-model="form.path"></el-input>
<el-input v-model="form.path" autocomplete="off" />
</el-form-item>
<el-form-item label="请求" prop="method">
<el-select placeholder="请选择" v-model="form.method">
<el-select v-model="form.method" placeholder="请选择">
<el-option
v-for="item in methodOptions"
:key="item.value"
:label="`${item.label}(${item.value})`"
:value="item.value"
v-for="item in methodOptions"
></el-option>
/>
</el-select>
</el-form-item>
<el-form-item label="api分组" prop="apiGroup">
<el-input autocomplete="off" v-model="form.apiGroup"></el-input>
<el-input v-model="form.apiGroup" autocomplete="off" />
</el-form-item>
<el-form-item label="api简介" prop="description">
<el-input autocomplete="off" v-model="form.description"></el-input>
<el-input v-model="form.description" autocomplete="off" />
</el-form-item>
</el-form>
<div class="warning">新增Api需要在角色管理内配置权限才可使用</div>
<div class="dialog-footer" slot="footer">
<div slot="footer" class="dialog-footer">
<el-button @click="closeDialog"> </el-button>
<el-button @click="enterDialog" type="primary"> </el-button>
<el-button type="primary" @click="enterDialog"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
// 获取列表内容封装在mixins内部 getTableData方法 初始化已封装完成 条件搜索时候 请把条件安好后台定制的结构体字段 放到 this.searchInfo 中即可实现条件搜索
@@ -128,219 +127,221 @@ import {
updateApi,
deleteApi,
deleteApisByIds
} from "@/api/api";
import infoList from "@/mixins/infoList";
import { toSQLLine } from "@/utils/stringFun";
} from '@/api/api'
import infoList from '@/mixins/infoList'
import { toSQLLine } from '@/utils/stringFun'
const methodOptions = [
{
value: "POST",
label: "创建",
type: "success"
value: 'POST',
label: '创建',
type: 'success'
},
{
value: "GET",
label: "查看",
type: ""
value: 'GET',
label: '查看',
type: ''
},
{
value: "PUT",
label: "更新",
type: "warning"
value: 'PUT',
label: '更新',
type: 'warning'
},
{
value: "DELETE",
label: "删除",
type: "danger"
value: 'DELETE',
label: '删除',
type: 'danger'
}
];
]
export default {
name: "Api",
name: 'Api',
filters: {
methodFiletr(value) {
const target = methodOptions.filter(item => item.value === value)[0]
// return target && `${target.label}(${target.value})`
return target && `${target.label}`
},
tagTypeFiletr(value) {
const target = methodOptions.filter(item => item.value === value)[0]
return target && `${target.type}`
}
},
mixins: [infoList],
data() {
return {
deleteVisible:false,
deleteVisible: false,
listApi: getApiList,
dialogFormVisible: false,
dialogTitle: "新增Api",
apis:[],
dialogTitle: '新增Api',
apis: [],
form: {
path: "",
apiGroup: "",
method: "",
description: ""
path: '',
apiGroup: '',
method: '',
description: ''
},
methodOptions: methodOptions,
type: "",
type: '',
rules: {
path: [{ required: true, message: "请输入api路径", trigger: "blur" }],
path: [{ required: true, message: '请输入api路径', trigger: 'blur' }],
apiGroup: [
{ required: true, message: "请输入组名称", trigger: "blur" }
{ required: true, message: '请输入组名称', trigger: 'blur' }
],
method: [
{ required: true, message: "请选择请求方式", trigger: "blur" }
{ required: true, message: '请选择请求方式', trigger: 'blur' }
],
description: [
{ required: true, message: "请输入api介绍", trigger: "blur" }
{ required: true, message: '请输入api介绍', trigger: 'blur' }
]
}
};
}
},
created() {
this.getTableData()
},
methods: {
// 选中api
handleSelectionChange(val) {
this.apis = val;
},
async onDelete(){
const ids = this.apis.map(item=>item.ID)
const res = await deleteApisByIds({ids})
if(res.code==0){
this.$message({
type:"success",
message:res.msg
})
if (this.tableData.length == ids.length && this.page > 1) {
this.page--;
}
this.deleteVisible = false
this.getTableData()
handleSelectionChange(val) {
this.apis = val
},
async onDelete() {
const ids = this.apis.map(item => item.ID)
const res = await deleteApisByIds({ ids })
if (res.code === 0) {
this.$message({
type: 'success',
message: res.msg
})
if (this.tableData.length === ids.length && this.page > 1) {
this.page--
}
},
this.deleteVisible = false
this.getTableData()
}
},
// 排序
sortChange({ prop, order }) {
if (prop) {
this.searchInfo.orderKey = toSQLLine(prop);
this.searchInfo.desc = order == "descending";
this.searchInfo.orderKey = toSQLLine(prop)
this.searchInfo.desc = order === 'descending'
}
this.getTableData();
this.getTableData()
},
//条件搜索前端看此方法
// 条件搜索前端看此方法
onSubmit() {
this.page = 1;
this.pageSize = 10;
this.getTableData();
this.page = 1
this.pageSize = 10
this.getTableData()
},
initForm() {
this.$refs.apiForm.resetFields();
this.$refs.apiForm.resetFields()
this.form = {
path: "",
apiGroup: "",
method: "",
description: ""
};
path: '',
apiGroup: '',
method: '',
description: ''
}
},
closeDialog() {
this.initForm();
this.dialogFormVisible = false;
this.initForm()
this.dialogFormVisible = false
},
openDialog(type) {
switch (type) {
case "addApi":
this.dialogTitle = "新增Api";
break;
case "edit":
this.dialogTitle = "编辑Api";
break;
case 'addApi':
this.dialogTitle = '新增Api'
break
case 'edit':
this.dialogTitle = '编辑Api'
break
default:
break;
break
}
this.type = type;
this.dialogFormVisible = true;
this.type = type
this.dialogFormVisible = true
},
async editApi(row) {
const res = await getApiById({ id: row.ID });
this.form = res.data.api;
this.openDialog("edit");
const res = await getApiById({ id: row.ID })
this.form = res.data.api
this.openDialog('edit')
},
async deleteApi(row) {
this.$confirm("此操作将永久删除所有角色下该api, 是否继续?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
this.$confirm('此操作将永久删除所有角色下该api, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
.then(async () => {
const res = await deleteApi(row);
if (res.code == 0) {
.then(async() => {
const res = await deleteApi(row)
if (res.code === 0) {
this.$message({
type: "success",
message: "删除成功!"
});
if (this.tableData.length == 1 && this.page > 1 ) {
this.page--;
type: 'success',
message: '删除成功!'
})
if (this.tableData.length === 1 && this.page > 1) {
this.page--
}
this.getTableData();
this.getTableData()
}
})
.catch(() => {
this.$message({
type: "info",
message: "已取消删除"
});
});
type: 'info',
message: '已取消删除'
})
})
},
async enterDialog() {
this.$refs.apiForm.validate(async valid => {
if (valid) {
switch (this.type) {
case "addApi":
case 'addApi':
{
const res = await createApi(this.form);
if (res.code == 0) {
const res = await createApi(this.form)
if (res.code === 0) {
this.$message({
type: "success",
message: "添加成功",
type: 'success',
message: '添加成功',
showClose: true
});
})
}
this.getTableData();
this.closeDialog();
this.getTableData()
this.closeDialog()
}
break;
case "edit":
break
case 'edit':
{
const res = await updateApi(this.form);
if (res.code == 0) {
const res = await updateApi(this.form)
if (res.code === 0) {
this.$message({
type: "success",
message: "编辑成功",
type: 'success',
message: '编辑成功',
showClose: true
});
})
}
this.getTableData();
this.closeDialog();
this.getTableData()
this.closeDialog()
}
break;
break
default:
// eslint-disable-next-line no-lone-blocks
{
this.$message({
type: "error",
message: "未知操作",
type: 'error',
message: '未知操作',
showClose: true
});
})
}
break;
break
}
}
});
})
}
},
filters: {
methodFiletr(value) {
const target = methodOptions.filter(item => item.value === value)[0];
// return target && `${target.label}(${target.value})`
return target && `${target.label}`;
},
tagTypeFiletr(value) {
const target = methodOptions.filter(item => item.value === value)[0];
return target && `${target.type}`;
}
},
created() {
this.getTableData();
}
};
}
</script>
<style scoped lang="scss">
.button-box {
padding: 10px 20px;
@@ -354,4 +355,4 @@ export default {
.warning {
color: #dc143c;
}
</style>
</style>

View File

@@ -1,7 +1,7 @@
<template>
<div class="authority">
<div class="button-box clearflex">
<el-button @click="addAuthority('0')" type="primary">新增角色</el-button>
<el-button type="primary" @click="addAuthority('0')">新增角色</el-button>
</div>
<el-table
:data="tableData"
@@ -11,74 +11,74 @@
stripe
style="width: 100%"
>
<el-table-column label="角色id" min-width="180" prop="authorityId"></el-table-column>
<el-table-column label="角色名称" min-width="180" prop="authorityName"></el-table-column>
<el-table-column label="角色id" min-width="180" prop="authorityId" />
<el-table-column label="角色名称" min-width="180" prop="authorityName" />
<el-table-column fixed="right" label="操作" width="460">
<template slot-scope="scope">
<el-button @click="opdendrawer(scope.row)" size="small" type="primary">设置权限</el-button>
<el-button size="small" type="primary" @click="opdendrawer(scope.row)">设置权限</el-button>
<el-button
@click="addAuthority(scope.row.authorityId)"
icon="el-icon-plus"
size="small"
type="primary"
@click="addAuthority(scope.row.authorityId)"
>新增子角色</el-button>
<el-button
@click="copyAuthority(scope.row)"
icon="el-icon-copy-document"
size="small"
type="primary"
@click="copyAuthority(scope.row)"
>拷贝</el-button>
<el-button
@click="editAuthority(scope.row)"
icon="el-icon-edit"
size="small"
type="primary"
@click="editAuthority(scope.row)"
>编辑</el-button>
<el-button
@click="deleteAuth(scope.row)"
icon="el-icon-delete"
size="small"
type="danger"
@click="deleteAuth(scope.row)"
>删除</el-button>
</template>
</el-table-column>
</el-table>
<!-- 新增角色弹窗 -->
<el-dialog :title="dialogTitle" :visible.sync="dialogFormVisible">
<el-form :model="form" :rules="rules" ref="authorityForm">
<el-form ref="authorityForm" :model="form" :rules="rules">
<el-form-item label="父级角色" prop="parentId">
<el-cascader
v-model="form.parentId"
:disabled="dialogType=='add'"
:options="AuthorityOption"
:props="{ checkStrictly: true,label:'authorityName',value:'authorityId',disabled:'disabled',emitPath:false}"
:show-all-levels="false"
filterable
v-model="form.parentId"
></el-cascader>
/>
</el-form-item>
<el-form-item label="角色ID" prop="authorityId">
<el-input :disabled="dialogType=='edit'" autocomplete="off" v-model="form.authorityId"></el-input>
<el-input v-model="form.authorityId" :disabled="dialogType=='edit'" autocomplete="off" />
</el-form-item>
<el-form-item label="角色姓名" prop="authorityName">
<el-input autocomplete="off" v-model="form.authorityName"></el-input>
<el-input v-model="form.authorityName" autocomplete="off" />
</el-form-item>
</el-form>
<div class="dialog-footer" slot="footer">
<div slot="footer" class="dialog-footer">
<el-button @click="closeDialog"> </el-button>
<el-button @click="enterDialog" type="primary"> </el-button>
<el-button type="primary" @click="enterDialog"> </el-button>
</div>
</el-dialog>
<el-drawer :visible.sync="drawer" :with-header="false" size="40%" title="角色配置" v-if="drawer">
<el-drawer v-if="drawer" :visible.sync="drawer" :with-header="false" size="40%" title="角色配置">
<el-tabs :before-leave="autoEnter" class="role-box" type="border-card">
<el-tab-pane label="角色菜单">
<Menus :row="activeRow" ref="menus" />
<Menus ref="menus" :row="activeRow" />
</el-tab-pane>
<el-tab-pane label="角色api">
<apis :row="activeRow" ref="apis" />
<apis ref="apis" :row="activeRow" />
</el-tab-pane>
<el-tab-pane label="资源权限">
<Datas :authority="tableData" :row="activeRow" ref="datas" />
<Datas ref="datas" :authority="tableData" :row="activeRow" />
</el-tab-pane>
</el-tabs>
</el-drawer>
@@ -94,266 +94,267 @@ import {
createAuthority,
updateAuthority,
copyAuthority
} from "@/api/authority";
} from '@/api/authority'
import Menus from "@/view/superAdmin/authority/components/menus";
import Apis from "@/view/superAdmin/authority/components/apis";
import Datas from "@/view/superAdmin/authority/components/datas";
import Menus from '@/view/superAdmin/authority/components/menus'
import Apis from '@/view/superAdmin/authority/components/apis'
import Datas from '@/view/superAdmin/authority/components/datas'
import infoList from "@/mixins/infoList";
import infoList from '@/mixins/infoList'
export default {
name: "Authority",
mixins: [infoList],
data() {
var mustUint = (rule, value, callback) => {
if (!/^[0-9]*[1-9][0-9]*$/.test(value)) {
return callback(new Error("请输入正整数"));
}
return callback();
};
return {
AuthorityOption: [
{
authorityId: "0",
authorityName: "根角色"
}
],
listApi: getAuthorityList,
drawer: false,
dialogType: "add",
activeRow: {},
activeUserId: 0,
dialogTitle: "新增角色",
dialogFormVisible: false,
apiDialogFlag: false,
copyForm: {},
form: {
authorityId: "",
authorityName: "",
parentId: "0"
},
rules: {
authorityId: [
{ required: true, message: "请输入角色ID", trigger: "blur" },
{ validator: mustUint, trigger: "blur" }
],
authorityName: [
{ required: true, message: "请输入角色名", trigger: "blur" }
],
parentId: [
{ required: true, message: "请选择请求方式", trigger: "blur" }
]
}
};
},
name: 'Authority',
components: {
Menus,
Apis,
Datas
},
mixins: [infoList],
data() {
var mustUint = (rule, value, callback) => {
if (!/^[0-9]*[1-9][0-9]*$/.test(value)) {
return callback(new Error('请输入正整数'))
}
return callback()
}
return {
AuthorityOption: [
{
authorityId: '0',
authorityName: '根角色'
}
],
listApi: getAuthorityList,
drawer: false,
dialogType: 'add',
activeRow: {},
activeUserId: 0,
dialogTitle: '新增角色',
dialogFormVisible: false,
apiDialogFlag: false,
copyForm: {},
form: {
authorityId: '',
authorityName: '',
parentId: '0'
},
rules: {
authorityId: [
{ required: true, message: '请输入角色ID', trigger: 'blur' },
{ validator: mustUint, trigger: 'blur' }
],
authorityName: [
{ required: true, message: '请输入角色名', trigger: 'blur' }
],
parentId: [
{ required: true, message: '请选择请求方式', trigger: 'blur' }
]
}
}
},
async created() {
this.pageSize = 999
await this.getTableData()
},
methods: {
autoEnter(activeName, oldActiveName) {
const paneArr = ["menus", "apis", "datas"];
const paneArr = ['menus', 'apis', 'datas']
if (oldActiveName) {
if (this.$refs[paneArr[oldActiveName]].needConfirm) {
this.$refs[paneArr[oldActiveName]].enterAndNext();
this.$refs[paneArr[oldActiveName]].needConfirm = false;
this.$refs[paneArr[oldActiveName]].enterAndNext()
this.$refs[paneArr[oldActiveName]].needConfirm = false
}
}
},
// 拷贝角色
copyAuthority(row) {
this.setOptions();
this.dialogTitle = "拷贝角色";
this.dialogType = "copy";
for (let k in this.form) {
this.form[k] = row[k];
this.setOptions()
this.dialogTitle = '拷贝角色'
this.dialogType = 'copy'
for (const k in this.form) {
this.form[k] = row[k]
}
this.copyForm = row;
this.dialogFormVisible = true;
this.copyForm = row
this.dialogFormVisible = true
},
opdendrawer(row) {
this.drawer = true;
this.activeRow = row;
this.drawer = true
this.activeRow = row
},
// 删除角色
deleteAuth(row) {
this.$confirm("此操作将永久删除该角色, 是否继续?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
this.$confirm('此操作将永久删除该角色, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
.then(async () => {
const res = await deleteAuthority({ authorityId: row.authorityId });
if (res.code == 0) {
.then(async() => {
const res = await deleteAuthority({ authorityId: row.authorityId })
if (res.code === 0) {
this.$message({
type: "success",
message: "删除成功!"
});
if (this.tableData.length == 1 && this.page > 1 ) {
this.page--;
type: 'success',
message: '删除成功!'
})
if (this.tableData.length === 1 && this.page > 1) {
this.page--
}
this.getTableData();
this.getTableData()
}
})
.catch(() => {
this.$message({
type: "info",
message: "已取消删除"
});
});
type: 'info',
message: '已取消删除'
})
})
},
// 初始化表单
initForm() {
if (this.$refs.authorityForm) {
this.$refs.authorityForm.resetFields();
this.$refs.authorityForm.resetFields()
}
this.form = {
authorityId: "",
authorityName: "",
parentId: "0"
};
authorityId: '',
authorityName: '',
parentId: '0'
}
},
// 关闭窗口
closeDialog() {
this.initForm();
this.dialogFormVisible = false;
this.apiDialogFlag = false;
this.initForm()
this.dialogFormVisible = false
this.apiDialogFlag = false
},
// 确定弹窗
async enterDialog() {
if (this.form.authorityId == "0") {
if (this.form.authorityId === '0') {
this.$message({
type: "error",
message: "角色id不能为0"
});
return false;
type: 'error',
message: '角色id不能为0'
})
return false
}
this.$refs.authorityForm.validate(async valid => {
if (valid) {
switch (this.dialogType) {
case "add":
case 'add':
{
const res = await createAuthority(this.form);
if (res.code == 0) {
const res = await createAuthority(this.form)
if (res.code === 0) {
this.$message({
type: "success",
message: "添加成功!"
});
this.getTableData();
this.closeDialog();
type: 'success',
message: '添加成功!'
})
this.getTableData()
this.closeDialog()
}
}
break;
case "edit":
break
case 'edit':
{
const res = await updateAuthority(this.form);
if (res.code == 0) {
const res = await updateAuthority(this.form)
if (res.code === 0) {
this.$message({
type: "success",
message: "添加成功!"
});
this.getTableData();
this.closeDialog();
type: 'success',
message: '添加成功!'
})
this.getTableData()
this.closeDialog()
}
}
break;
case "copy": {
break
case 'copy': {
const data = {
authority: {
authorityId: "string",
authorityName: "string",
authorityId: 'string',
authorityName: 'string',
datauthorityId: [],
parentId: "string"
parentId: 'string'
},
oldAuthorityId: 0
};
data.authority.authorityId = this.form.authorityId;
data.authority.authorityName = this.form.authorityName;
data.authority.parentId = this.form.parentId;
data.authority.dataAuthorityId = this.copyForm.dataAuthorityId;
data.oldAuthorityId = this.copyForm.authorityId;
const res = await copyAuthority(data);
if (res.code == 0) {
}
data.authority.authorityId = this.form.authorityId
data.authority.authorityName = this.form.authorityName
data.authority.parentId = this.form.parentId
data.authority.dataAuthorityId = this.copyForm.dataAuthorityId
data.oldAuthorityId = this.copyForm.authorityId
const res = await copyAuthority(data)
if (res.code === 0) {
this.$message({
type: "success",
message: "复制成功!"
});
this.getTableData();
type: 'success',
message: '复制成功!'
})
this.getTableData()
}
}
}
this.initForm();
this.dialogFormVisible = false;
this.initForm()
this.dialogFormVisible = false
}
});
})
},
setOptions() {
this.AuthorityOption = [
{
authorityId: "0",
authorityName: "根角色"
authorityId: '0',
authorityName: '根角色'
}
];
this.setAuthorityOptions(this.tableData, this.AuthorityOption, false);
]
this.setAuthorityOptions(this.tableData, this.AuthorityOption, false)
},
setAuthorityOptions(AuthorityData, optionsData, disabled) {
this.form.authorityId = String(this.form.authorityId);
this.form.authorityId = String(this.form.authorityId)
AuthorityData &&
AuthorityData.map(item => {
if (item.children && item.children.length) {
const option = {
authorityId: item.authorityId,
authorityName: item.authorityName,
disabled: disabled || item.authorityId == this.form.authorityId,
disabled: disabled || item.authorityId === this.form.authorityId,
children: []
};
}
this.setAuthorityOptions(
item.children,
option.children,
disabled || item.authorityId == this.form.authorityId
);
optionsData.push(option);
disabled || item.authorityId === this.form.authorityId
)
optionsData.push(option)
} else {
const option = {
authorityId: item.authorityId,
authorityName: item.authorityName,
disabled: disabled || item.authorityId == this.form.authorityId
};
optionsData.push(option);
disabled: disabled || item.authorityId === this.form.authorityId
}
optionsData.push(option)
}
});
})
},
// 增加角色
addAuthority(parentId) {
this.initForm();
this.dialogTitle = "新增角色";
this.dialogType = "add";
this.form.parentId = parentId;
this.setOptions();
this.dialogFormVisible = true;
this.initForm()
this.dialogTitle = '新增角色'
this.dialogType = 'add'
this.form.parentId = parentId
this.setOptions()
this.dialogFormVisible = true
},
// 编辑角色
editAuthority(row) {
this.setOptions();
this.dialogTitle = "编辑角色";
this.dialogType = "edit";
for (let key in this.form) {
this.form[key] = row[key];
this.setOptions()
this.dialogTitle = '编辑角色'
this.dialogType = 'edit'
for (const key in this.form) {
this.form[key] = row[key]
}
this.setOptions();
this.dialogFormVisible = true;
this.setOptions()
this.dialogFormVisible = true
}
},
async created() {
this.pageSize = 999;
await this.getTableData();
}
};
}
</script>
<style lang="scss">
.authority {
.el-input-number {
@@ -375,4 +376,4 @@ export default {
overflow: auto;
}
}
</style>
</style>

View File

@@ -1,21 +1,22 @@
<template>
<div>
<div class="clearflex">
<el-button @click="authApiEnter" class="fl-right" size="small" type="primary"> </el-button>
<el-button class="fl-right" size="small" type="primary" @click="authApiEnter"> </el-button>
</div>
<el-tree
ref="apiTree"
:data="apiTreeData"
:default-checked-keys="apiTreeIds"
:props="apiDefaultProps"
@check="nodeChange"
default-expand-all
highlight-current
node-key="onlyId"
ref="apiTree"
show-checkbox
></el-tree>
@check="nodeChange"
/>
</div>
</template>
<script>
import { getAllApis } from '@/api/api'
import { UpdateCasbin, getPolicyPathByAuthorityId } from '@/api/casbin'
@@ -33,28 +34,43 @@ export default {
return {
apiTreeData: [],
apiTreeIds: [],
needConfirm:false,
needConfirm: false,
apiDefaultProps: {
children: 'children',
label: 'description'
}
}
},
async created() {
// 获取api并整理成树结构
const res2 = await getAllApis()
const apis = res2.data.apis
this.apiTreeData = this.buildApiTree(apis)
const res = await getPolicyPathByAuthorityId({
authorityId: this.row.authorityId
})
this.activeUserId = this.row.authorityId
this.apiTreeIds = []
res.data.paths && res.data.paths.map(item => {
this.apiTreeIds.push('p:' + item.path + 'm:' + item.method)
})
},
methods: {
nodeChange(){
nodeChange() {
this.needConfirm = true
},
// 暴露给外层使用的切换拦截统一方法
enterAndNext(){
enterAndNext() {
this.authApiEnter()
},
// 创建api树方法
buildApiTree(apis) {
const apiObj = new Object()
const apiObj = {}
apis &&
apis.map(item => {
item.onlyId = "p:"+item.path+"m:"+item.method
if (Object.prototype.hasOwnProperty.call(apiObj,item.apiGroup)) {
item.onlyId = 'p:' + item.path + 'm:' + item.method
if (Object.prototype.hasOwnProperty.call(apiObj, item.apiGroup)) {
apiObj[item.apiGroup].push(item)
} else {
Object.assign(apiObj, { [item.apiGroup]: [item] })
@@ -75,10 +91,10 @@ export default {
async authApiEnter() {
const checkArr = this.$refs.apiTree.getCheckedNodes(true)
var casbinInfos = []
checkArr&&checkArr.map(item=>{
checkArr && checkArr.map(item => {
var casbinInfo = {
path:item.path,
method:item.method
path: item.path,
method: item.method
}
casbinInfos.push(casbinInfo)
})
@@ -86,27 +102,10 @@ export default {
authorityId: this.activeUserId,
casbinInfos
})
if (res.code == 0) {
this.$message({ type: 'success', message: "api设置成功" })
if (res.code === 0) {
this.$message({ type: 'success', message: 'api设置成功' })
}
}
},
async created() {
// 获取api并整理成树结构
const res2 = await getAllApis()
const apis = res2.data.apis
this.apiTreeData = this.buildApiTree(apis)
const res = await getPolicyPathByAuthorityId({
authorityId: this.row.authorityId
})
this.activeUserId = this.row.authorityId
this.apiTreeIds = []
res.data.paths&&res.data.paths.map(item=>{
this.apiTreeIds.push("p:"+item.path+"m:"+item.method)
})
}
}
</script>
<style lang="scss">
</style>

View File

@@ -1,27 +1,21 @@
<template>
<div>
<div class="clearflex" style="margin:18px">
<el-button @click="authDataEnter" class="fl-right" size="small" type="primary"> </el-button>
<el-button @click="all" class="fl-left" size="small" type="primary">全选</el-button>
<el-button @click="self" class="fl-left" size="small" type="primary">本角色</el-button>
<el-button @click="selfAndChildren" class="fl-left" size="small" type="primary">本角色及子角色</el-button>
<div class="clearflex" style="margin:18px">
<el-button class="fl-right" size="small" type="primary" @click="authDataEnter"> </el-button>
<el-button class="fl-left" size="small" type="primary" @click="all">全选</el-button>
<el-button class="fl-left" size="small" type="primary" @click="self">本角色</el-button>
<el-button class="fl-left" size="small" type="primary" @click="selfAndChildren">本角色及子角色</el-button>
</div>
<el-checkbox-group v-model="dataAuthorityId" @change="selectAuthority">
<el-checkbox v-for="(item,key) in authoritys" :label="item" :key="key">{{item.authorityName}}</el-checkbox>
<el-checkbox-group v-model="dataAuthorityId" @change="selectAuthority">
<el-checkbox v-for="(item,key) in authoritys" :key="key" :label="item">{{ item.authorityName }}</el-checkbox>
</el-checkbox-group>
</div>
</template>
<script>
import {setDataAuthority} from '@/api/authority'
import { setDataAuthority } from '@/api/authority'
export default {
name: 'Datas',
data() {
return {
authoritys:[],
dataAuthorityId:[],
needConfirm:false
}
},
props: {
row: {
default: function() {
@@ -36,69 +30,74 @@ export default {
type: Array
}
},
methods:{
// 暴露给外层使用的切换拦截统一方法
enterAndNext(){
this.authDataEnter()
},
all(){
this.dataAuthorityId = [...this.authoritys]
this.row.dataAuthorityId = this.dataAuthorityId
this.needConfirm = true
},
self(){
this.dataAuthorityId = this.authoritys.filter(item=>item.authorityId===this.row.authorityId)
this.row.dataAuthorityId = this.dataAuthorityId
this.needConfirm = true
},
selfAndChildren(){
const arrBox = []
this.getChildrenId(this.row,arrBox)
this.dataAuthorityId = this.authoritys.filter(item=>arrBox.indexOf(item.authorityId)>-1)
this.row.dataAuthorityId = this.dataAuthorityId
this.needConfirm = true
},
getChildrenId(row,arrBox){
arrBox.push(row.authorityId)
row.children&&row.children.map(item=>{
this.getChildrenId(item,arrBox)
})
},
// 提交
async authDataEnter(){
const res = await setDataAuthority(this.row)
if(res.code == 0){
this.$message({ type: 'success', message: "资源设置成功" })
}
},
// 平铺角色
roundAuthority(authoritys){
authoritys&&authoritys.map(item=>{
const obj = {}
obj.authorityId = item.authorityId
obj.authorityName = item.authorityName
this.authoritys.push(obj)
if(item.children&&item.children.length){
this.roundAuthority(item.children)
}
})
},
// 选择
selectAuthority(){
this.row.dataAuthorityId = this.dataAuthorityId
this.needConfirm = true
}
data() {
return {
authoritys: [],
dataAuthorityId: [],
needConfirm: false
}
},
created() {
this.authoritys = []
this.dataAuthorityId = []
this.roundAuthority(this.authority)
this.row.dataAuthorityId&&this.row.dataAuthorityId.map(item=>{
const obj = this.authoritys&&this.authoritys.filter(au=>au.authorityId === item.authorityId)&&this.authoritys.filter(au=>au.authorityId === item.authorityId)[0]
this.dataAuthorityId.push(obj)
this.authoritys = []
this.dataAuthorityId = []
this.roundAuthority(this.authority)
this.row.dataAuthorityId && this.row.dataAuthorityId.map(item => {
const obj = this.authoritys && this.authoritys.filter(au => au.authorityId === item.authorityId) && this.authoritys.filter(au => au.authorityId === item.authorityId)[0]
this.dataAuthorityId.push(obj)
})
},
methods: {
// 暴露给外层使用的切换拦截统一方法
enterAndNext() {
this.authDataEnter()
},
all() {
this.dataAuthorityId = [...this.authoritys]
this.row.dataAuthorityId = this.dataAuthorityId
this.needConfirm = true
},
self() {
this.dataAuthorityId = this.authoritys.filter(item => item.authorityId === this.row.authorityId)
this.row.dataAuthorityId = this.dataAuthorityId
this.needConfirm = true
},
selfAndChildren() {
const arrBox = []
this.getChildrenId(this.row, arrBox)
this.dataAuthorityId = this.authoritys.filter(item => arrBox.indexOf(item.authorityId) > -1)
this.row.dataAuthorityId = this.dataAuthorityId
this.needConfirm = true
},
getChildrenId(row, arrBox) {
arrBox.push(row.authorityId)
row.children && row.children.map(item => {
this.getChildrenId(item, arrBox)
})
},
// 提交
async authDataEnter() {
const res = await setDataAuthority(this.row)
if (res.code === 0) {
this.$message({ type: 'success', message: '资源设置成功' })
}
},
// 平铺角色
roundAuthority(authoritys) {
authoritys && authoritys.map(item => {
const obj = {}
obj.authorityId = item.authorityId
obj.authorityName = item.authorityName
this.authoritys.push(obj)
if (item.children && item.children.length) {
this.roundAuthority(item.children)
}
})
},
// 选择
selectAuthority() {
this.row.dataAuthorityId = this.dataAuthorityId
this.needConfirm = true
}
}
}
</script>
<style lang="less">
</style>

View File

@@ -1,40 +1,42 @@
<template>
<div>
<div class="clearflex">
<el-button @click="relation" class="fl-right" size="small" type="primary"> </el-button>
<el-button class="fl-right" size="small" type="primary" @click="relation"> </el-button>
</div>
<el-tree
ref="menuTree"
:data="menuTreeData"
:default-checked-keys="menuTreeIds"
:props="menuDefaultProps"
@check="nodeChange"
default-expand-all
highlight-current
node-key="ID"
ref="menuTree"
show-checkbox
@check="nodeChange"
>
<span class="custom-tree-node" slot-scope="{ node , data }">
<span slot-scope="{ node , data }" class="custom-tree-node">
<span>{{ node.label }}</span>
<span>
<el-button
type="text"
size="mini"
:style="{color:row.defaultRouter == data.name?'#E6A23C':'#85ce61'}"
:style="{color:row.defaultRouter === data.name?'#E6A23C':'#85ce61'}"
:disabled="!node.checked"
@click="() => setDefault(data)">
{{row.defaultRouter == data.name?"首页":"设为首页"}}
@click="() => setDefault(data)"
>
{{ row.defaultRouter === data.name?"首页":"设为首页" }}
</el-button>
</span>
</span>
</el-tree>
</div>
</template>
<script>
import { getBaseMenuTree, getMenuAuthority, addMenuAuthority } from '@/api/menu'
import {
updateAuthority,
} from "@/api/authority";
updateAuthority
} from '@/api/authority'
export default {
name: 'Menus',
props: {
@@ -49,45 +51,15 @@ export default {
return {
menuTreeData: [],
menuTreeIds: [],
needConfirm:false,
needConfirm: false,
menuDefaultProps: {
children: 'children',
label: function(data){
label: function(data) {
return data.meta.title
}
}
}
},
methods: {
async setDefault(data){
const res = await updateAuthority({authorityId: this.row.authorityId,AuthorityName: this.row.authorityName,parentId: this.row.parentId,defaultRouter:data.name})
if(res.code == 0){
this.$message({type:"success",message:"设置成功"})
this.row.defaultRouter = res.data.authority.defaultRouter
}
},
nodeChange(){
this.needConfirm = true
},
// 暴露给外层使用的切换拦截统一方法
enterAndNext(){
this.relation()
},
// 关联树 确认方法
async relation() {
const checkArr = this.$refs.menuTree.getCheckedNodes(false, true)
const res = await addMenuAuthority({
menus: checkArr,
authorityId: this.row.authorityId
})
if (res.code == 0) {
this.$message({
type: 'success',
message: '菜单设置成功!'
})
}
}
},
async created() {
// 获取所有菜单树
const res = await getBaseMenuTree()
@@ -103,8 +75,36 @@ export default {
}
})
this.menuTreeIds = arr
},
methods: {
async setDefault(data) {
const res = await updateAuthority({ authorityId: this.row.authorityId, AuthorityName: this.row.authorityName, parentId: this.row.parentId, defaultRouter: data.name })
if (res.code === 0) {
this.$message({ type: 'success', message: '设置成功' })
this.row.defaultRouter = res.data.authority.defaultRouter
}
},
nodeChange() {
this.needConfirm = true
},
// 暴露给外层使用的切换拦截统一方法
enterAndNext() {
this.relation()
},
// 关联树 确认方法
async relation() {
const checkArr = this.$refs.menuTree.getCheckedNodes(false, true)
const res = await addMenuAuthority({
menus: checkArr,
authorityId: this.row.authorityId
})
if (res.code === 0) {
this.$message({
type: 'success',
message: '菜单设置成功!'
})
}
}
}
}
</script>
<style lang="scss">
</style>

View File

@@ -3,62 +3,62 @@
<div class="search-term">
<el-form :inline="true" :model="searchInfo" class="demo-form-inline">
<el-form-item label="字典名(中)">
<el-input placeholder="搜索条件" v-model="searchInfo.name"></el-input>
<el-input v-model="searchInfo.name" placeholder="搜索条件" />
</el-form-item>
<el-form-item label="字典名(英)">
<el-input placeholder="搜索条件" v-model="searchInfo.type"></el-input>
<el-input v-model="searchInfo.type" placeholder="搜索条件" />
</el-form-item>
<el-form-item label="状态" prop="status">
<el-select v-model="searchInfo.status" clear placeholder="请选择">
<el-option key="true" label="是" value="true"></el-option>
<el-option key="false" label="否" value="false"></el-option>
<el-option key="true" label="是" value="true" />
<el-option key="false" label="否" value="false" />
</el-select>
</el-form-item>
<el-form-item label="描述">
<el-input placeholder="搜索条件" v-model="searchInfo.desc"></el-input>
<el-input v-model="searchInfo.desc" placeholder="搜索条件" />
</el-form-item>
<el-form-item>
<el-button @click="onSubmit" type="primary">查询</el-button>
<el-button type="primary" @click="onSubmit">查询</el-button>
</el-form-item>
<el-form-item>
<el-button @click="openDialog" type="primary">新增字典</el-button>
<el-button type="primary" @click="openDialog">新增字典</el-button>
</el-form-item>
</el-form>
</div>
<el-table
ref="multipleTable"
:data="tableData"
border
ref="multipleTable"
stripe
style="width: 100%"
tooltip-effect="dark"
>
<el-table-column type="selection" width="55"></el-table-column>
<el-table-column type="selection" width="55" />
<el-table-column label="日期" width="180">
<template slot-scope="scope">{{scope.row.CreatedAt|formatDate}}</template>
<template slot-scope="scope">{{ scope.row.CreatedAt|formatDate }}</template>
</el-table-column>
<el-table-column label="字典名(中)" prop="name" width="120"></el-table-column>
<el-table-column label="字典名(中)" prop="name" width="120" />
<el-table-column label="字典名(英)" prop="type" width="120"></el-table-column>
<el-table-column label="字典名(英)" prop="type" width="120" />
<el-table-column label="状态" prop="status" width="120">
<template slot-scope="scope">{{scope.row.status|formatBoolean}}</template>
<template slot-scope="scope">{{ scope.row.status|formatBoolean }}</template>
</el-table-column>
<el-table-column label="描述" prop="desc" width="280"></el-table-column>
<el-table-column label="描述" prop="desc" width="280" />
<el-table-column label="按钮组">
<template slot-scope="scope">
<el-button @click="toDetile(scope.row)" size="small" type="success">详情</el-button>
<el-button @click="updateSysDictionary(scope.row)" size="small" type="primary">变更</el-button>
<el-popover placement="top" width="160" v-model="scope.row.visible">
<el-button size="small" type="success" @click="toDetile(scope.row)">详情</el-button>
<el-button size="small" type="primary" @click="updateSysDictionary(scope.row)">变更</el-button>
<el-popover v-model="scope.row.visible" placement="top" width="160">
<p>确定要删除吗</p>
<div style="text-align: right; margin: 0">
<el-button size="mini" type="text" @click="scope.row.visible = false">取消</el-button>
<el-button type="primary" size="mini" @click="deleteSysDictionary(scope.row)">确定</el-button>
</div>
<el-button type="danger" icon="el-icon-delete" size="mini" slot="reference" style="margin-left:10px">删除</el-button>
<el-button slot="reference" type="danger" icon="el-icon-delete" size="mini" style="margin-left:10px">删除</el-button>
</el-popover>
</template>
</el-table-column>
@@ -70,10 +70,10 @@
:page-sizes="[10, 30, 50, 100]"
:style="{float:'right',padding:'20px'}"
:total="total"
layout="total, sizes, prev, pager, next, jumper"
@current-change="handleCurrentChange"
@size-change="handleSizeChange"
layout="total, sizes, prev, pager, next, jumper"
></el-pagination>
/>
<el-dialog :before-close="closeDialog" :visible.sync="dialogFormVisible" title="弹窗操作">
<el-form ref="elForm" :model="formData" :rules="rules" size="medium" label-width="110px">
@@ -83,7 +83,7 @@
placeholder="请输入字典名(中)"
clearable
:style="{width: '100%'}"
></el-input>
/>
</el-form-item>
<el-form-item label="字典名(英)" prop="type">
<el-input
@@ -91,19 +91,19 @@
placeholder="请输入字典名(英)"
clearable
:style="{width: '100%'}"
></el-input>
/>
</el-form-item>
<el-form-item label="状态" prop="status" required>
<el-switch v-model="formData.status" active-text="开启" inactive-text="停用"></el-switch>
<el-switch v-model="formData.status" active-text="开启" inactive-text="停用" />
</el-form-item>
<el-form-item label="描述" prop="desc">
<el-input v-model="formData.desc" placeholder="请输入描述" clearable :style="{width: '100%'}"></el-input>
<el-input v-model="formData.desc" placeholder="请输入描述" clearable :style="{width: '100%'}" />
</el-form-item>
</el-form>
<div class="dialog-footer" slot="footer">
<div slot="footer" class="dialog-footer">
<el-button @click="closeDialog"> </el-button>
<el-button @click="enterDialog" type="primary"> </el-button>
<el-button type="primary" @click="enterDialog"> </el-button>
</div>
</el-dialog>
@@ -118,17 +118,34 @@ import {
updateSysDictionary,
findSysDictionary,
getSysDictionaryList
} from "@/api/sysDictionary"; // 此处请自行替换地址
import { formatTimeToStr } from "@/utils/date";
import infoList from "@/mixins/infoList";
} from '@/api/sysDictionary' // 此处请自行替换地址
import { formatTimeToStr } from '@/utils/date'
import infoList from '@/mixins/infoList'
export default {
name: "SysDictionary",
name: 'SysDictionary',
filters: {
formatDate: function(time) {
if (time !== null && time !== '') {
var date = new Date(time)
return formatTimeToStr(date, 'yyyy-MM-dd hh:mm:ss')
} else {
return ''
}
},
formatBoolean: function(bool) {
if (bool !== null) {
return bool ? '是' : '否'
} else {
return ''
}
}
},
mixins: [infoList],
data() {
return {
listApi: getSysDictionaryList,
dialogFormVisible: false,
type: "",
type: '',
formData: {
name: null,
type: null,
@@ -139,124 +156,107 @@ export default {
name: [
{
required: true,
message: "请输入字典名(中)",
trigger: "blur"
message: '请输入字典名(中)',
trigger: 'blur'
}
],
type: [
{
required: true,
message: "请输入字典名(英)",
trigger: "blur"
message: '请输入字典名(英)',
trigger: 'blur'
}
],
desc: [
{
required: true,
message: "请输入描述",
trigger: "blur"
message: '请输入描述',
trigger: 'blur'
}
]
}
};
},
filters: {
formatDate: function(time) {
if (time != null && time != "") {
var date = new Date(time);
return formatTimeToStr(date, "yyyy-MM-dd hh:mm:ss");
} else {
return "";
}
},
formatBoolean: function(bool) {
if (bool != null) {
return bool ? "是" : "否";
} else {
return "";
}
}
},
async created() {
this.getTableData()
},
methods: {
toDetile(row) {
this.$router.push({
name: "dictionaryDetail",
name: 'dictionaryDetail',
params: {
id: row.ID
}
});
})
},
//条件搜索前端看此方法
// 条件搜索前端看此方法
onSubmit() {
this.page = 1;
this.pageSize = 10;
if (this.searchInfo.status == "") {
this.searchInfo.status = null;
this.page = 1
this.pageSize = 10
if (this.searchInfo.status === '') {
this.searchInfo.status = null
}
this.getTableData();
this.getTableData()
},
async updateSysDictionary(row) {
const res = await findSysDictionary({ ID: row.ID });
this.type = "update";
if (res.code == 0) {
this.formData = res.data.resysDictionary;
this.dialogFormVisible = true;
const res = await findSysDictionary({ ID: row.ID })
this.type = 'update'
if (res.code === 0) {
this.formData = res.data.resysDictionary
this.dialogFormVisible = true
}
},
closeDialog() {
this.dialogFormVisible = false;
this.dialogFormVisible = false
this.formData = {
name: null,
type: null,
status: true,
desc: null
};
}
},
async deleteSysDictionary(row) {
row.visible = false;
const res = await deleteSysDictionary({ ID: row.ID });
if (res.code == 0) {
row.visible = false
const res = await deleteSysDictionary({ ID: row.ID })
if (res.code === 0) {
this.$message({
type: "success",
message: "删除成功"
});
if (this.tableData.length == 1 && this.page > 1 ) {
this.page--;
type: 'success',
message: '删除成功'
})
if (this.tableData.length === 1 && this.page > 1) {
this.page--
}
this.getTableData();
this.getTableData()
}
},
async enterDialog() {
this.$refs["elForm"].validate(async valid => {
if (!valid) return;
let res;
this.$refs['elForm'].validate(async valid => {
if (!valid) return
let res
switch (this.type) {
case "create":
res = await createSysDictionary(this.formData);
break;
case "update":
res = await updateSysDictionary(this.formData);
break;
case 'create':
res = await createSysDictionary(this.formData)
break
case 'update':
res = await updateSysDictionary(this.formData)
break
default:
res = await createSysDictionary(this.formData);
break;
res = await createSysDictionary(this.formData)
break
}
if (res.code == 0) {
this.closeDialog();
this.getTableData();
if (res.code === 0) {
this.closeDialog()
this.getTableData()
}
});
})
},
openDialog() {
this.type = "create";
this.dialogFormVisible = true;
this.type = 'create'
this.dialogFormVisible = true
}
},
async created() {
this.getTableData();
}
};
}
</script>
<style>
</style>
</style>

View File

@@ -3,58 +3,58 @@
<div class="search-term">
<el-form :inline="true" :model="searchInfo" class="demo-form-inline">
<el-form-item label="展示值">
<el-input placeholder="搜索条件" v-model="searchInfo.label"></el-input>
<el-input v-model="searchInfo.label" placeholder="搜索条件" />
</el-form-item>
<el-form-item label="字典值">
<el-input placeholder="搜索条件" v-model="searchInfo.value"></el-input>
<el-input v-model="searchInfo.value" placeholder="搜索条件" />
</el-form-item>
<el-form-item label="启用状态" prop="status">
<el-select v-model="searchInfo.status" placeholder="请选择">
<el-option key="true" label="是" value="true"></el-option>
<el-option key="false" label="否" value="false"></el-option>
<el-option key="true" label="是" value="true" />
<el-option key="false" label="否" value="false" />
</el-select>
</el-form-item>
<el-form-item>
<el-button @click="onSubmit" type="primary">查询</el-button>
<el-button type="primary" @click="onSubmit">查询</el-button>
</el-form-item>
<el-form-item>
<el-button @click="openDialog" type="primary">新增字典项</el-button>
<el-button type="primary" @click="openDialog">新增字典项</el-button>
</el-form-item>
</el-form>
</div>
<el-table
ref="multipleTable"
:data="tableData"
border
ref="multipleTable"
stripe
style="width: 100%"
tooltip-effect="dark"
>
<el-table-column type="selection" width="55"></el-table-column>
<el-table-column type="selection" width="55" />
<el-table-column label="日期" width="180">
<template slot-scope="scope">{{scope.row.CreatedAt|formatDate}}</template>
<template slot-scope="scope">{{ scope.row.CreatedAt|formatDate }}</template>
</el-table-column>
<el-table-column label="展示值" prop="label" width="120"></el-table-column>
<el-table-column label="展示值" prop="label" width="120" />
<el-table-column label="字典值" prop="value" width="120"></el-table-column>
<el-table-column label="字典值" prop="value" width="120" />
<el-table-column label="启用状态" prop="status" width="120">
<template slot-scope="scope">{{scope.row.status|formatBoolean}}</template>
<template slot-scope="scope">{{ scope.row.status|formatBoolean }}</template>
</el-table-column>
<el-table-column label="排序标记" prop="sort" width="120"></el-table-column>
<el-table-column label="排序标记" prop="sort" width="120" />
<el-table-column label="按钮组">
<template slot-scope="scope">
<el-button @click="updateSysDictionaryDetail(scope.row)" size="small" type="primary">变更</el-button>
<el-popover placement="top" width="160" v-model="scope.row.visible">
<el-button size="small" type="primary" @click="updateSysDictionaryDetail(scope.row)">变更</el-button>
<el-popover v-model="scope.row.visible" placement="top" width="160">
<p>确定要删除吗</p>
<div style="text-align: right; margin: 0">
<el-button size="mini" type="text" @click="scope.row.visible = false">取消</el-button>
<el-button type="primary" size="mini" @click="deleteSysDictionaryDetail(scope.row)">确定</el-button>
</div>
<el-button type="danger" icon="el-icon-delete" size="mini" slot="reference">删除</el-button>
<el-button slot="reference" type="danger" icon="el-icon-delete" size="mini">删除</el-button>
</el-popover>
</template>
</el-table-column>
@@ -66,10 +66,10 @@
:page-sizes="[10, 30, 50, 100]"
:style="{float:'right',padding:'20px'}"
:total="total"
layout="total, sizes, prev, pager, next, jumper"
@current-change="handleCurrentChange"
@size-change="handleSizeChange"
layout="total, sizes, prev, pager, next, jumper"
></el-pagination>
/>
<el-dialog :before-close="closeDialog" :visible.sync="dialogFormVisible" title="弹窗操作">
<el-form ref="elForm" :model="formData" :rules="rules" size="medium" label-width="110px">
@@ -79,7 +79,7 @@
placeholder="请输入展示值"
clearable
:style="{width: '100%'}"
></el-input>
/>
</el-form-item>
<el-form-item label="字典值" prop="value">
<el-input-number
@@ -89,18 +89,18 @@
placeholder="请输入字典值"
clearable
:style="{width: '100%'}"
></el-input-number>
/>
</el-form-item>
<el-form-item label="启用状态" prop="status" required>
<el-switch v-model="formData.status" active-text="开启" inactive-text="停用"></el-switch>
<el-switch v-model="formData.status" active-text="开启" inactive-text="停用" />
</el-form-item>
<el-form-item label="排序标记" prop="sort">
<el-input-number v-model.number="formData.sort" placeholder="排序标记"></el-input-number>
<el-input-number v-model.number="formData.sort" placeholder="排序标记" />
</el-form-item>
</el-form>
<div class="dialog-footer" slot="footer">
<div slot="footer" class="dialog-footer">
<el-button @click="closeDialog"> </el-button>
<el-button @click="enterDialog" type="primary"> </el-button>
<el-button type="primary" @click="enterDialog"> </el-button>
</div>
</el-dialog>
</div>
@@ -113,18 +113,35 @@ import {
updateSysDictionaryDetail,
findSysDictionaryDetail,
getSysDictionaryDetailList
} from "@/api/sysDictionaryDetail"; // 此处请自行替换地址
import { formatTimeToStr } from "@/utils/date";
import infoList from "@/mixins/infoList";
} from '@/api/sysDictionaryDetail' // 此处请自行替换地址
import { formatTimeToStr } from '@/utils/date'
import infoList from '@/mixins/infoList'
export default {
name: "SysDictionaryDetail",
name: 'SysDictionaryDetail',
filters: {
formatDate: function(time) {
if (time !== null && time !== '') {
var date = new Date(time)
return formatTimeToStr(date, 'yyyy-MM-dd hh:mm:ss')
} else {
return ''
}
},
formatBoolean: function(bool) {
if (bool !== null) {
return bool ? '是' : '否'
} else {
return ''
}
}
},
mixins: [infoList],
data() {
return {
listApi: getSysDictionaryDetailList,
dialogFormVisible: false,
type: "",
type: '',
formData: {
label: null,
value: null,
@@ -135,123 +152,106 @@ export default {
label: [
{
required: true,
message: "请输入展示值",
trigger: "blur"
message: '请输入展示值',
trigger: 'blur'
}
],
value: [
{
required: true,
message: "请输入字典值",
trigger: "blur"
message: '请输入字典值',
trigger: 'blur'
}
],
sort: [
{
required: true,
message: "排序标记",
trigger: "blur"
message: '排序标记',
trigger: 'blur'
}
]
}
};
},
filters: {
formatDate: function(time) {
if (time != null && time != "") {
var date = new Date(time);
return formatTimeToStr(date, "yyyy-MM-dd hh:mm:ss");
} else {
return "";
}
},
formatBoolean: function(bool) {
if (bool != null) {
return bool ? "是" : "否";
} else {
return "";
}
}
},
created() {
this.searchInfo.sysDictionaryID = Number(this.$route.params.id)
this.getTableData()
},
methods: {
//条件搜索前端看此方法
// 条件搜索前端看此方法
onSubmit() {
this.page = 1;
this.pageSize = 10;
if (this.searchInfo.status == "") {
this.searchInfo.status = null;
this.page = 1
this.pageSize = 10
if (this.searchInfo.status === '') {
this.searchInfo.status = null
}
this.getTableData();
this.getTableData()
},
async updateSysDictionaryDetail(row) {
const res = await findSysDictionaryDetail({ ID: row.ID });
this.type = "update";
if (res.code == 0) {
this.formData = res.data.resysDictionaryDetail;
this.dialogFormVisible = true;
const res = await findSysDictionaryDetail({ ID: row.ID })
this.type = 'update'
if (res.code === 0) {
this.formData = res.data.resysDictionaryDetail
this.dialogFormVisible = true
}
},
closeDialog() {
this.dialogFormVisible = false;
this.dialogFormVisible = false
this.formData = {
label: null,
value: null,
status: true,
sort: null,
sysDictionaryID: ""
};
sysDictionaryID: ''
}
},
async deleteSysDictionaryDetail(row) {
row.visible = false;
const res = await deleteSysDictionaryDetail({ ID: row.ID });
if (res.code == 0) {
row.visible = false
const res = await deleteSysDictionaryDetail({ ID: row.ID })
if (res.code === 0) {
this.$message({
type: "success",
message: "删除成功"
});
if (this.tableData.length == 1 && this.page > 1 ) {
this.page--;
type: 'success',
message: '删除成功'
})
if (this.tableData.length === 1 && this.page > 1) {
this.page--
}
this.getTableData();
this.getTableData()
}
},
async enterDialog() {
this.formData.sysDictionaryID = Number(this.$route.params.id);
this.$refs["elForm"].validate(async valid => {
if (!valid) return;
let res;
this.formData.sysDictionaryID = Number(this.$route.params.id)
this.$refs['elForm'].validate(async valid => {
if (!valid) return
let res
switch (this.type) {
case "create":
res = await createSysDictionaryDetail(this.formData);
break;
case "update":
res = await updateSysDictionaryDetail(this.formData);
break;
case 'create':
res = await createSysDictionaryDetail(this.formData)
break
case 'update':
res = await updateSysDictionaryDetail(this.formData)
break
default:
res = await createSysDictionaryDetail(this.formData);
break;
res = await createSysDictionaryDetail(this.formData)
break
}
if (res.code == 0) {
if (res.code === 0) {
this.$message({
type: "success",
message: "创建/更改成功"
});
this.closeDialog();
this.getTableData();
type: 'success',
message: '创建/更改成功'
})
this.closeDialog()
this.getTableData()
}
});
})
},
openDialog() {
this.type = "create";
this.dialogFormVisible = true;
this.type = 'create'
this.dialogFormVisible = true
}
},
created() {
this.searchInfo.sysDictionaryID = Number(this.$route.params.id);
this.getTableData();
}
};
}
</script>
<style>
</style>
</style>

View File

@@ -1,15 +1,14 @@
<template>
<div>
<keep-alive>
<router-view v-if="$route.meta.keepAlive"></router-view>
<router-view v-if="$route.meta.keepAlive" />
</keep-alive>
<router-view v-if="!$route.meta.keepAlive"></router-view>
<router-view v-if="!$route.meta.keepAlive" />
</div>
</template>
<script>
export default {
name: "SuperAdmin",
};
name: 'SuperAdmin'
}
</script>
<style lang="scss"></style>

View File

@@ -1,9 +1,9 @@
<template>
<div>
<el-form
ref="menuForm"
:inline="true"
label-width="85px"
ref="menuForm"
label-position="top"
>
<el-form-item prop="icon" style="width:100%">
@@ -11,10 +11,10 @@
class="icon"
:class="'el-icon-'+ meta.icon"
style="position: absolute; z-index: 9999; padding: 5px 10px; "
></i>
<el-select clearable filterable class="gva-select" v-model="meta.icon" placeholder="请选择">
/>
<el-select v-model="meta.icon" clearable filterable class="gva-select" placeholder="请选择">
<el-option v-for="item in options" :key="item.key" :label="item.key" :value="item.key">
<span class="icon" :class="item.label"></span>
<span class="icon" :class="item.label" />
<span style="float: left">{{ item.key }}</span>
</el-option>
</el-select>
@@ -25,307 +25,307 @@
<script>
export default {
name: "icon",
data() {
return {
input: "",
options: [
{ key: "platform-eleme", label: "el-icon-platform-eleme" },
{ key: "eleme", label: "el-icon-eleme" },
{ key: "delete-solid", label: "el-icon-delete-solid" },
{ key: "delete", label: "el-icon-delete" },
{ key: "s-tools", label: "el-icon-s-tools" },
{ key: "setting", label: "el-icon-setting" },
{ key: "user-solid", label: "el-icon-user-solid" },
{ key: "user", label: "el-icon-user" },
{ key: "phone", label: "el-icon-phone" },
{ key: "phone-outline", label: "el-icon-phone-outline" },
{ key: "more", label: "el-icon-more" },
{ key: "more-outline", label: "el-icon-more-outline" },
{ key: "star-on", label: "el-icon-star-on" },
{ key: "star-off", label: "el-icon-star-off" },
{ key: "s-goods", label: "el-icon-s-goods" },
{ key: "goods", label: "el-icon-goods" },
{ key: "warning", label: "el-icon-warning" },
{ key: "warning-outline", label: "el-icon-warning-outline" },
{ key: "question", label: "el-icon-question" },
{ key: "info", label: "el-icon-info" },
{ key: "remove", label: "el-icon-remove" },
{ key: "circle-plus", label: "el-icon-circle-plus" },
{ key: "success", label: "el-icon-success" },
{ key: "error", label: "el-icon-error" },
{ key: "zoom-in", label: "el-icon-zoom-in" },
{ key: "zoom-out", label: "el-icon-zoom-out" },
{ key: "remove-outline", label: "el-icon-remove-outline" },
{ key: "circle-plus-outline", label: "el-icon-circle-plus-outline" },
{ key: "circle-check", label: "el-icon-circle-check" },
{ key: "circle-close", label: "el-icon-circle-close" },
{ key: "s-help", label: "el-icon-s-help" },
{ key: "help", label: "el-icon-help" },
{ key: "minus", label: "el-icon-minus" },
{ key: "plus", label: "el-icon-plus" },
{ key: "check", label: "el-icon-check" },
{ key: "close", label: "el-icon-close" },
{ key: "picture", label: "el-icon-picture" },
{ key: "picture-outline", label: "el-icon-picture-outline" },
{
key: "picture-outline-round",
label: "el-icon-picture-outline-round"
},
{ key: "upload", label: "el-icon-upload" },
{ key: "upload2", label: "el-icon-upload2" },
{ key: "download", label: "el-icon-download" },
{ key: "camera-solid", label: "el-icon-camera-solid" },
{ key: "camera", label: "el-icon-camera" },
{ key: "video-camera-solid", label: "el-icon-video-camera-solid" },
{ key: "video-camera", label: "el-icon-video-camera" },
{ key: "message-solid", label: "el-icon-message-solid" },
{ key: "bell", label: "el-icon-bell" },
{ key: "s-cooperation", label: "el-icon-s-cooperation" },
{ key: "s-order", label: "el-icon-s-order" },
{ key: "s-platform", label: "el-icon-s-platform" },
{ key: "s-fold", label: "el-icon-s-fold" },
{ key: "s-unfold", label: "el-icon-s-unfold" },
{ key: "s-operation", label: "el-icon-s-operation" },
{ key: "s-promotion", label: "el-icon-s-promotion" },
{ key: "s-home", label: "el-icon-s-home" },
{ key: "s-release", label: "el-icon-s-release" },
{ key: "s-ticket", label: "el-icon-s-ticket" },
{ key: "s-management", label: "el-icon-s-management" },
{ key: "s-open", label: "el-icon-s-open" },
{ key: "s-shop", label: "el-icon-s-shop" },
{ key: "s-marketing", label: "el-icon-s-marketing" },
{ key: "s-flag", label: "el-icon-s-flag" },
{ key: "s-comment", label: "el-icon-s-comment" },
{ key: "s-finance", label: "el-icon-s-finance" },
{ key: "s-claim", label: "el-icon-s-claim" },
{ key: "s-custom", label: "el-icon-s-custom" },
{ key: "s-opportunity", label: "el-icon-s-opportunity" },
{ key: "s-data", label: "el-icon-s-data" },
{ key: "s-check", label: "el-icon-s-check" },
{ key: "s-grid", label: "el-icon-s-grid" },
{ key: "menu", label: "el-icon-menu" },
{ key: "share", label: "el-icon-share" },
{ key: "d-caret", label: "el-icon-d-caret" },
{ key: "caret-left", label: "el-icon-caret-left" },
{ key: "caret-right", label: "el-icon-caret-right" },
{ key: "caret-bottom", label: "el-icon-caret-bottom" },
{ key: "caret-top", label: "el-icon-caret-top" },
{ key: "bottom-left", label: "el-icon-bottom-left" },
{ key: "bottom-right", label: "el-icon-bottom-right" },
{ key: "back", label: "el-icon-back" },
{ key: "right", label: "el-icon-right" },
{ key: "bottom", label: "el-icon-bottom" },
{ key: "top", label: "el-icon-top" },
{ key: "top-left", label: "el-icon-top-left" },
{ key: "top-right", label: "el-icon-top-right" },
{ key: "arrow-left", label: "el-icon-arrow-left" },
{ key: "arrow-right", label: "el-icon-arrow-right" },
{ key: "arrow-down", label: "el-icon-arrow-down" },
{ key: "arrow-up", label: "el-icon-arrow-up" },
{ key: "d-arrow-left", label: "el-icon-d-arrow-left" },
{ key: "d-arrow-right", label: "el-icon-d-arrow-right" },
{ key: "video-pause", label: "el-icon-video-pause" },
{ key: "video-play", label: "el-icon-video-play" },
{ key: "refresh", label: "el-icon-refresh" },
{ key: "refresh-right", label: "el-icon-refresh-right" },
{ key: "refresh-left", label: "el-icon-refresh-left" },
{ key: "finished", label: "el-icon-finished" },
{ key: "sort", label: "el-icon-sort" },
{ key: "sort-up", label: "el-icon-sort-up" },
{ key: "sort-down", label: "el-icon-sort-down" },
{ key: "rank", label: "el-icon-rank" },
{ key: "loading", label: "el-icon-loading" },
{ key: "view", label: "el-icon-view" },
{ key: "c-scale-to-original", label: "el-icon-c-scale-to-original" },
{ key: "date", label: "el-icon-date" },
{ key: "edit", label: "el-icon-edit" },
{ key: "edit-outline", label: "el-icon-edit-outline" },
{ key: "folder", label: "el-icon-folder" },
{ key: "folder-opened", label: "el-icon-folder-opened" },
{ key: "folder-add", label: "el-icon-folder-add" },
{ key: "folder-remove", label: "el-icon-folder-remove" },
{ key: "folder-delete", label: "el-icon-folder-delete" },
{ key: "folder-checked", label: "el-icon-folder-checked" },
{ key: "tickets", label: "el-icon-tickets" },
{ key: "document-remove", label: "el-icon-document-remove" },
{ key: "document-delete", label: "el-icon-document-delete" },
{ key: "document-copy", label: "el-icon-document-copy" },
{ key: "document-checked", label: "el-icon-document-checked" },
{ key: "document", label: "el-icon-document" },
{ key: "document-add", label: "el-icon-document-add" },
{ key: "printer", label: "el-icon-printer" },
{ key: "paperclip", label: "el-icon-paperclip" },
{ key: "takeaway-box", label: "el-icon-takeaway-box" },
{ key: "search", label: "el-icon-search" },
{ key: "monitor", label: "el-icon-monitor" },
{ key: "attract", label: "el-icon-attract" },
{ key: "mobile", label: "el-icon-mobile" },
{ key: "scissors", label: "el-icon-scissors" },
{ key: "umbrella", label: "el-icon-umbrella" },
{ key: "headset", label: "el-icon-headset" },
{ key: "brush", label: "el-icon-brush" },
{ key: "mouse", label: "el-icon-mouse" },
{ key: "coordinate", label: "el-icon-coordinate" },
{ key: "magic-stick", label: "el-icon-magic-stick" },
{ key: "reading", label: "el-icon-reading" },
{ key: "data-line", label: "el-icon-data-line" },
{ key: "data-board", label: "el-icon-data-board" },
{ key: "pie-chart", label: "el-icon-pie-chart" },
{ key: "data-analysis", label: "el-icon-data-analysis" },
{ key: "collection-tag", label: "el-icon-collection-tag" },
{ key: "film", label: "el-icon-film" },
{ key: "suitcase", label: "el-icon-suitcase" },
{ key: "suitcase-1", label: "el-icon-suitcase-1" },
{ key: "receiving", label: "el-icon-receiving" },
{ key: "collection", label: "el-icon-collection" },
{ key: "files", label: "el-icon-files" },
{ key: "notebook-1", label: "el-icon-notebook-1" },
{ key: "notebook-2", label: "el-icon-notebook-2" },
{ key: "toilet-paper", label: "el-icon-toilet-paper" },
{ key: "office-building", label: "el-icon-office-building" },
{ key: "school", label: "el-icon-school" },
{ key: "table-lamp", label: "el-icon-table-lamp" },
{ key: "house", label: "el-icon-house" },
{ key: "no-smoking", label: "el-icon-no-smoking" },
{ key: "smoking", label: "el-icon-smoking" },
{ key: "shopping-cart-full", label: "el-icon-shopping-cart-full" },
{ key: "shopping-cart-1", label: "el-icon-shopping-cart-1" },
{ key: "shopping-cart-2", label: "el-icon-shopping-cart-2" },
{ key: "shopping-bag-1", label: "el-icon-shopping-bag-1" },
{ key: "shopping-bag-2", label: "el-icon-shopping-bag-2" },
{ key: "sold-out", label: "el-icon-sold-out" },
{ key: "sell", label: "el-icon-sell" },
{ key: "present", label: "el-icon-present" },
{ key: "box", label: "el-icon-box" },
{ key: "bank-card", label: "el-icon-bank-card" },
{ key: "money", label: "el-icon-money" },
{ key: "coin", label: "el-icon-coin" },
{ key: "wallet", label: "el-icon-wallet" },
{ key: "discount", label: "el-icon-discount" },
{ key: "price-tag", label: "el-icon-price-tag" },
{ key: "news", label: "el-icon-news" },
{ key: "guide", label: "el-icon-guide" },
{ key: "male", label: "el-icon-male" },
{ key: "female", label: "el-icon-female" },
{ key: "thumb", label: "el-icon-thumb" },
{ key: "cpu", label: "el-icon-cpu" },
{ key: "link", label: "el-icon-link" },
{ key: "connection", label: "el-icon-connection" },
{ key: "open", label: "el-icon-open" },
{ key: "turn-off", label: "el-icon-turn-off" },
{ key: "set-up", label: "el-icon-set-up" },
{ key: "chat-round", label: "el-icon-chat-round" },
{ key: "chat-line-round", label: "el-icon-chat-line-round" },
{ key: "chat-square", label: "el-icon-chat-square" },
{ key: "chat-dot-round", label: "el-icon-chat-dot-round" },
{ key: "chat-dot-square", label: "el-icon-chat-dot-square" },
{ key: "chat-line-square", label: "el-icon-chat-line-square" },
{ key: "message", label: "el-icon-message" },
{ key: "postcard", label: "el-icon-postcard" },
{ key: "position", label: "el-icon-position" },
{ key: "turn-off-microphone", label: "el-icon-turn-off-microphone" },
{ key: "microphone", label: "el-icon-microphone" },
{ key: "close-notification", label: "el-icon-close-notification" },
{ key: "bangzhu", label: "el-icon-bangzhu" },
{ key: "time", label: "el-icon-time" },
{ key: "odometer", label: "el-icon-odometer" },
{ key: "crop", label: "el-icon-crop" },
{ key: "aim", label: "el-icon-aim" },
{ key: "switch-button", label: "el-icon-switch-button" },
{ key: "full-screen", label: "el-icon-full-screen" },
{ key: "copy-document", label: "el-icon-copy-document" },
{ key: "mic", label: "el-icon-mic" },
{ key: "stopwatch", label: "el-icon-stopwatch" },
{ key: "medal-1", label: "el-icon-medal-1" },
{ key: "medal", label: "el-icon-medal" },
{ key: "trophy", label: "el-icon-trophy" },
{ key: "trophy-1", label: "el-icon-trophy-1" },
{ key: "first-aid-kit", label: "el-icon-first-aid-kit" },
{ key: "discover", label: "el-icon-discover" },
{ key: "place", label: "el-icon-place" },
{ key: "location", label: "el-icon-location" },
{ key: "location-outline", label: "el-icon-location-outline" },
{ key: "location-information", label: "el-icon-location-information" },
{ key: "add-location", label: "el-icon-add-location" },
{ key: "delete-location", label: "el-icon-delete-location" },
{ key: "map-location", label: "el-icon-map-location" },
{ key: "alarm-clock", label: "el-icon-alarm-clock" },
{ key: "timer", label: "el-icon-timer" },
{ key: "watch-1", label: "el-icon-watch-1" },
{ key: "watch", label: "el-icon-watch" },
{ key: "lock", label: "el-icon-lock" },
{ key: "unlock", label: "el-icon-unlock" },
{ key: "key", label: "el-icon-key" },
{ key: "service", label: "el-icon-service" },
{ key: "mobile-phone", label: "el-icon-mobile-phone" },
{ key: "bicycle", label: "el-icon-bicycle" },
{ key: "truck", label: "el-icon-truck" },
{ key: "ship", label: "el-icon-ship" },
{ key: "basketball", label: "el-icon-basketball" },
{ key: "football", label: "el-icon-football" },
{ key: "soccer", label: "el-icon-soccer" },
{ key: "baseball", label: "el-icon-baseball" },
{ key: "wind-power", label: "el-icon-wind-power" },
{ key: "light-rain", label: "el-icon-light-rain" },
{ key: "lightning", label: "el-icon-lightning" },
{ key: "heavy-rain", label: "el-icon-heavy-rain" },
{ key: "sunrise", label: "el-icon-sunrise" },
{ key: "sunrise-1", label: "el-icon-sunrise-1" },
{ key: "sunset", label: "el-icon-sunset" },
{ key: "sunny", label: "el-icon-sunny" },
{ key: "cloudy", label: "el-icon-cloudy" },
{ key: "partly-cloudy", label: "el-icon-partly-cloudy" },
{ key: "cloudy-and-sunny", label: "el-icon-cloudy-and-sunny" },
{ key: "moon", label: "el-icon-moon" },
{ key: "moon-night", label: "el-icon-moon-night" },
{ key: "dish", label: "el-icon-dish" },
{ key: "dish-1", label: "el-icon-dish-1" },
{ key: "food", label: "el-icon-food" },
{ key: "chicken", label: "el-icon-chicken" },
{ key: "fork-spoon", label: "el-icon-fork-spoon" },
{ key: "knife-fork", label: "el-icon-knife-fork" },
{ key: "burger", label: "el-icon-burger" },
{ key: "tableware", label: "el-icon-tableware" },
{ key: "sugar", label: "el-icon-sugar" },
{ key: "dessert", label: "el-icon-dessert" },
{ key: "ice-cream", label: "el-icon-ice-cream" },
{ key: "hot-water", label: "el-icon-hot-water" },
{ key: "water-cup", label: "el-icon-water-cup" },
{ key: "coffee-cup", label: "el-icon-coffee-cup" },
{ key: "cold-drink", label: "el-icon-cold-drink" },
{ key: "goblet", label: "el-icon-goblet" },
{ key: "goblet-full", label: "el-icon-goblet-full" },
{ key: "goblet-square", label: "el-icon-goblet-square" },
{ key: "goblet-square-full", label: "el-icon-goblet-square-full" },
{ key: "refrigerator", label: "el-icon-refrigerator" },
{ key: "grape", label: "el-icon-grape" },
{ key: "watermelon", label: "el-icon-watermelon" },
{ key: "cherry", label: "el-icon-cherry" },
{ key: "apple", label: "el-icon-apple" },
{ key: "pear", label: "el-icon-pear" },
{ key: "orange", label: "el-icon-orange" },
{ key: "coffee", label: "el-icon-coffee" },
{ key: "ice-tea", label: "el-icon-ice-tea" },
{ key: "ice-drink", label: "el-icon-ice-drink" },
{ key: "potato-strips", label: "el-icon-potato-strips" },
{ key: "lollipop", label: "el-icon-lollipop" },
{ key: "ice-cream-square", label: "el-icon-ice-cream-square" },
{ key: "ice-cream-round", label: "el-icon-ice-cream-round" }
],
value: ""
};
},
name: 'Icon',
props: {
meta: {
default: function() {
return {};
return {}
},
type: Object
}
},
data() {
return {
input: '',
options: [
{ key: 'platform-eleme', label: 'el-icon-platform-eleme' },
{ key: 'eleme', label: 'el-icon-eleme' },
{ key: 'delete-solid', label: 'el-icon-delete-solid' },
{ key: 'delete', label: 'el-icon-delete' },
{ key: 's-tools', label: 'el-icon-s-tools' },
{ key: 'setting', label: 'el-icon-setting' },
{ key: 'user-solid', label: 'el-icon-user-solid' },
{ key: 'user', label: 'el-icon-user' },
{ key: 'phone', label: 'el-icon-phone' },
{ key: 'phone-outline', label: 'el-icon-phone-outline' },
{ key: 'more', label: 'el-icon-more' },
{ key: 'more-outline', label: 'el-icon-more-outline' },
{ key: 'star-on', label: 'el-icon-star-on' },
{ key: 'star-off', label: 'el-icon-star-off' },
{ key: 's-goods', label: 'el-icon-s-goods' },
{ key: 'goods', label: 'el-icon-goods' },
{ key: 'warning', label: 'el-icon-warning' },
{ key: 'warning-outline', label: 'el-icon-warning-outline' },
{ key: 'question', label: 'el-icon-question' },
{ key: 'info', label: 'el-icon-info' },
{ key: 'remove', label: 'el-icon-remove' },
{ key: 'circle-plus', label: 'el-icon-circle-plus' },
{ key: 'success', label: 'el-icon-success' },
{ key: 'error', label: 'el-icon-error' },
{ key: 'zoom-in', label: 'el-icon-zoom-in' },
{ key: 'zoom-out', label: 'el-icon-zoom-out' },
{ key: 'remove-outline', label: 'el-icon-remove-outline' },
{ key: 'circle-plus-outline', label: 'el-icon-circle-plus-outline' },
{ key: 'circle-check', label: 'el-icon-circle-check' },
{ key: 'circle-close', label: 'el-icon-circle-close' },
{ key: 's-help', label: 'el-icon-s-help' },
{ key: 'help', label: 'el-icon-help' },
{ key: 'minus', label: 'el-icon-minus' },
{ key: 'plus', label: 'el-icon-plus' },
{ key: 'check', label: 'el-icon-check' },
{ key: 'close', label: 'el-icon-close' },
{ key: 'picture', label: 'el-icon-picture' },
{ key: 'picture-outline', label: 'el-icon-picture-outline' },
{
key: 'picture-outline-round',
label: 'el-icon-picture-outline-round'
},
{ key: 'upload', label: 'el-icon-upload' },
{ key: 'upload2', label: 'el-icon-upload2' },
{ key: 'download', label: 'el-icon-download' },
{ key: 'camera-solid', label: 'el-icon-camera-solid' },
{ key: 'camera', label: 'el-icon-camera' },
{ key: 'video-camera-solid', label: 'el-icon-video-camera-solid' },
{ key: 'video-camera', label: 'el-icon-video-camera' },
{ key: 'message-solid', label: 'el-icon-message-solid' },
{ key: 'bell', label: 'el-icon-bell' },
{ key: 's-cooperation', label: 'el-icon-s-cooperation' },
{ key: 's-order', label: 'el-icon-s-order' },
{ key: 's-platform', label: 'el-icon-s-platform' },
{ key: 's-fold', label: 'el-icon-s-fold' },
{ key: 's-unfold', label: 'el-icon-s-unfold' },
{ key: 's-operation', label: 'el-icon-s-operation' },
{ key: 's-promotion', label: 'el-icon-s-promotion' },
{ key: 's-home', label: 'el-icon-s-home' },
{ key: 's-release', label: 'el-icon-s-release' },
{ key: 's-ticket', label: 'el-icon-s-ticket' },
{ key: 's-management', label: 'el-icon-s-management' },
{ key: 's-open', label: 'el-icon-s-open' },
{ key: 's-shop', label: 'el-icon-s-shop' },
{ key: 's-marketing', label: 'el-icon-s-marketing' },
{ key: 's-flag', label: 'el-icon-s-flag' },
{ key: 's-comment', label: 'el-icon-s-comment' },
{ key: 's-finance', label: 'el-icon-s-finance' },
{ key: 's-claim', label: 'el-icon-s-claim' },
{ key: 's-custom', label: 'el-icon-s-custom' },
{ key: 's-opportunity', label: 'el-icon-s-opportunity' },
{ key: 's-data', label: 'el-icon-s-data' },
{ key: 's-check', label: 'el-icon-s-check' },
{ key: 's-grid', label: 'el-icon-s-grid' },
{ key: 'menu', label: 'el-icon-menu' },
{ key: 'share', label: 'el-icon-share' },
{ key: 'd-caret', label: 'el-icon-d-caret' },
{ key: 'caret-left', label: 'el-icon-caret-left' },
{ key: 'caret-right', label: 'el-icon-caret-right' },
{ key: 'caret-bottom', label: 'el-icon-caret-bottom' },
{ key: 'caret-top', label: 'el-icon-caret-top' },
{ key: 'bottom-left', label: 'el-icon-bottom-left' },
{ key: 'bottom-right', label: 'el-icon-bottom-right' },
{ key: 'back', label: 'el-icon-back' },
{ key: 'right', label: 'el-icon-right' },
{ key: 'bottom', label: 'el-icon-bottom' },
{ key: 'top', label: 'el-icon-top' },
{ key: 'top-left', label: 'el-icon-top-left' },
{ key: 'top-right', label: 'el-icon-top-right' },
{ key: 'arrow-left', label: 'el-icon-arrow-left' },
{ key: 'arrow-right', label: 'el-icon-arrow-right' },
{ key: 'arrow-down', label: 'el-icon-arrow-down' },
{ key: 'arrow-up', label: 'el-icon-arrow-up' },
{ key: 'd-arrow-left', label: 'el-icon-d-arrow-left' },
{ key: 'd-arrow-right', label: 'el-icon-d-arrow-right' },
{ key: 'video-pause', label: 'el-icon-video-pause' },
{ key: 'video-play', label: 'el-icon-video-play' },
{ key: 'refresh', label: 'el-icon-refresh' },
{ key: 'refresh-right', label: 'el-icon-refresh-right' },
{ key: 'refresh-left', label: 'el-icon-refresh-left' },
{ key: 'finished', label: 'el-icon-finished' },
{ key: 'sort', label: 'el-icon-sort' },
{ key: 'sort-up', label: 'el-icon-sort-up' },
{ key: 'sort-down', label: 'el-icon-sort-down' },
{ key: 'rank', label: 'el-icon-rank' },
{ key: 'loading', label: 'el-icon-loading' },
{ key: 'view', label: 'el-icon-view' },
{ key: 'c-scale-to-original', label: 'el-icon-c-scale-to-original' },
{ key: 'date', label: 'el-icon-date' },
{ key: 'edit', label: 'el-icon-edit' },
{ key: 'edit-outline', label: 'el-icon-edit-outline' },
{ key: 'folder', label: 'el-icon-folder' },
{ key: 'folder-opened', label: 'el-icon-folder-opened' },
{ key: 'folder-add', label: 'el-icon-folder-add' },
{ key: 'folder-remove', label: 'el-icon-folder-remove' },
{ key: 'folder-delete', label: 'el-icon-folder-delete' },
{ key: 'folder-checked', label: 'el-icon-folder-checked' },
{ key: 'tickets', label: 'el-icon-tickets' },
{ key: 'document-remove', label: 'el-icon-document-remove' },
{ key: 'document-delete', label: 'el-icon-document-delete' },
{ key: 'document-copy', label: 'el-icon-document-copy' },
{ key: 'document-checked', label: 'el-icon-document-checked' },
{ key: 'document', label: 'el-icon-document' },
{ key: 'document-add', label: 'el-icon-document-add' },
{ key: 'printer', label: 'el-icon-printer' },
{ key: 'paperclip', label: 'el-icon-paperclip' },
{ key: 'takeaway-box', label: 'el-icon-takeaway-box' },
{ key: 'search', label: 'el-icon-search' },
{ key: 'monitor', label: 'el-icon-monitor' },
{ key: 'attract', label: 'el-icon-attract' },
{ key: 'mobile', label: 'el-icon-mobile' },
{ key: 'scissors', label: 'el-icon-scissors' },
{ key: 'umbrella', label: 'el-icon-umbrella' },
{ key: 'headset', label: 'el-icon-headset' },
{ key: 'brush', label: 'el-icon-brush' },
{ key: 'mouse', label: 'el-icon-mouse' },
{ key: 'coordinate', label: 'el-icon-coordinate' },
{ key: 'magic-stick', label: 'el-icon-magic-stick' },
{ key: 'reading', label: 'el-icon-reading' },
{ key: 'data-line', label: 'el-icon-data-line' },
{ key: 'data-board', label: 'el-icon-data-board' },
{ key: 'pie-chart', label: 'el-icon-pie-chart' },
{ key: 'data-analysis', label: 'el-icon-data-analysis' },
{ key: 'collection-tag', label: 'el-icon-collection-tag' },
{ key: 'film', label: 'el-icon-film' },
{ key: 'suitcase', label: 'el-icon-suitcase' },
{ key: 'suitcase-1', label: 'el-icon-suitcase-1' },
{ key: 'receiving', label: 'el-icon-receiving' },
{ key: 'collection', label: 'el-icon-collection' },
{ key: 'files', label: 'el-icon-files' },
{ key: 'notebook-1', label: 'el-icon-notebook-1' },
{ key: 'notebook-2', label: 'el-icon-notebook-2' },
{ key: 'toilet-paper', label: 'el-icon-toilet-paper' },
{ key: 'office-building', label: 'el-icon-office-building' },
{ key: 'school', label: 'el-icon-school' },
{ key: 'table-lamp', label: 'el-icon-table-lamp' },
{ key: 'house', label: 'el-icon-house' },
{ key: 'no-smoking', label: 'el-icon-no-smoking' },
{ key: 'smoking', label: 'el-icon-smoking' },
{ key: 'shopping-cart-full', label: 'el-icon-shopping-cart-full' },
{ key: 'shopping-cart-1', label: 'el-icon-shopping-cart-1' },
{ key: 'shopping-cart-2', label: 'el-icon-shopping-cart-2' },
{ key: 'shopping-bag-1', label: 'el-icon-shopping-bag-1' },
{ key: 'shopping-bag-2', label: 'el-icon-shopping-bag-2' },
{ key: 'sold-out', label: 'el-icon-sold-out' },
{ key: 'sell', label: 'el-icon-sell' },
{ key: 'present', label: 'el-icon-present' },
{ key: 'box', label: 'el-icon-box' },
{ key: 'bank-card', label: 'el-icon-bank-card' },
{ key: 'money', label: 'el-icon-money' },
{ key: 'coin', label: 'el-icon-coin' },
{ key: 'wallet', label: 'el-icon-wallet' },
{ key: 'discount', label: 'el-icon-discount' },
{ key: 'price-tag', label: 'el-icon-price-tag' },
{ key: 'news', label: 'el-icon-news' },
{ key: 'guide', label: 'el-icon-guide' },
{ key: 'male', label: 'el-icon-male' },
{ key: 'female', label: 'el-icon-female' },
{ key: 'thumb', label: 'el-icon-thumb' },
{ key: 'cpu', label: 'el-icon-cpu' },
{ key: 'link', label: 'el-icon-link' },
{ key: 'connection', label: 'el-icon-connection' },
{ key: 'open', label: 'el-icon-open' },
{ key: 'turn-off', label: 'el-icon-turn-off' },
{ key: 'set-up', label: 'el-icon-set-up' },
{ key: 'chat-round', label: 'el-icon-chat-round' },
{ key: 'chat-line-round', label: 'el-icon-chat-line-round' },
{ key: 'chat-square', label: 'el-icon-chat-square' },
{ key: 'chat-dot-round', label: 'el-icon-chat-dot-round' },
{ key: 'chat-dot-square', label: 'el-icon-chat-dot-square' },
{ key: 'chat-line-square', label: 'el-icon-chat-line-square' },
{ key: 'message', label: 'el-icon-message' },
{ key: 'postcard', label: 'el-icon-postcard' },
{ key: 'position', label: 'el-icon-position' },
{ key: 'turn-off-microphone', label: 'el-icon-turn-off-microphone' },
{ key: 'microphone', label: 'el-icon-microphone' },
{ key: 'close-notification', label: 'el-icon-close-notification' },
{ key: 'bangzhu', label: 'el-icon-bangzhu' },
{ key: 'time', label: 'el-icon-time' },
{ key: 'odometer', label: 'el-icon-odometer' },
{ key: 'crop', label: 'el-icon-crop' },
{ key: 'aim', label: 'el-icon-aim' },
{ key: 'switch-button', label: 'el-icon-switch-button' },
{ key: 'full-screen', label: 'el-icon-full-screen' },
{ key: 'copy-document', label: 'el-icon-copy-document' },
{ key: 'mic', label: 'el-icon-mic' },
{ key: 'stopwatch', label: 'el-icon-stopwatch' },
{ key: 'medal-1', label: 'el-icon-medal-1' },
{ key: 'medal', label: 'el-icon-medal' },
{ key: 'trophy', label: 'el-icon-trophy' },
{ key: 'trophy-1', label: 'el-icon-trophy-1' },
{ key: 'first-aid-kit', label: 'el-icon-first-aid-kit' },
{ key: 'discover', label: 'el-icon-discover' },
{ key: 'place', label: 'el-icon-place' },
{ key: 'location', label: 'el-icon-location' },
{ key: 'location-outline', label: 'el-icon-location-outline' },
{ key: 'location-information', label: 'el-icon-location-information' },
{ key: 'add-location', label: 'el-icon-add-location' },
{ key: 'delete-location', label: 'el-icon-delete-location' },
{ key: 'map-location', label: 'el-icon-map-location' },
{ key: 'alarm-clock', label: 'el-icon-alarm-clock' },
{ key: 'timer', label: 'el-icon-timer' },
{ key: 'watch-1', label: 'el-icon-watch-1' },
{ key: 'watch', label: 'el-icon-watch' },
{ key: 'lock', label: 'el-icon-lock' },
{ key: 'unlock', label: 'el-icon-unlock' },
{ key: 'key', label: 'el-icon-key' },
{ key: 'service', label: 'el-icon-service' },
{ key: 'mobile-phone', label: 'el-icon-mobile-phone' },
{ key: 'bicycle', label: 'el-icon-bicycle' },
{ key: 'truck', label: 'el-icon-truck' },
{ key: 'ship', label: 'el-icon-ship' },
{ key: 'basketball', label: 'el-icon-basketball' },
{ key: 'football', label: 'el-icon-football' },
{ key: 'soccer', label: 'el-icon-soccer' },
{ key: 'baseball', label: 'el-icon-baseball' },
{ key: 'wind-power', label: 'el-icon-wind-power' },
{ key: 'light-rain', label: 'el-icon-light-rain' },
{ key: 'lightning', label: 'el-icon-lightning' },
{ key: 'heavy-rain', label: 'el-icon-heavy-rain' },
{ key: 'sunrise', label: 'el-icon-sunrise' },
{ key: 'sunrise-1', label: 'el-icon-sunrise-1' },
{ key: 'sunset', label: 'el-icon-sunset' },
{ key: 'sunny', label: 'el-icon-sunny' },
{ key: 'cloudy', label: 'el-icon-cloudy' },
{ key: 'partly-cloudy', label: 'el-icon-partly-cloudy' },
{ key: 'cloudy-and-sunny', label: 'el-icon-cloudy-and-sunny' },
{ key: 'moon', label: 'el-icon-moon' },
{ key: 'moon-night', label: 'el-icon-moon-night' },
{ key: 'dish', label: 'el-icon-dish' },
{ key: 'dish-1', label: 'el-icon-dish-1' },
{ key: 'food', label: 'el-icon-food' },
{ key: 'chicken', label: 'el-icon-chicken' },
{ key: 'fork-spoon', label: 'el-icon-fork-spoon' },
{ key: 'knife-fork', label: 'el-icon-knife-fork' },
{ key: 'burger', label: 'el-icon-burger' },
{ key: 'tableware', label: 'el-icon-tableware' },
{ key: 'sugar', label: 'el-icon-sugar' },
{ key: 'dessert', label: 'el-icon-dessert' },
{ key: 'ice-cream', label: 'el-icon-ice-cream' },
{ key: 'hot-water', label: 'el-icon-hot-water' },
{ key: 'water-cup', label: 'el-icon-water-cup' },
{ key: 'coffee-cup', label: 'el-icon-coffee-cup' },
{ key: 'cold-drink', label: 'el-icon-cold-drink' },
{ key: 'goblet', label: 'el-icon-goblet' },
{ key: 'goblet-full', label: 'el-icon-goblet-full' },
{ key: 'goblet-square', label: 'el-icon-goblet-square' },
{ key: 'goblet-square-full', label: 'el-icon-goblet-square-full' },
{ key: 'refrigerator', label: 'el-icon-refrigerator' },
{ key: 'grape', label: 'el-icon-grape' },
{ key: 'watermelon', label: 'el-icon-watermelon' },
{ key: 'cherry', label: 'el-icon-cherry' },
{ key: 'apple', label: 'el-icon-apple' },
{ key: 'pear', label: 'el-icon-pear' },
{ key: 'orange', label: 'el-icon-orange' },
{ key: 'coffee', label: 'el-icon-coffee' },
{ key: 'ice-tea', label: 'el-icon-ice-tea' },
{ key: 'ice-drink', label: 'el-icon-ice-drink' },
{ key: 'potato-strips', label: 'el-icon-potato-strips' },
{ key: 'lollipop', label: 'el-icon-lollipop' },
{ key: 'ice-cream-square', label: 'el-icon-ice-cream-square' },
{ key: 'ice-cream-round', label: 'el-icon-ice-cream-round' }
],
value: ''
}
},
methods: {}
};
}
</script>
<style lang="scss">

View File

@@ -1,52 +1,52 @@
<template>
<div>
<div class="button-box clearflex">
<el-button @click="addMenu('0')" type="primary">新增根菜单</el-button>
<el-button type="primary" @click="addMenu('0')">新增根菜单</el-button>
</div>
<!-- 由于此处菜单跟左侧列表一一对应所以不需要分页 pageSize默认999 -->
<el-table :data="tableData" border row-key="ID" stripe>
<el-table-column label="ID" min-width="100" prop="ID"></el-table-column>
<el-table-column label="路由Name" min-width="160" prop="name"></el-table-column>
<el-table-column label="路由Path" min-width="160" prop="path"></el-table-column>
<el-table-column label="ID" min-width="100" prop="ID" />
<el-table-column label="路由Name" min-width="160" prop="name" />
<el-table-column label="路由Path" min-width="160" prop="path" />
<el-table-column label="是否隐藏" min-width="100" prop="hidden">
<template slot-scope="scope">
<span>{{scope.row.hidden?"隐藏":"显示"}}</span>
<span>{{ scope.row.hidden?"隐藏":"显示" }}</span>
</template>
</el-table-column>
<el-table-column label="父节点" min-width="90" prop="parentId"></el-table-column>
<el-table-column label="排序" min-width="70" prop="sort"></el-table-column>
<el-table-column label="文件路径" min-width="360" prop="component"></el-table-column>
<el-table-column label="父节点" min-width="90" prop="parentId" />
<el-table-column label="排序" min-width="70" prop="sort" />
<el-table-column label="文件路径" min-width="360" prop="component" />
<el-table-column label="展示名称" min-width="120" prop="authorityName">
<template slot-scope="scope">
<span>{{scope.row.meta.title}}</span>
<span>{{ scope.row.meta.title }}</span>
</template>
</el-table-column>
<el-table-column label="图标" min-width="140" prop="authorityName">
<template slot-scope="scope">
<i :class="`el-icon-${scope.row.meta.icon}`"></i>
<span>{{scope.row.meta.icon}}</span>
<i :class="`el-icon-${scope.row.meta.icon}`" />
<span>{{ scope.row.meta.icon }}</span>
</template>
</el-table-column>
<el-table-column fixed="right" label="操作" width="300">
<template slot-scope="scope">
<el-button
@click="addMenu(scope.row.ID)"
size="small"
type="primary"
icon="el-icon-edit"
@click="addMenu(scope.row.ID)"
>添加子菜单</el-button>
<el-button
@click="editMenu(scope.row.ID)"
size="small"
type="primary"
icon="el-icon-edit"
@click="editMenu(scope.row.ID)"
>编辑</el-button>
<el-button
@click="deleteMenu(scope.row.ID)"
size="small"
type="danger"
icon="el-icon-delete"
@click="deleteMenu(scope.row.ID)"
>删除</el-button>
</template>
</el-table-column>
@@ -54,55 +54,55 @@
<el-dialog :before-close="handleClose" :title="dialogTitle" :visible.sync="dialogFormVisible">
<el-form
ref="menuForm"
:inline="true"
:model="form"
:rules="rules"
label-position="top"
label-width="85px"
ref="menuForm"
>
<el-form-item label="路由name" prop="path" style="width:30%">
<el-input
@change="changeName"
v-model="form.name"
autocomplete="off"
placeholder="唯一英文字符串"
v-model="form.name"
></el-input>
@change="changeName"
/>
</el-form-item>
<el-form-item prop="path" style="width:30%">
<div style="display:inline-block" slot="label">
<div slot="label" style="display:inline-block">
路由path
<el-checkbox style="float:right;margin-left:20px;" v-model="checkFlag">添加参数</el-checkbox>
<el-checkbox v-model="checkFlag" style="float:right;margin-left:20px;">添加参数</el-checkbox>
</div>
<el-input
v-model="form.path"
:disabled="!checkFlag"
autocomplete="off"
placeholder="建议只在后方拼接参数"
v-model="form.path"
></el-input>
/>
</el-form-item>
<el-form-item label="是否隐藏" style="width:30%">
<el-select placeholder="是否在列表隐藏" v-model="form.hidden">
<el-option :value="false" label="否"></el-option>
<el-option :value="true" label="是"></el-option>
<el-select v-model="form.hidden" placeholder="是否在列表隐藏">
<el-option :value="false" label="否" />
<el-option :value="true" label="是" />
</el-select>
</el-form-item>
<el-form-item label="父节点Id" style="width:30%">
<el-cascader
:disabled="!this.isEdit"
v-model="form.parentId"
:disabled="!isEdit"
:options="menuOption"
:props="{ checkStrictly: true,label:'title',value:'ID',disabled:'disabled',emitPath:false}"
:show-all-levels="false"
filterable
v-model="form.parentId"
></el-cascader>
/>
</el-form-item>
<el-form-item label="文件路径" prop="component" style="width:60%">
<el-input autocomplete="off" v-model="form.component"></el-input>
<el-input v-model="form.component" autocomplete="off" />
<span style="font-size:12px;margin-right:12px;">如果菜单包含子菜单请创建router-view二级路由页面或者</span><el-button size="mini" @click="form.component = 'view/routerHolder.vue'">点我设置</el-button>
</el-form-item>
<el-form-item label="展示名称" prop="meta.title" style="width:30%">
<el-input autocomplete="off" v-model="form.meta.title"></el-input>
<el-input v-model="form.meta.title" autocomplete="off" />
</el-form-item>
<el-form-item label="图标" prop="meta.icon" style="width:30%">
<icon :meta="form.meta">
@@ -110,18 +110,18 @@
</icon>
</el-form-item>
<el-form-item label="排序标记" prop="sort" style="width:30%">
<el-input autocomplete="off" v-model.number="form.sort"></el-input>
<el-input v-model.number="form.sort" autocomplete="off" />
</el-form-item>
<el-form-item label="keepAlive" prop="meta.keepAlive" style="width:30%">
<el-select placeholder="是否keepAlive缓存页面" v-model="form.meta.keepAlive">
<el-option :value="false" label="否"></el-option>
<el-option :value="true" label="是"></el-option>
<el-select v-model="form.meta.keepAlive" placeholder="是否keepAlive缓存页面">
<el-option :value="false" label="否" />
<el-option :value="true" label="是" />
</el-select>
</el-form-item>
<el-form-item label="closeTab" prop="meta.closeTab" style="width:30%">
<el-select placeholder="是否自动关闭tab" v-model="form.meta.closeTab">
<el-option :value="false" label="否"></el-option>
<el-option :value="true" label="是"></el-option>
<el-select v-model="form.meta.closeTab" placeholder="是否自动关闭tab">
<el-option :value="false" label="否" />
<el-option :value="true" label="是" />
</el-select>
</el-form-item>
</el-form>
@@ -137,22 +137,22 @@
<el-table-column prop="type" label="参数类型" width="180">
<template slot-scope="scope">
<el-select v-model="scope.row.type" placeholder="请选择">
<el-option key="query" value="query" label="query"></el-option>
<el-option key="params" value="params" label="params"></el-option>
<el-option key="query" value="query" label="query" />
<el-option key="params" value="params" label="params" />
</el-select>
</template>
</el-table-column>
<el-table-column prop="key" label="参数key" width="180">
<template slot-scope="scope">
<div>
<el-input v-model="scope.row.key"></el-input>
<el-input v-model="scope.row.key" />
</div>
</template>
</el-table-column>
<el-table-column prop="value" label="参数值">
<template slot-scope="scope">
<div>
<el-input v-model="scope.row.value"></el-input>
<el-input v-model="scope.row.value" />
</div>
</template>
</el-table-column>
@@ -170,9 +170,9 @@
</el-table-column>
</el-table>
</div>
<div class="dialog-footer" slot="footer">
<div slot="footer" class="dialog-footer">
<el-button @click="closeDialog"> </el-button>
<el-button @click="enterDialog" type="primary"> </el-button>
<el-button type="primary" @click="enterDialog"> </el-button>
</div>
</el-dialog>
</div>
@@ -187,34 +187,37 @@ import {
addBaseMenu,
deleteBaseMenu,
getBaseMenuById
} from "@/api/menu";
import infoList from "@/mixins/infoList";
import icon from "@/view/superAdmin/menu/icon";
} from '@/api/menu'
import infoList from '@/mixins/infoList'
import icon from '@/view/superAdmin/menu/icon'
export default {
name: "Menus",
name: 'Menus',
components: {
icon
},
mixins: [infoList],
data() {
return {
checkFlag: false,
listApi: getMenuList,
dialogFormVisible: false,
dialogTitle: "新增菜单",
dialogTitle: '新增菜单',
menuOption: [
{
ID: "0",
title: "根菜单"
ID: '0',
title: '根菜单'
}
],
form: {
ID: 0,
path: "",
name: "",
hidden: "",
parentId: "",
component: "",
path: '',
name: '',
hidden: '',
parentId: '',
component: '',
meta: {
title: "",
icon: "",
title: '',
icon: '',
defaultMenu: false,
closeTab: false,
keepAlive: false
@@ -222,46 +225,47 @@ export default {
parameters: []
},
rules: {
path: [{ required: true, message: "请输入菜单name", trigger: "blur" }],
path: [{ required: true, message: '请输入菜单name', trigger: 'blur' }],
component: [
{ required: true, message: "请输入文件路径", trigger: "blur" }
{ required: true, message: '请输入文件路径', trigger: 'blur' }
],
"meta.title": [
{ required: true, message: "请输入菜单展示名称", trigger: "blur" }
'meta.title': [
{ required: true, message: '请输入菜单展示名称', trigger: 'blur' }
]
},
isEdit: false,
test: ""
};
test: ''
}
},
components: {
icon
async created() {
this.pageSize = 999
await this.getTableData()
},
methods: {
addParameter(form) {
if (!form.parameters) {
this.$set(form, "parameters", []);
this.$set(form, 'parameters', [])
}
form.parameters.push({
type: "query",
key: "",
value: ""
});
type: 'query',
key: '',
value: ''
})
},
deleteParameter(parameters, index) {
parameters.splice(index, 1);
parameters.splice(index, 1)
},
changeName() {
this.form.path = this.form.name;
this.form.path = this.form.name
},
setOptions() {
this.menuOption = [
{
ID: "0",
title: "根目录"
ID: '0',
title: '根目录'
}
];
this.setMenuOptions(this.tableData, this.menuOption, false);
]
this.setMenuOptions(this.tableData, this.menuOption, false)
},
setMenuOptions(menuData, optionsData, disabled) {
menuData &&
@@ -270,143 +274,140 @@ export default {
const option = {
title: item.meta.title,
ID: String(item.ID),
disabled: disabled || item.ID == this.form.ID,
disabled: disabled || item.ID === this.form.ID,
children: []
};
}
this.setMenuOptions(
item.children,
option.children,
disabled || item.ID == this.form.ID
);
optionsData.push(option);
disabled || item.ID === this.form.ID
)
optionsData.push(option)
} else {
const option = {
title: item.meta.title,
ID: String(item.ID),
disabled: disabled || item.ID == this.form.ID
};
optionsData.push(option);
disabled: disabled || item.ID === this.form.ID
}
optionsData.push(option)
}
});
})
},
handleClose(done) {
this.initForm();
done();
this.initForm()
done()
},
// 懒加载子菜单
load(tree, treeNode, resolve) {
resolve([
{
id: 31,
date: "2016-05-01",
name: "王小虎",
address: "上海市普陀区金沙江路 1519 弄"
date: '2016-05-01',
name: '王小虎',
address: '上海市普陀区金沙江路 1519 弄'
},
{
id: 32,
date: "2016-05-01",
name: "王小虎",
address: "上海市普陀区金沙江路 1519 弄"
date: '2016-05-01',
name: '王小虎',
address: '上海市普陀区金沙江路 1519 弄'
}
]);
])
},
// 删除菜单
deleteMenu(ID) {
this.$confirm("此操作将永久删除所有角色下该菜单, 是否继续?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
this.$confirm('此操作将永久删除所有角色下该菜单, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
.then(async () => {
const res = await deleteBaseMenu({ ID });
if (res.code == 0) {
.then(async() => {
const res = await deleteBaseMenu({ ID })
if (res.code === 0) {
this.$message({
type: "success",
message: "删除成功!"
});
if (this.tableData.length == 1 && this.page > 1 ) {
this.page--;
type: 'success',
message: '删除成功!'
})
if (this.tableData.length === 1 && this.page > 1) {
this.page--
}
this.getTableData();
this.getTableData()
}
})
.catch(() => {
this.$message({
type: "info",
message: "已取消删除"
});
});
type: 'info',
message: '已取消删除'
})
})
},
// 初始化弹窗内表格方法
initForm() {
this.checkFlag = false;
this.$refs.menuForm.resetFields();
this.checkFlag = false
this.$refs.menuForm.resetFields()
this.form = {
ID: 0,
path: "",
name: "",
hidden: "",
parentId: "",
component: "",
path: '',
name: '',
hidden: '',
parentId: '',
component: '',
meta: {
title: "",
icon: "",
title: '',
icon: '',
defaultMenu: false,
keepAlive: ""
keepAlive: ''
}
};
}
},
// 关闭弹窗
closeDialog() {
this.initForm();
this.dialogFormVisible = false;
this.initForm()
this.dialogFormVisible = false
},
// 添加menu
async enterDialog() {
this.$refs.menuForm.validate(async valid => {
if (valid) {
let res;
let res
if (this.isEdit) {
res = await updateBaseMenu(this.form);
res = await updateBaseMenu(this.form)
} else {
res = await addBaseMenu(this.form);
res = await addBaseMenu(this.form)
}
if (res.code == 0) {
if (res.code === 0) {
this.$message({
type: "success",
message: this.isEdit ? "编辑成功" : "添加成功!"
});
this.getTableData();
type: 'success',
message: this.isEdit ? '编辑成功' : '添加成功!'
})
this.getTableData()
}
this.initForm();
this.dialogFormVisible = false;
this.initForm()
this.dialogFormVisible = false
}
});
})
},
// 添加菜单方法id为 0则为添加根菜单
addMenu(id) {
this.dialogTitle = "新增菜单";
this.form.parentId = String(id);
this.isEdit = false;
this.setOptions();
this.dialogFormVisible = true;
this.dialogTitle = '新增菜单'
this.form.parentId = String(id)
this.isEdit = false
this.setOptions()
this.dialogFormVisible = true
},
// 修改菜单方法
async editMenu(id) {
this.dialogTitle = "编辑菜单";
const res = await getBaseMenuById({ id });
this.form = res.data.menu;
this.isEdit = true;
this.setOptions();
this.dialogFormVisible = true;
this.dialogTitle = '编辑菜单'
const res = await getBaseMenuById({ id })
this.form = res.data.menu
this.isEdit = true
this.setOptions()
this.dialogFormVisible = true
}
},
async created() {
this.pageSize = 999;
await this.getTableData();
}
};
}
</script>
<style scoped lang="scss">
.button-box {
padding: 10px 20px;

View File

@@ -3,46 +3,46 @@
<div class="search-term">
<el-form :inline="true" :model="searchInfo" class="demo-form-inline">
<el-form-item label="请求方法">
<el-input placeholder="搜索条件" v-model="searchInfo.method"></el-input>
<el-input v-model="searchInfo.method" placeholder="搜索条件" />
</el-form-item>
<el-form-item label="请求路径">
<el-input placeholder="搜索条件" v-model="searchInfo.path"></el-input>
<el-input v-model="searchInfo.path" placeholder="搜索条件" />
</el-form-item>
<el-form-item label="结果状态码">
<el-input placeholder="搜索条件" v-model="searchInfo.status"></el-input>
<el-input v-model="searchInfo.status" placeholder="搜索条件" />
</el-form-item>
<el-form-item>
<el-button @click="onSubmit" type="primary">查询</el-button>
<el-button type="primary" @click="onSubmit">查询</el-button>
</el-form-item>
<el-form-item>
<el-popover placement="top" v-model="deleteVisible" width="160">
<el-popover v-model="deleteVisible" placement="top" width="160">
<p>确定要删除吗</p>
<div style="text-align: right; margin: 0">
<el-button @click="deleteVisible = false" size="mini" type="text">取消</el-button>
<el-button @click="onDelete" size="mini" type="primary">确定</el-button>
<el-button size="mini" type="text" @click="deleteVisible = false">取消</el-button>
<el-button size="mini" type="primary" @click="onDelete">确定</el-button>
</div>
<el-button icon="el-icon-delete" size="mini" slot="reference" type="danger">批量删除</el-button>
<el-button slot="reference" icon="el-icon-delete" size="mini" type="danger">批量删除</el-button>
</el-popover>
</el-form-item>
</el-form>
</div>
<el-table
:data="tableData"
@selection-change="handleSelectionChange"
border
ref="multipleTable"
:data="tableData"
border
stripe
style="width: 100%"
tooltip-effect="dark"
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" width="55"></el-table-column>
<el-table-column type="selection" width="55" />
<el-table-column label="操作人" width="140">
<template slot-scope="scope">
<div>{{scope.row.user.userName}}({{scope.row.user.nickName}})</div>
<div>{{ scope.row.user.userName }}({{ scope.row.user.nickName }})</div>
</template>
</el-table-column>
<el-table-column label="日期" width="180">
<template slot-scope="scope">{{scope.row.CreatedAt|formatDate}}</template>
<template slot-scope="scope">{{ scope.row.CreatedAt|formatDate }}</template>
</el-table-column>
<el-table-column label="状态码" prop="status" width="120">
<template slot-scope="scope">
@@ -51,17 +51,17 @@
</div>
</template>
</el-table-column>
<el-table-column label="请求ip" prop="ip" width="120"></el-table-column>
<el-table-column label="请求方法" prop="method" width="120"></el-table-column>
<el-table-column label="请求路径" prop="path" width="240"></el-table-column>
<el-table-column label="请求ip" prop="ip" width="120" />
<el-table-column label="请求方法" prop="method" width="120" />
<el-table-column label="请求路径" prop="path" width="240" />
<el-table-column label="请求" prop="path" width="80">
<template slot-scope="scope">
<div>
<el-popover placement="top-start" trigger="hover" v-if="scope.row.body">
<el-popover v-if="scope.row.body" placement="top-start" trigger="hover">
<div class="popover-box">
<pre>{{fmtBody(scope.row.body)}}</pre>
<pre>{{ fmtBody(scope.row.body) }}</pre>
</div>
<i class="el-icon-view" slot="reference"></i>
<i slot="reference" class="el-icon-view" />
</el-popover>
<span v-else></span>
@@ -71,11 +71,11 @@
<el-table-column label="响应" prop="path" width="80">
<template slot-scope="scope">
<div>
<el-popover placement="top-start" trigger="hover" v-if="scope.row.resp">
<el-popover v-if="scope.row.resp" placement="top-start" trigger="hover">
<div class="popover-box">
<pre>{{fmtBody(scope.row.resp)}}</pre>
<pre>{{ fmtBody(scope.row.resp) }}</pre>
</div>
<i class="el-icon-view" slot="reference"></i>
<i slot="reference" class="el-icon-view" />
</el-popover>
<span v-else></span>
</div>
@@ -83,13 +83,13 @@
</el-table-column>
<el-table-column label="按钮组">
<template slot-scope="scope">
<el-popover placement="top" v-model="scope.row.visible" width="160">
<el-popover v-model="scope.row.visible" placement="top" width="160">
<p>确定要删除吗</p>
<div style="text-align: right; margin: 0">
<el-button @click="scope.row.visible = false" size="mini" type="text">取消</el-button>
<el-button @click="deleteSysOperationRecord(scope.row)" size="mini" type="primary">确定</el-button>
<el-button size="mini" type="text" @click="scope.row.visible = false">取消</el-button>
<el-button size="mini" type="primary" @click="deleteSysOperationRecord(scope.row)">确定</el-button>
</div>
<el-button icon="el-icon-delete" size="mini" slot="reference" type="danger">删除</el-button>
<el-button slot="reference" icon="el-icon-delete" size="mini" type="danger">删除</el-button>
</el-popover>
</template>
</el-table-column>
@@ -100,10 +100,10 @@
:page-sizes="[10, 30, 50, 100]"
:style="{float:'right',padding:'20px'}"
:total="total"
layout="total, sizes, prev, pager, next, jumper"
@current-change="handleCurrentChange"
@size-change="handleSizeChange"
layout="total, sizes, prev, pager, next, jumper"
></el-pagination>
/>
</div>
</template>
@@ -112,18 +112,35 @@ import {
deleteSysOperationRecord,
getSysOperationRecordList,
deleteSysOperationRecordByIds
} from "@/api/sysOperationRecord"; // 此处请自行替换地址
import { formatTimeToStr } from "@/utils/date";
import infoList from "@/mixins/infoList";
} from '@/api/sysOperationRecord' // 此处请自行替换地址
import { formatTimeToStr } from '@/utils/date'
import infoList from '@/mixins/infoList'
export default {
name: "SysOperationRecord",
name: 'SysOperationRecord',
filters: {
formatDate: function(time) {
if (time !== null && time !== '') {
var date = new Date(time)
return formatTimeToStr(date, 'yyyy-MM-dd hh:mm:ss')
} else {
return ''
}
},
formatBoolean: function(bool) {
if (bool !== null) {
return bool ? '是' : '否'
} else {
return ''
}
}
},
mixins: [infoList],
data() {
return {
listApi: getSysOperationRecordList,
dialogFormVisible: false,
type: "",
type: '',
deleteVisible: false,
multipleSelection: [],
formData: {
@@ -136,80 +153,63 @@ export default {
error_message: null,
user_id: null
}
};
},
filters: {
formatDate: function(time) {
if (time != null && time != "") {
var date = new Date(time);
return formatTimeToStr(date, "yyyy-MM-dd hh:mm:ss");
} else {
return "";
}
},
formatBoolean: function(bool) {
if (bool != null) {
return bool ? "是" : "否";
} else {
return "";
}
}
},
created() {
this.getTableData()
},
methods: {
//条件搜索前端看此方法
// 条件搜索前端看此方法
onSubmit() {
this.page = 1;
this.pageSize = 10;
this.getTableData();
this.page = 1
this.pageSize = 10
this.getTableData()
},
handleSelectionChange(val) {
this.multipleSelection = val;
this.multipleSelection = val
},
async onDelete() {
const ids = [];
const ids = []
this.multipleSelection &&
this.multipleSelection.map(item => {
ids.push(item.ID);
});
const res = await deleteSysOperationRecordByIds({ ids });
if (res.code == 0) {
ids.push(item.ID)
})
const res = await deleteSysOperationRecordByIds({ ids })
if (res.code === 0) {
this.$message({
type: "success",
message: "删除成功"
});
if (this.tableData.length == ids.length && this.page > 1) {
this.page--;
type: 'success',
message: '删除成功'
})
if (this.tableData.length === ids.length && this.page > 1) {
this.page--
}
this.deleteVisible = false;
this.getTableData();
this.deleteVisible = false
this.getTableData()
}
},
async deleteSysOperationRecord(row) {
row.visible = false;
const res = await deleteSysOperationRecord({ ID: row.ID });
if (res.code == 0) {
row.visible = false
const res = await deleteSysOperationRecord({ ID: row.ID })
if (res.code === 0) {
this.$message({
type: "success",
message: "删除成功"
});
if (this.tableData.length == 1 && this.page > 1 ) {
this.page--;
type: 'success',
message: '删除成功'
})
if (this.tableData.length === 1 && this.page > 1) {
this.page--
}
this.getTableData();
this.getTableData()
}
},
fmtBody(value) {
try {
return JSON.parse(value);
return JSON.parse(value)
} catch (err) {
return value;
return value
}
}
},
created() {
this.getTableData();
}
};
}
</script>
<style lang="scss">
@@ -236,4 +236,4 @@ export default {
.popover-box::-webkit-scrollbar {
display: none; /* Chrome Safari */
}
</style>
</style>

View File

@@ -1,40 +1,40 @@
<template>
<div>
<div class="button-box clearflex">
<el-button @click="addUser" type="primary">新增用户</el-button>
<el-button type="primary" @click="addUser">新增用户</el-button>
</div>
<el-table :data="tableData" border stripe>
<el-table-column label="头像" min-width="50">
<template slot-scope="scope">
<div :style="{'textAlign':'center'}">
<CustomPic :picSrc="scope.row.headerImg" />
<CustomPic :pic-src="scope.row.headerImg" />
</div>
</template>
</el-table-column>
<el-table-column label="uuid" min-width="250" prop="uuid"></el-table-column>
<el-table-column label="用户名" min-width="150" prop="userName"></el-table-column>
<el-table-column label="昵称" min-width="150" prop="nickName"></el-table-column>
<el-table-column label="uuid" min-width="250" prop="uuid" />
<el-table-column label="用户名" min-width="150" prop="userName" />
<el-table-column label="昵称" min-width="150" prop="nickName" />
<el-table-column label="用户角色" min-width="150">
<template slot-scope="scope">
<el-cascader
@change="changeAuthority(scope.row)"
v-model="scope.row.authority.authorityId"
:options="authOptions"
:show-all-levels="false"
:props="{ checkStrictly: true,label:'authorityName',value:'authorityId',disabled:'disabled',emitPath:false}"
filterable
></el-cascader>
@change="changeAuthority(scope.row)"
/>
</template>
</el-table-column>
<el-table-column label="操作" min-width="150">
<template slot-scope="scope">
<el-popover placement="top" width="160" v-model="scope.row.visible">
<el-popover v-model="scope.row.visible" placement="top" width="160">
<p>确定要删除此用户吗</p>
<div style="text-align: right; margin: 0">
<el-button size="mini" type="text" @click="scope.row.visible = false">取消</el-button>
<el-button type="primary" size="mini" @click="deleteUser(scope.row)">确定</el-button>
</div>
<el-button type="danger" icon="el-icon-delete" size="small" slot="reference">删除</el-button>
<el-button slot="reference" type="danger" icon="el-icon-delete" size="small">删除</el-button>
</el-popover>
</template>
</el-table-column>
@@ -45,25 +45,25 @@
:page-sizes="[10, 30, 50, 100]"
:style="{float:'right',padding:'20px'}"
:total="total"
layout="total, sizes, prev, pager, next, jumper"
@current-change="handleCurrentChange"
@size-change="handleSizeChange"
layout="total, sizes, prev, pager, next, jumper"
></el-pagination>
/>
<el-dialog :visible.sync="addUserDialog" custom-class="user-dialog" title="新增用户">
<el-form :rules="rules" ref="userForm" :model="userInfo">
<el-form ref="userForm" :rules="rules" :model="userInfo">
<el-form-item label="用户名" label-width="80px" prop="username">
<el-input v-model="userInfo.username"></el-input>
<el-input v-model="userInfo.username" />
</el-form-item>
<el-form-item label="密码" label-width="80px" prop="password">
<el-input v-model="userInfo.password"></el-input>
<el-input v-model="userInfo.password" />
</el-form-item>
<el-form-item label="别名" label-width="80px" prop="nickName">
<el-input v-model="userInfo.nickName"></el-input>
<el-input v-model="userInfo.nickName" />
</el-form-item>
<el-form-item label="头像" label-width="80px">
<div style="display:inline-block" @click="openHeaderChange">
<img class="header-img-box" v-if="userInfo.headerImg" :src="userInfo.headerImg" />
<img v-if="userInfo.headerImg" class="header-img-box" :src="userInfo.headerImg">
<div v-else class="header-img-box">从媒体库选择</div>
</div>
</el-form-item>
@@ -74,37 +74,36 @@
:show-all-levels="false"
:props="{ checkStrictly: true,label:'authorityName',value:'authorityId',disabled:'disabled',emitPath:false}"
filterable
></el-cascader>
/>
</el-form-item>
</el-form>
<div class="dialog-footer" slot="footer">
<div slot="footer" class="dialog-footer">
<el-button @click="closeAddUserDialog"> </el-button>
<el-button @click="enterAddUserDialog" type="primary"> </el-button>
<el-button type="primary" @click="enterAddUserDialog"> </el-button>
</div>
</el-dialog>
<ChooseImg ref="chooseImg" :target="userInfo" :targetKey="`headerImg`"/>
<ChooseImg ref="chooseImg" :target="userInfo" :target-key="`headerImg`" />
</div>
</template>
<script>
// 获取列表内容封装在mixins内部 getTableData方法 初始化已封装完成
const path = process.env.VUE_APP_BASE_API;
const path = process.env.VUE_APP_BASE_API
import {
getUserList,
setUserAuthority,
register,
deleteUser
} from "@/api/user";
import { getAuthorityList } from "@/api/authority";
import infoList from "@/mixins/infoList";
import { mapGetters } from "vuex";
import CustomPic from "@/components/customPic";
import ChooseImg from "@/components/chooseImg";
} from '@/api/user'
import { getAuthorityList } from '@/api/authority'
import infoList from '@/mixins/infoList'
import { mapGetters } from 'vuex'
import CustomPic from '@/components/customPic'
import ChooseImg from '@/components/chooseImg'
export default {
name: "Api",
name: 'Api',
components: { CustomPic, ChooseImg },
mixins: [infoList],
components: { CustomPic,ChooseImg },
data() {
return {
listApi: getUserList,
@@ -112,40 +111,45 @@ export default {
authOptions: [],
addUserDialog: false,
userInfo: {
username: "",
password: "",
nickName: "",
headerImg: "",
authorityId: ""
username: '',
password: '',
nickName: '',
headerImg: '',
authorityId: ''
},
rules: {
username: [
{ required: true, message: "请输入用户名", trigger: "blur" },
{ min: 5, message: "最低5位字符", trigger: "blur" }
{ required: true, message: '请输入用户名', trigger: 'blur' },
{ min: 5, message: '最低5位字符', trigger: 'blur' }
],
password: [
{ required: true, message: "请输入用户密码", trigger: "blur" },
{ min: 6, message: "最低6位字符", trigger: "blur" }
{ required: true, message: '请输入用户密码', trigger: 'blur' },
{ min: 6, message: '最低6位字符', trigger: 'blur' }
],
nickName: [
{ required: true, message: "请输入用户昵称", trigger: "blur" }
{ required: true, message: '请输入用户昵称', trigger: 'blur' }
],
authorityId: [
{ required: true, message: "请选择用户角色", trigger: "blur" }
{ required: true, message: '请选择用户角色', trigger: 'blur' }
]
}
};
}
},
computed: {
...mapGetters("user", ["token"])
...mapGetters('user', ['token'])
},
async created() {
this.getTableData()
const res = await getAuthorityList({ page: 1, pageSize: 999 })
this.setOptions(res.data.list)
},
methods: {
openHeaderChange(){
openHeaderChange() {
this.$refs.chooseImg.open()
},
setOptions(authData) {
this.authOptions = [];
this.setAuthorityOptions(authData, this.authOptions);
this.authOptions = []
this.setAuthorityOptions(authData, this.authOptions)
},
setAuthorityOptions(AuthorityData, optionsData) {
AuthorityData &&
@@ -155,66 +159,61 @@ export default {
authorityId: item.authorityId,
authorityName: item.authorityName,
children: []
};
this.setAuthorityOptions(item.children, option.children);
optionsData.push(option);
}
this.setAuthorityOptions(item.children, option.children)
optionsData.push(option)
} else {
const option = {
authorityId: item.authorityId,
authorityName: item.authorityName
};
optionsData.push(option);
}
optionsData.push(option)
}
});
})
},
async deleteUser(row) {
const res = await deleteUser({ id: row.ID });
if (res.code == 0) {
this.getTableData();
row.visible = false;
const res = await deleteUser({ id: row.ID })
if (res.code === 0) {
this.getTableData()
row.visible = false
}
},
async enterAddUserDialog() {
this.$refs.userForm.validate(async valid => {
if (valid) {
const res = await register(this.userInfo);
if (res.code == 0) {
this.$message({ type: "success", message: "创建成功" });
const res = await register(this.userInfo)
if (res.code === 0) {
this.$message({ type: 'success', message: '创建成功' })
}
await this.getTableData();
this.closeAddUserDialog();
await this.getTableData()
this.closeAddUserDialog()
}
});
})
},
closeAddUserDialog() {
this.$refs.userForm.resetFields();
this.addUserDialog = false;
this.$refs.userForm.resetFields()
this.addUserDialog = false
},
handleAvatarSuccess(res) {
this.userInfo.headerImg = res.data.file.url;
this.userInfo.headerImg = res.data.file.url
},
addUser() {
this.addUserDialog = true;
this.addUserDialog = true
},
async changeAuthority(row) {
const res = await setUserAuthority({
uuid: row.uuid,
authorityId: row.authority.authorityId
});
if (res.code == 0) {
this.$message({ type: "success", message: "角色设置成功" });
})
if (res.code === 0) {
this.$message({ type: 'success', message: '角色设置成功' })
}
}
},
async created() {
this.getTableData();
const res = await getAuthorityList({ page: 1, pageSize: 999 });
this.setOptions(res.data.list);
}
};
}
</script>
<style lang="scss">
<style lang="scss">
.button-box {
padding: 10px 20px;
.el-button {
@@ -251,4 +250,4 @@ export default {
display: block;
}
}
</style>
</style>

View File

@@ -7,23 +7,23 @@
<div>
<el-row :gutter="10">
<el-col :span="12">os:</el-col>
<el-col :span="12" v-text="state.os.goos"></el-col>
<el-col :span="12" v-text="state.os.goos" />
</el-row>
<el-row :gutter="10">
<el-col :span="12">cpu nums:</el-col>
<el-col :span="12" v-text="state.os.numCpu"></el-col>
<el-col :span="12" v-text="state.os.numCpu" />
</el-row>
<el-row :gutter="10">
<el-col :span="12">compiler:</el-col>
<el-col :span="12" v-text="state.os.compiler"></el-col>
<el-col :span="12" v-text="state.os.compiler" />
</el-row>
<el-row :gutter="10">
<el-col :span="12">go version:</el-col>
<el-col :span="12" v-text="state.os.goVersion"></el-col>
<el-col :span="12" v-text="state.os.goVersion" />
</el-row>
<el-row :gutter="10">
<el-col :span="12">goroutine nums:</el-col>
<el-col :span="12" v-text="state.os.numGoroutine"></el-col>
<el-col :span="12" v-text="state.os.numGoroutine" />
</el-row>
</div>
</el-card>
@@ -36,19 +36,19 @@
<el-col :span="12">
<el-row :gutter="10">
<el-col :span="12">total (MB)</el-col>
<el-col :span="12" v-text="state.disk.totalMb"></el-col>
<el-col :span="12" v-text="state.disk.totalMb" />
</el-row>
<el-row :gutter="10">
<el-col :span="12">used (MB)</el-col>
<el-col :span="12" v-text="state.disk.usedMb"></el-col>
<el-col :span="12" v-text="state.disk.usedMb" />
</el-row>
<el-row :gutter="10">
<el-col :span="12">total (GB)</el-col>
<el-col :span="12" v-text="state.disk.totalGb"></el-col>
<el-col :span="12" v-text="state.disk.totalGb" />
</el-row>
<el-row :gutter="10">
<el-col :span="12">used (GB)</el-col>
<el-col :span="12" v-text="state.disk.usedGb"></el-col>
<el-col :span="12" v-text="state.disk.usedGb" />
</el-row>
</el-col>
<el-col :span="12">
@@ -56,7 +56,7 @@
type="dashboard"
:percentage="state.disk.usedPercent"
:color="colors"
></el-progress>
/>
</el-col>
</el-row>
</div>
@@ -66,55 +66,55 @@
<el-row :gutter="15" class="system_state">
<el-col :span="12">
<el-card
class="card_item"
v-if="state.cpu"
class="card_item"
:body-style="{ height: '180px', 'overflow-y': 'scroll' }"
>
<div slot="header">CPU</div>
<div>
<el-row :gutter="10">
<el-col :span="12">physical number of cores:</el-col>
<el-col :span="12" v-text="state.cpu.cores"> </el-col>
<el-col :span="12" v-text="state.cpu.cores" />
</el-row>
<template v-for="(item, index) in state.cpu.cpus">
<el-row :key="index" :gutter="10">
<el-col :span="12">core {{ index }}:</el-col>
<el-col :span="12"
><el-progress
type="line"
:percentage="+item.toFixed(0)"
:color="colors"
></el-progress
></el-col>
<el-col
:span="12"
><el-progress
type="line"
:percentage="+item.toFixed(0)"
:color="colors"
/></el-col>
</el-row>
</template>
</div>
</el-card>
</el-col>
<el-col :span="12">
<el-card class="card_item" v-if="state.ram">
<el-card v-if="state.ram" class="card_item">
<div slot="header">Ram</div>
<div>
<el-row :gutter="10">
<el-col :span="12">
<el-row :gutter="10">
<el-col :span="12">total (MB)</el-col>
<el-col :span="12" v-text="state.ram.totalMb"></el-col>
<el-col :span="12" v-text="state.ram.totalMb" />
</el-row>
<el-row :gutter="10">
<el-col :span="12">used (MB)</el-col>
<el-col :span="12" v-text="state.ram.usedMb"></el-col>
<el-col :span="12" v-text="state.ram.usedMb" />
</el-row>
<el-row :gutter="10">
<el-col :span="12">total (GB)</el-col>
<el-col :span="12" v-text="state.ram.totalMb / 1024"></el-col>
<el-col :span="12" v-text="state.ram.totalMb / 1024" />
</el-row>
<el-row :gutter="10">
<el-col :span="12">used (GB)</el-col>
<el-col
:span="12"
v-text="(state.ram.usedMb / 1024).toFixed(2)"
></el-col>
/>
</el-row>
</el-col>
<el-col :span="12">
@@ -122,7 +122,7 @@
type="dashboard"
:percentage="state.ram.usedPercent"
:color="colors"
></el-progress>
/>
</el-col>
</el-row>
</div>
@@ -133,37 +133,37 @@
</template>
<script>
import { getSystemState } from "@/api/system.js";
import { getSystemState } from '@/api/system'
export default {
name: "State",
name: 'State',
data() {
return {
timer:null,
timer: null,
state: {},
colors: [
{ color: "#5cb87a", percentage: 20 },
{ color: "#e6a23c", percentage: 40 },
{ color: "#f56c6c", percentage: 80 },
],
};
{ color: '#5cb87a', percentage: 20 },
{ color: '#e6a23c', percentage: 40 },
{ color: '#f56c6c', percentage: 80 }
]
}
},
created() {
this.reload();
created() {
this.reload()
this.timer = setInterval(() => {
this.reload();
}, 1000*10);
this.reload()
}, 1000 * 10)
},
beforeDestroy(){
beforeDestroy() {
clearInterval(this.timer)
this.timer = null
},
methods: {
async reload() {
const { data } = await getSystemState();
this.state = data.server;
},
},
};
const { data } = await getSystemState()
this.state = data.server
}
}
}
</script>
<style>

View File

@@ -2,15 +2,15 @@
<div>
<span style="color:red">搜索时如果条件为LIKE只支持字符串</span>
<el-form
:model="dialogMiddle"
ref="fieldDialogFrom"
:model="dialogMiddle"
label-width="120px"
label-position="left"
:rules="rules"
>
<el-form-item label="Field名称" prop="fieldName">
<el-col :span="6">
<el-input v-model="dialogMiddle.fieldName" autocomplete="off"></el-input>
<el-input v-model="dialogMiddle.fieldName" autocomplete="off" />
</el-col>
<el-col :offset="1" :span="2">
<el-button @click="autoFill">自动填充</el-button>
@@ -18,22 +18,22 @@
</el-form-item>
<el-form-item label="Field中文名" prop="fieldDesc">
<el-col :span="6">
<el-input v-model="dialogMiddle.fieldDesc" autocomplete="off"></el-input>
<el-input v-model="dialogMiddle.fieldDesc" autocomplete="off" />
</el-col>
</el-form-item>
<el-form-item label="FieldJSON" prop="fieldJson">
<el-col :span="6">
<el-input v-model="dialogMiddle.fieldJson" autocomplete="off"></el-input>
<el-input v-model="dialogMiddle.fieldJson" autocomplete="off" />
</el-col>
</el-form-item>
<el-form-item label="数据库字段名" prop="columnName">
<el-col :span="6">
<el-input v-model="dialogMiddle.columnName" autocomplete="off"></el-input>
<el-input v-model="dialogMiddle.columnName" autocomplete="off" />
</el-col>
</el-form-item>
<el-form-item label="数据库字段描述" prop="comment">
<el-col :span="6">
<el-input v-model="dialogMiddle.comment" autocomplete="off"></el-input>
<el-input v-model="dialogMiddle.comment" autocomplete="off" />
</el-col>
</el-form-item>
<el-form-item label="Field数据类型" prop="fieldType">
@@ -41,15 +41,15 @@
<el-select
v-model="dialogMiddle.fieldType"
placeholder="请选择field数据类型"
@change="getDbfdOptions"
clearable
@change="getDbfdOptions"
>
<el-option
v-for="item in typeOptions"
:key="item.value"
:label="item.label"
:value="item.value"
></el-option>
/>
</el-select>
</el-col>
</el-form-item>
@@ -57,8 +57,8 @@
<el-form-item label="数据库字段类型" prop="dataType">
<el-col :span="8">
<el-select
:disabled="!dialogMiddle.fieldType"
v-model="dialogMiddle.dataType"
:disabled="!dialogMiddle.fieldType"
placeholder="请选择数据库字段类型"
clearable
>
@@ -67,13 +67,13 @@
:key="item.label"
:label="item.label"
:value="item.label"
></el-option>
/>
</el-select>
</el-col>
</el-form-item>
<el-form-item label="数据库字段长度" prop="dataTypeLong">
<el-col :span="8">
<el-input placeholder="自定义类型必须指定长度" :disabled="!dialogMiddle.dataType" v-model="dialogMiddle.dataTypeLong"></el-input>
<el-input v-model="dialogMiddle.dataTypeLong" placeholder="自定义类型必须指定长度" :disabled="!dialogMiddle.dataType" />
</el-col>
</el-form-item>
<el-form-item label="Field查询条件" prop="fieldSearchType">
@@ -84,37 +84,39 @@
:key="item.value"
:label="item.label"
:value="item.value"
></el-option>
/>
</el-select>
</el-col>
</el-form-item>
<el-form-item label="关联字典" prop="dictType">
<el-col :span="8">
<el-select :disabled="dialogMiddle.fieldType!='int'" v-model="dialogMiddle.dictType" placeholder="请选择字典" clearable>
<el-select v-model="dialogMiddle.dictType" :disabled="dialogMiddle.fieldType!=='int'" placeholder="请选择字典" clearable>
<el-option
v-for="item in dictOptions"
:key="item.type"
:label="`${item.type}(${item.name})`"
:value="item.type"
></el-option>
/>
</el-select>
</el-col>
</el-form-item>
</el-form>
</div>
</template>
<script>
import { getDict } from "@/utils/dictionary";
import { toSQLLine , toLowerCase } from "@/utils/stringFun.js";
import { getSysDictionaryList } from "@/api/sysDictionary";
import { getDict } from '@/utils/dictionary'
import { toLowerCase, toSQLLine } from '@/utils/stringFun'
import { getSysDictionaryList } from '@/api/sysDictionary'
export default {
name: "FieldDialog",
name: 'FieldDialog',
props: {
dialogMiddle: {
type: Object,
default: function() {
return {};
return {}
}
}
},
@@ -124,92 +126,89 @@ export default {
dictOptions: [],
typeSearchOptions: [
{
label: "=",
value: "="
label: '=',
value: '='
},
{
label: "<>",
value: "<>"
label: '<>',
value: '<>'
},
{
label: ">",
value: ">"
label: '>',
value: '>'
},
{
label: "<",
value: "<"
label: '<',
value: '<'
},
{
label: "LIKE",
value: "LIKE"
label: 'LIKE',
value: 'LIKE'
}
],
typeOptions: [
{
label: "字符串",
value: "string"
label: '字符串',
value: 'string'
},
{
label: "整型",
value: "int"
label: '整型',
value: 'int'
},
{
label: "布尔值",
value: "bool"
label: '布尔值',
value: 'bool'
},
{
label: "浮点型",
value: "float64"
label: '浮点型',
value: 'float64'
},
{
label: "时间",
value: "time.Time"
label: '时间',
value: 'time.Time'
}
],
rules: {
fieldName: [
{ required: true, message: "请输入field英文名", trigger: "blur" }
{ required: true, message: '请输入field英文名', trigger: 'blur' }
],
fieldDesc: [
{ required: true, message: "请输入field中文名", trigger: "blur" }
{ required: true, message: '请输入field中文名', trigger: 'blur' }
],
fieldJson: [
{ required: true, message: "请输入field格式化json", trigger: "blur" }
{ required: true, message: '请输入field格式化json', trigger: 'blur' }
],
columnName: [
{ required: true, message: "请输入数据库字段", trigger: "blur" }
{ required: true, message: '请输入数据库字段', trigger: 'blur' }
],
fieldType: [
{ required: true, message: "请选择field数据类型", trigger: "blur" }
{ required: true, message: '请选择field数据类型', trigger: 'blur' }
]
}
};
},
methods: {
autoFill(){
this.dialogMiddle.fieldJson = toLowerCase(this.dialogMiddle.fieldName)
this.dialogMiddle.columnName = toSQLLine(this.dialogMiddle.fieldJson)
},
async getDbfdOptions() {
this.dialogMiddle.dataType = ""
this.dialogMiddle.dataTypeLong = ""
this.dialogMiddle.fieldSearchType = ""
this.dialogMiddle.dictType = ""
if (this.dialogMiddle.fieldType) {
const res = await getDict(this.dialogMiddle.fieldType);
this.dbfdOptions = res;
}
}
},
async created() {
const dictRes = await getSysDictionaryList({
page: 1,
pageSize: 999999
});
})
this.dictOptions = dictRes.data.list
},
};
methods: {
autoFill() {
this.dialogMiddle.fieldJson = toLowerCase(this.dialogMiddle.fieldName)
this.dialogMiddle.columnName = toSQLLine(this.dialogMiddle.fieldJson)
},
async getDbfdOptions() {
this.dialogMiddle.dataType = ''
this.dialogMiddle.dataTypeLong = ''
this.dialogMiddle.fieldSearchType = ''
this.dialogMiddle.dictType = ''
if (this.dialogMiddle.fieldType) {
this.dbfdOptions = await getDict(this.dialogMiddle.fieldType)
}
}
}
}
</script>
<style lang="scss">
</style>

View File

@@ -1,58 +1,54 @@
<template>
<div class="previewCode">
<el-tabs v-model="activeName">
<el-tab-pane :label="key" :name="key" v-for="(item,key) in previewCode" :key="key">
<div style="background:#fff;padding:0 20px" :id="key"></div>
</el-tab-pane>
</el-tabs>
</div>
<div class="previewCode">
<el-tabs v-model="activeName">
<el-tab-pane v-for="(item,key) in previewCode" :key="key" :label="key" :name="key">
<div :id="key" style="background:#fff;padding:0 20px" />
</el-tab-pane>
</el-tabs>
</div>
</template>
<script>
import marked from "marked"
import hljs from "highlight.js";
import marked from 'marked'
import hljs from 'highlight.js'
// import 'highlight.js/styles/atelier-cave-light.css';
import 'highlight.js/styles/atelier-plateau-light.css';
import 'highlight.js/styles/atelier-plateau-light.css'
export default {
props:{
previewCode:{
type:Object,
default(){
return {}
}
}
},
data(){
return{
activeName: "",
}
},
mounted(){
marked.setOptions({
renderer: new marked.Renderer(),
highlight: function(code) {
return hljs.highlightAuto(code).value;
},
pedantic: false,
gfm: true,
tables: true,
breaks: false,
sanitize: false,
smartLists: true,
smartypants: false,
xhtml: false
}
);
for(const key in this.previewCode){
if(this.activeName == ""){
this.activeName = key
}
document.getElementById(key).innerHTML = marked(this.previewCode[key])
}
props: {
previewCode: {
type: Object,
default() {
return {}
}
}
},
data() {
return {
activeName: ''
}
},
mounted() {
marked.setOptions({
renderer: new marked.Renderer(),
highlight: function(code) {
return hljs.highlightAuto(code).value
},
pedantic: false,
gfm: true,
tables: true,
breaks: false,
sanitize: false,
smartLists: true,
smartypants: false,
xhtml: false
}
)
for (const key in this.previewCode) {
if (this.activeName === '') {
this.activeName = key
}
document.getElementById(key).innerHTML = marked(this.previewCode[key])
}
}
}
</script>
<style lang="scss">
</style>

View File

@@ -6,18 +6,18 @@
<template slot="title">
<div :style="{fontSize:'16px',paddingLeft:'20px'}">
点这里从现有数据库创建代码
<i class="header-icon el-icon-thumb"></i>
<i class="header-icon el-icon-thumb" />
</div>
</template>
<el-form ref="getTableForm" :inline="true" :model="dbform" label-width="120px">
<el-form-item label="数据库名" prop="structName">
<el-select @change="getTable" v-model="dbform.dbName" filterable placeholder="请选择数据库">
<el-select v-model="dbform.dbName" filterable placeholder="请选择数据库" @change="getTable">
<el-option
v-for="item in dbOptions"
:key="item.database"
:label="item.database"
:value="item.database"
></el-option>
/>
</el-select>
</el-form-item>
<el-form-item label="表名" prop="structName">
@@ -32,57 +32,57 @@
:key="item.tableName"
:label="item.tableName"
:value="item.tableName"
></el-option>
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button @click="getColumn" type="primary">使用此表创建</el-button>
<el-button type="primary" @click="getColumn">使用此表创建</el-button>
</el-form-item>
</el-form>
</el-collapse-item>
</el-collapse>
<el-divider></el-divider>
<el-divider />
<!-- 初始版本自动化代码工具 -->
<el-form ref="autoCodeForm" :rules="rules" :model="form" label-width="120px" :inline="true">
<el-form-item label="Struct名称" prop="structName">
<el-input v-model="form.structName" placeholder="首字母自动转换大写"></el-input>
<el-input v-model="form.structName" placeholder="首字母自动转换大写" />
</el-form-item>
<el-form-item label="tableName" prop="tableName">
<el-input v-model="form.tableName" placeholder="指定表名(非必填)"></el-input>
<el-input v-model="form.tableName" placeholder="指定表名(非必填)" />
</el-form-item>
<el-form-item label="Struct简称" prop="abbreviation">
<el-input v-model="form.abbreviation" placeholder="简称会作为入参对象名和路由group"></el-input>
<el-input v-model="form.abbreviation" placeholder="简称会作为入参对象名和路由group" />
</el-form-item>
<el-form-item label="Struct中文名称" prop="description">
<el-input v-model="form.description" placeholder="中文描述作为自动api描述"></el-input>
<el-input v-model="form.description" placeholder="中文描述作为自动api描述" />
</el-form-item>
<el-form-item label="文件名称" prop="packageName">
<el-input v-model="form.packageName" placeholder="生成文件的默认名称"></el-input>
<el-input v-model="form.packageName" placeholder="生成文件的默认名称" />
</el-form-item>
<el-form-item label="自动创建api">
<el-checkbox v-model="form.autoCreateApiToSql"></el-checkbox>
<el-checkbox v-model="form.autoCreateApiToSql" />
</el-form-item>
<el-form-item label="自动移动文件">
<el-checkbox v-model="form.autoMoveFile"></el-checkbox>
<el-checkbox v-model="form.autoMoveFile" />
</el-form-item>
</el-form>
<!-- 组件列表 -->
<div class="button-box clearflex">
<el-button @click="editAndAddField()" type="primary">新增Field</el-button>
<el-button type="primary" @click="editAndAddField()">新增Field</el-button>
</div>
<el-table :data="form.fields" border stripe>
<el-table-column type="index" label="序列" width="100"></el-table-column>
<el-table-column prop="fieldName" label="Field名"></el-table-column>
<el-table-column prop="fieldDesc" label="中文名"></el-table-column>
<el-table-column prop="fieldJson" label="FieldJson"></el-table-column>
<el-table-column prop="fieldType" label="Field数据类型" width="130"></el-table-column>
<el-table-column prop="dataType" label="数据库字段类型" width="130"></el-table-column>
<el-table-column prop="dataTypeLong" label="数据库字段长度" width="130"></el-table-column>
<el-table-column prop="columnName" label="数据库字段" width="130"></el-table-column>
<el-table-column prop="comment" label="数据库字段描述" width="130"></el-table-column>
<el-table-column prop="fieldSearchType" label="搜索条件" width="130"></el-table-column>
<el-table-column prop="dictType" label="字典" width="130"></el-table-column>
<el-table-column type="index" label="序列" width="100" />
<el-table-column prop="fieldName" label="Field名" />
<el-table-column prop="fieldDesc" label="中文名" />
<el-table-column prop="fieldJson" label="FieldJson" />
<el-table-column prop="fieldType" label="Field数据类型" width="130" />
<el-table-column prop="dataType" label="数据库字段类型" width="130" />
<el-table-column prop="dataTypeLong" label="数据库字段长度" width="130" />
<el-table-column prop="columnName" label="数据库字段" width="130" />
<el-table-column prop="comment" label="数据库字段描述" width="130" />
<el-table-column prop="fieldSearchType" label="搜索条件" width="130" />
<el-table-column prop="dictType" label="字典" width="130" />
<el-table-column label="操作" width="300">
<template slot-scope="scope">
<el-button
@@ -94,22 +94,22 @@
<el-button
size="mini"
type="text"
:disabled="scope.$index == 0"
:disabled="scope.$index === 0"
@click="moveUpField(scope.$index)"
>上移</el-button>
<el-button
size="mini"
type="text"
:disabled="(scope.$index + 1) == form.fields.length"
:disabled="(scope.$index + 1) === form.fields.length"
@click="moveDownField(scope.$index)"
>下移</el-button>
<el-popover placement="top" v-model="scope.row.visible">
<el-popover v-model="scope.row.visible" placement="top">
<p>确定删除吗</p>
<div style="text-align: right; margin: 0">
<el-button size="mini" type="text" @click="scope.row.visible = false">取消</el-button>
<el-button type="primary" size="mini" @click="deleteField(scope.$index)">确定</el-button>
</div>
<el-button size="mini" type="danger" icon="el-icon-delete" slot="reference">删除</el-button>
<el-button slot="reference" size="mini" type="danger" icon="el-icon-delete">删除</el-button>
</el-popover>
</template>
</el-table-column>
@@ -117,12 +117,12 @@
<el-tag type="danger">id , created_at , updated_at , deleted_at 会自动生成请勿重复创建</el-tag>
<!-- 组件列表 -->
<div class="button-box clearflex">
<el-button @click="enterForm(true)" type="primary">预览代码</el-button>
<el-button @click="enterForm(false)" type="primary">生成代码</el-button>
<el-button type="primary" @click="enterForm(true)">预览代码</el-button>
<el-button type="primary" @click="enterForm(false)">生成代码</el-button>
</div>
<!-- 组件弹窗 -->
<el-dialog title="组件内容" :visible.sync="dialogFlag">
<FieldDialog v-if="dialogFlag" :dialogMiddle="dialogMiddle" ref="fieldDialog" />
<FieldDialog v-if="dialogFlag" ref="fieldDialog" :dialog-middle="dialogMiddle" />
<div slot="footer" class="dialog-footer">
<el-button @click="closeDialog"> </el-button>
<el-button type="primary" @click="enterDialog"> </el-button>
@@ -130,265 +130,266 @@
</el-dialog>
<el-dialog :visible.sync="previewFlag">
<PreviewCodeDialg v-if="previewFlag" :previewCode="preViewCode"></PreviewCodeDialg>
<PreviewCodeDialg v-if="previewFlag" :preview-code="preViewCode" />
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="previewFlag = false"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
const fieldTemplate = {
fieldName: "",
fieldDesc: "",
fieldType: "",
dataType: "",
fieldJson: "",
columnName: "",
dataTypeLong: "",
comment: "",
fieldSearchType: "",
dictType: ""
};
fieldName: '',
fieldDesc: '',
fieldType: '',
dataType: '',
fieldJson: '',
columnName: '',
dataTypeLong: '',
comment: '',
fieldSearchType: '',
dictType: ''
}
import FieldDialog from "@/view/systemTools/autoCode/component/fieldDialog.vue";
import PreviewCodeDialg from "@/view/systemTools/autoCode/component/previewCodeDialg.vue";
import { toUpperCase, toHump } from "@/utils/stringFun.js";
import { createTemp, getDB, getTable, getColumn, preview } from "@/api/autoCode.js";
import { getDict } from "@/utils/dictionary";
import FieldDialog from '@/view/systemTools/autoCode/component/fieldDialog.vue'
import PreviewCodeDialg from '@/view/systemTools/autoCode/component/previewCodeDialg.vue'
import { toUpperCase, toHump } from '@/utils/stringFun'
import { createTemp, getDB, getTable, getColumn, preview } from '@/api/autoCode'
import { getDict } from '@/utils/dictionary'
export default {
name: "autoCode",
name: 'AutoCode',
components: {
FieldDialog,
PreviewCodeDialg
},
data() {
return {
activeNames: [""],
preViewCode:{},
activeNames: [''],
preViewCode: {},
dbform: {
dbName: "",
tableName: ""
dbName: '',
tableName: ''
},
dbOptions: [],
tableOptions: [],
addFlag: "",
addFlag: '',
fdMap: {},
form: {
structName: "",
tableName: "",
packageName: "",
abbreviation: "",
description: "",
structName: '',
tableName: '',
packageName: '',
abbreviation: '',
description: '',
autoCreateApiToSql: false,
autoMoveFile: false,
fields: []
},
rules: {
structName: [
{ required: true, message: "请输入结构体名称", trigger: "blur" }
{ required: true, message: '请输入结构体名称', trigger: 'blur' }
],
abbreviation: [
{ required: true, message: "请输入结构体简称", trigger: "blur" }
{ required: true, message: '请输入结构体简称', trigger: 'blur' }
],
description: [
{ required: true, message: "请输入结构体描述", trigger: "blur" }
{ required: true, message: '请输入结构体描述', trigger: 'blur' }
],
packageName: [
{
required: true,
message: "文件名称sys_xxxx_xxxx",
trigger: "blur"
message: '文件名称sys_xxxx_xxxx',
trigger: 'blur'
}
]
},
dialogMiddle: {},
bk: {},
dialogFlag: false,
previewFlag:false
};
previewFlag: false
}
},
components: {
FieldDialog,
PreviewCodeDialg
created() {
this.getDb()
this.setFdMap()
},
methods: {
editAndAddField(item) {
this.dialogFlag = true;
this.dialogFlag = true
if (item) {
this.addFlag = "edit";
this.bk = JSON.parse(JSON.stringify(item));
this.dialogMiddle = item;
this.addFlag = 'edit'
this.bk = JSON.parse(JSON.stringify(item))
this.dialogMiddle = item
} else {
this.addFlag = "add";
this.dialogMiddle = JSON.parse(JSON.stringify(fieldTemplate));
this.addFlag = 'add'
this.dialogMiddle = JSON.parse(JSON.stringify(fieldTemplate))
}
},
moveUpField(index) {
if (index == 0) {
return;
if (index === 0) {
return
}
const oldUpField = this.form.fields[index - 1];
this.form.fields.splice(index - 1, 1);
this.form.fields.splice(index, 0, oldUpField);
const oldUpField = this.form.fields[index - 1]
this.form.fields.splice(index - 1, 1)
this.form.fields.splice(index, 0, oldUpField)
},
moveDownField(index) {
const fCount = this.form.fields.length;
if (index == fCount - 1) {
return;
const fCount = this.form.fields.length
if (index === fCount - 1) {
return
}
const oldDownField = this.form.fields[index + 1];
this.form.fields.splice(index + 1, 1);
this.form.fields.splice(index, 0, oldDownField);
const oldDownField = this.form.fields[index + 1]
this.form.fields.splice(index + 1, 1)
this.form.fields.splice(index, 0, oldDownField)
},
enterDialog() {
this.$refs.fieldDialog.$refs.fieldDialogFrom.validate(valid => {
if (valid) {
this.dialogMiddle.fieldName = toUpperCase(
this.dialogMiddle.fieldName
);
if (this.addFlag == "add") {
this.form.fields.push(this.dialogMiddle);
)
if (this.addFlag === 'add') {
this.form.fields.push(this.dialogMiddle)
}
this.dialogFlag = false;
this.dialogFlag = false
} else {
return false;
return false
}
});
})
},
closeDialog() {
if (this.addFlag == "edit") {
this.dialogMiddle = this.bk;
if (this.addFlag === 'edit') {
this.dialogMiddle = this.bk
}
this.dialogFlag = false;
this.dialogFlag = false
},
deleteField(index) {
this.form.fields.splice(index, 1);
this.form.fields.splice(index, 1)
},
async enterForm(isPreview) {
if (this.form.fields.length <= 0) {
this.$message({
type: "error",
message: "请填写至少一个field"
});
return false;
type: 'error',
message: '请填写至少一个field'
})
return false
}
if (
this.form.fields.some(item => item.fieldName == this.form.structName)
this.form.fields.some(item => item.fieldName === this.form.structName)
) {
this.$message({
type: "error",
message: "存在与结构体同名的字段"
});
return false;
type: 'error',
message: '存在与结构体同名的字段'
})
return false
}
this.$refs.autoCodeForm.validate(async valid => {
if (valid) {
this.form.structName = toUpperCase(this.form.structName);
if (this.form.structName == this.form.abbreviation) {
this.form.structName = toUpperCase(this.form.structName)
if (this.form.structName === this.form.abbreviation) {
this.$message({
type: "error",
message: "structName和struct简称不能相同"
});
return false;
type: 'error',
message: 'structName和struct简称不能相同'
})
return false
}
if(isPreview){
const data = await preview(this.form);
console.log(data.code == 0)
if (isPreview) {
const data = await preview(this.form)
this.preViewCode = data.data.autoCode
this.previewFlag = true
}else{
const data = await createTemp(this.form);
if (data.headers?.success == "false") {
return;
} else {
const data = await createTemp(this.form)
if (data.headers?.success === 'false') {
return
} else {
this.$message({
type: "success",
message: "自动化代码创建成功,正在下载"
});
type: 'success',
message: '自动化代码创建成功,正在下载'
})
}
const blob = new Blob([data]);
const fileName = "ginvueadmin.zip";
if ("download" in document.createElement("a")) {
const blob = new Blob([data])
const fileName = 'ginvueadmin.zip'
if ('download' in document.createElement('a')) {
// 不是IE浏览器
let url = window.URL.createObjectURL(blob);
let link = document.createElement("a");
link.style.display = "none";
link.href = url;
link.setAttribute("download", fileName);
document.body.appendChild(link);
link.click();
document.body.removeChild(link); // 下载完成移除元素
window.URL.revokeObjectURL(url); // 释放掉blob对象
const url = window.URL.createObjectURL(blob)
const link = document.createElement('a')
link.style.display = 'none'
link.href = url
link.setAttribute('download', fileName)
document.body.appendChild(link)
link.click()
document.body.removeChild(link) // 下载完成移除元素
window.URL.revokeObjectURL(url) // 释放掉blob对象
} else {
// IE 10+
window.navigator.msSaveBlob(blob, fileName);
window.navigator.msSaveBlob(blob, fileName)
}
}
} else {
return false;
return false
}
});
})
},
async getDb() {
const res = await getDB();
if (res.code == 0) {
this.dbOptions = res.data.dbs;
const res = await getDB()
if (res.code === 0) {
this.dbOptions = res.data.dbs
}
},
async getTable() {
const res = await getTable({ dbName: this.dbform.dbName });
if (res.code == 0) {
this.tableOptions = res.data.tables;
const res = await getTable({ dbName: this.dbform.dbName })
if (res.code === 0) {
this.tableOptions = res.data.tables
}
this.dbform.tableName = "";
this.dbform.tableName = ''
},
async getColumn() {
const gormModelList = ["id", "created_at", "updated_at", "deleted_at"];
const res = await getColumn(this.dbform);
if (res.code == 0) {
const tbHump = toHump(this.dbform.tableName);
this.form.structName = toUpperCase(tbHump);
this.form.tableName = this.dbform.tableName;
this.form.packageName = tbHump;
this.form.abbreviation = tbHump;
this.form.description = tbHump + "表";
this.form.autoCreateApiToSql = true;
this.form.fields = [];
const gormModelList = ['id', 'created_at', 'updated_at', 'deleted_at']
const res = await getColumn(this.dbform)
if (res.code === 0) {
const tbHump = toHump(this.dbform.tableName)
this.form.structName = toUpperCase(tbHump)
this.form.tableName = this.dbform.tableName
this.form.packageName = tbHump
this.form.abbreviation = tbHump
this.form.description = tbHump + '表'
this.form.autoCreateApiToSql = true
this.form.fields = []
res.data.columns &&
res.data.columns.map(item => {
if (!gormModelList.some(gormfd => gormfd == item.columnName)) {
const fbHump = toHump(item.columnName);
if (!gormModelList.some(gormfd => gormfd === item.columnName)) {
const fbHump = toHump(item.columnName)
this.form.fields.push({
fieldName: toUpperCase(fbHump),
fieldDesc: item.columnComment || fbHump + "字段",
fieldDesc: item.columnComment || fbHump + '字段',
fieldType: this.fdMap[item.dataType],
dataType: item.dataType,
fieldJson: fbHump,
dataTypeLong: item.dataTypeLong,
columnName: item.columnName,
comment: item.columnComment,
fieldSearchType: "",
dictType: ""
});
fieldSearchType: '',
dictType: ''
})
}
});
})
}
},
async setFdMap() {
const fdTypes = ["string", "int", "bool", "float64", "time.Time"];
const fdTypes = ['string', 'int', 'bool', 'float64', 'time.Time']
fdTypes.map(async fdtype => {
const res = await getDict(fdtype);
res&&res.map(item => {
this.fdMap[item.label] = fdtype;
});
});
const res = await getDict(fdtype)
res && res.map(item => {
this.fdMap[item.label] = fdtype
})
})
}
},
created() {
this.getDb();
this.setFdMap();
}
};
}
</script>
<style scope lang="scss">
<style scoped lang="scss">
.button-box {
padding: 10px 20px;
.el-button {

View File

@@ -1,20 +1,17 @@
<template>
<div style="height:80vh">
<iframe width="100%" height="100%" :src="basePath+':8888/form-generator/#/'" frameborder="0"></iframe>
<iframe width="100%" height="100%" :src="basePath+':8888/form-generator/#/'" frameborder="0" />
</div>
</template>
<script>
var path = process.env.VUE_APP_BASE_PATH
export default {
name:"FormGenerator",
data(){
return{
basePath:path
}
},
};
name: 'FormGenerator',
data() {
return {
basePath: path
}
}
}
</script>
<style lang="scss">
</style>

View File

@@ -1,15 +1,14 @@
<template>
<div>
<keep-alive>
<router-view v-if="$route.meta.keepAlive"></router-view>
<router-view v-if="$route.meta.keepAlive" />
</keep-alive>
<router-view v-if="!$route.meta.keepAlive"></router-view>
<router-view v-if="!$route.meta.keepAlive" />
</div>
</template>
<script>
export default {
name: "System",
};
name: 'System'
}
</script>
<style lang="scss"></style>

View File

@@ -1,32 +1,32 @@
<template>
<div class="system">
<el-form :model="config" label-width="100px" ref="form" class="system">
<el-form ref="form" :model="config" label-width="100px" class="system">
<!-- System start -->
<h2>系统配置</h2>
<el-form-item label="环境值">
<el-input v-model="config.system.env"></el-input>
<el-input v-model="config.system.env" />
</el-form-item>
<el-form-item label="端口值">
<el-input v-model.number="config.system.addr"></el-input>
<el-input v-model.number="config.system.addr" />
</el-form-item>
<el-form-item label="数据库类型">
<el-select v-model="config.system.dbType">
<el-option value="mysql"></el-option>
<el-option value="sqlite"></el-option>
<el-option value="sqlserver"></el-option>
<el-option value="postgresql"></el-option>
<el-option value="mysql" />
<el-option value="sqlite" />
<el-option value="sqlserver" />
<el-option value="postgresql" />
</el-select>
</el-form-item>
<el-form-item label="Oss类型">
<el-select v-model="config.system.ossType">
<el-option value="local"></el-option>
<el-option value="qiniu"></el-option>
<el-option value="tencent-cos"></el-option>
<el-option value="aliyun-oss"></el-option>
<el-option value="local" />
<el-option value="qiniu" />
<el-option value="tencent-cos" />
<el-option value="aliyun-oss" />
</el-select>
</el-form-item>
<el-form-item label="配置文件环境变量名">
<el-input v-model.number="config.system.configEnv"></el-input>
<el-input v-model.number="config.system.configEnv" />
</el-form-item>
<el-form-item label="数据初始化">
<el-checkbox v-model="config.system.needInitData">开启</el-checkbox>
@@ -39,73 +39,73 @@
<!-- JWT start -->
<h2>jwt签名</h2>
<el-form-item label="jwt签名">
<el-input v-model="config.jwt.signingKey"></el-input>
<el-input v-model="config.jwt.signingKey" />
</el-form-item>
<!-- JWT end -->
<!-- Zap start -->
<h2>Zap日志配置</h2>
<el-form-item label="级别">
<el-input v-model.number="config.zap.level"></el-input>
<el-input v-model.number="config.zap.level" />
</el-form-item>
<el-form-item label="输出">
<el-input v-model="config.zap.format"></el-input>
<el-input v-model="config.zap.format" />
</el-form-item>
<el-form-item label="日志前缀">
<el-input v-model="config.zap.prefix"></el-input>
<el-input v-model="config.zap.prefix" />
</el-form-item>
<el-form-item label="日志文件夹">
<el-input v-model="config.zap.director"></el-input>
<el-input v-model="config.zap.director" />
</el-form-item>
<el-form-item label="软链接名称">
<el-input v-model="config.zap.linkName"></el-input>
<el-input v-model="config.zap.linkName" />
</el-form-item>
<el-form-item label="编码级">
<el-input v-model="config.zap.encodeLevel"></el-input>
<el-input v-model="config.zap.encodeLevel" />
</el-form-item>
<el-form-item label="栈名">
<el-input v-model="config.zap.stacktraceKey"></el-input>
<el-input v-model="config.zap.stacktraceKey" />
</el-form-item>
<el-form-item label="显示行">
<el-checkbox v-model="config.zap.showLine"></el-checkbox>
<el-checkbox v-model="config.zap.showLine" />
</el-form-item>
<el-form-item label="输出控制台">
<el-checkbox v-model="config.zap.logInConsole"></el-checkbox>
<el-checkbox v-model="config.zap.logInConsole" />
</el-form-item>
<!-- Zap end -->
<!-- Redis start -->
<h2>Redis admin数据库配置</h2>
<el-form-item label="db">
<el-input v-model="config.redis.db"></el-input>
<el-input v-model="config.redis.db" />
</el-form-item>
<el-form-item label="addr">
<el-input v-model="config.redis.addr"></el-input>
<el-input v-model="config.redis.addr" />
</el-form-item>
<el-form-item label="password">
<el-input v-model="config.redis.password"></el-input>
<el-input v-model="config.redis.password" />
</el-form-item>
<!-- Redis end -->
<!-- Email start -->
<h2>邮箱配置</h2>
<el-form-item label="接收者邮箱">
<el-input v-model="config.email.to" placeholder="可多个,以逗号分隔"></el-input>
<el-input v-model="config.email.to" placeholder="可多个,以逗号分隔" />
</el-form-item>
<el-form-item label="端口">
<el-input v-model.number="config.email.port"></el-input>
<el-input v-model.number="config.email.port" />
</el-form-item>
<el-form-item label="发送者邮箱">
<el-input v-model="config.email.from"></el-input>
<el-input v-model="config.email.from" />
</el-form-item>
<el-form-item label="host">
<el-input v-model="config.email.host"></el-input>
<el-input v-model="config.email.host" />
</el-form-item>
<el-form-item label="是否为ssl">
<el-checkbox v-model="config.email.isSSL"></el-checkbox>
<el-checkbox v-model="config.email.isSSL" />
</el-form-item>
<el-form-item label="secret">
<el-input v-model="config.email.secret"></el-input>
<el-input v-model="config.email.secret" />
</el-form-item>
<el-form-item label="测试邮件">
<el-button @click="email">测试邮件</el-button>
@@ -115,204 +115,204 @@
<!-- Casbin start -->
<h2>casbin配置</h2>
<el-form-item label="模型地址">
<el-input v-model="config.casbin.modelPath"></el-input>
<el-input v-model="config.casbin.modelPath" />
</el-form-item>
<!-- Casbin end -->
<!-- Captcha start -->
<h2>验证码配置</h2>
<el-form-item label="keyLong">
<el-input v-model.number="config.captcha.keyLong"></el-input>
<el-input v-model.number="config.captcha.keyLong" />
</el-form-item>
<el-form-item label="imgWidth">
<el-input v-model.number="config.captcha.imgWidth"></el-input>
<el-input v-model.number="config.captcha.imgWidth" />
</el-form-item>
<el-form-item label="imgHeight">
<el-input v-model.number="config.captcha.imgHeight"></el-input>
<el-input v-model.number="config.captcha.imgHeight" />
</el-form-item>
<!-- Captcha end -->
<!-- dbType start -->
<template v-if="config.system.dbType == 'mysql'">
<template v-if="config.system.dbType === 'mysql'">
<h2>mysql admin数据库配置</h2>
<el-form-item label="username">
<el-input v-model="config.mysql.username"></el-input>
<el-input v-model="config.mysql.username" />
</el-form-item>
<el-form-item label="password">
<el-input v-model="config.mysql.password"></el-input>
<el-input v-model="config.mysql.password" />
</el-form-item>
<el-form-item label="path">
<el-input v-model="config.mysql.path"></el-input>
<el-input v-model="config.mysql.path" />
</el-form-item>
<el-form-item label="dbname">
<el-input v-model="config.mysql.dbname"></el-input>
<el-input v-model="config.mysql.dbname" />
</el-form-item>
<el-form-item label="maxIdleConns">
<el-input v-model.number="config.mysql.maxIdleConns"></el-input>
<el-input v-model.number="config.mysql.maxIdleConns" />
</el-form-item>
<el-form-item label="maxOpenConns">
<el-input v-model.number="config.mysql.maxOpenConns"></el-input>
<el-input v-model.number="config.mysql.maxOpenConns" />
</el-form-item>
<el-form-item label="logMode">
<el-checkbox v-model="config.mysql.logMode"></el-checkbox>
<el-checkbox v-model="config.mysql.logMode" />
</el-form-item>
</template>
<template v-if="config.system.dbType == 'sqlite'">
<template v-if="config.system.dbType === 'sqlite'">
<h2>sqlite admin数据库配置</h2>
<el-form-item label="path">
<el-input v-model="config.mysql.path"></el-input>
<el-input v-model="config.mysql.path" />
</el-form-item>
<el-form-item label="maxIdleConns">
<el-input v-model.number="config.mysql.maxIdleConns"></el-input>
<el-input v-model.number="config.mysql.maxIdleConns" />
</el-form-item>
<el-form-item label="maxOpenConns">
<el-input v-model.number="config.mysql.maxOpenConns"></el-input>
<el-input v-model.number="config.mysql.maxOpenConns" />
</el-form-item>
<el-form-item label="logger">
<el-checkbox v-model="config.mysql.logger"></el-checkbox>
<el-checkbox v-model="config.mysql.logger" />
</el-form-item>
</template>
<template v-if="config.system.dbType == 'sqlserver'">
<template v-if="config.system.dbType === 'sqlserver'">
<h2>sqlserver admin数据库配置</h2>
<el-form-item label="username">
<el-input v-model="config.sqlserver.username"></el-input>
<el-input v-model="config.sqlserver.username" />
</el-form-item>
<el-form-item label="password">
<el-input v-model="config.sqlserver.password"></el-input>
<el-input v-model="config.sqlserver.password" />
</el-form-item>
<el-form-item label="path">
<el-input v-model="config.sqlserver.path"></el-input>
<el-input v-model="config.sqlserver.path" />
</el-form-item>
<el-form-item label="dbname">
<el-input v-model="config.sqlserver.dbname"></el-input>
<el-input v-model="config.sqlserver.dbname" />
</el-form-item>
<el-form-item label="maxIdleConns">
<el-input v-model.number="config.sqlserver.maxIdleConns"></el-input>
<el-input v-model.number="config.sqlserver.maxIdleConns" />
</el-form-item>
<el-form-item label="maxOpenConns">
<el-input v-model.number="config.sqlserver.maxOpenConns"></el-input>
<el-input v-model.number="config.sqlserver.maxOpenConns" />
</el-form-item>
<el-form-item label="logger">
<el-checkbox v-model="config.sqlserver.logger"></el-checkbox>
<el-checkbox v-model="config.sqlserver.logger" />
</el-form-item>
</template>
<template v-if="config.system.dbType == 'postgresql'">
<template v-if="config.system.dbType === 'postgresql'">
<h2>postgresql admin数据库配置</h2>
<el-form-item label="username">
<el-input v-model="config.mysql.username"></el-input>
<el-input v-model="config.mysql.username" />
</el-form-item>
<el-form-item label="password">
<el-input v-model="config.mysql.password"></el-input>
<el-input v-model="config.mysql.password" />
</el-form-item>
<el-form-item label="dbName">
<el-input v-model="config.mysql.dbName"></el-input>
<el-input v-model="config.mysql.dbName" />
</el-form-item>
<el-form-item label="port">
<el-input v-model="config.mysql.port"></el-input>
<el-input v-model="config.mysql.port" />
</el-form-item>
<el-form-item label="config">
<el-input v-model="config.mysql.config"></el-input>
<el-input v-model="config.mysql.config" />
</el-form-item>
<el-form-item label="maxIdleConns">
<el-input v-model.number="config.mysql.maxIdleConns"></el-input>
<el-input v-model.number="config.mysql.maxIdleConns" />
</el-form-item>
<el-form-item label="maxOpenConns">
<el-input v-model.number="config.mysql.maxOpenConns"></el-input>
<el-input v-model.number="config.mysql.maxOpenConns" />
</el-form-item>
<el-form-item label="logger">
<el-checkbox v-model="config.mysql.logger"></el-checkbox>
<el-checkbox v-model="config.mysql.logger" />
</el-form-item>
<el-form-item label="prefer-simple-protocol">
<el-checkbox v-model="config.mysql.preferSimpleProtocol"></el-checkbox>
<el-checkbox v-model="config.mysql.preferSimpleProtocol" />
</el-form-item>
</template>
<!-- dbType end -->
<!-- ossType start -->
<template v-if="config.system.ossType == 'local'">
<template v-if="config.system.ossType === 'local'">
<h2>本地上传配置</h2>
<el-form-item label="本地文件路径">
<el-input v-model="config.local.path"></el-input>
<el-input v-model="config.local.path" />
</el-form-item>
</template>
<template v-if="config.system.ossType == 'qiniu'">
<template v-if="config.system.ossType === 'qiniu'">
<h2>qiniu上传配置</h2>
<el-form-item label="存储区域">
<el-input v-model="config.qiniu.zone"></el-input>
<el-input v-model="config.qiniu.zone" />
</el-form-item>
<el-form-item label="空间名称">
<el-input v-model="config.qiniu.bucket"></el-input>
<el-input v-model="config.qiniu.bucket" />
</el-form-item>
<el-form-item label="CDN加速域名">
<el-input v-model="config.qiniu.imgPath"></el-input>
<el-input v-model="config.qiniu.imgPath" />
</el-form-item>
<el-form-item label="是否使用https">
<el-checkbox v-model="config.qiniu.useHttps">开启</el-checkbox>
</el-form-item>
<el-form-item label="accessKey">
<el-input v-model="config.qiniu.accessKey"></el-input>
<el-input v-model="config.qiniu.accessKey" />
</el-form-item>
<el-form-item label="secretKey">
<el-input v-model="config.qiniu.secretKey"></el-input>
<el-input v-model="config.qiniu.secretKey" />
</el-form-item>
<el-form-item label="上传是否使用CDN上传加速">
<el-checkbox v-model="config.qiniu.useCdnDomains">开启</el-checkbox>
</el-form-item>
</template>
<template v-if="config.system.ossType == 'tencent-cos'">
<template v-if="config.system.ossType === 'tencent-cos'">
<h2>腾讯云COS上传配置</h2>
<el-form-item label="bucket">
<el-input v-model="config.tencentCOS.bucket"></el-input>
<el-input v-model="config.tencentCOS.bucket" />
</el-form-item>
<el-form-item label="region">
<el-input v-model="config.tencentCOS.region"></el-input>
<el-input v-model="config.tencentCOS.region" />
</el-form-item>
<el-form-item label="secretID">
<el-input v-model="config.tencentCOS.secretID"></el-input>
<el-input v-model="config.tencentCOS.secretID" />
</el-form-item>
<el-form-item label="secretKey">
<el-input v-model="config.tencentCOS.secretKey"></el-input>
<el-input v-model="config.tencentCOS.secretKey" />
</el-form-item>
<el-form-item label="pathPrefix">
<el-input v-model="config.tencentCOS.pathPrefix"></el-input>
<el-input v-model="config.tencentCOS.pathPrefix" />
</el-form-item>
<el-form-item label="baseURL">
<el-input v-model="config.tencentCOS.baseURL"></el-input>
<el-input v-model="config.tencentCOS.baseURL" />
</el-form-item>
</template>
<template v-if="config.system.ossType == 'aliyun-oss'">
<template v-if="config.system.ossType === 'aliyun-oss'">
<h2>阿里云OSS上传配置</h2>
<el-form-item label="endpoint">
<el-input v-model="config.aliyunOSS.endpoint"></el-input>
<el-input v-model="config.aliyunOSS.endpoint" />
</el-form-item>
<el-form-item label="accessKeyId">
<el-input v-model="config.aliyunOSS.accessKeyId"></el-input>
<el-input v-model="config.aliyunOSS.accessKeyId" />
</el-form-item>
<el-form-item label="accessKeySecret">
<el-input v-model="config.aliyunOSS.accessKeySecret"></el-input>
<el-input v-model="config.aliyunOSS.accessKeySecret" />
</el-form-item>
<el-form-item label="bucketName">
<el-input v-model="config.aliyunOSS.bucketName"></el-input>
<el-input v-model="config.aliyunOSS.bucketName" />
</el-form-item>
<el-form-item label="bucketUrl">
<el-input v-model="config.aliyunOSS.bucketUrl"></el-input>
<el-input v-model="config.aliyunOSS.bucketUrl" />
</el-form-item>
</template>
<!-- ossType end -->
<el-form-item>
<el-button @click="update" type="primary">立即更新</el-button>
<el-button @click="reload" type="primary">重启服务开发中</el-button>
<el-button type="primary" @click="update">立即更新</el-button>
<el-button type="primary" @click="reload">重启服务开发中</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script>
import { getSystemConfig, setSystemConfig } from "@/api/system";
import { emailTest } from "@/api/email";
import { getSystemConfig, setSystemConfig } from '@/api/system'
import { emailTest } from '@/api/email'
export default {
name: "Config",
name: 'Config',
data() {
return {
config: {
@@ -323,54 +323,55 @@ export default {
sqlite: {},
redis: {},
qiniu: {},
tencentCOS:{},
aliyunOSS:{},
tencentCOS: {},
aliyunOSS: {},
captcha: {},
zap: {},
local: {},
email: {}
}
};
}
},
async created() {
await this.initForm();
await this.initForm()
},
methods: {
async initForm() {
const res = await getSystemConfig();
if (res.code == 0) {
this.config = res.data.config;
const res = await getSystemConfig()
if (res.code === 0) {
this.config = res.data.config
}
},
reload() {},
async update() {
const res = await setSystemConfig({ config: this.config });
if (res.code == 0) {
const res = await setSystemConfig({ config: this.config })
if (res.code === 0) {
this.$message({
type: "success",
message: "配置文件设置成功"
});
await this.initForm();
type: 'success',
message: '配置文件设置成功'
})
await this.initForm()
}
},
async email() {
const res = await emailTest();
if (res.code == 0) {
const res = await emailTest()
if (res.code === 0) {
this.$message({
type: "success",
message: "邮件发送成功"
});
await this.initForm();
type: 'success',
message: '邮件发送成功'
})
await this.initForm()
} else {
this.$message({
type: "error",
message: "邮件发送失败"
});
type: 'error',
message: '邮件发送失败'
})
}
}
}
};
}
</script>
<style lang="scss">
.system {
h2 {

View File

@@ -5,125 +5,123 @@ const buildConf = require('./build.config')
const packageConf = require('./package.json')
function resolve(dir) {
return path.join(__dirname, dir)
return path.join(__dirname, dir)
}
module.exports = {
// 基础配置 详情看文档
publicPath: './',
outputDir: 'dist',
assetsDir: 'static',
lintOnSave: process.env.NODE_ENV === 'development',
productionSourceMap: false,
devServer: {
port: process.env.VUE_APP_CLI_PORT,
open: true,
overlay: {
warnings: false,
errors: true
},
proxy: {
// 把key的路径代理到target位置
// detail: https://cli.vuejs.org/config/#devserver-proxy
[process.env.VUE_APP_BASE_API]: { //需要代理的路径 例如 '/api'
target: `${process.env.VUE_APP_BASE_PATH}:${process.env.VUE_APP_SERVER_PORT}/`, //代理到 目标路径
changeOrigin: true,
pathRewrite: { // 修改路径数据
['^' + process.env.VUE_APP_BASE_API]: '' // 举例 '^/api:""' 把路径中的/api字符串删除
}
}
},
// 基础配置 详情看文档
publicPath: './',
outputDir: 'dist',
assetsDir: 'static',
lintOnSave: process.env.NODE_ENV === 'development',
productionSourceMap: false,
devServer: {
port: process.env.VUE_APP_CLI_PORT,
open: true,
overlay: {
warnings: false,
errors: true
},
configureWebpack: {
// @路径走src文件夹
resolve: {
alias: {
'@': resolve('src')
}
proxy: {
// 把key的路径代理到target位置
// detail: https://cli.vuejs.org/config/#devserver-proxy
[process.env.VUE_APP_BASE_API]: { // 需要代理的路径 例如 '/api'
target: `${process.env.VUE_APP_BASE_PATH}:${process.env.VUE_APP_SERVER_PORT}/`, // 代理到 目标路径
changeOrigin: true,
pathRewrite: { // 修改路径数据
['^' + process.env.VUE_APP_BASE_API]: '' // 举例 '^/api:""' 把路径中的/api字符串删除
}
},
chainWebpack(config) {
// set preserveWhitespace
config.module
.rule('vue')
.use('vue-loader')
.loader('vue-loader')
.tap(options => {
options.compilerOptions.preserveWhitespace = true
return options
})
.end()
config
// https://webpack.js.org/configuration/devtool/#development
.when(process.env.NODE_ENV === 'development',
config => config.devtool('cheap-source-map')
)
config
.when(process.env.NODE_ENV !== 'development',
config => {
// 不打包 begin
// 1.目前已经测试通过[vue,axios,echarts]可以cdn引用其它组件测试通过后可继续添加
// 2.此处添加不打包后需在public/index.html head中添加相应cdn资源链接
config.set('externals', buildConf.cdns.reduce((p, a) => {
p[a.name] = a.scope
return p
},{}))
// 不打包 end
config.plugin('html')
.tap(args => {
if(buildConf.title) {
args[0].title = buildConf.title
}
if(buildConf.cdns.length > 0) {
args[0].cdns = buildConf.cdns.map(conf => {
if (conf.path) {
conf.js = `${buildConf.baseCdnUrl}${conf.path}`
} else {
conf.js = `${buildConf.baseCdnUrl}/${conf.name}/${packageConf.dependencies[conf.name].replace('^', '')}/${conf.name}.min.js`
}
return conf
})
}
return args
})
config
.plugin('ScriptExtHtmlWebpackPlugin')
.after('html')
.use('script-ext-html-webpack-plugin', [{
// `runtime` must same as runtimeChunk name. default is `runtime`
inline: /single\..*\.js$/
}])
.end()
config
.optimization.splitChunks({
chunks: 'all',
cacheGroups: {
libs: {
name: 'chunk-libs',
test: /[\\/]node_modules[\\/]/,
priority: 10,
chunks: 'initial' // only package third parties that are initially dependent
},
elementUI: {
name: 'chunk-elementUI', // split elementUI into a single package
priority: 20, // the weight needs to be larger than libs and app or it will be packaged into libs or app
test: /[\\/]node_modules[\\/]_?element-ui(.*)/ // in order to adapt to cnpm
},
commons: {
name: 'chunk-commons',
test: resolve('src/components'), // can customize your rules
minChunks: 3, // minimum common number
priority: 5,
reuseExistingChunk: true
}
}
})
config.optimization.runtimeChunk('single')
}
)
}
}
}
},
configureWebpack: {
// @路径走src文件夹
resolve: {
alias: {
'@': resolve('src')
}
}
},
chainWebpack(config) {
// set preserveWhitespace
config.module
.rule('vue')
.use('vue-loader')
.loader('vue-loader')
.tap(options => {
options.compilerOptions.preserveWhitespace = true
return options
})
.end()
config
// https://webpack.js.org/configuration/devtool/#development
.when(process.env.NODE_ENV === 'development',
config => config.devtool('cheap-source-map')
)
config
.when(process.env.NODE_ENV !== 'development',
config => {
// 不打包 begin
// 1.目前已经测试通过[vue,axios,echarts]可以cdn引用其它组件测试通过后可继续添加
// 2.此处添加不打包后需在public/index.html head中添加相应cdn资源链接
config.set('externals', buildConf.cdns.reduce((p, a) => {
p[a.name] = a.scope
return p
}, {}))
// 不打包 end
config.plugin('html')
.tap(args => {
if (buildConf.title) {
args[0].title = buildConf.title
}
if (buildConf.cdns.length > 0) {
args[0].cdns = buildConf.cdns.map(conf => {
if (conf.path) {
conf.js = `${buildConf.baseCdnUrl}${conf.path}`
} else {
conf.js = `${buildConf.baseCdnUrl}/${conf.name}/${packageConf.dependencies[conf.name].replace('^', '')}/${conf.name}.min.js`
}
return conf
})
}
return args
})
config
.plugin('ScriptExtHtmlWebpackPlugin')
.after('html')
.use('script-ext-html-webpack-plugin', [{
// `runtime` must same as runtimeChunk name. default is `runtime`
inline: /single\..*\.js$/
}])
.end()
config
.optimization.splitChunks({
chunks: 'all',
cacheGroups: {
libs: {
name: 'chunk-libs',
test: /[\\/]node_modules[\\/]/,
priority: 10,
chunks: 'initial' // only package third parties that are initially dependent
},
elementUI: {
name: 'chunk-elementUI', // split elementUI into a single package
priority: 20, // the weight needs to be larger than libs and app or it will be packaged into libs or app
test: /[\\/]node_modules[\\/]_?element-ui(.*)/ // in order to adapt to cnpm
},
commons: {
name: 'chunk-commons',
test: resolve('src/components'), // can customize your rules
minChunks: 3, // minimum common number
priority: 5,
reuseExistingChunk: true
}
}
})
config.optimization.runtimeChunk('single')
}
)
}
}