Merge branch 'seo' into master

This commit is contained in:
奇淼(piexlmax
2021-11-25 15:33:27 +08:00
committed by GitHub
211 changed files with 5425 additions and 5143 deletions
+17 -17
View File
@@ -9,15 +9,15 @@ 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
// @Summary 批量删除SysOperationRecord
// @Summary 删除SysOperationRecord
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
@@ -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
})
}
+7
View File
@@ -141,3 +141,10 @@ export const getUserInfo = () => {
method: 'get'
})
}
export const resetPassword = () => {
return service({
url: '/user/resetPassword',
method: 'post'
})
}
+62 -62
View File
@@ -9,11 +9,11 @@ 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
@@ -25,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
@@ -37,15 +37,15 @@ export const deleteWorkflowProcess = (data) => {
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body request.IdsReq true "批量删除WorkflowProcess"
// @Param data body request.IdsReq true "删除WorkflowProcess"
// @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
@@ -57,11 +57,11 @@ 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
@@ -73,11 +73,11 @@ 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
@@ -89,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
@@ -105,11 +105,11 @@ 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
@@ -120,12 +120,12 @@ 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
@@ -136,12 +136,12 @@ 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
})
return service({
url: '/workflowProcess/completeWorkflowMove',
method: 'post',
data,
params
})
}
// @Tags WorkflowProcess
@@ -152,10 +152,10 @@ export const completeWorkflowMove = (data, params = { businessType: data.wf.busi
// @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/getMyStated',
method: 'get'
})
}
// @Tags WorkflowProcess
@@ -166,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
@@ -181,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
})
}

Before

Width:  |  Height:  |  Size: 70 KiB

After

Width:  |  Height:  |  Size: 70 KiB

+5 -2
View File
@@ -2,11 +2,11 @@
<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')" />
<el-avatar v-else :size="30" :src="noAvatar" />
</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">
<img v-else :src="noAvatar" class="avatar">
</template>
<template v-if="picType === 'file'">
<img :src="file" class="file">
@@ -15,6 +15,7 @@
</template>
<script>
import noAvatar from '@/assets/noBody.png'
import { mapGetters } from 'vuex'
const path = import.meta.env.VITE_BASE_API
export default {
@@ -33,6 +34,7 @@ export default {
},
data() {
return {
noAvatar: noAvatar,
path: path + '/'
}
},
@@ -66,6 +68,7 @@ export default {
display: flex;
justify-content: center;
align-items: center;
margin-right: 8px;
}
.file{
width: 80px;
@@ -1,54 +0,0 @@
<template>
<div class="commit-table">
<div class="commit-table-title">Gva 仓库commit 记录</div>
<el-table v-loading="loading" :data="dataTimeline" style="width: 100%">
<el-table-column prop="from" show-overflow-tooltip label="日期" width="180" />
<el-table-column prop="title" show-overflow-tooltip label="推送者" width="120" />
<el-table-column prop="message" show-overflow-tooltip label="commit 信息" />
</el-table>
</div>
</template>
<script>
import { Commits } from '@/api/github'
export default {
data() {
return {
loading: true,
dataTimeline: [],
}
},
created() {
this.loadCommits()
},
methods: {
loadCommits() {
Commits(0).then(({ data }) => {
this.loading = false
data.forEach((element, index) => {
if (element.commit.message && index < 6) {
this.dataTimeline.push({
from: new Date(element.commit.author.date),
title: element.commit.author.name,
showDayAndMonth: true,
message: element.commit.message,
})
}
})
})
},
}
}
</script>
<style lang="scss" scoped>
.commit-table{
padding: 20px;
background-color: #fff;
height: 400px;
&-title{
color: rgb(56,137,206);
font-size: 18px;
margin-bottom: 20px;
}
}
</style>
@@ -0,0 +1,47 @@
<template>
<div
class="warning-bar"
>
<el-icon>
<warning-filled />
</el-icon>
<span>
{{ title }}
</span>
</div>
</template>
<script>
import { WarningFilled } from '@element-plus/icons'
export default {
components: {
[WarningFilled.name]: WarningFilled
},
props: {
title: {
type: String,
default: ''
},
}
}
</script>
<style lang="scss" scoped>
.warning-bar{
background-color: #FFF5ED;
font-size: 14px;
padding: 6px 14px;
display: flex;
align-items: center;
border-radius: 2px;
.el-icon{
font-size: 18px;
color: #ED6A0C;
}
margin-bottom: 12px;
span{
line-height: 22px;
color:#F67207;
margin-left: 8px;
}
}
</style>
+12 -20
View File
@@ -5,24 +5,16 @@
// 加载网站配置文件夹
import { register } from './global'
export const run = function(app) {
export default {
install: (app) => {
register(app)
console.log(
`%c gva启动完成 %c 当前版本V2.4.6 Apache%c`,
'background:#35495e ; padding: 1px; border-radius: 3px 0 0 3px; color: #fff',
'background:#007aff ;padding: 1px 5px; border-radius: 0 3px 3px 0; color: #fff; font-weight: bold;',
'background:transparent'
)
console.log(`欢迎使用 %c Gin-Vue-Admin %c
%c 微信 %c shouzi_1994 %c
%c QQ群 %c 622360840 %c
`,
'background:#007aff ;padding: 1px 5px; border-radius: 3px; color: #fff; font-weight: bold;margin-bottom:4px;',
'background:transparent',
'background:#35495e ; padding: 1px; border-radius: 3px 0 0 3px; color: #fff',
'background:#007aff ;padding: 1px 5px; border-radius: 0 3px 3px 0; color: #fff; font-weight: bold;;margin-bottom:4px;',
'background:transparent',
'background:#35495e ; padding: 1px; border-radius: 3px 0 0 3px; color: #fff',
'background:#007aff ;padding: 1px 5px; border-radius: 0 3px 3px 0; color: #fff; font-weight: bold;;margin-bottom:4px;',
'background:transparent')
}
console.log(`
欢迎使用 Gin-Vue-Admin
当前版本:V2.4.6 Beta
加群方式:微信:shouzi_1994 QQ群:622360840
默认自动化文档地址:http://127.0.0.1:${import.meta.env.VITE_SERVER_PORT}/swagger/index.html
默认前端文件运行地址:http://127.0.0.1:${import.meta.env.VITE_CLI_PORT}
如果项目让您获得了收益,希望您能请团队喝杯可乐:https://www.gin-vue-admin.com/docs/coffee
`)
}
}
+38 -35
View File
@@ -1,39 +1,42 @@
// 权限按钮展示指令
import { store } from '@/store'
export const auth = (app) => {
app.directive('auth', {
// 当被绑定的元素插入到 DOM 中时……
mounted: 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
export default {
install: (app) => {
app.directive('auth', {
// 当被绑定的元素插入到 DOM 中时……
mounted: 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'
}
}
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'
}
}
})
})
}
}
+9 -6
View File
@@ -1,22 +1,25 @@
import { createApp } from 'vue'
import 'element-plus/dist/index.css'
import './style/element_visiable.scss'
import ElementPlus from 'element-plus'
import zhCn from 'element-plus/es/locale/lang/zh-cn'
// 引入gin-vue-admin前端初始化相关内容
import './core/gin-vue-admin'
// 引入封装的router
import router from '@/router/index'
import { run } from '@/core/gin-vue-admin.js'
import run from '@/core/gin-vue-admin.js'
import auth from '@/directive/auth'
import '@/permission'
import { store } from '@/store/index'
import { auth } from '@/directive/auth'
import App from './App.vue'
const app = createApp(App)
run(app)
auth(app)
app.config.productionTip = false
app.use(store).use(router).use(ElementPlus, { locale: zhCn }).mount('#app')
app.use(run)
.use(auth)
.use(store)
.use(router)
.use(ElementPlus, { locale: zhCn }).mount('#app')
export default app
+1 -1
View File
@@ -9,7 +9,7 @@ const getRouter = async() => {
await store.dispatch('router/SetAsyncRouter')
await store.dispatch('user/GetUserInfo')
const asyncRouters = store.getters['router/asyncRouters']
asyncRouters.map(asyncRouter => {
asyncRouters.forEach(asyncRouter => {
router.addRoute(asyncRouter)
})
}
+1 -1
View File
@@ -21,7 +21,7 @@ export const dictionary = {
if (res.code === 0) {
const dictionaryMap = {}
const dict = []
res.data.resysDictionary.sysDictionaryDetails && res.data.resysDictionary.sysDictionaryDetails.map(item => {
res.data.resysDictionary.sysDictionaryDetails && res.data.resysDictionary.sysDictionaryDetails.forEach(item => {
dict.push({
label: item.label,
value: item.value
+24 -1
View File
@@ -3,9 +3,10 @@ import { asyncRouterHandle } from '@/utils/asyncRouter'
import { asyncMenu } from '@/api/menu'
const routerList = []
const keepAliveRouters = []
const formatRouter = (routes) => {
routes && routes.map(item => {
routes && routes.forEach(item => {
if ((!item.children || item.children.every(ch => ch.hidden)) && item.name !== '404' && !item.hidden) {
routerList.push({ label: item.meta.title, value: item.name })
}
@@ -16,11 +17,24 @@ const formatRouter = (routes) => {
})
}
const KeepAliveFilter = (routes) => {
routes && routes.forEach(item => {
// 子菜单中有 keep-alive 的,父菜单也必须 keep-alive,否则无效。这里将子菜单中有 keep-alive 的父菜单也加入。
if ((item.children && item.children.some(ch => ch.meta.keepAlive) || item.meta.keepAlive)) {
item.component().then(val => { keepAliveRouters.push(val.default.name) })
}
if (item.children && item.children.length > 0) {
KeepAliveFilter(item.children)
}
})
}
export const router = {
namespaced: true,
state: {
asyncRouters: [],
routerList: routerList,
keepAliveRouters: keepAliveRouters
},
mutations: {
setRouterList(state, routerList) {
@@ -29,6 +43,10 @@ export const router = {
// 设置动态路由
setAsyncRouter(state, asyncRouters) {
state.asyncRouters = asyncRouters
},
// 设置需要缓存的路由
setKeepAliveRouters(state, keepAliveRouters) {
state.keepAliveRouters = keepAliveRouters
}
},
actions: {
@@ -62,8 +80,10 @@ export const router = {
})
asyncRouterHandle(baseRouter)
KeepAliveFilter(asyncRouter)
commit('setAsyncRouter', baseRouter)
commit('setRouterList', routerList)
commit('setKeepAliveRouters', keepAliveRouters)
return true
}
},
@@ -74,6 +94,9 @@ export const router = {
},
routerList(state) {
return state.routerList
},
keepAliveRouters(state) {
return state.keepAliveRouters
}
}
}
+5 -32
View File
@@ -1,7 +1,6 @@
import { login, getUserInfo } from '@/api/user'
import { login, getUserInfo, setUserInfo } from '@/api/user'
import { jsonInBlacklist } from '@/api/jwt'
import router from '@/router/index'
import { setUserInfo } from '@/api/user'
import { ElMessage } from 'element-plus'
export const user = {
@@ -13,7 +12,7 @@ export const user = {
headerImg: '',
authority: {},
sideMode: 'dark',
activeColor: '#1890ff',
activeColor: '#4D70FF',
baseColor: '#fff'
},
token: '',
@@ -45,15 +44,9 @@ export const user = {
...userInfo
}
},
ChangeActiveColor: async(state, val) => {
state.userInfo.activeColor = val
},
ChangeSideMode: async(state, val) => {
ChangeSideMode: (state, val) => {
state.userInfo.sideMode = val
},
ChangeBaseColor: (state, val) => {
state.userInfo.baseColor = val
}
},
actions: {
async GetUserInfo({ commit }) {
@@ -70,7 +63,7 @@ export const user = {
commit('setToken', res.data.token)
await dispatch('router/SetAsyncRouter', {}, { root: true })
const asyncRouters = rootGetters['router/asyncRouters']
asyncRouters.map(asyncRouter => {
asyncRouters.forEach(asyncRouter => {
router.addRoute(asyncRouter)
})
// const redirect = router.history.current.query.redirect
@@ -89,16 +82,6 @@ export const user = {
commit('LoginOut')
}
},
async changeActiveColor({ commit, state }, data) {
const res = await setUserInfo({ activeColor: data, ID: state.userInfo.ID })
if (res.code === 0) {
commit('ChangeActiveColor', data)
ElMessage({
type: 'success',
message: '设置成功'
})
}
},
async changeSideMode({ commit, state }, data) {
const res = await setUserInfo({ sideMode: data, ID: state.userInfo.ID })
if (res.code === 0) {
@@ -109,16 +92,6 @@ export const user = {
})
}
},
async changeBaseColor({ commit, state }, data) {
const res = await setUserInfo({ baseColor: data, ID: state.userInfo.ID })
if (res.code === 0) {
commit('ChangeBaseColor', data)
ElMessage({
type: 'success',
message: '设置成功'
})
}
}
},
getters: {
userInfo(state) {
@@ -150,7 +123,7 @@ export const user = {
},
activeColor(state) {
if (state.userInfo.sideMode === 'dark' || state.userInfo.sideMode === 'light') {
return '#1890ff'
return '#4D70FF'
}
return state.userInfo.activeColor
}
File diff suppressed because it is too large Load Diff
-14
View File
@@ -58,17 +58,3 @@
.title-3 {
text-align: center;
}
.el-pager li.active{
color: #409EFF !important;
border: 1px solid #409EFF;
}
.el-pager li.active+li{
border-left: 1px;
}
.el-pager li:hover{
color: #409EFF !important;
border: 1px solid #409EFF;
}
+3 -4
View File
@@ -1,6 +1,6 @@
// basice
$font-size: 14px;
$icon-size:17px;
$icon-size:18px;
$active-color:#1890ff;
$bg-main:#f0f2f5;
$border-color: #f4f4f4;
@@ -11,10 +11,9 @@ $el-icon-mini:24px;
$width-aside:220px;
$width-hideside-aside:54px;
$width-mobile-aside:210px;
$color-aside:rgba(255, 255, 255,.9);
$color-aside:rgba(255, 255, 255, .9);
$icon-arrow-size-aside:12px;
$width-submenu-aside:55px;
$bg-aside:#191a23;
$height-aside-tilte:60px;
$height-aside-img:30px;
$width-aside-img:30px;
@@ -34,4 +33,4 @@ $color-table-thead:#262626;
$height-car:68px;
// mobile
$padding-xs: 5px;
$margin-xs: 5px;
$margin-xs: 5px;
+182 -12
View File
@@ -1,21 +1,191 @@
/* 改变主题色变量 */
$--color-primary: #1890ff;
#app{
.el-button{
font-weight: 400;
border-radius: 4px;
border-radius: 2px;
}
}
///* 改变 icon 字体路径变量,必需 */
//$--font-path: '~element-ui/lib/theme-chalk/fonts';
//
//
//
//@import "~element-ui/packages/theme-chalk/src/index";
//
:export {
colorPrimary: $--color-primary
.el-dialog{
border-radius: 2px;
}
::-webkit-scrollbar-track-piece {
background-color: #f8f8f8;
}
::-webkit-scrollbar {
width: 9px;
height: 9px;
}
::-webkit-scrollbar-thumb {
background-color: #dddddd;
background-clip: padding-box;
min-height: 28px;
border-radius: 4px;
}
::-webkit-scrollbar-thumb:hover {
background-color: #bbb;
}
.el-button--primary {
--el-button-font-color: #ffffff;
--el-button-background-color: #4D70FF;
--el-button-border-color: #4D70FF;
--el-button-hover-color: #0d84ff;
--el-button-active-font-color: #e6e6e6;
--el-button-active-background-color: #0d84ff;
--el-button-active-border-color: #0d84ff;
}
.el-button--primary {
--el-button-font-color: #ffffff;
--el-button-background-color: #4D70FF;
--el-button-border-color: #4D70FF;
--el-button-hover-color: #0d84ff;
--el-button-active-font-color: #e6e6e6;
--el-button-active-background-color: #0d84ff;
--el-button-active-border-color: #0d84ff;
}
:root {
--el-color-primary: #4D70FF;
}
.gva-search-box {
.el-collapse {
border: none;
.el-collapse-item__header,
.el-collapse-item__wrap {
border-bottom: none;
}
}
padding: 24px;
padding-bottom: 2px;
background-color: #fff;
border-radius: 2px;
margin-bottom: 12px;
.el-form {
.el-form-item {
padding-right: 28px;
}
}
}
.gva-form-box {
padding: 24px;
background-color: #fff;
border-radius: 2px;
}
.gva-table-box {
padding: 24px;
background-color: #fff;
border-radius: 2px;
}
.gva-pagination {
display: flex;
justify-content: flex-end;
.el-pagination__editor {
.el-input__inner {
height: 32px;
}
}
.el-pagination__total {
line-height: 32px !important;
}
.btn-prev {
padding-right: 6px;
display: inline-flex;
justify-content: center;
align-items: center;
width: 32px;
height: 32px;
}
.number {
display: inline-flex;
justify-content: center;
align-items: center;
width: 32px;
height: 32px;
}
.btn-quicknext {
display: inline-flex;
justify-content: center;
align-items: center;
width: 32px;
height: 32px;
}
.btn-next {
padding-left: 6px;
width: 32px;
height: 32px;
display: inline-flex;
justify-content: center;
align-items: center;
}
.active {
background: #4D70FF;
border-radius: 2px;
color: #ffffff !important;
}
.el-pager li.active+li {
border-left: 1px solid #ddd !important;
}
.el-pagination__sizes {
.el-input {
.el-input__suffix {
margin-top: 2px;
}
}
}
.el-pagination__jump {
.el-pagination__editor {}
}
}
.el-button--mini {
min-height: 32px;
}
.el-button {
padding: 8px 16px;
border-radius: 2px;
&.el-button--text {
padding: 8px 0;
}
}
.el-dialog {
padding: 12px;
.el-dialog__body {
padding: 12px 6px;
}
.el-dialog__header {
.el-dialog__title {
font-size: 14px;
font-weight: 500;
}
padding: 2px 20px 12px 20px;
border-bottom: 1px solid #E4E4E4;
}
.el-dialog__headerbtn {
top: 16px;
}
.el-dialog__footer {
padding: 0 16px 16px 0;
.dialog-footer {
.el-button {
padding-left: 24px;
padding-right: 24px;
}
.el-button+.el-button {
margin-left: 30px;
}
}
}
}
-128
View File
@@ -1,128 +0,0 @@
.login-register-box {
height: 100vh;
.login-box {
width: 40vw;
position: absolute;
left: 50%;
margin-left: -22vw;
top: 5vh;
.logo {
height: 35vh;
width: 35vh;
}
}
}
.link-icon {
width: 20px;
min-width: 20px;
height: 20px;
border-radius: 10px;
}
.vPic {
width: 33%;
height: 38px;
float: right !important;
background: #ccc;
img {
cursor: pointer;
vertical-align: middle;
}
}
.logo_login {
width: 100px;
}
#userLayout.user-layout-wrapper {
height: 100%;
position: relative;
&.mobile {
.container {
.main {
max-width: 368px;
width: 98%;
}
}
}
.container {
position: relative;
overflow: auto;
width: 100%;
min-height: 100%;
background: #f0f2f5 url(@/assets/background.svg) no-repeat 50%;
background-size: 100%;
padding: 110px 0 144px;
a {
text-decoration: none;
}
.top {
text-align: center;
margin-top: -40px;
.header {
height: 44px;
line-height: 44px;
margin-bottom: 30px;
.badge {
position: absolute;
display: inline-block;
line-height: 1;
vertical-align: middle;
margin-left: -12px;
margin-top: -10px;
opacity: 0.8;
}
.logo {
height: 44px;
vertical-align: top;
margin-right: 16px;
border-style: none;
}
.title {
font-size: 33px;
color: rgba(0, 0, 0, 0.85);
font-family: Avenir, "Helvetica Neue", Arial, Helvetica, sans-serif;
font-weight: 600;
position: relative;
top: 2px;
}
}
.desc {
font-size: 14px;
color: rgba(0, 0, 0, 0.45);
margin-top: 12px;
}
}
.main {
min-width: 260px;
width: 368px;
margin: 0 auto;
}
.footer {
position: relative;
width: 100%;
padding: 0 20px;
margin: 40px 0 10px;
text-align: center;
.links {
margin-bottom: 8px;
font-size: 14px;
width: 330px;
display: inline-flex;
flex-direction: row;
justify-content: space-between;
padding-right: 40px;
a {
color: rgba(0, 0, 0, 0.45);
transition: all 0.3s;
}
}
.copyright {
color: rgba(0, 0, 0, 0.45);
font-size: 14px;
padding-right: 40px;
}
}
}
}
+77 -151
View File
@@ -568,7 +568,6 @@ li {
-webkit-transition: width .2s;
transition: width .2s;
width: $width-aside;
background-color: $bg-aside;
height: 100%;
position: fixed;
font-size: 0;
@@ -583,7 +582,6 @@ li {
.tilte {
min-height: $height-aside-tilte;
line-height: $height-aside-tilte;
background: $bg-aside;
text-align: center;
transition: all 0.3s;
.logoimg {
@@ -610,19 +608,13 @@ li {
padding: 0 15px !important;
}
}
.el-menu-vertical {
background-color: $bg-aside;
}
.el-sub-menu {
background-color: $bg-aside;
.el-menu {
.el-menu-item {
background-color: #000408;
height: 44px;
line-height: 44px;
}
.is-active {
background-color: #1890ff;
// 关闭三级菜单二级菜单样式
ul {
border: none;
@@ -630,7 +622,6 @@ li {
}
// 关闭三级菜单二级菜单样式
.is-active.is-opened {
background-color: #191a23;
ul {
border: none;
}
@@ -645,16 +636,10 @@ li {
.el-menu-item:hover span {
color: #fff;
}
.el-sub-menu__title:hover {
background-color: $bg-aside;
}
.el-sub-menu__title:hover i,
.el-sub-menu__title:hover span {
color: #fff;
}
.el-menu--inline {
// border-left: 5px solid #2c3b41;
}
}
.hideside {
.aside {
@@ -720,26 +705,10 @@ li {
}
}
.admin-box {
padding: 14px 20px;
.el-button {
padding: 7px 10px;
}
.el-input__inner {
height: 30px;
line-height: 30px;
}
.el-input__icon {
line-height: 30px;
}
}
.admin-box {
min-height: calc(100vh - 200px);
background-color: $white-bg;
padding: 14px;
margin: 114px 14px 20px;
border-radius: 2px;
padding: 12px 16px;
margin: 100px 2px 20px;
.el-table--border {
border-radius: 4px;
margin-bottom: 14px;
@@ -749,26 +718,28 @@ li {
color: $color-table-thead;
}
th {
padding: 5px 0;
padding: 6px 0;
background: #F7FBFF;
.cell {
min-height: 34px;
line-height: 34px;
color: rgba($color: #000000, $alpha: 0.85);
font-size: 14px;
line-height: 40px;
min-height: 40px;
}
}
td {
padding: 8px 0;
padding: 6px 0;
.cell {
min-height: 40px;
line-height: 40px;
color: rgba($color: #000000, $alpha: 0.65);
}
}
td,
th.is-leaf {
td.is-leaf {
border-bottom: 1px solid #e8e8e8;
}
}
.search-term {
border-left: none;
border-right: none;
padding: 0 5px;
.el-form-item {
margin-bottom: 10px;
th.is-leaf {
border-bottom: none;
}
}
.el-pagination {
@@ -778,18 +749,32 @@ li {
.upload {
padding: 0;
}
.system {
padding: 0;
}
.el-form.el-form--inline {
.el-form-item:last-child {
margin-bottom: 0;
}
}
.edit_container,
.edit {
padding: 0;
}
.el-input {
.el-input__suffix {
margin-top: -3px;
}
&.is-disabled {
.el-input__suffix {
margin-top: 0px;
}
}
}
.el-cascader {
.el-input {
.el-input__suffix {
margin-top: 0px;
}
}
}
.el-input__inner {
border-color: rgba($color: #000000, $alpha: 0.15);
height: 32px;
border-radius: 2px;
}
}
.admin-box:after,
@@ -805,13 +790,6 @@ li {
padding: 0 0 10px 0px;
}
.search-term {
background: $white-bg;
padding: 0 15px;
border-left: 1px solid #ebeef5;
border-right: 1px solid #ebeef5;
}
// table
.has-gutter {
tr {
@@ -833,7 +811,7 @@ li {
.el-table th,
.el-table tr {
background-color: #fafafa;
background-color: #ffffff;
}
.el-pagination {
@@ -886,36 +864,6 @@ li {
}
}
// upload-demo
.upload-demo,
.upload {
.upload-box{
margin-bottom: 12px;
display: flex;
justify-content: flex-end;
.upload-btn{
margin-left: 12px;
}
}
background-color: $white-bg;
padding: 15px;
.el-upload-list__item-status-label {
right: 0;
left: 120px;
}
.el-upload__tip {
margin: 10px 0;
}
}
// system
.system {
padding: 15px;
.el-input__inner {
width: 80%;
}
}
// .el-menu .el-menu--inline {
// background: #2c3b41;
// }
@@ -973,14 +921,6 @@ li {
// border-bottom: 1px solid #e8e8e8;
// }
// }
// .search-term {
// border-left: none;
// border-right: none;
// padding: 0 5px;
// .el-form-item {
// margin-bottom: 10px;
// }
// }
// .el-pagination {
// padding: 20px 0 0 0;
// }
@@ -1025,8 +965,8 @@ li {
background-color: $bg-main;
.menu-total {
cursor: pointer;
font-size: 22px;
color: #838383;
font-size: 24px;
color: #000000;
margin-top: 16px;
}
// background-color: #f0f2f5;
@@ -1049,11 +989,10 @@ li {
border: none;
border-left: 1px solid $border-color;
border-right: 1px solid $border-color;
+.el-tabs__item{
+.el-tabs__item {
border-left: 0px solid $border-color;
}
}
.el-tabs__item.is-active {
background-color: rgba(64, 158, 255, .08);
}
@@ -1122,19 +1061,15 @@ li {
.el-input-number__increase {
position: absolute;
z-index: 1;
top: 6px !important;
top: 3px !important;
width: 42px;
height: 26px;
line-height: 26px;
height: 29px;
line-height: 29px;
text-align: center;
background: #F5F7FA;
color: #606266;
cursor: pointer;
font-size: 13px;
}
.table-button+span {
margin-left: 10px !important;
font-size: 12px;
}
$headerHigh: 52px;
@@ -1158,11 +1093,9 @@ $mainHight: 100vh;
.layout-cont {
.right-box {
height: $height-header;
line-height: $height-header;
text-align: center;
vertical-align: middle;
margin-right: 10px;
display: flex;
justify-content: flex-end;
align-items: center;
img {
vertical-align: middle;
border: 1px solid #ccc;
@@ -1170,6 +1103,7 @@ $mainHight: 100vh;
}
}
.header-cont {
padding: 0 16px;
height: $height-header;
background: #fff;
}
@@ -1178,8 +1112,19 @@ $mainHight: 100vh;
height: $height-header;
line-height: $height-header;
display: inline-block;
background-color: #fff;
padding: 0;
margin-left: 46px;
font-size: 16px;
.el-breadcrumb__item {
.el-breadcrumb__inner {
color: rgba($color: #000000, $alpha: 0.45);
}
}
.el-breadcrumb__item:nth-last-child(1) {
.el-breadcrumb__inner {
color: rgba($color: #000000, $alpha: 0.65);
}
}
}
&.el-main {
overflow: auto;
@@ -1189,7 +1134,7 @@ $mainHight: 100vh;
overflow: visible;
position: relative;
.menu-total {
margin-left:6px;
margin-left: 6px;
cursor: pointer;
float: left;
margin-top: 10px;
@@ -1244,10 +1189,6 @@ $mainHight: 100vh;
}
}
.screenfull {
display: inline-block;
}
.header-avatar {
display: flex;
justify-content: center;
@@ -1255,10 +1196,8 @@ $mainHight: 100vh;
}
.search-component {
display: inline-block;
display: inline-flex;
overflow: hidden;
height: 60px;
width: 120px;
text-align: center;
.el-input__inner {
border: none;
@@ -1269,27 +1208,31 @@ $mainHight: 100vh;
}
.search-icon {
font-size: $icon-size;
margin-right: 14px;
display: inline-block;
vertical-align: middle;
box-sizing: border-box;
color: #606266;
color: rgba($color: #000000, $alpha: 0.65);
}
.dropdown-group {
min-width: 100px;
}
.user-box {
cursor: pointer;
margin-right: 24px;
color: rgba($color: #000000, $alpha: 0.65);
}
}
.transition-box {
overflow: hidden;
width: 120px;
margin-right: 32px;
text-align: center;
}
.screenfull {
overflow: hidden;
width: 40px;
text-align: center;
color: rgba($color: #000000, $alpha: 0.65);
}
.el-dropdown {
@@ -1402,31 +1345,14 @@ $mainHight: 100vh;
}
}
.gva-btn-list{
.gva-btn-list {
margin-bottom: 12px;
display: flex;
justify-content: flex-end;
.el-button+.el-button{
.el-button+.el-button {
margin-left: 12px;
}
}
::-webkit-scrollbar-track-piece {
background-color: #f8f8f8;
}
::-webkit-scrollbar {
width: 9px;
height: 9px;
}
::-webkit-scrollbar-thumb {
background-color: #dddddd;
background-clip: padding-box;
min-height: 28px;
border-radius: 4px;
}
::-webkit-scrollbar-thumb:hover {
background-color: #bbb;
.justify-content-flex-end {
justify-content: flex-end;
}
+66 -78
View File
@@ -1,89 +1,77 @@
@import '@/style/basics.scss';
@media screen and (min-width: 320px)and (max-width: 750px){
.el-header{
padding: 0 $padding-xs;
@media screen and (min-width: 320px)and (max-width: 750px) {
.el-header {
padding: 0 $padding-xs;
}
.layout-cont {
.main-cont {
.breadcrumb {
padding: 0 $padding-xs;
}
}
.layout-cont {
.main-cont{
.breadcrumb{
padding: 0 $padding-xs;
}
.layout-cont {
.right-box {
margin-right: $margin-xs;
}
}
.el-main {
.admin-box {
margin-left: 0;
margin-right: 0;
}
.big.admin-box {
padding: 0;
}
.big {
.bottom {
.chart-player {
height: auto!important;
margin-bottom: 15px;
}
.todoapp {
background-color: #fff;
padding-bottom: 10px;
}
}
}
.layout-cont{
.right-box{
margin-right: $margin-xs;
}
}
.search-component{
width: 30px;
}
.screenfull{
width: 26px;
text-align: center;
}
.el-main{
.admin-box{
margin-left: 0;
margin-right: 0;
}
.big.admin-box{
padding: 0;
}
.big {
.bottom {
.chart-player{
height: auto!important;
margin-bottom: 15px;
}
.todoapp{
background-color: #fff;
padding-bottom: 10px;
}
}
}
}
.card .car-left,
.card .car-right{
}
.card .car-left,
.card .car-right {
width: 100%;
height: 100%;
}
.card {
padding-left: $padding-xs;
padding-right: $padding-xs;
}
.card {
.text {
width: 100%;
height: 100%;
}
.card{
padding-left: $padding-xs;
padding-right: $padding-xs;
}
.card {
.text{
width: 100%;
h4{
white-space: break-spaces;
}
h4 {
white-space: break-spaces;
}
}
.shadow{
margin-left: 4px;
margin-right: 4px;
.grid-content{
margin-bottom: 10px;
padding: 0;
}
}
.shadow {
margin-left: 4px;
margin-right: 4px;
.grid-content {
margin-bottom: 10px;
padding: 0;
}
.el-dialog{
width: 90%;
}
.el-dialog {
width: 90%;
}
.el-transfer {
.el-transfer-panel {
width: 40%;
display: inline-block;
}
.el-transfer{
.el-transfer-panel{
width: 40%;
display: inline-block;
}
.el-transfer__buttons{
padding: 0 5px;
display: inline-block;
}
.el-transfer__buttons {
padding: 0 5px;
display: inline-block;
}
}
}
}
+1 -1
View File
@@ -1,7 +1,7 @@
const modules = import.meta.glob('../view/**/*.vue')
export const asyncRouterHandle = (asyncRouter) => {
asyncRouter.map(item => {
asyncRouter.forEach(item => {
if (item.component) {
item.component = dynamicImport(modules, item.component)
} else {
@@ -1,19 +1,22 @@
<template>
<div class="dashbord-line-box">
<div class="dashbord-line-title">Gva 仓库commit 记录</div>
<div class="dashboard-line-box">
<div class="dashboard-line-title">
访问趋势
</div>
<div
ref="echart"
class="dashbord-line"
class="dashboard-line"
/>
</div>
</template>
<script>
import echarts from 'echarts'
import * as echarts from 'echarts'
import { toRaw } from 'vue'
import 'echarts/theme/macarons'
var dataAxis = []
for (var i = 1; i < 21; i++) {
dataAxis.push(`${i}号`)
for (var i = 1; i < 13; i++) {
dataAxis.push(`${i}月`)
}
var data = [
220,
@@ -28,14 +31,6 @@ var data = [
321,
90,
149,
210,
122,
133,
334,
198,
123,
125,
220,
]
var yMax = 500
var dataShadow = []
@@ -57,7 +52,7 @@ export default {
this.initChart()
})
},
beforeDestroy() {
beforeUnmount() {
if (!this.chart) {
return
}
@@ -70,7 +65,13 @@ export default {
this.setOptions()
},
setOptions() {
this.chart.setOption({
toRaw(this.chart).setOption({
grid: {
left: '40',
right: '20',
top: '40',
bottom: '20',
},
xAxis: {
data: dataAxis,
axisTick: {
@@ -102,21 +103,14 @@ export default {
series: [
{
type: 'bar',
barWidth: '40%',
itemStyle: {
borderRadius: [5, 5, 0, 0],
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: '#83bff6' },
{ offset: 0.5, color: '#188df0' },
{ offset: 1, color: '#188df0' },
]),
color: '#188df0',
},
emphasis: {
itemStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: '#2378f7' },
{ offset: 0.7, color: '#2378f7' },
{ offset: 1, color: '#83bff6' },
]),
color: '#188df0',
},
},
data: data,
@@ -128,16 +122,15 @@ export default {
}
</script>
<style lang="scss" scoped>
.dashbord-line-box {
padding: 20px;
.dashbord-line {
.dashboard-line-box {
.dashboard-line {
background-color: #fff;
height: 360px;
width: calc(100% - 40px);
width: 100%;
}
.dashbord-line-title {
color: rgb(56, 137, 206);
font-size: 18px;
.dashboard-line-title {
font-weight: 600;
margin-bottom: 12px;
}
}
</style>
@@ -0,0 +1,110 @@
<template>
<div class="commit-table">
<div class="commit-table-title">
更新日志
</div>
<div class="log">
<div v-for="(item,key) in dataTimeline" :key="key" class="log-item">
<div class="flex-1 flex key-box"><span class="key" :class="key<3&&'top'">{{ key+1 }}</span></div>
<div class="flex-5 flex message">{{ item.message }}</div>
<div class="flex-3 flex form">{{ item.from }}</div>
</div>
</div>
</div>
</template>
<script>
import { Commits } from '@/api/github'
import { formatTimeToStr } from '@/utils/date.js'
export default {
data() {
return {
loading: true,
dataTimeline: [],
}
},
created() {
this.loadCommits()
},
methods: {
loadCommits() {
Commits(0).then(({ data }) => {
this.loading = false
data.forEach((element, index) => {
if (element.commit.message && index < 10) {
this.dataTimeline.push({
from: formatTimeToStr(element.commit.author.date, 'yyyy-MM-dd'),
title: element.commit.author.name,
showDayAndMonth: true,
message: element.commit.message,
})
}
})
})
},
}
}
</script>
<style lang="scss" scoped>
.commit-table{
background-color: #fff;
height: 400px;
&-title{
font-weight: 600;
margin-bottom: 12px;
}
.log{
&-item{
display: flex;
justify-content: space-between;
margin-top: 14px;
.key-box{
justify-content: center;
}
.key{
&.top{
background: #314659;
color: #FFFFFF;;
}
display: inline-flex;
justify-content: center;
align-items: center;
width: 20px;
height: 20px;
border-radius: 50%;
background: #F0F2F5;
text-align: center;
color:rgba($color: #000000, $alpha: 0.65)
}
.message{
color: rgba(0, 0, 0, 0.65);
}
.form{
color: rgba(0, 0, 0, 0.65);
margin-left: 12px;
}
.flex{
line-height: 20px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.flex-1{
flex:1;
}
.flex-2{
flex:2;
}
.flex-3{
flex:3;
}
.flex-4{
flex:4;
}
.flex-5{
flex:5;
}
}
}
}
</style>
+135 -99
View File
@@ -1,97 +1,105 @@
<template>
<div class="page">
<div class="mycard dashbord1">
<div class="dashbord1-left">
<div class="dashbord1-left-title">早安,管理员,请开始一天的工作吧</div>
<div class="dashbord1-left-dot">今日晴,0℃ - 10℃,天气寒冷,注意添加衣物。</div>
<div class="dashbord1-left-rows">
<div class="gva-card-box">
<div class="gva-card gva-top-card">
<div class="gva-top-card-left">
<div class="gva-top-card-left-title">早安,管理员,请开始一天的工作吧</div>
<div class="gva-top-card-left-dot">今日晴,0℃ - 10℃,天气寒冷,注意添加衣物。</div>
<div class="gva-top-card-left-rows">
<el-row>
<el-col :span="8" :xs="24" :sm="8">
<div class="flex-center">
<i class="el-icon-sort icon" />今日流量 (1231231)
</div>
</el-col>
<el-col :span="8" :xs="24" :sm="8">
<div class="flex-center">
<i class="el-icon-s-custom icon" />总用户数 (24001)
</div>
</el-col>
<el-col :span="8" :xs="24" :sm="8">
<div class="flex-center">
<i class="el-icon-s-comment icon" />好评率 (99%)
</div>
</el-col>
</el-row>
</div>
<div>
<div class="gva-top-card-left-item">
使用教学:
<a
style="color:#409EFF"
target="view_window"
href="https://www.bilibili.com/video/BV1Rg411u7xH/"
>https://www.bilibili.com/video/BV1Rg411u7xH</a>
</div>
<div class="gva-top-card-left-item">
插件仓库:
<a
style="color:#409EFF"
target="view_window"
href="https://github.com/flipped-aurora/gva-plugins"
>https://github.com/flipped-aurora/gva-plugins</a>
</div>
</div>
</div>
<img src="@/assets/dashboard.png" class="gva-top-card-right" alt>
</div>
</div>
<div class="gva-card-box">
<el-card class="gva-card quick-entrance">
<template #header>
<div class="card-header">
<span>快捷入口</span>
</div>
</template>
<el-row :gutter="20">
<el-col
v-for="(card, key) in toolCards"
:key="key"
:span="4"
:xs="8"
class="quick-entrance-items"
@click="toTarget(card.name)"
>
<div class="quick-entrance-item">
<div class="quick-entrance-item-icon" :style="{ backgroundColor: card.bg }">
<i :class="card.icon" :style="{ color: card.color }" />
</div>
<p>{{ card.label }}</p>
</div>
</el-col>
</el-row>
</el-card>
<!-- <div class="quick-entrance-title"></div> -->
</div>
<div class="gva-card-box">
<div class="gva-card">
<div class="card-header">
<span>数据统计</span>
</div>
<div class="echart-box">
<el-row :gutter="20">
<el-col :span="8" :xs="24" :sm="8">
<div class="flex-center">
<i class="el-icon-sort icon" />今日流量 (1231231)
</div>
<el-col :xs="24" :sm="18">
<echarts-line />
</el-col>
<el-col :span="8" :xs="24" :sm="8">
<div class="flex-center">
<i class="el-icon-s-custom icon" />总用户数 (24001)
</div>
</el-col>
<el-col :span="8" :xs="24" :sm="8">
<div class="flex-center">
<i class="el-icon-s-comment icon" />好评率 (99%)
</div>
<el-col :xs="24" :sm="6">
<dashboard-table />
</el-col>
</el-row>
</div>
</div>
<img src="@/assets/dashbord.png" class="dashbord1-right" alt>
</div>
<div class="mycard dashbord2">
<div>
<div class="dashbord2-item">
使用教学:
<a
style="color:#409EFF"
target="view_window"
href="https://www.bilibili.com/video/BV1Rg411u7xH/"
>https://www.bilibili.com/video/BV1Rg411u7xH</a>
</div>
<div class="dashbord2-item">
插件仓库:
<a
style="color:#409EFF"
target="view_window"
href="https://github.com/flipped-aurora/gva-plugins"
>https://github.com/flipped-aurora/gva-plugins</a>
</div>
</div>
</div>
<el-card class="mycard quick-entrance">
<template #header>
<div class="card-header">
<span>快捷入口</span>
</div>
</template>
<el-row :gutter="20">
<el-col
v-for="(card, key) in toolCards"
:key="key"
:span="4"
:xs="8"
class="quick-entrance-items"
@click="toTarget(card.name)"
>
<div class="quick-entrance-item">
<div class="quick-entrance-item-icon" :style="{ backgroundColor: card.bg }">
<i :class="card.icon" :style="{ color: card.color }" />
</div>
<p>{{ card.label }}</p>
</div>
</el-col>
</el-row>
</el-card>
<!-- <div class="quick-entrance-title"></div> -->
<div class="mycard">
<el-row :gutter="0">
<el-col :xs="24" :sm="16">
<echarts-line />
</el-col>
<el-col :xs="24" :sm="8">
<dashbord-table />
</el-col>
</el-row>
</div>
</div>
</template>
<script>
import echartsLine from '@/components/dashbordCharts/echartsLine.vue'
import dashbordTable from '@/components/dashbordTable/dashbordTable.vue'
import echartsLine from '@/view/dashboard/dashboardCharts/echartsLine.vue'
import dashboardTable from '@/view/dashboard/dashboardTable/dashboardTable.vue'
export default {
name: 'Dashboard',
components: {
echartsLine,
dashbordTable
dashboardTable
},
data() {
return {
@@ -157,36 +165,52 @@ export default {
.page {
background: #f0f2f5;
padding: 0;
.mycard {
.gva-card-box{
padding: 12px 16px;
&+.gva-card-box{
padding-top: 0px;
}
}
.gva-card {
box-sizing: border-box;
background-color: #fff;
border-radius: 10px;
border-radius: 2px;
height: auto;
padding: 10px 30px;
padding: 26px 30px;
overflow: hidden;
margin-bottom: 15px;
box-shadow: 0 0 7px 1px rgba(0, 0, 0, 0.03);
}
.dashbord1 {
height: 120px;
.gva-top-card {
height: 260px;
@include flex-center;
justify-content: space-between;
color: #777;
&-left {
height: 100%;
display: flex;
flex-direction: column;
&-title {
margin-top: 15px;
font-size: 22px;
color: #000;
color: #343844;
}
&-dot {
font-size: 14px;
margin-top: 10px;
color: #6B7687;
margin-top: 24px;
}
&-rows {
// margin-top: 15px;
margin-top: 18px;
color: #6B7687;
width: 600px;
align-items: center;
}
&-item{
+.gva-top-card-left-item{
margin-top: 24px;
}
margin-top: 14px;
}
}
&-right {
height: 600px;
@@ -194,14 +218,14 @@ export default {
margin-top: 28px;
}
}
.dashbord2 {
@include flex-center;
justify-content: flex-start;
height: 60px;
&-item {
line-height: 25px;
::v-deep(.el-card__header){
padding:0;
border-bottom: none;
}
.card-header{
padding-bottom: 20px;
border-bottom: 1px solid #e8e8e8;
}
}
.quick-entrance-title {
height: 30px;
font-size: 22px;
@@ -215,6 +239,15 @@ export default {
text-align: center;
color: #333;
.quick-entrance-item {
padding: 16px 28px;
margin-top: -16px;
margin-bottom: -16px;
border-radius: 4px;
transition: all 0.2s;
&:hover{
box-shadow: 0px 0px 7px 0px rgba(217, 217, 217, 0.55);
}
cursor: pointer;
height: auto;
text-align: center;
// align-items: center;
@@ -234,6 +267,9 @@ export default {
}
}
}
.echart-box{
padding: 14px;
}
}
.icon {
font-size: 20px;
@@ -249,9 +285,9 @@ export default {
//小屏幕不显示右侧,将登陆框居中
@media (max-width: 750px) {
.mycard {
.gva-card {
padding: 20px 10px !important;
.dashbord1 {
.gva-top-card {
height: auto;
&-left {
&-title {
@@ -266,7 +302,7 @@ export default {
display: none;
}
}
.dashbord2 {
.gva-middle-card {
&-item {
line-height: 20px;
}
+26 -23
View File
@@ -1,29 +1,32 @@
<template>
<div class="hello">
<el-divider content-position="left">大文件上传</el-divider>
<form id="fromCont" method="post">
<div class="fileUpload" @click="inputChange">
选择文件
<input v-show="false" id="file" ref="Input" multiple="multiple" type="file" @change="choseFile">
</div>
</form>
<el-button :disabled="limitFileSize" type="primary" size="mini" class="uploadBtn" @click="getFile">上传文件</el-button>
<div class="el-upload__tip">请上传不超过5MB的文件</div>
<div class="list">
<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" />
<div class="break-point">
<div class="gva-table-box">
<el-divider content-position="left">大文件上传</el-divider>
<form id="fromCont" method="post">
<div class="fileUpload" @click="inputChange">
选择文件
<input v-show="false" id="file" ref="Input" multiple="multiple" type="file" @change="choseFile">
</div>
</transition>
</div>
<!-- <span
</form>
<el-button :disabled="limitFileSize" type="primary" size="mini" class="uploadBtn" @click="getFile">上传文件</el-button>
<div class="el-upload__tip">请上传不超过5MB的文件</div>
<div class="list">
<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" />
</div>
</transition>
</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 class="tips">此版本为先行体验功能测试版,样式美化和性能优化正在进行中,上传切片文件和合成的完整文件分别再QMPlusserver目录的breakpointDir文件夹和fileDir文件夹</div>
</div>
</div>
</template>
<script>
@@ -35,7 +38,7 @@ import {
removeChunk
} from '@/api/breakpoint'
export default {
name: 'HelloWorld',
name: 'BreakPoint',
data() {
return {
file: null,
@@ -124,7 +127,7 @@ export default {
},
sliceFile() {
this.waitUpLoad &&
this.waitUpLoad.map(item => {
this.waitUpLoad.forEach(item => {
// 需要上传的切片
item.formData.append('chunkTotal', this.formDataList.length) // 切片总数携带给后台 总有用的
const fileR = new FileReader() // 功能同上
+50 -50
View File
@@ -1,55 +1,54 @@
<template>
<div>
<div class="search-term">
<warning-bar title="在资源权限中将此角色的资源权限清空 或者不包含创建者的角色 即可屏蔽此客户资源的显示" />
<div class="gva-table-box">
<div class="gva-btn-list">
<el-button size="mini" type="primary" icon="el-icon-plus" @click="openDialog">新增</el-button>
</div>
<el-table
ref="multipleTable"
:data="tableData"
style="width: 100%"
tooltip-effect="dark"
row-key="ID"
>
<el-table-column type="selection" width="55" />
<el-table-column align="left" label="接入日期" width="180">
<template #default="scope">
<span>{{ formatDate(scope.row.CreatedAt) }}</span>
</template>
</el-table-column>
<el-table-column align="left" label="姓名" prop="customerName" width="120" />
<el-table-column align="left" label="电话" prop="customerPhoneData" width="120" />
<el-table-column align="left" label="接入人ID" prop="sysUserId" width="120" />
<el-table-column align="left" label="按钮组" min-width="160">
<template #default="scope">
<el-button size="small" type="text" icon="el-icon-edit" @click="updateCustomer(scope.row)">变更</el-button>
<el-popover :visible="scope.row.visible" placement="top" width="160">
<p>确定要删除吗?</p>
<div style="text-align: right; margin-top: 8px;">
<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>
<template #reference>
<el-button type="text" icon="el-icon-delete" size="mini">删除</el-button>
</template>
</el-popover>
</template>
</el-table-column>
</el-table>
<div class="gva-pagination">
<el-pagination
:current-page="page"
:page-size="pageSize"
:page-sizes="[10, 30, 50, 100]"
:total="total"
layout="total, sizes, prev, pager, next, jumper"
@current-change="handleCurrentChange"
@size-change="handleSizeChange"
/>
</div>
</div>
<el-table
ref="multipleTable"
:data="tableData"
border
stripe
style="width: 100%"
tooltip-effect="dark"
>
<el-table-column type="selection" width="55" />
<el-table-column label="接入日期" width="180">
<template #default="scope">
<span>{{ formatDate(scope.row.CreatedAt) }}</span>
</template>
</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 #default="scope">
<el-button size="small" type="text" @click="updateCustomer(scope.row)">变更</el-button>
<el-popover v-model:visible="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>
<template #reference>
<el-button type="danger" icon="el-icon-delete" size="mini">删除</el-button>
</template>
</el-popover>
</template>
</el-table-column>
</el-table>
<el-pagination
:current-page="page"
:page-size="pageSize"
: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"
/>
<el-dialog v-model="dialogFormVisible" :before-close="closeDialog" title="客户">
<el-form :inline="true" :model="form" label-width="80px">
<el-form-item label="客户名">
@@ -61,12 +60,11 @@
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button @click="closeDialog">取 消</el-button>
<el-button type="primary" @click="enterDialog">确 定</el-button>
<el-button size="small" @click="closeDialog">取 消</el-button>
<el-button size="small" type="primary" @click="enterDialog">确 定</el-button>
</div>
</template>
</el-dialog>
<div class="tips">在资源权限中将此角色的资源权限清空 或者不包含创建者的角色 即可屏蔽此客户资源的显示</div>
</div>
</template>
@@ -79,9 +77,11 @@ import {
getExaCustomerList
} from '@/api/customer'
import infoList from '@/mixins/infoList'
import warningBar from '@/components/warningBar/warningBar.vue'
export default {
name: 'Customer',
components: { warningBar },
mixins: [infoList],
data() {
return {
@@ -119,7 +119,7 @@ export default {
if (res.code === 0) {
this.$message({
type: 'success',
message: ''
message: '删除成功'
})
if (this.tableData.length === 1 && this.page > 1) {
this.page--
+33 -29
View File
@@ -1,32 +1,35 @@
<template>
<div class="upload">
<div class="btn-list">
<el-upload
class="excel-btn"
:action="`${path}/excel/importExcel`"
:headers="{'x-token':token}"
:on-success="loadExcel"
:show-file-list="false"
>
<el-button size="mini" type="primary" icon="el-icon-upload2">导入</el-button>
</el-upload>
<el-button class="excel-btn" size="mini" type="primary" icon="el-icon-download" @click="handleExcelExport('ExcelExport.xlsx')">导出</el-button>
<el-button class="excel-btn" size="mini" type="success" icon="el-icon-download" @click="downloadExcelTemplate()">下载模板</el-button>
</div>
<el-table :data="tableData" border row-key="ID" stripe>
<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">
<div class="gva-table-box">
<template #default="scope">
<span>{{ scope.row.hidden?"隐藏":"显示" }}</span>
</template>
</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 class="gva-btn-list">
<el-upload
class="excel-btn"
:action="`${path}/excel/importExcel`"
:headers="{'x-token':token}"
:on-success="loadExcel"
:show-file-list="false"
>
<el-button size="mini" type="primary" icon="el-icon-upload2">导入</el-button>
</el-upload>
<el-button class="excel-btn" size="mini" type="primary" icon="el-icon-download" @click="handleExcelExport('ExcelExport.xlsx')">导出</el-button>
<el-button class="excel-btn" size="mini" type="success" icon="el-icon-download" @click="downloadExcelTemplate()">下载模板</el-button>
</div>
<el-table :data="tableData" row-key="ID">
<el-table-column align="left" label="ID" min-width="100" prop="ID" />
<el-table-column align="left" show-overflow-tooltip label="路由Name" min-width="160" prop="name" />
<el-table-column align="left" show-overflow-tooltip label="路由Path" min-width="160" prop="path" />
<el-table-column align="left" label="是否隐藏" min-width="100" prop="hidden">
<template #default="scope">
<span>{{ scope.row.hidden?"隐藏":"显示" }}</span>
</template>
</el-table-column>
<el-table-column align="left" label="父节点" min-width="90" prop="parentId" />
<el-table-column align="left" label="排序" min-width="70" prop="sort" />
<el-table-column align="left" label="文件路径" min-width="360" prop="component" />
</el-table>
</div>
</div>
</template>
@@ -75,8 +78,9 @@ export default {
display: flex;
margin-bottom: 12px;
justify-content: flex-end;
.excel-btn+.excel-btn{
margin-left: 12px;
}
}
.excel-btn+.excel-btn{
margin-left: 10px;
}
</style>
+2 -7
View File
@@ -1,17 +1,12 @@
<template>
<div>
<router-view v-if="$route.meta.keepAlive" v-slot="{ Component }">
<router-view v-slot="{ Component }">
<transition mode="out-in" name="el-fade-in-linear">
<keep-alive>
<keep-alive :include="$store.getters['router/keepAliveRouters']">
<component :is="Component" />
</keep-alive>
</transition>
</router-view>
<router-view v-if="!$route.meta.keepAlive" v-slot="{ Component }">
<transition mode="out-in" name="el-fade-in-linear">
<component :is="Component" />
</transition>
</router-view>
</div>
</template>
+28 -21
View File
@@ -1,7 +1,7 @@
<template>
<div v-loading.fullscreen.lock="fullscreenLoading">
<div class="upload">
<div class="upload-box">
<div class="gva-table-box">
<div class="gva-btn-list">
<el-upload
:action="`${path}/fileUploadAndDownload/upload`"
:before-upload="checkFile"
@@ -22,20 +22,20 @@
/>
</div>
<el-table :data="tableData" border stripe>
<el-table-column label="预览" width="100">
<el-table :data="tableData">
<el-table-column align="left" label="预览" width="100">
<template #default="scope">
<CustomPic pic-type="file" :pic-src="scope.row.url" />
</template>
</el-table-column>
<el-table-column label="日期" prop="UpdatedAt" width="180">
<el-table-column align="left" label="日期" prop="UpdatedAt" width="180">
<template #default="scope">
<div>{{ formatDate(scope.row.UpdatedAt) }}</div>
</template>
</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">
<el-table-column align="left" label="文件名" prop="name" width="180" />
<el-table-column align="left" label="链接" prop="url" min-width="300" />
<el-table-column align="left" label="标签" prop="tag" width="100">
<template #default="scope">
<el-tag
:type="scope.row.tag === 'jpg' ? 'primary' : 'success'"
@@ -43,23 +43,25 @@
>{{ scope.row.tag }}</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" width="160">
<el-table-column align="left" label="操作" width="160">
<template #default="scope">
<el-button size="small" type="text" @click="downloadFile(scope.row)">下载</el-button>
<el-button size="small" type="text" @click="deleteFile(scope.row)">删除</el-button>
<el-button size="small" icon="el-icon-download" type="text" @click="downloadFile(scope.row)">下载</el-button>
<el-button size="small" icon="el-icon-delete" type="text" @click="deleteFile(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<el-pagination
:current-page="page"
:page-size="pageSize"
: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"
/>
<div class="gva-pagination">
<el-pagination
:current-page="page"
:page-size="pageSize"
: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"
/>
</div>
</div>
</div>
</template>
@@ -170,3 +172,8 @@ export default {
}
}
</script>
<style scoped>
.upload-btn+.upload-btn {
margin-left: 12px;
}
</style>
+38 -11
View File
@@ -5,7 +5,7 @@
<div>
<div class="hello_title">GIN-VUE-ADMIN</div>
<p class="in-two a-fadeinT">初始化须知</p>
<p class="init_p">1.您需有用一定的VUE和golang基础</p>
<p class="init_p">1.您需有用一定的VUE和GOLANG基础</p>
<p class="init_p">2.请您确认是否已经阅读过官方文档</p>
<p class="init_p">3.请您确认是否了解后续的配置流程</p>
<p class="init_p">注:开发组不为文档中书写过的内容提供无偿服务</p>
@@ -22,8 +22,9 @@
<div v-if="hello > 0 " :class="[(hello > 0 && !out)? 'slide-in-left' : '' , out ? 'slide-out-right' : '']" class=" form">
<el-form ref="form" :model="form" label-width="100px">
<el-form-item label="数据库类型">
<el-select v-model="form.sqlType" disabled placeholder="请选择">
<el-option key="mysql" label="mysql(目前只支持mysql)" value="mysql" />
<el-select v-model="form.dbType" placeholder="请选择" @change="changeDB">
<el-option key="mysql" label="mysql" value="mysql" />
<el-option key="pgsql" label="pgsql(测试版)" value="pgsql" />
</el-select>
</el-form-item>
<el-form-item label="host">
@@ -63,7 +64,7 @@ export default {
hello: 0,
out: false,
form: {
sqlType: 'mysql',
dbType: 'mysql',
host: '127.0.0.1',
port: '3306',
userName: 'root',
@@ -72,14 +73,40 @@ export default {
}
}
},
created() {
// setInterval(() => {
// if (this.hello < 3) {
// this.hello = this.hello + 1
// }
// }, 2000)
},
methods: {
changeDB(val) {
switch (val) {
case 'mysql':
this.form = {
dbType: 'mysql',
host: '127.0.0.1',
port: '3306',
userName: 'root',
password: '',
dbName: 'gva'
}
break
case 'pgsql':
this.form = {
dbType: 'pgsql',
host: '127.0.0.1',
port: '5432',
userName: 'postgres',
password: '',
dbName: 'gva'
}
break
default:
this.form = {
dbType: 'mysql',
host: '127.0.0.1',
port: '3306',
userName: 'root',
password: '',
dbName: 'gva'
}
}
},
showNext() {
this.hello = this.hello + 1
},
-106
View File
@@ -1,106 +0,0 @@
<template>
<div class="init">
<p class="in-one a-fadeinT">欢迎使用GIN-VUE-ADMIN</p>
<p class="in-two a-fadeinT">您需要初始化您的数据库并且填充初始数据</p>
<div class="form-card in-three a-fadeinB">
<el-form ref="form" :model="form" label-width="100px">
<el-form-item label="数据库类型">
<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-form-item>
<el-form-item label="port">
<el-input v-model="form.port" placeholder="请输入数据库端口" />
</el-form-item>
<el-form-item label="userName">
<el-input v-model="form.userName" placeholder="请输入数据库用户名" />
</el-form-item>
<el-form-item label="password">
<el-input
v-model="form.password"
placeholder="请输入数据库密码(没有则为空)"
/>
</el-form-item>
<el-form-item label="dbName">
<el-input v-model="form.dbName" placeholder="请输入数据库名称" />
</el-form-item>
<el-form-item>
<div style="text-align: right">
<el-button type="primary" @click="onSubmit">立即初始化</el-button>
</div>
</el-form-item>
</el-form>
</div>
</div>
</template>
<script>
import { initDB } from '@/api/initdb'
export default {
name: 'Init',
data() {
return {
form: {
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)'
})
try {
const res = await initDB(this.form)
if (res.code === 0) {
this.$message({
type: 'success',
message: res.msg
})
this.$router.push({ name: 'Login' })
}
loading.close()
} catch (err) {
loading.close()
}
}
}
}
</script>
<style lang="scss">
.init {
height: 100vh;
flex-direction: column;
display: flex;
align-items: center;
background: #fff;
}
.in-one {
font-size: 26px;
line-height: 98px;
}
.in-two {
font-size: 22px;
}
.form-card {
margin-top: 60px;
box-shadow: 0px 0px 5px 0px rgba(5, 12, 66, 0.15);
width: 60vw;
height: auto;
background: #fff;
padding: 20px;
border-radius: 6px;
}
</style>
@@ -120,7 +120,7 @@ export default {
}
this.setTab(this.$route)
},
beforeDestroy() {
beforeUnmount() {
emitter.off('collapse')
emitter.off('mobile')
},
+3 -3
View File
@@ -58,7 +58,7 @@ export default {
this.isCollapse = item
})
},
beforeDestroy() {
beforeUnmount() {
emitter.off('collapse')
},
methods: {
@@ -66,8 +66,8 @@ export default {
selectMenuItem(index, _, ele) {
const query = {}
const params = {}
ele.route.parameters &&
ele.route.parameters.map(item => {
ele?.route?.parameters &&
ele.route.parameters.forEach(item => {
if (item.type === 'query') {
query[item.key] = item.value
} else {
@@ -15,6 +15,8 @@
</template>
<script>
// 此文件内容为版权信息,如需改动,请联系wx:shouzi_1994购买授权 未授权状态只需保留此代码 不影响任何正常使用
// 项目为apatch协议 请遵守版权协议内容
export default {
name: 'BottomInfo'
}
+9 -13
View File
@@ -21,14 +21,14 @@
<el-col>
<el-header class="header-cont">
<el-row class="pd-0">
<el-col :xs="2" :lg="1" :md="1" :sm="1" :xl="1">
<el-col :xs="2" :lg="1" :md="1" :sm="1" :xl="1" style="z-index:100">
<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-col :xs="10" :lg="14" :md="14" :sm="9" :xl="14" :pull="1">
<el-breadcrumb class="breadcrumb">
<el-breadcrumb-item
v-for="item in matched.slice(1,matched.length)"
:key="item.path"
@@ -36,7 +36,7 @@
</el-breadcrumb>
</el-col>
<el-col :xs="12" :lg="9" :md="9" :sm="14" :xl="9">
<div class="fl-right right-box">
<div class="right-box">
<Search />
<Screenfull class="screenfull" :style="{cursor:'pointer'}" />
<el-dropdown>
@@ -78,19 +78,13 @@
<HistoryComponent ref="layoutHistoryComponent" />
</div>
</transition>
<router-view v-if="$route.meta.keepAlive && reloadFlag" v-slot="{ Component }" v-loading="loadingFlag" element-loading-text="正在加载中" class="admin-box">
<router-view v-if="reloadFlag" v-slot="{ Component }" v-loading="loadingFlag" element-loading-text="正在加载中" class="admin-box">
<transition mode="out-in" name="el-fade-in-linear">
<keep-alive>
<keep-alive :include="$store.getters['router/keepAliveRouters']">
<component :is="Component" />
</keep-alive>
</transition>
</router-view>
<router-view v-if="!$route.meta.keepAlive && reloadFlag" v-slot="{ Component }" v-loading="loadingFlag" element-loading-text="正在加载中" class="admin-box">
<transition mode="out-in" name="el-fade-in-linear">
<component :is="Component" />
</transition>
</router-view>
<BottomInfo />
<setting />
</el-main>
@@ -160,7 +154,7 @@ export default {
return this.$route.matched
}
},
mounted() {
created() {
const screenWidth = document.body.clientWidth
if (screenWidth < 1000) {
this.isMobile = true
@@ -175,6 +169,8 @@ export default {
this.isSider = true
this.isCollapse = false
}
},
mounted() {
emitter.emit('collapse', this.isCollapse)
emitter.emit('mobile', this.isMobile)
emitter.on('reload', this.reload)
+6 -35
View File
@@ -1,38 +1,11 @@
<template>
<div @click="click">
<!-- <svg
t="1508738709248"
class="screenfull-svg"
viewBox="0 0 1024 1024"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
p-id="2069"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="32"
height="32"
v-if="isShow"
>
<path
d="M333.493443 428.647617 428.322206 333.832158 262.572184 168.045297 366.707916 64.444754 64.09683 64.444754 63.853283 366.570793 167.283957 262.460644Z"
p-id="2070"/>
<path
d="M854.845439 760.133334 688.61037 593.95864 593.805144 688.764889 759.554142 854.56096 655.44604 958.161503 958.055079 958.161503 958.274066 656.035464Z"
p-id="2071"/>
<path
d="M688.535669 428.550403 854.31025 262.801405 957.935352 366.921787 957.935352 64.34754 655.809313 64.081481 759.919463 167.535691 593.70793 333.731874Z"
p-id="2072"/>
<path
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
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" />
@@ -63,8 +36,6 @@
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
@@ -119,7 +90,7 @@ export default {
screenfull.on('change', this.changeFullShow)
}
},
destroyed() {
unmounted() {
screenfull.off('change', this.changeFullShow)
},
methods: {
@@ -135,13 +106,13 @@ export default {
}
</script>
<style scoped>
<style scoped lang="scss">
.screenfull-svg {
width: 17px;
height: 17px;
width: 16px;
height: 16px;
cursor: pointer;
fill: #606266;
vertical-align: middle;
margin-right: 15px;
margin-right: 32px;
fill: rgba(0, 0, 0, 0.45);
}
</style>
+13 -8
View File
@@ -20,13 +20,16 @@
</div>
</transition>
<div
:style="{display:'inline-block',float:'right',width:'31px',textAlign:'left',fontSize:'16px',paddingTop:'2px'}"
v-if="btnShow"
class="user-box"
>
<i :style="{cursor:'pointer',paddingLeft:'1px'}" class="el-icon-refresh reload" :class="[reload ? 'reloading' : '']" @click="handleReload" />
<i class="el-icon-refresh reload" :class="[reload ? 'reloading' : '']" @click="handleReload" />
</div>
<div :style="{display:'inline-block',float:'right'}" class="user-box">
<i :style="{cursor:'pointer'}" class="el-icon-search search-icon" @click="showSearch()" />
<div
v-if="btnShow"
class="user-box"
>
<i class="el-icon-search search-icon" @click="showSearch()" />
</div>
</div>
</template>
@@ -41,6 +44,7 @@ export default {
return {
value: '',
show: false,
btnShow: true,
reload: false
}
},
@@ -55,8 +59,12 @@ export default {
},
hiddenSearch() {
this.show = false
setTimeout(() => {
this.btnShow = true
}, 500)
},
showSearch() {
this.btnShow = false
this.show = true
this.$nextTick(() => {
this.$refs['search-input'].focus()
@@ -74,10 +82,7 @@ export default {
</script>
<style scoped lang="scss">
.reload{
font-size: 17px;
&:hover{
transform: scale(1.02)
}
font-size: 18px;
}
.reloading{
+25 -37
View File
@@ -9,30 +9,25 @@
>
<div class="setting_body">
<div class="setting_card">
<div class="setting_title">侧边栏主题 (注:自定义请先配置背景色)</div>
<div class="setting_content">
<div class="theme-box">
<div class="item" @click="changeMode('light')">
<i v-if="mode === 'light'" class="el-icon-check check" />
<img src="https://gw.alipayobjects.com/zos/antfincdn/NQ%24zoisaD2/jpRkZQMyYRryryPNtyIC.svg">
<div class="item-top">
<i v-if="mode === 'light'" class="el-icon-check check" />
<img src="https://gw.alipayobjects.com/zos/antfincdn/NQ%24zoisaD2/jpRkZQMyYRryryPNtyIC.svg">
</div>
<p>
简约白
</p>
</div>
<div class="item" @click="changeMode('dark')">
<i v-if="mode === 'dark'" class="el-icon-check check" />
<img src="https://gw.alipayobjects.com/zos/antfincdn/XwFOFbLkSM/LCkqqYNmvBEbokSDscrm.svg">
</div>
</div>
<div class="color-box">
<div>
<div class="setting_title">自定义背景色</div>
<el-color-picker :value="sideMode" @change="changeMode" />
</div>
<div>
<div class="setting_title">自定义基础色</div>
<el-color-picker :value="baseColor" @change="changeBaseColor" />
</div>
<div>
<div class="setting_title">活跃色</div>
<el-color-picker :value="activeColor" @change="activeColorChange" />
<div class="item-top">
<i v-if="mode === 'dark'" class="el-icon-check check" />
<img src="https://gw.alipayobjects.com/zos/antfincdn/XwFOFbLkSM/LCkqqYNmvBEbokSDscrm.svg">
</div>
<p>
商务黑
</p>
</div>
</div>
</div>
@@ -53,7 +48,7 @@ export default {
}
},
computed: {
...mapGetters('user', ['sideMode', 'baseColor', 'activeColor', 'mode'])
...mapGetters('user', ['mode'])
},
methods: {
handleClose() {
@@ -69,20 +64,6 @@ export default {
}
this.$store.dispatch('user/changeSideMode', e)
},
changeBaseColor(e) {
if (e === null) {
this.$store.dispatch('user/changeBaseColor', '#fff')
return
}
this.$store.dispatch('user/changeBaseColor', e)
},
activeColorChange(e) {
if (e === null) {
this.$store.dispatch('user/changeActiveColor', '#1890ff')
return
}
this.$store.dispatch('user/changeActiveColor', e)
}
}
}
</script>
@@ -126,17 +107,24 @@ export default {
}
}
.item{
position: relative;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
margin-right: 20px;
.item-top{
position: relative;
}
.check{
position: absolute;
font-size: 20px;
color: #00afff;
right:10px;
bottom: 10px;
}
img{
margin-right: 20px;
p{
text-align: center;
font-size: 12px;
}
}
}
+39 -6
View File
@@ -10,7 +10,12 @@
重新上传</span>
</div>
<div class="user-personality">
<p class="nickname">{{ userInfo.nickName }}</p>
<p v-if="!editFlag" class="nickName">{{ userInfo.nickName }} <i class="el-icon-edit pointer" style="color:#66b1ff" @click="openEidt" /></p>
<p v-if="editFlag" class="nickName">
<el-input v-model="nickName" />
<i class="el-icon-check pointer" style="color:#67c23a" @click="enterEdit" />
<i class="el-icon-close pointer" style="color:#f23c3c" @click="closeEdit" />
</p>
<p class="person-info">这个家伙很懒,什么都没有留下</p>
</div>
<div class="user-information">
@@ -26,9 +31,9 @@
<li>
<i class="el-icon-video-camera-solid" />中国·北京市·朝阳区
</li>
<el-tooltip class="item" effect="light" content="goLang/JavaScript/Vue/Gorm" placement="top">
<el-tooltip class="item" effect="light" content="GoLang/JavaScript/Vue/Gorm" placement="top">
<li>
<i class="el-icon-medal-1" />goLang/JavaScript/Vue/Gorm
<i class="el-icon-medal-1" />GoLang/JavaScript/Vue/Gorm
</li>
</el-tooltip>
@@ -93,8 +98,8 @@
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button @click="showPassword=false">取 消</el-button>
<el-button type="primary" @click="savePassword">确 定</el-button>
<el-button size="small" @click="showPassword=false">取 消</el-button>
<el-button size="small" type="primary" @click="savePassword">确 定</el-button>
</div>
</template>
</el-dialog>
@@ -118,6 +123,8 @@ export default {
activeName: 'second',
showPassword: false,
pwdModify: {},
nickName: '',
editFlag: false,
rules: {
password: [
{ required: true, message: '请输入密码', trigger: 'blur' },
@@ -188,6 +195,26 @@ export default {
})
}
},
openEidt() {
this.nickName = this.userInfo.nickName
this.editFlag = true
},
closeEdit() {
this.nickName = ''
this.editFlag = false
},
async enterEdit() {
const res = await setUserInfo({ nickName: this.nickName, ID: this.userInfo.ID })
if (res.code === 0) {
this.ResetUserInfo({ nickName: this.nickName })
this.$message({
type: 'success',
message: '设置成功'
})
}
this.nickName = ''
this.editFlag = false
},
handleClick(tab, event) {
console.log(tab, event)
}
@@ -236,7 +263,10 @@ export default {
p {
font-size: 16px;
}
.nickname {
.nickName {
display: flex;
justify-content: center;
align-items: center;
font-size: 26px;
}
.person-info{
@@ -314,4 +344,7 @@ export default {
color:transparent;
}
}
.pointer{
cursor: pointer;
}
</style>
+2 -7
View File
@@ -1,18 +1,13 @@
<!-- 此路由可作为父类路由通用路由页面使用 如需自定义父类路由页面 请参考 @/view/superAdmin/index.vue -->
<template>
<div>
<router-view v-if="$route.meta.keepAlive" v-slot="{ Component }">
<router-view v-slot="{ Component }">
<transition mode="out-in" name="el-fade-in-linear">
<keep-alive>
<keep-alive :include="$store.getters['router/keepAliveRouters']">
<component :is="Component" />
</keep-alive>
</transition>
</router-view>
<router-view v-if="!$route.meta.keepAlive" v-slot="{ Component }">
<transition mode="out-in" name="el-fade-in-linear">
<component :is="Component" />
</transition>
</router-view>
</div>
</template>
+69 -65
View File
@@ -1,14 +1,14 @@
<template>
<div>
<div class="search-term">
<el-form :inline="true" :model="searchInfo">
<div class="gva-search-box">
<el-form ref="searchForm" :inline="true" :model="searchInfo">
<el-form-item label="路径">
<el-input v-model="searchInfo.path" placeholder="路径" />
</el-form-item>
<el-form-item label="描述">
<el-input v-model="searchInfo.description" placeholder="描述" />
</el-form-item>
<el-form-item label="api组">
<el-form-item label="API组">
<el-input v-model="searchInfo.apiGroup" placeholder="api组" />
</el-form-item>
<el-form-item label="请求">
@@ -21,75 +21,82 @@
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button size="mini" type="primary" icon="el-icon-search" @click="onSubmit">查询</el-button>
<el-button size="mini" icon="el-icon-refresh" @click="onReset">重置</el-button>
</el-form-item>
</el-form>
</div>
<div class="gva-table-box">
<div class="gva-btn-list">
<el-button size="mini" type="primary" icon="el-icon-search" @click="onSubmit">查询</el-button>
<el-button size="mini" type="primary" icon="el-icon-plus" @click="openDialog('addApi')">新增</el-button>
<el-popover v-model:visible="deleteVisible" placement="top" width="160">
<p>确定要删除吗?</p>
<div style="text-align: right; margin: 0">
<div style="text-align: right; margin-top: 8px;">
<el-button size="mini" type="text" @click="deleteVisible = false">取消</el-button>
<el-button size="mini" type="primary" @click="onDelete">确定</el-button>
</div>
<template #reference>
<el-button icon="el-icon-delete" size="mini" type="danger" style="margin-left: 10px;">批量删除</el-button>
<el-button icon="el-icon-delete" size="mini" :disabled="!apis.length" style="margin-left: 10px;">删除</el-button>
</template>
</el-popover>
</div>
</div>
<el-table :data="tableData" border stripe @sort-change="sortChange" @selection-change="handleSelectionChange">
<el-table-column
type="selection"
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 #default="scope">
<div>
{{ scope.row.method }}
<el-tag
:key="scope.row.methodFiletr"
:type="tagTypeFiletr(scope.row.method)"
effect="dark"
size="mini"
>{{ methodFiletr(scope.row.method) }}</el-tag>
</div>
</template>
</el-table-column>
<el-table :data="tableData" @sort-change="sortChange" @selection-change="handleSelectionChange">
<el-table-column
type="selection"
width="55"
/>
<el-table-column align="left" label="id" min-width="60" prop="ID" sortable="custom" />
<el-table-column align="left" label="API路径" min-width="150" prop="path" sortable="custom" />
<el-table-column align="left" label="API分组" min-width="150" prop="apiGroup" sortable="custom" />
<el-table-column align="left" label="API简介" min-width="150" prop="description" sortable="custom" />
<el-table-column align="left" label="请求" min-width="150" prop="method" sortable="custom">
<template #default="scope">
<div>
{{ scope.row.method }} / {{ methodFiletr(scope.row.method) }}
</div>
</template>
</el-table-column>
<el-table-column fixed="right" label="操作" width="200">
<template #default="scope">
<el-button size="small" type="primary" icon="el-icon-edit" @click="editApi(scope.row)">编辑</el-button>
<el-button
size="small"
type="danger"
icon="el-icon-delete"
@click="deleteApi(scope.row)"
>删除</el-button>
</template>
</el-table-column>
</el-table>
<el-pagination
:current-page="page"
:page-size="pageSize"
: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"
/>
<el-table-column align="left" fixed="right" label="操作" width="200">
<template #default="scope">
<el-button
icon="el-icon-edit"
size="small"
type="text"
@click="editApi(scope.row)"
>编辑</el-button>
<el-button
icon="el-icon-delete"
size="small"
type="text"
@click="deleteApi(scope.row)"
>删除</el-button>
</template>
</el-table-column>
</el-table>
<div class="gva-pagination">
<el-pagination
:current-page="page"
:page-size="pageSize"
:page-sizes="[10, 30, 50, 100]"
:total="total"
layout="total, sizes, prev, pager, next, jumper"
@current-change="handleCurrentChange"
@size-change="handleSizeChange"
/>
</div>
</div>
<el-dialog v-model="dialogFormVisible" :before-close="closeDialog" :title="dialogTitle">
<el-form ref="apiForm" :inline="true" :model="form" :rules="rules" label-width="80px">
<warning-bar title="新增API,需要在角色管理内配置权限才可使用" />
<el-form ref="apiForm" :model="form" :rules="rules" label-width="80px">
<el-form-item label="路径" prop="path">
<el-input v-model="form.path" autocomplete="off" />
</el-form-item>
<el-form-item label="请求" prop="method">
<el-select v-model="form.method" placeholder="请选择">
<el-select v-model="form.method" placeholder="请选择" style="width:100%">
<el-option
v-for="item in methodOptions"
:key="item.value"
@@ -105,11 +112,10 @@
<el-input v-model="form.description" autocomplete="off" />
</el-form-item>
</el-form>
<div class="warning">新增Api需要在角色管理内配置权限才可使用</div>
<template #footer>
<div class="dialog-footer">
<el-button @click="closeDialog">取 消</el-button>
<el-button type="primary" @click="enterDialog">确 定</el-button>
<el-button size="small" @click="closeDialog">取 消</el-button>
<el-button size="small" type="primary" @click="enterDialog">确 定</el-button>
</div>
</template>
</el-dialog>
@@ -129,6 +135,7 @@ import {
} from '@/api/api'
import infoList from '@/mixins/infoList'
import { toSQLLine } from '@/utils/stringFun'
import warningBar from '@/components/warningBar/warningBar.vue'
const methodOptions = [
{
value: 'POST',
@@ -154,6 +161,9 @@ const methodOptions = [
export default {
name: 'Api',
components: {
warningBar
},
mixins: [infoList],
data() {
return {
@@ -223,6 +233,9 @@ export default {
}
this.getTableData()
},
onReset() {
this.searchInfo = {}
},
// 条件搜索前端看此方法
onSubmit() {
this.page = 1
@@ -280,12 +293,6 @@ export default {
this.getTableData()
}
})
.catch(() => {
this.$message({
type: 'info',
message: '已取消删除'
})
})
},
async enterDialog() {
this.$refs.apiForm.validate(async valid => {
@@ -345,9 +352,6 @@ export default {
float: right;
}
}
.el-tag--mini {
margin-left: 5px;
}
.warning {
color: #dc143c;
}
+56 -48
View File
@@ -1,55 +1,61 @@
<template>
<div class="authority">
<div class="gva-btn-list">
<el-button size="mini" type="primary" icon="el-icon-plus" @click="addAuthority('0')">新增角色</el-button>
<warning-bar title="注:右上角头像下拉可切换角色" />
<div class="gva-table-box">
<div class="gva-btn-list">
<el-button size="mini" type="primary" icon="el-icon-plus" @click="addAuthority('0')">新增角色</el-button>
</div>
<el-table
:data="tableData"
:tree-props="{children: 'children', hasChildren: 'hasChildren'}"
row-key="authorityId"
style="width: 100%"
>
<el-table-column label="角色ID" min-width="180" prop="authorityId" />
<el-table-column align="left" label="角色名称" min-width="180" prop="authorityName" />
<el-table-column align="left" label="操作" width="460">
<template #default="scope">
<el-button
icon="el-icon-setting"
size="mini"
type="text"
@click="opdendrawer(scope.row)"
>设置权限</el-button>
<el-button
icon="el-icon-plus"
size="mini"
type="text"
@click="addAuthority(scope.row.authorityId)"
>新增子角色</el-button>
<el-button
icon="el-icon-copy-document"
size="mini"
type="text"
@click="copyAuthority(scope.row)"
>拷贝</el-button>
<el-button
icon="el-icon-edit"
size="mini"
type="text"
@click="editAuthority(scope.row)"
>编辑</el-button>
<el-button
icon="el-icon-delete"
size="mini"
type="text"
@click="deleteAuth(scope.row)"
>删除</el-button>
</template>
</el-table-column>
</el-table>
</div>
<el-table
:data="tableData"
:tree-props="{children: 'children', hasChildren: 'hasChildren'}"
border
row-key="authorityId"
stripe
style="width: 100%"
>
<el-table-column label="角色id" min-width="180" prop="authorityId" />
<el-table-column label="角色名称" min-width="180" prop="authorityName" />
<el-table-column label="操作" width="460">
<template #default="scope">
<el-button size="mini" type="primary" @click="opdendrawer(scope.row)">设置权限</el-button>
<el-button
icon="el-icon-plus"
size="mini"
type="primary"
@click="addAuthority(scope.row.authorityId)"
>新增子角色</el-button>
<el-button
icon="el-icon-copy-document"
size="mini"
type="primary"
@click="copyAuthority(scope.row)"
>拷贝</el-button>
<el-button
icon="el-icon-edit"
size="mini"
type="primary"
@click="editAuthority(scope.row)"
>编辑</el-button>
<el-button
icon="el-icon-delete"
size="mini"
type="danger"
@click="deleteAuth(scope.row)"
>删除</el-button>
</template>
</el-table-column>
</el-table>
<span style="color: red;font-size: 12px">注:右上角头像下拉可切换角色</span>
<!-- 新增角色弹窗 -->
<el-dialog v-model="dialogFormVisible" :title="dialogTitle">
<el-form ref="authorityForm" :model="form" :rules="rules">
<el-form ref="authorityForm" :model="form" :rules="rules" label-width="80px">
<el-form-item label="父级角色" prop="parentId">
<el-cascader
v-model="form.parentId"
style="width:100%"
:disabled="dialogType=='add'"
:options="AuthorityOption"
:props="{ checkStrictly: true,label:'authorityName',value:'authorityId',disabled:'disabled',emitPath:false}"
@@ -66,8 +72,8 @@
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button @click="closeDialog">取 消</el-button>
<el-button type="primary" @click="enterDialog">确 定</el-button>
<el-button size="small" @click="closeDialog">取 消</el-button>
<el-button size="small" type="primary" @click="enterDialog">确 定</el-button>
</div>
</template>
</el-dialog>
@@ -102,6 +108,7 @@ import {
import Menus from '@/view/superAdmin/authority/components/menus.vue'
import Apis from '@/view/superAdmin/authority/components/apis.vue'
import Datas from '@/view/superAdmin/authority/components/datas.vue'
import warningBar from '@/components/warningBar/warningBar.vue'
import infoList from '@/mixins/infoList'
export default {
@@ -109,7 +116,8 @@ export default {
components: {
Menus,
Apis,
Datas
Datas,
warningBar
},
mixins: [infoList],
data() {
@@ -313,7 +321,7 @@ export default {
setAuthorityOptions(AuthorityData, optionsData, disabled) {
this.form.authorityId = String(this.form.authorityId)
AuthorityData &&
AuthorityData.map(item => {
AuthorityData.forEach(item => {
if (item.children && item.children.length) {
const option = {
authorityId: item.authorityId,
@@ -52,7 +52,7 @@ export default {
})
this.activeUserId = this.row.authorityId
this.apiTreeIds = []
res.data.paths && res.data.paths.map(item => {
res.data.paths && res.data.paths.forEach(item => {
this.apiTreeIds.push('p:' + item.path + 'm:' + item.method)
})
},
@@ -68,7 +68,7 @@ export default {
buildApiTree(apis) {
const apiObj = {}
apis &&
apis.map(item => {
apis.forEach(item => {
item.onlyId = 'p:' + item.path + 'm:' + item.method
if (Object.prototype.hasOwnProperty.call(apiObj, item.apiGroup)) {
apiObj[item.apiGroup].push(item)
@@ -91,7 +91,7 @@ export default {
async authApiEnter() {
const checkArr = this.$refs.apiTree.getCheckedNodes(true)
var casbinInfos = []
checkArr && checkArr.map(item => {
checkArr && checkArr.forEach(item => {
var casbinInfo = {
path: item.path,
method: item.method
@@ -9,16 +9,17 @@
<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>
<span>
此功能仅用于创建角色和角色的many2many关系表,具体使用还须自己结合表实现业务,详情参考示例代码(客户示例)
</span>
<warning-bar title="此功能仅用于创建角色和角色的many2many关系表,具体使用还须自己结合表实现业务,详情参考示例代码(客户示例)" />
</div>
</template>
<script>
import { setDataAuthority } from '@/api/authority'
import warningBar from '@/components/warningBar/warningBar.vue'
export default {
name: 'Datas',
components: { warningBar },
props: {
row: {
default: function() {
@@ -44,7 +45,7 @@ export default {
this.authoritys = []
this.dataAuthorityId = []
this.roundAuthority(this.authority)
this.row.dataAuthorityId && this.row.dataAuthorityId.map(item => {
this.row.dataAuthorityId && this.row.dataAuthorityId.forEach(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)
})
@@ -73,7 +74,7 @@ export default {
},
getChildrenId(row, arrBox) {
arrBox.push(row.authorityId)
row.children && row.children.map(item => {
row.children && row.children.forEach(item => {
this.getChildrenId(item, arrBox)
})
},
@@ -86,7 +87,7 @@ export default {
},
// 平铺角色
roundAuthority(authoritys) {
authoritys && authoritys.map(item => {
authoritys && authoritys.forEach(item => {
const obj = {}
obj.authorityId = item.authorityId
obj.authorityName = item.authorityName
@@ -70,7 +70,7 @@ export default {
const res1 = await getMenuAuthority({ authorityId: this.row.authorityId })
const menus = res1.data.menus
const arr = []
menus.map(item => {
menus.forEach(item => {
// 防止直接选中父级造成全选
if (!menus.some(same => same.parentId === item.menuId)) {
arr.push(Number(item.menuId))
@@ -1,6 +1,9 @@
<template>
<div>
<div class="search-term">
<warning-bar
title="获取字典且缓存方法已在前端utils/dictionary 已经封装完成 不必自己书写 使用方法查看文件内注释"
/>
<div class="gva-search-box">
<el-form :inline="true" :model="searchInfo">
<el-form-item label="字典名(中)">
<el-input v-model="searchInfo.name" placeholder="搜索条件" />
@@ -17,64 +20,68 @@
<el-form-item label="描述">
<el-input v-model="searchInfo.desc" placeholder="搜索条件" />
</el-form-item>
<el-form-item>
<el-button size="mini" type="primary" icon="el-icon-search" @click="onSubmit">查询</el-button>
<el-button size="mini" icon="el-icon-refresh" @click="onReset">重置</el-button>
</el-form-item>
</el-form>
</div>
<div class="gva-table-box">
<div class="gva-btn-list">
<el-button size="mini" type="primary" icon="el-icon-search" @click="onSubmit">查询</el-button>
<el-button size="mini" type="primary" icon="el-icon-plus" @click="openDialog">新增</el-button>
</div>
<el-table
ref="multipleTable"
:data="tableData"
style="width: 100%"
tooltip-effect="dark"
row-key="ID"
>
<el-table-column type="selection" width="55" />
<el-table-column align="left" label="日期" width="180">
<template #default="scope">{{ formatDate(scope.row.CreatedAt) }}</template>
</el-table-column>
<el-table-column align="left" label="字典名(中)" prop="name" width="160" />
<el-table-column align="left" label="字典名(英)" prop="type" width="120" />
<el-table-column align="left" label="状态" prop="status" width="120">
<template #default="scope">{{ formatBoolean(scope.row.status) }}</template>
</el-table-column>
<el-table-column align="left" label="描述" prop="desc" width="280" />
<el-table-column align="left" label="按钮组">
<template #default="scope">
<el-button size="mini" icon="el-icon-document" type="text" @click="toDetile(scope.row)">详情</el-button>
<el-button size="mini" icon="el-icon-edit" type="text" @click="updateSysDictionary(scope.row)">变更</el-button>
<el-popover :visible="scope.row.visible" placement="top" width="160">
<p>确定要删除吗?</p>
<div style="text-align: right; margin-top: 8px;">
<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>
<template #reference>
<el-button type="text" icon="el-icon-delete" size="mini" style="margin-left:10px">删除</el-button>
</template>
</el-popover>
</template>
</el-table-column>
</el-table>
<div class="gva-pagination">
<el-pagination
:current-page="page"
:page-size="pageSize"
:page-sizes="[10, 30, 50, 100]"
:total="total"
layout="total, sizes, prev, pager, next, jumper"
@current-change="handleCurrentChange"
@size-change="handleSizeChange"
/>
</div>
</div>
<el-table
ref="multipleTable"
:data="tableData"
border
stripe
style="width: 100%"
tooltip-effect="dark"
>
<el-table-column type="selection" width="55" />
<el-table-column label="日期" width="180">
<template #default="scope">{{ formatDate(scope.row.CreatedAt) }}</template>
</el-table-column>
<el-table-column label="字典名(中)" prop="name" width="120" />
<el-table-column label="字典名(英)" prop="type" width="120" />
<el-table-column label="状态" prop="status" width="120">
<template #default="scope">{{ formatBoolean(scope.row.status) }}</template>
</el-table-column>
<el-table-column label="描述" prop="desc" width="280" />
<el-table-column label="按钮组">
<template #default="scope">
<el-button size="mini" type="success" @click="toDetile(scope.row)">详情</el-button>
<el-button size="mini" type="primary" @click="updateSysDictionary(scope.row)">变更</el-button>
<el-popover v-model:visible="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>
<template #reference>
<el-button type="danger" icon="el-icon-delete" size="mini" style="margin-left:10px">删除</el-button>
</template>
</el-popover>
</template>
</el-table-column>
</el-table>
<el-pagination
:current-page="page"
:page-size="pageSize"
: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"
/>
<el-dialog v-model="dialogFormVisible" :before-close="closeDialog" title="弹窗操作">
<el-form ref="elForm" :model="formData" :rules="rules" size="medium" label-width="110px">
<el-form-item label="字典名(中)" prop="name">
@@ -102,14 +109,11 @@
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button @click="closeDialog">取 消</el-button>
<el-button type="primary" @click="enterDialog">确 定</el-button>
<el-button size="small" @click="closeDialog">取 消</el-button>
<el-button size="small" type="primary" @click="enterDialog">确 定</el-button>
</div>
</template>
</el-dialog>
<div style="margin-top:40px;color:red">获取字典且缓存方法已在前端utils/dictionary 已经封装完成 不必自己书写 使用方法查看文件内注释</div>
</div>
</template>
@@ -122,8 +126,12 @@ import {
getSysDictionaryList
} from '@/api/sysDictionary' // 此处请自行替换地址
import infoList from '@/mixins/infoList'
import warningBar from '@/components/warningBar/warningBar.vue'
export default {
name: 'SysDictionary',
components: {
warningBar
},
mixins: [infoList],
data() {
return {
@@ -173,6 +181,9 @@ export default {
}
})
},
onReset() {
this.searchInfo = {}
},
// 条件搜索前端看此方法
onSubmit() {
this.page = 1
@@ -1,6 +1,6 @@
<template>
<div>
<div class="search-term">
<div class="gva-search-box">
<el-form :inline="true" :model="searchInfo">
<el-form-item label="展示值">
<el-input v-model="searchInfo.label" placeholder="搜索条件" />
@@ -14,62 +14,67 @@
<el-option key="false" label="否" value="false" />
</el-select>
</el-form-item>
<el-form-item>
<el-button size="mini" type="primary" icon="el-icon-search" @click="onSubmit">查询</el-button>
<el-button size="mini" icon="el-icon-refresh" @click="onReset">重置</el-button>
</el-form-item>
</el-form>
</div>
<div class="gva-table-box">
<div class="gva-btn-list">
<el-button size="mini" type="primary" icon="el-icon-search" @click="onSubmit">查询</el-button>
<el-button size="mini" type="primary" icon="el-icon-plus" @click="openDialog">新增字典项</el-button>
</div>
<el-table
ref="multipleTable"
:data="tableData"
style="width: 100%"
tooltip-effect="dark"
row-key="ID"
>
<el-table-column type="selection" width="55" />
<el-table-column align="left" label="日期" width="180">
<template #default="scope">{{ formatDate(scope.row.CreatedAt) }}</template>
</el-table-column>
<el-table-column align="left" label="展示值" prop="label" width="120" />
<el-table-column align="left" label="字典值" prop="value" width="120" />
<el-table-column align="left" label="启用状态" prop="status" width="120">
<template #default="scope">{{ formatBoolean(scope.row.status) }}</template>
</el-table-column>
<el-table-column align="left" label="排序标记" prop="sort" width="120" />
<el-table-column align="left" label="按钮组">
<template #default="scope">
<el-button size="small" type="text" icon="el-icon-edit" @click="updateSysDictionaryDetail(scope.row)">变更</el-button>
<el-popover :visible="scope.row.visible" placement="top" width="160">
<p>确定要删除吗?</p>
<div style="text-align: right; margin-top: 8px;">
<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>
<template #reference>
<el-button type="text" icon="el-icon-delete" size="mini">删除</el-button>
</template>
</el-popover>
</template>
</el-table-column>
</el-table>
<div class="gva-pagination">
<el-pagination
:current-page="page"
:page-size="pageSize"
:page-sizes="[10, 30, 50, 100]"
:total="total"
layout="total, sizes, prev, pager, next, jumper"
@current-change="handleCurrentChange"
@size-change="handleSizeChange"
/>
</div>
</div>
<el-table
ref="multipleTable"
:data="tableData"
border
stripe
style="width: 100%"
tooltip-effect="dark"
>
<el-table-column type="selection" width="55" />
<el-table-column label="日期" width="180">
<template #default="scope">{{ formatDate(scope.row.CreatedAt) }}</template>
</el-table-column>
<el-table-column label="展示值" prop="label" width="120" />
<el-table-column label="字典值" prop="value" width="120" />
<el-table-column label="启用状态" prop="status" width="120">
<template #default="scope">{{ formatBoolean(scope.row.status) }}</template>
</el-table-column>
<el-table-column label="排序标记" prop="sort" width="120" />
<el-table-column label="按钮组">
<template #default="scope">
<el-button size="small" type="primary" @click="updateSysDictionaryDetail(scope.row)">变更</el-button>
<el-popover v-model:visible="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>
<template #reference>
<el-button type="danger" icon="el-icon-delete" size="mini">删除</el-button>
</template>
</el-popover>
</template>
</el-table-column>
</el-table>
<el-pagination
:current-page="page"
:page-size="pageSize"
: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"
/>
<el-dialog v-model="dialogFormVisible" :before-close="closeDialog" title="弹窗操作">
<el-form ref="elForm" :model="formData" :rules="rules" size="medium" label-width="110px">
@@ -100,8 +105,8 @@
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button @click="closeDialog">取 消</el-button>
<el-button type="primary" @click="enterDialog">确 定</el-button>
<el-button size="small" @click="closeDialog">取 消</el-button>
<el-button size="small" type="primary" @click="enterDialog">确 定</el-button>
</div>
</template>
</el-dialog>
@@ -162,6 +167,9 @@ export default {
this.getTableData()
},
methods: {
onReset() {
this.searchInfo = {}
},
// 条件搜索前端看此方法
onSubmit() {
this.page = 1
+2 -7
View File
@@ -1,17 +1,12 @@
<template>
<div>
<router-view v-if="$route.meta.keepAlive" v-slot="{ Component }">
<router-view v-slot="{ Component }">
<transition mode="out-in" name="el-fade-in-linear">
<keep-alive>
<keep-alive :include="$store.getters['router/keepAliveRouters']">
<component :is="Component" />
</keep-alive>
</transition>
</router-view>
<router-view v-if="!$route.meta.keepAlive" v-slot="{ Component }">
<transition mode="out-in" name="el-fade-in-linear">
<component :is="Component" />
</transition>
</router-view>
</div>
</template>
+11 -20
View File
@@ -1,25 +1,16 @@
<template>
<div>
<el-form
ref="menuForm"
:inline="true"
label-width="85px"
label-position="top"
>
<el-form-item prop="icon" style="width:100%">
<i
class="icon"
:class="'el-icon-'+ metaData.icon"
style="position: absolute; z-index: 9999; padding: 5px 10px; "
/>
<el-select v-model="metaData.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 style="float: left">{{ item.key }}</span>
</el-option>
</el-select>
</el-form-item>
</el-form>
<i
class="icon"
:class="'el-icon-'+ metaData.icon"
style="position: absolute; z-index: 9999; padding: 5px 10px; "
/>
<el-select v-model="metaData.icon" style="width:100%" 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 style="float: left">{{ item.key }}</span>
</el-option>
</el-select>
</div>
</template>
+73 -86
View File
@@ -1,58 +1,60 @@
<template>
<div>
<div class="gva-btn-list">
<el-button size="mini" type="primary" icon="el-icon-plus" @click="addMenu('0')">新增根菜单</el-button>
<div class="gva-table-box">
<div class="gva-btn-list">
<el-button size="mini" type="primary" icon="el-icon-plus" @click="addMenu('0')">新增根菜单</el-button>
</div>
<!-- 由于此处菜单跟左侧列表一一对应所以不需要分页 pageSize默认999 -->
<el-table :data="tableData" row-key="ID">
<el-table-column align="left" label="ID" min-width="100" prop="ID" />
<el-table-column align="left" label="路由Name" show-overflow-tooltip min-width="160" prop="name" />
<el-table-column align="left" label="路由Path" show-overflow-tooltip min-width="160" prop="path" />
<el-table-column align="left" label="是否隐藏" min-width="100" prop="hidden">
<template #default="scope">
<span>{{ scope.row.hidden?"隐藏":"显示" }}</span>
</template>
</el-table-column>
<el-table-column align="left" label="父节点" min-width="90" prop="parentId" />
<el-table-column align="left" label="排序" min-width="70" prop="sort" />
<el-table-column align="left" label="文件路径" min-width="360" prop="component" />
<el-table-column align="left" label="展示名称" min-width="120" prop="authorityName">
<template #default="scope">
<span>{{ scope.row.meta.title }}</span>
</template>
</el-table-column>
<el-table-column align="left" label="图标" min-width="140" prop="authorityName">
<template #default="scope">
<i :class="`el-icon-${scope.row.meta.icon}`" />
<span>{{ scope.row.meta.icon }}</span>
</template>
</el-table-column>
<el-table-column align="left" fixed="right" label="操作" width="300">
<template #default="scope">
<el-button
size="mini"
type="text"
icon="el-icon-plus"
@click="addMenu(scope.row.ID)"
>添加子菜单</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="editMenu(scope.row.ID)"
>编辑</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="deleteMenu(scope.row.ID)"
>删除</el-button>
</template>
</el-table-column>
</el-table>
</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 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 #default="scope">
<span>{{ scope.row.hidden?"隐藏":"显示" }}</span>
</template>
</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 #default="scope">
<span>{{ scope.row.meta.title }}</span>
</template>
</el-table-column>
<el-table-column label="图标" min-width="140" prop="authorityName">
<template #default="scope">
<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 #default="scope">
<el-button
size="mini"
type="primary"
icon="el-icon-edit"
@click="addMenu(scope.row.ID)"
>添加子菜单</el-button>
<el-button
size="mini"
type="primary"
icon="el-icon-edit"
@click="editMenu(scope.row.ID)"
>编辑</el-button>
<el-button
size="mini"
type="danger"
icon="el-icon-delete"
@click="deleteMenu(scope.row.ID)"
>删除</el-button>
</template>
</el-table-column>
</el-table>
<el-dialog v-model="dialogFormVisible" :before-close="handleClose" :title="dialogTitle">
<warning-bar title="新增菜单,需要在角色管理内篇日志权限才可使用" />
<el-form
v-if="dialogFormVisible"
ref="menuForm"
@@ -62,7 +64,7 @@
label-position="top"
label-width="85px"
>
<el-form-item label="路由name" prop="path" style="width:30%">
<el-form-item label="路由Name" prop="path" style="width:30%">
<el-input
v-model="form.name"
autocomplete="off"
@@ -73,7 +75,7 @@
<el-form-item prop="path" style="width:30%">
<template #label>
<div style="display:inline-flex">
路由path
路由Path
<el-checkbox v-model="checkFlag" style="float:right;margin-left:20px;">添加参数</el-checkbox>
</div>
</template>
@@ -91,9 +93,10 @@
<el-option :value="true" label="是" />
</el-select>
</el-form-item>
<el-form-item label="父节点Id" style="width:30%">
<el-form-item label="父节点ID" style="width:30%">
<el-cascader
v-model="form.parentId"
style="width:100%"
:disabled="!isEdit"
:options="menuOption"
:props="{ checkStrictly: true,label:'title',value:'ID',disabled:'disabled',emitPath:false}"
@@ -109,25 +112,24 @@
<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" />
<icon :meta="form.meta" style="width:100%" />
</el-form-item>
<el-form-item label="排序标记" prop="sort" style="width:30%">
<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 v-model="form.meta.keepAlive" placeholder="是否keepAlive缓存页面">
<el-form-item label="KeepAlive" prop="meta.keepAlive" style="width:30%">
<el-select v-model="form.meta.keepAlive" style="width:100%" 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 v-model="form.meta.closeTab" placeholder="是否自动关闭tab">
<el-form-item label="CloseTab" prop="meta.closeTab" style="width:30%">
<el-select v-model="form.meta.closeTab" style="width:100%" placeholder="是否自动关闭tab">
<el-option :value="false" label="否" />
<el-option :value="true" label="是" />
</el-select>
</el-form-item>
</el-form>
<div class="warning">新增菜单需要在角色管理内配置权限才可使用</div>
<div>
<el-button
size="small"
@@ -135,8 +137,8 @@
icon="el-icon-edit"
@click="addParameter(form)"
>新增菜单参数</el-button>
<el-table :data="form.parameters" stripe style="width: 100%">
<el-table-column prop="type" label="参数类型" width="180">
<el-table :data="form.parameters" style="width: 100%">
<el-table-column align="left" prop="type" label="参数类型" width="180">
<template #default="scope">
<el-select v-model="scope.row.type" placeholder="请选择">
<el-option key="query" value="query" label="query" />
@@ -144,21 +146,21 @@
</el-select>
</template>
</el-table-column>
<el-table-column prop="key" label="参数key" width="180">
<el-table-column align="left" prop="key" label="参数key" width="180">
<template #default="scope">
<div>
<el-input v-model="scope.row.key" />
</div>
</template>
</el-table-column>
<el-table-column prop="value" label="参数值">
<el-table-column align="left" prop="value" label="参数值">
<template #default="scope">
<div>
<el-input v-model="scope.row.value" />
</div>
</template>
</el-table-column>
<el-table-column>
<el-table-column align="left">
<template #default="scope">
<div>
<el-button
@@ -174,8 +176,8 @@
</div>
<template #footer>
<div class="dialog-footer">
<el-button @click="closeDialog">取 消</el-button>
<el-button type="primary" @click="enterDialog">确 定</el-button>
<el-button size="small" @click="closeDialog">取 消</el-button>
<el-button size="small" type="primary" @click="enterDialog">确 定</el-button>
</div>
</template>
</el-dialog>
@@ -194,10 +196,12 @@ import {
} from '@/api/menu'
import infoList from '@/mixins/infoList'
import icon from '@/view/superAdmin/menu/icon.vue'
import warningBar from '@/components/warningBar/warningBar.vue'
export default {
name: 'Menus',
components: {
icon
icon,
warningBar
},
mixins: [infoList],
data() {
@@ -273,7 +277,7 @@ export default {
},
setMenuOptions(menuData, optionsData, disabled) {
menuData &&
menuData.map(item => {
menuData.forEach(item => {
if (item.children && item.children.length) {
const option = {
title: item.meta.title,
@@ -301,23 +305,6 @@ export default {
this.initForm()
done()
},
// 懒加载子菜单
load(tree, treeNode, resolve) {
resolve([
{
id: 31,
date: '2016-05-01',
name: '王小虎',
address: '上海市普陀区金沙江路 1519 弄'
},
{
id: 32,
date: '2016-05-01',
name: '王小虎',
address: '上海市普陀区金沙江路 1519 弄'
}
])
},
// 删除菜单
deleteMenu(ID) {
this.$confirm('此操作将永久删除所有角色下该菜单, 是否继续?', '提示', {
@@ -1,6 +1,6 @@
<template>
<div>
<div class="search-term">
<div class="gva-search-box">
<el-form :inline="true" :model="searchInfo">
<el-form-item label="请求方法">
<el-input v-model="searchInfo.method" placeholder="搜索条件" />
@@ -11,105 +11,111 @@
<el-form-item label="结果状态码">
<el-input v-model="searchInfo.status" placeholder="搜索条件" />
</el-form-item>
<el-form-item>
<el-button size="mini" type="primary" icon="el-icon-search" @click="onSubmit">查询</el-button>
<el-button size="mini" icon="el-icon-refresh" @click="onReset">重置</el-button>
</el-form-item>
</el-form>
</div>
<div class="gva-table-box">
<div class="gva-btn-list">
<el-button size="mini" type="primary" icon="el-icon-search" @click="onSubmit">查询</el-button>
<el-popover v-model:visible="deleteVisible" placement="top" width="160">
<p>确定要删除吗?</p>
<div style="text-align: right; margin: 0">
<div style="text-align: right; margin-top: 8px;">
<el-button size="mini" type="text" @click="deleteVisible = false">取消</el-button>
<el-button size="mini" type="primary" @click="onDelete">确定</el-button>
</div>
<template #reference>
<el-button icon="el-icon-delete" size="mini" type="danger" style="margin-left: 10px;">批量删除</el-button>
<el-button icon="el-icon-delete" size="mini" style="margin-left: 10px;" :disabled="!multipleSelection.length">删除</el-button>
</template>
</el-popover>
</div>
</div>
<el-table
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 label="操作人" width="140">
<template #default="scope">
<div>{{ scope.row.user.userName }}({{ scope.row.user.nickName }})</div>
</template>
</el-table-column>
<el-table-column label="日期" width="180">
<template #default="scope">{{ formatDate(scope.row.CreatedAt) }}</template>
</el-table-column>
<el-table-column label="状态码" prop="status" width="120">
<template #default="scope">
<div>
<el-tag type="success">{{ scope.row.status }}</el-tag>
</div>
</template>
</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 #default="scope">
<div>
<el-popover v-if="scope.row.body" placement="top-start" trigger="hover">
<div class="popover-box">
<pre>{{ fmtBody(scope.row.body) }}</pre>
</div>
<template #reference>
<i class="el-icon-view" />
</template>
</el-popover>
<span v-else>无</span>
</div>
</template>
</el-table-column>
<el-table-column label="响应" prop="path" width="80">
<template #default="scope">
<div>
<el-popover v-if="scope.row.resp" placement="top-start" trigger="hover">
<div class="popover-box">
<pre>{{ fmtBody(scope.row.resp) }}</pre>
</div>
<template #reference>
<i class="el-icon-view" />
</template>
</el-popover>
<span v-else>无</span>
</div>
</template>
</el-table-column>
<el-table-column label="按钮组">
<template #default="scope">
<el-popover v-model:visible="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 size="mini" type="primary" @click="deleteSysOperationRecord(scope.row)">确定</el-button>
<el-table
ref="multipleTable"
:data="tableData"
style="width: 100%"
tooltip-effect="dark"
row-key="ID"
@selection-change="handleSelectionChange"
>
<el-table-column align="left" type="selection" width="55" />
<el-table-column align="left" label="操作人" width="140">
<template #default="scope">
<div>{{ scope.row.user.userName }}({{ scope.row.user.nickName }})</div>
</template>
</el-table-column>
<el-table-column align="left" label="日期" width="180">
<template #default="scope">{{ formatDate(scope.row.CreatedAt) }}</template>
</el-table-column>
<el-table-column align="left" label="状态码" prop="status" width="120">
<template #default="scope">
<div>
<el-tag type="success">{{ scope.row.status }}</el-tag>
</div>
<template #reference>
<el-button icon="el-icon-delete" size="mini" type="danger">删除</el-button>
</template>
</el-popover>
</template>
</el-table-column>
</el-table>
<el-pagination
:current-page="page"
:page-size="pageSize"
: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"
/>
</template>
</el-table-column>
<el-table-column align="left" label="请求IP" prop="ip" width="120" />
<el-table-column align="left" label="请求方法" prop="method" width="120" />
<el-table-column align="left" label="请求路径" prop="path" width="240" />
<el-table-column align="left" label="请求" prop="path" width="80">
<template #default="scope">
<div>
<el-popover v-if="scope.row.body" placement="left-start" trigger="click">
<div class="popover-box">
<pre>{{ fmtBody(scope.row.body) }}</pre>
</div>
<template #reference>
<i class="el-icon-view" />
</template>
</el-popover>
<span v-else>无</span>
</div>
</template>
</el-table-column>
<el-table-column align="left" label="响应" prop="path" width="80">
<template #default="scope">
<div>
<el-popover v-if="scope.row.resp" placement="left-start" trigger="click">
<div class="popover-box">
<pre>{{ fmtBody(scope.row.resp) }}</pre>
</div>
<template #reference>
<i class="el-icon-view" />
</template>
</el-popover>
<span v-else>无</span>
</div>
</template>
</el-table-column>
<el-table-column align="left" label="按钮组">
<template #default="scope">
<el-popover :visible="scope.row.visible" placement="top" width="160">
<p>确定要删除吗?</p>
<div style="text-align: right; margin-top: 8px;">
<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>
<template #reference>
<el-button icon="el-icon-delete" size="mini" type="text">删除</el-button>
</template>
</el-popover>
</template>
</el-table-column>
</el-table>
<div class="gva-pagination">
<el-pagination
:current-page="page"
:page-size="pageSize"
:page-sizes="[10, 30, 50, 100]"
:total="total"
layout="total, sizes, prev, pager, next, jumper"
@current-change="handleCurrentChange"
@size-change="handleSizeChange"
/>
</div>
</div>
</div>
</template>
@@ -147,6 +153,9 @@ export default {
this.getTableData()
},
methods: {
onReset() {
this.searchInfo = {}
},
// 条件搜索前端看此方法
onSubmit() {
this.page = 1
@@ -159,7 +168,7 @@ export default {
async onDelete() {
const ids = []
this.multipleSelection &&
this.multipleSelection.map(item => {
this.multipleSelection.forEach(item => {
ids.push(item.ID)
})
const res = await deleteSysOperationRecordByIds({ ids })
+146 -72
View File
@@ -1,70 +1,90 @@
<template>
<div>
<div class="gva-btn-list">
<el-button size="mini" type="primary" icon="el-icon-plus" @click="addUser">新增用户</el-button>
<warning-bar title="注:右上角头像下拉可切换角色" />
<div class="gva-table-box">
<div class="gva-btn-list">
<el-button size="mini" type="primary" icon="el-icon-plus" @click="addUser">新增用户</el-button>
</div>
<el-table :data="tableData">
<el-table-column align="left" label="头像" min-width="50">
<template #default="scope">
<CustomPic style="margin-top:8px" :pic-src="scope.row.headerImg" />
</template>
</el-table-column>
<el-table-column align="left" label="UUID" min-width="250" prop="uuid" />
<el-table-column align="left" label="用户名" min-width="150" prop="userName" />
<el-table-column align="left" label="昵称" min-width="100" prop="nickName">
<template #default="scope">
<p v-if="!scope.row.editFlag" class="nickName">{{ scope.row.nickName }} <i class="el-icon-edit pointer" style="color:#66b1ff" @click="openEidt(scope.row)" /></p>
<p v-if="scope.row.editFlag" class="nickName">
<el-input v-model="scope.row.nickName" />
<i class="el-icon-check pointer" style="color:#67c23a" @click="enterEdit(scope.row)" />
<i class="el-icon-close pointer" style="color:#f23c3c" @click="closeEdit(scope.row)" />
</p>
</template>
</el-table-column>
<el-table-column align="left" label="用户角色" min-width="150">
<template #default="scope">
<el-cascader
v-model="scope.row.authorityIds"
:options="authOptions"
:show-all-levels="false"
collapse-tags
:props="{ multiple:true,checkStrictly: true,label:'authorityName',value:'authorityId',disabled:'disabled',emitPath:false}"
:clearable="false"
@visible-change="(flag)=>{changeAuthority(scope.row,flag)}"
@remove-tag="()=>{changeAuthority(scope.row,false)}"
/>
</template>
</el-table-column>
<el-table-column align="left" label="操作" min-width="150">
<template #default="scope">
<el-popover :visible="scope.row.visible" placement="top" width="160">
<p>确定要删除此用户吗</p>
<div style="text-align: right; margin-top: 8px;">
<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>
<template #reference>
<el-button type="text" icon="el-icon-delete" size="mini">删除</el-button>
</template>
</el-popover>
<el-button type="text" icon="el-icon-magic-stick" size="mini" @click="resetPassword(scope.row)">重置密码</el-button>
</template>
</el-table-column>
</el-table>
<div class="gva-pagination">
<el-pagination
:current-page="page"
:page-size="pageSize"
:page-sizes="[10, 30, 50, 100]"
:total="total"
layout="total, sizes, prev, pager, next, jumper"
@current-change="handleCurrentChange"
@size-change="handleSizeChange"
/>
</div>
</div>
<el-table :data="tableData" border stripe>
<el-table-column label="头像" min-width="50">
<template #default="scope">
<div :style="{'textAlign':'center'}">
<CustomPic :pic-src="scope.row.headerImg" />
</div>
</template>
</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 #default="scope">
<el-dialog v-model="addUserDialog" custom-class="user-dialog" title="新增用户">
<el-form ref="userForm" :rules="rules" :model="userInfo" label-width="80px">
<el-form-item label="用户名" prop="username">
<el-input v-model="userInfo.username" />
</el-form-item>
<el-form-item label="密码" prop="password">
<el-input v-model="userInfo.password" />
</el-form-item>
<el-form-item label="别名" prop="nickName">
<el-input v-model="userInfo.nickName" />
</el-form-item>
<el-form-item label="用户角色" prop="authorityId">
<el-cascader
v-model="scope.row.authorityIds"
v-model="userInfo.authorityIds"
style="width:100%"
:options="authOptions"
:show-all-levels="false"
:props="{ multiple:true,checkStrictly: true,label:'authorityName',value:'authorityId',disabled:'disabled',emitPath:false}"
filterable
:clearable="false"
@visible-change="(flag)=>{changeAuthority(scope.row,flag)}"
@remove-tag="()=>{changeAuthority(scope.row,false)}"
/>
</template>
</el-table-column>
<el-table-column label="操作" min-width="150">
<template #default="scope">
<el-popover v-model:visible="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>
<template #reference>
<el-button type="danger" icon="el-icon-delete" size="mini">删除</el-button>
</template>
</el-popover>
</template>
</el-table-column>
</el-table>
<span style="color: red;font-size: 12px">注:右上角头像下拉可切换角色</span>
<el-pagination
:current-page="page"
:page-size="pageSize"
: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"
/>
<el-dialog v-model="addUserDialog" custom-class="user-dialog" title="新增用户">
<el-form ref="userForm" :rules="rules" :model="userInfo">
<el-form-item label="用户名" label-width="80px" prop="username">
<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-form-item>
<el-form-item label="别名" label-width="80px" prop="nickName">
<el-input v-model="userInfo.nickName" />
</el-form-item>
<el-form-item label="头像" label-width="80px">
<div style="display:inline-block" @click="openHeaderChange">
@@ -72,21 +92,12 @@
<div v-else class="header-img-box">从媒体库选择</div>
</div>
</el-form-item>
<el-form-item label="用户角色" label-width="80px" prop="authorityId">
<el-cascader
v-model="userInfo.authorityIds"
:options="authOptions"
:show-all-levels="false"
:props="{ multiple:true,checkStrictly: true,label:'authorityName',value:'authorityId',disabled:'disabled',emitPath:false}"
filterable
:clearable="false"
/>
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button @click="closeAddUserDialog">取 消</el-button>
<el-button type="primary" @click="enterAddUserDialog">确 定</el-button>
<el-button size="small" @click="closeAddUserDialog">取 消</el-button>
<el-button size="small" type="primary" @click="enterAddUserDialog">确 定</el-button>
</div>
</template>
</el-dialog>
@@ -108,9 +119,11 @@ import infoList from '@/mixins/infoList'
import { mapGetters } from 'vuex'
import CustomPic from '@/components/customPic/index.vue'
import ChooseImg from '@/components/chooseImg/index.vue'
import warningBar from '@/components/warningBar/warningBar.vue'
import { setUserInfo, resetPassword } from '@/api/user.js'
export default {
name: 'Api',
components: { CustomPic, ChooseImg },
components: { CustomPic, ChooseImg, warningBar },
mixins: [infoList],
data() {
return {
@@ -118,6 +131,7 @@ export default {
path: path,
authOptions: [],
addUserDialog: false,
backNickName: '',
userInfo: {
username: '',
password: '',
@@ -158,6 +172,32 @@ export default {
this.setOptions(res.data.list)
},
methods: {
resetPassword(row) {
this.$confirm(
'是否将此用户密码重置为123456?',
'警告',
{
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
}
).then(async() => {
const res = await resetPassword({
ID: row.ID,
})
if (res.code === 0) {
this.$message({
type: 'success',
message: res.msg,
})
} else {
this.$message({
type: 'error',
message: res.msg,
})
}
})
},
setAuthorityIds() {
this.tableData && this.tableData.forEach((user) => {
const authorityIds = user.authorities && user.authorities.map(i => {
@@ -173,9 +213,33 @@ export default {
this.authOptions = []
this.setAuthorityOptions(authData, this.authOptions)
},
openEidt(row) {
if (this.tableData.some(item => item.editFlag)) {
this.$message('当前存在正在编辑的用户')
return
}
this.backNickName = row.nickName
row.editFlag = true
},
async enterEdit(row) {
const res = await setUserInfo({ nickName: row.nickName, ID: row.ID })
if (res.code === 0) {
this.$message({
type: 'success',
message: '设置成功'
})
}
this.backNickName = ''
row.editFlag = false
},
closeEdit(row) {
row.nickName = this.backNickName
this.backNickName = ''
row.editFlag = false
},
setAuthorityOptions(AuthorityData, optionsData) {
AuthorityData &&
AuthorityData.map(item => {
AuthorityData.forEach(item => {
if (item.children && item.children.length) {
const option = {
authorityId: item.authorityId,
@@ -271,4 +335,14 @@ export default {
display: block;
}
}
.nickName{
display: flex;
justify-content: flex-start;
align-items: center;
}
.pointer{
cursor: pointer;
font-size: 16px;
margin-left: 2px;
}
</style>
+1 -1
View File
@@ -159,7 +159,7 @@ export default {
this.reload()
}, 1000 * 10)
},
beforeDestroy() {
beforeUnmount() {
clearInterval(this.timer)
this.timer = null
},
@@ -1,6 +1,6 @@
<template>
<div>
<span style="color:red">搜索时如果条件为LIKE只支持字符串</span>
<warning-bar title="id , created_at , updated_at , deleted_at 会自动生成请勿重复创建。搜索时如果条件为LIKE只支持字符串" />
<el-form
ref="fieldDialogFrom"
:model="middleDate"
@@ -9,97 +9,88 @@
:rules="rules"
>
<el-form-item label="Field名称" prop="fieldName">
<el-col :span="6">
<el-input v-model="middleDate.fieldName" autocomplete="off" />
</el-col>
<el-col :offset="1" :span="2">
<el-button size="mini" @click="autoFill">自动填充</el-button>
</el-col>
<el-input v-model="middleDate.fieldName" autocomplete="off" style="width:80%" />
<el-button size="mini" style="width:18%;margin-left:2%" @click="autoFill">自动填充</el-button>
</el-form-item>
<el-form-item label="Field中文名" prop="fieldDesc">
<el-col :span="6">
<el-input v-model="middleDate.fieldDesc" autocomplete="off" />
</el-col>
<el-input v-model="middleDate.fieldDesc" autocomplete="off" />
</el-form-item>
<el-form-item label="FieldJSON" prop="fieldJson">
<el-col :span="6">
<el-input v-model="middleDate.fieldJson" autocomplete="off" />
</el-col>
<el-input v-model="middleDate.fieldJson" autocomplete="off" />
</el-form-item>
<el-form-item label="数据库字段名" prop="columnName">
<el-col :span="6">
<el-input v-model="middleDate.columnName" autocomplete="off" />
</el-col>
<el-input v-model="middleDate.columnName" autocomplete="off" />
</el-form-item>
<el-form-item label="数据库字段描述" prop="comment">
<el-col :span="6">
<el-input v-model="middleDate.comment" autocomplete="off" />
</el-col>
<el-input v-model="middleDate.comment" autocomplete="off" />
</el-form-item>
<el-form-item label="Field数据类型" prop="fieldType">
<el-col :span="8">
<el-select
v-model="middleDate.fieldType"
placeholder="请选择field数据类型"
clearable
@change="getDbfdOptions"
>
<el-option
v-for="item in typeOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-col>
<el-select
v-model="middleDate.fieldType"
style="width:100%"
placeholder="请选择field数据类型"
clearable
@change="getDbfdOptions"
>
<el-option
v-for="item in typeOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="数据库字段类型" prop="dataType">
<el-col :span="8">
<el-select
v-model="middleDate.dataType"
:disabled="!middleDate.fieldType"
placeholder="请选择数据库字段类型"
clearable
>
<el-option
v-for="item in dbfdOptions"
:key="item.label"
:label="item.label"
:value="item.label"
/>
</el-select>
</el-col>
<el-select
v-model="middleDate.dataType"
style="width:100%"
:disabled="!middleDate.fieldType"
placeholder="请选择数据库字段类型"
clearable
>
<el-option
v-for="item in dbfdOptions"
:key="item.label"
:label="item.label"
:value="item.label"
/>
</el-select>
</el-form-item>
<el-form-item label="数据库字段长度" prop="dataTypeLong">
<el-col :span="8">
<el-input v-model="middleDate.dataTypeLong" placeholder="自定义类型必须指定长度" :disabled="!middleDate.dataType" />
</el-col>
<el-input v-model="middleDate.dataTypeLong" placeholder="自定义类型必须指定长度" :disabled="!middleDate.dataType" />
</el-form-item>
<el-form-item label="Field查询条件" prop="fieldSearchType">
<el-col :span="8">
<el-select v-model="middleDate.fieldSearchType" placeholder="请选择Field查询条件" clearable>
<el-option
v-for="item in typeSearchOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-col>
<el-select
v-model="middleDate.fieldSearchType"
style="width:100%"
placeholder="请选择Field查询条件"
clearable
>
<el-option
v-for="item in typeSearchOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="关联字典" prop="dictType">
<el-col :span="8">
<el-select v-model="middleDate.dictType" :disabled="middleDate.fieldType!=='int'" placeholder="请选择字典" clearable>
<el-option
v-for="item in dictOptions"
:key="item.type"
:label="`${item.type}(${item.name})`"
:value="item.type"
/>
</el-select>
</el-col>
<el-select
v-model="middleDate.dictType"
style="width:100%"
:disabled="middleDate.fieldType!=='int'"
placeholder="请选择字典"
clearable
>
<el-option
v-for="item in dictOptions"
:key="item.type"
:label="`${item.type}(${item.name})`"
:value="item.type"
/>
</el-select>
</el-form-item>
</el-form>
</div>
@@ -109,9 +100,11 @@
import { getDict } from '@/utils/dictionary'
import { toLowerCase, toSQLLine } from '@/utils/stringFun'
import { getSysDictionaryList } from '@/api/sysDictionary'
import warningBar from '@/components/warningBar/warningBar.vue'
export default {
name: 'FieldDialog',
components: { warningBar },
props: {
dialogMiddle: {
type: Object,
@@ -196,6 +189,7 @@ export default {
})
this.dictOptions = dictRes.data.list
this.getDict()
},
methods: {
autoFill() {
@@ -207,6 +201,9 @@ export default {
this.middleDate.dataTypeLong = ''
this.middleDate.fieldSearchType = ''
this.middleDate.dictType = ''
this.getDict()
},
async getDict() {
if (this.middleDate.fieldType) {
this.dbfdOptions = await getDict(this.middleDate.fieldType)
}
@@ -1,10 +1,5 @@
<template>
<div class="previewCode">
<div class="previewCodeTool">
<p>操作栏:</p>
<el-button @click="selectText">全选</el-button>
<el-button @click="copy">复制</el-button>
</div>
<el-tabs v-model="activeName">
<el-tab-pane v-for="(item, key) in previewCode" :key="key" :label="key" :name="key">
<div :id="key" class="tab-info" />
@@ -82,12 +77,6 @@ export default {
<style lang="scss">
.previewCode {
.previewCodeTool {
display: flex;
align-items: center;
padding: 5px 0;
margin-top: -40px;
}
.tab-info {
height: 50vh;
background: #fff;
+158 -134
View File
@@ -1,136 +1,139 @@
<template>
<div>
<!-- 从数据库直接获取字段 -->
<el-collapse v-model="activeNames">
<el-collapse-item name="1">
<template #title>
<div :style="{fontSize:'16px',paddingLeft:'20px'}">
点这里从现有数据库创建代码
<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 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-select>
</el-form-item>
<el-form-item label="表名" prop="structName">
<el-select
v-model="dbform.tableName"
:disabled="!dbform.dbName"
filterable
placeholder="请选择表"
>
<el-option
v-for="item in tableOptions"
:key="item.tableName"
:label="item.tableName"
:value="item.tableName"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button size="mini" type="primary" @click="getColumn">使用此表创建</el-button>
</el-form-item>
</el-form>
</el-collapse-item>
</el-collapse>
<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-form-item>
<el-form-item label="tableName" prop="tableName">
<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-form-item>
<el-form-item label="Struct中文名称" prop="description">
<el-input v-model="form.description" placeholder="中文描述作为自动api描述" />
</el-form-item>
<el-form-item label="文件名称" prop="packageName">
<el-input v-model="form.packageName" placeholder="生成文件的默认名称(建议为驼峰格式,首字母小写,如sysXxxXxxx)" />
</el-form-item>
<el-form-item>
<template #label>
<el-tooltip content="注:把自动生成的API注册进数据库" placement="bottom" effect="light">
<div> 自动创建API </div>
</el-tooltip>
</template>
<el-checkbox v-model="form.autoCreateApiToSql" />
</el-form-item>
<el-form-item>
<template #label>
<el-tooltip content="注:自动迁移生成的文件到ymal配置的对应位置" placement="bottom" effect="light">
<div> 自动移动文件 </div>
</el-tooltip>
</template>
<el-checkbox v-model="form.autoMoveFile" />
</el-form-item>
</el-form>
<!-- 组件列表 -->
<div class="gva-btn-list">
<el-button size="mini" 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 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 #default="scope">
<el-button
size="mini"
type="primary"
icon="el-icon-edit"
@click="editAndAddField(scope.row)"
>编辑</el-button>
<el-button
size="mini"
type="text"
:disabled="scope.$index === 0"
@click="moveUpField(scope.$index)"
>上移</el-button>
<el-button
size="mini"
type="text"
:disabled="(scope.$index + 1) === form.fields.length"
@click="moveDownField(scope.$index)"
>下移</el-button>
<el-popover v-model:visible="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 class="gva-search-box">
<el-collapse v-model="activeNames" style="margin-bottom:12px">
<el-collapse-item name="1">
<template #title>
<div :style="{fontSize:'16px',paddingLeft:'20px'}">
点这里从现有数据库创建代码
<i class="header-icon el-icon-thumb" />
</div>
<template #reference>
<el-button size="mini" type="danger" icon="el-icon-delete">删除</el-button>
</template>
</el-popover>
</template>
</el-table-column>
</el-table>
<el-tag type="danger">id , created_at , updated_at , deleted_at 会自动生成请勿重复创建</el-tag>
</template>
<el-form ref="getTableForm" style="margin-top:24px" :inline="true" :model="dbform" label-width="120px">
<el-form-item label="数据库名" prop="structName">
<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-select>
</el-form-item>
<el-form-item label="表名" prop="structName">
<el-select
v-model="dbform.tableName"
:disabled="!dbform.dbName"
filterable
placeholder="请选择表"
>
<el-option
v-for="item in tableOptions"
:key="item.tableName"
:label="item.tableName"
:value="item.tableName"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button size="mini" type="primary" @click="getColumn">使用此表创建</el-button>
</el-form-item>
</el-form>
</el-collapse-item>
</el-collapse>
</div>
<div class="gva-search-box">
<!-- 初始版本自动化代码工具 -->
<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-form-item>
<el-form-item label="TableName" prop="tableName">
<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-form-item>
<el-form-item label="Struct中文名称" prop="description">
<el-input v-model="form.description" placeholder="中文描述作为自动api描述" />
</el-form-item>
<el-form-item label="文件名称" prop="packageName">
<el-input v-model="form.packageName" placeholder="生成文件的默认名称(建议为驼峰格式,首字母小写,如sysXxxXxxx)" />
</el-form-item>
<el-form-item>
<template #label>
<el-tooltip content="注:把自动生成的API注册进数据库" placement="bottom" effect="light">
<div> 自动创建API </div>
</el-tooltip>
</template>
<el-checkbox v-model="form.autoCreateApiToSql" />
</el-form-item>
<el-form-item>
<template #label>
<el-tooltip content="注:自动迁移生成的文件到ymal配置的对应位置" placement="bottom" effect="light">
<div> 自动移动文件 </div>
</el-tooltip>
</template>
<el-checkbox v-model="form.autoMoveFile" />
</el-form-item>
</el-form>
</div>
<!-- 组件列表 -->
<div class="gva-btn-list">
<el-button size="mini" type="primary" @click="enterForm(true)">预览代码</el-button>
<el-button size="mini" type="primary" @click="enterForm(false)">生成代码</el-button>
<div class="gva-table-box">
<div class="gva-btn-list">
<el-button size="mini" type="primary" @click="editAndAddField()">新增Field</el-button>
</div>
<el-table :data="form.fields">
<el-table-column align="left" type="index" label="序列" width="100" />
<el-table-column align="left" prop="fieldName" label="Field名" />
<el-table-column align="left" prop="fieldDesc" label="中文名" />
<el-table-column align="left" prop="fieldJson" label="FieldJson" />
<el-table-column align="left" prop="fieldType" label="Field数据类型" width="130" />
<el-table-column align="left" prop="dataType" label="数据库字段类型" width="130" />
<el-table-column align="left" prop="dataTypeLong" label="数据库字段长度" width="130" />
<el-table-column align="left" prop="columnName" label="数据库字段" width="130" />
<el-table-column align="left" prop="comment" label="数据库字段描述" width="130" />
<el-table-column align="left" prop="fieldSearchType" label="搜索条件" width="130" />
<el-table-column align="left" prop="dictType" label="字典" width="130" />
<el-table-column align="left" label="操作" width="300">
<template #default="scope">
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="editAndAddField(scope.row)"
>编辑</el-button>
<el-button
size="mini"
type="text"
:disabled="scope.$index === 0"
@click="moveUpField(scope.$index)"
>上移</el-button>
<el-button
size="mini"
type="text"
:disabled="(scope.$index + 1) === form.fields.length"
@click="moveDownField(scope.$index)"
>下移</el-button>
<el-popover :visible="scope.row.visible" placement="top">
<p>确定删除吗?</p>
<div style="text-align: right; margin-top: 8px;">
<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>
<template #reference>
<el-button size="mini" type="text" icon="el-icon-delete">删除</el-button>
</template>
</el-popover>
</template>
</el-table-column>
</el-table>
<!-- 组件列表 -->
<div class="gva-btn-list justify-content-flex-end auto-btn-list">
<el-button size="mini" type="primary" @click="enterForm(true)">预览代码</el-button>
<el-button size="mini" type="primary" @click="enterForm(false)">生成代码</el-button>
</div>
</div>
<!-- 组件弹窗 -->
<el-dialog v-model="dialogFlag" title="组件内容">
@@ -144,10 +147,17 @@
</el-dialog>
<el-dialog v-model="previewFlag">
<PreviewCodeDialog v-if="previewFlag" :preview-code="preViewCode" />
<template #title>
<div class="previewCodeTool">
<p>操作栏:</p>
<el-button size="mini" type="primary" @click="selectText">全选</el-button>
<el-button size="mini" type="primary" @click="copy">复制</el-button>
</div>
</template>
<PreviewCodeDialog v-if="previewFlag" ref="preview" :preview-code="preViewCode" />
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="previewFlag = false">确 定</el-button>
<div class="dialog-footer" style="padding-top:14px;padding-right:14px">
<el-button size="small" type="primary" @click="previewFlag = false">确 定</el-button>
</div>
</template>
</el-dialog>
@@ -235,6 +245,12 @@ export default {
}
},
methods: {
selectText() {
this.$refs.preview.selectText()
},
copy() {
this.$refs.preview.copy()
},
editAndAddField(item) {
this.dialogFlag = true
if (item) {
@@ -386,7 +402,7 @@ export default {
this.form.autoCreateApiToSql = true
this.form.fields = []
res.data.columns &&
res.data.columns.map(item => {
res.data.columns.forEach(item => {
if (!gormModelList.some(gormfd => gormfd === item.columnName)) {
const fbHump = toHump(item.columnName)
this.form.fields.push({
@@ -407,9 +423,9 @@ export default {
},
async setFdMap() {
const fdTypes = ['string', 'int', 'bool', 'float64', 'time.Time']
fdTypes.map(async fdtype => {
fdTypes.forEach(async fdtype => {
const res = await getDict(fdtype)
res && res.map(item => {
res && res.forEach(item => {
this.fdMap[item.label] = fdtype
})
})
@@ -425,6 +441,11 @@ export default {
</script>
<style scoped lang="scss">
.previewCodeTool {
display: flex;
align-items: center;
padding: 5px 0;
}
.button-box {
padding: 10px 20px;
.el-button {
@@ -432,4 +453,7 @@ export default {
float: right;
}
}
.auto-btn-list{
margin-top: 16px;
}
</style>
@@ -1,63 +1,63 @@
<template>
<div>
<div class="search-term">
<div class="gva-table-box">
<div class="gva-btn-list">
<el-button size="mini" type="primary" icon="el-icon-plus" @click="goAutoCode(null)">新增</el-button>
</div>
<el-table :data="tableData">
<el-table-column
type="selection"
width="55"
/>
<el-table-column align="left" label="id" width="60" prop="ID" />
<el-table-column align="left" label="日期" width="180">
<template #default="scope">{{ formatDate(scope.row.CreatedAt) }}</template>
</el-table-column>
<el-table-column align="left" label="结构体名" min-width="150" prop="structName" />
<el-table-column align="left" label="结构体描述" min-width="150" prop="structCNName" />
<el-table-column align="left" label="表名称" min-width="150" prop="tableName" />
<el-table-column align="left" label="回滚标记" min-width="150" prop="flag">
<template #default="scope">
<el-tag
v-if="scope.row.flag"
type="danger"
size="mini"
effect="dark"
>
已回滚
</el-tag>
<el-tag
v-else
size="mini"
type="success"
effect="dark"
>
未回滚
</el-tag>
</template>
</el-table-column>
<el-table-column align="left" label="操作" min-width="180">
<template #default="scope">
<div>
<el-button size="mini" type="text" :disabled="scope.row.flag === 1" @click="rollback(scope.row)">回滚</el-button>
<el-button size="mini" type="text" @click="goAutoCode(scope.row)">复用</el-button>
<el-button size="mini" type="text" @click="deleteRow(scope.row)">删除</el-button>
</div>
</template>
</el-table-column>
</el-table>
<div class="gva-pagination">
<el-pagination
:current-page="page"
:page-size="pageSize"
:page-sizes="[10, 30, 50, 100]"
:total="total"
layout="total, sizes, prev, pager, next, jumper"
@current-change="handleCurrentChange"
@size-change="handleSizeChange"
/>
</div>
</div>
<el-table :data="tableData" border stripe>
<el-table-column
type="selection"
width="55"
/>
<el-table-column label="id" width="60" prop="ID" />
<el-table-column label="日期" width="180">
<template #default="scope">{{ formatDate(scope.row.CreatedAt) }}</template>
</el-table-column>
<el-table-column label="结构体名" min-width="150" prop="structName" />
<el-table-column label="结构体描述" min-width="150" prop="structCNName" />
<el-table-column label="表名称" min-width="150" prop="tableName" />
<el-table-column label="回滚标记" min-width="150" prop="flag">
<template #default="scope">
<el-tag
v-if="scope.row.flag"
type="danger"
size="mini"
effect="dark"
>
已回滚
</el-tag>
<el-tag
v-else
size="mini"
type="success"
effect="dark"
>
未回滚
</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" min-width="180">
<template #default="scope">
<div>
<el-button size="mini" type="primary" :disabled="scope.row.flag === 1" @click="rollback(scope.row)">回滚</el-button>
<el-button size="mini" type="success" @click="goAutoCode(scope.row)">复用</el-button>
<el-button size="mini" type="danger" @click="deleteRow(scope.row)">删除</el-button>
</div>
</template>
</el-table-column>
</el-table>
<el-pagination
:current-page="page"
:page-size="pageSize"
: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"
/>
</div>
</template>
@@ -1,16 +1,18 @@
<template>
<div style="height:80vh">
<iframe width="100%" height="100%" :src="basePath+':8888/form-generator/#/'" frameborder="0" />
<iframe width="100%" height="100%" :src="`${basePath}:${basePort}/form-generator/#/`" frameborder="0" />
</div>
</template>
<script>
var path = import.meta.env.VITE_BASE_PATH
var port = import.meta.env.VITE_SERVER_PORT
export default {
name: 'FormGenerator',
data() {
return {
basePath: path
basePath: path,
basePort: port
}
}
}
+2 -7
View File
@@ -1,17 +1,12 @@
<template>
<div>
<router-view v-if="$route.meta.keepAlive" v-slot="{ Component }">
<router-view v-slot="{ Component }">
<transition mode="out-in" name="el-fade-in-linear">
<keep-alive>
<keep-alive :include="$store.getters['router/keepAliveRouters']">
<component :is="Component" />
</keep-alive>
</transition>
</router-view>
<router-view v-if="!$route.meta.keepAlive" v-slot="{ Component }">
<transition mode="out-in" name="el-fade-in-linear">
<component :is="Component" />
</transition>
</router-view>
</div>
</template>
+332 -292
View File
@@ -1,304 +1,330 @@
<template>
<div class="system">
<el-form ref="form" :model="config" label-width="100px" class="system">
<el-form ref="form" :model="config" label-width="240px">
<!-- System start -->
<h2>系统配置</h2>
<el-form-item label="环境值">
<el-input v-model="config.system.env" />
</el-form-item>
<el-form-item label="端口值">
<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 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 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-form-item>
<el-form-item label="数据初始化">
<el-checkbox v-model="config.system.needInitData">开启</el-checkbox>
</el-form-item>
<el-form-item label="多点登录拦截">
<el-checkbox v-model="config.system.useMultipoint">开启</el-checkbox>
</el-form-item>
<!-- System end -->
<el-collapse v-model="activeNames" @change="handleChange">
<el-collapse-item title="系统配置" name="1">
<el-form-item label="环境值">
<el-input v-model="config.system.env" />
</el-form-item>
<el-form-item label="端口值">
<el-input v-model.number="config.system.addr" />
</el-form-item>
<el-form-item label="数据库类型">
<el-select v-model="config.system.dbType" style="width:100%">
<el-option value="mysql" />
<el-option value="pgsql" />
</el-select>
</el-form-item>
<el-form-item label="Oss类型">
<el-select v-model="config.system.ossType" style="width:100%">
<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-checkbox v-model="config.system.useMultipoint">开启</el-checkbox>
</el-form-item>
<el-form-item label="限流次数">
<el-input-number v-model.number="config.system.iplimitCount" />
</el-form-item>
<el-form-item label="限流时间">
<el-input-number v-model.number="config.system.iplimitTime" />
</el-form-item>
</el-collapse-item>
<el-collapse-item title="jwt签名" name="2">
<el-form-item label="jwt签名">
<el-input v-model="config.jwt.signingKey" />
</el-form-item>
<el-form-item label="有效期(秒)">
<el-input v-model="config.jwt.expiresTime" />
</el-form-item>
<el-form-item label="缓冲期(秒)">
<el-input v-model="config.jwt.bufferTime" />
</el-form-item>
<el-form-item label="签发者">
<el-input v-model="config.jwt.issuer" />
</el-form-item>
</el-collapse-item>
<el-collapse-item title="Zap日志配置" name="3">
<el-form-item label="级别">
<el-input v-model.number="config.zap.level" />
</el-form-item>
<el-form-item label="输出">
<el-input v-model="config.zap.format" />
</el-form-item>
<el-form-item label="日志前缀">
<el-input v-model="config.zap.prefix" />
</el-form-item>
<el-form-item label="日志文件夹">
<el-input v-model="config.zap.director" />
</el-form-item>
<el-form-item label="编码级">
<el-input v-model="config.zap.encodeLevel" />
</el-form-item>
<el-form-item label="栈名">
<el-input v-model="config.zap.stacktraceKey" />
</el-form-item>
<el-form-item label="显示行">
<el-checkbox v-model="config.zap.showLine" />
</el-form-item>
<el-form-item label="输出控制台">
<el-checkbox v-model="config.zap.logInConsole" />
</el-form-item>
</el-collapse-item>
<el-collapse-item title="Redis admin数据库配置" name="4">
<el-form-item label="db">
<el-input v-model="config.redis.db" />
</el-form-item>
<el-form-item label="addr">
<el-input v-model="config.redis.addr" />
</el-form-item>
<el-form-item label="password">
<el-input v-model="config.redis.password" />
</el-form-item>
</el-collapse-item>
<!-- JWT start -->
<h2>jwt签名</h2>
<el-form-item label="jwt签名">
<el-input v-model="config.jwt.signingKey" />
</el-form-item>
<!-- JWT end -->
<el-collapse-item title="邮箱配置" name="5">
<el-form-item label="接收者邮箱">
<el-input v-model="config.email.to" placeholder="可多个,以逗号分隔" />
</el-form-item>
<el-form-item label="端口">
<el-input v-model.number="config.email.port" />
</el-form-item>
<el-form-item label="发送者邮箱">
<el-input v-model="config.email.from" />
</el-form-item>
<el-form-item label="host">
<el-input v-model="config.email.host" />
</el-form-item>
<el-form-item label="是否为ssl">
<el-checkbox v-model="config.email.isSSL" />
</el-form-item>
<el-form-item label="secret">
<el-input v-model="config.email.secret" />
</el-form-item>
<el-form-item label="测试邮件">
<el-button @click="email">测试邮件</el-button>
</el-form-item>
</el-collapse-item>
<el-collapse-item title="casbin配置" name="6">
<el-form-item label="模型地址">
<el-input v-model="config.casbin.modelPath" />
</el-form-item>
</el-collapse-item>
<!-- Zap start -->
<h2>Zap日志配置</h2>
<el-form-item label="级别">
<el-input v-model.number="config.zap.level" />
</el-form-item>
<el-form-item label="输出">
<el-input v-model="config.zap.format" />
</el-form-item>
<el-form-item label="日志前缀">
<el-input v-model="config.zap.prefix" />
</el-form-item>
<el-form-item label="日志文件夹">
<el-input v-model="config.zap.director" />
</el-form-item>
<el-form-item label="软链接名称">
<el-input v-model="config.zap.linkName" />
</el-form-item>
<el-form-item label="编码级">
<el-input v-model="config.zap.encodeLevel" />
</el-form-item>
<el-form-item label="栈名">
<el-input v-model="config.zap.stacktraceKey" />
</el-form-item>
<el-form-item label="显示行">
<el-checkbox v-model="config.zap.showLine" />
</el-form-item>
<el-form-item label="输出控制台">
<el-checkbox v-model="config.zap.logInConsole" />
</el-form-item>
<!-- Zap end -->
<el-collapse-item title="验证码配置" name="7">
<el-form-item label="keyLong">
<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-form-item>
<el-form-item label="imgHeight">
<el-input v-model.number="config.captcha.imgHeight" />
</el-form-item>
</el-collapse-item>
<!-- Redis start -->
<h2>Redis admin数据库配置</h2>
<el-form-item label="db">
<el-input v-model="config.redis.db" />
</el-form-item>
<el-form-item label="addr">
<el-input v-model="config.redis.addr" />
</el-form-item>
<el-form-item label="password">
<el-input v-model="config.redis.password" />
</el-form-item>
<!-- Redis end -->
<el-collapse-item title="验证码配置" name="8">
<el-form-item label="keyLong">
<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-form-item>
<el-form-item label="imgHeight">
<el-input v-model.number="config.captcha.imgHeight" />
</el-form-item>
</el-collapse-item>
<!-- Email start -->
<h2>邮箱配置</h2>
<el-form-item label="接收者邮箱">
<el-input v-model="config.email.to" placeholder="可多个,以逗号分隔" />
</el-form-item>
<el-form-item label="端口">
<el-input v-model.number="config.email.port" />
</el-form-item>
<el-form-item label="发送者邮箱">
<el-input v-model="config.email.from" />
</el-form-item>
<el-form-item label="host">
<el-input v-model="config.email.host" />
</el-form-item>
<el-form-item label="是否为ssl">
<el-checkbox v-model="config.email.isSSL" />
</el-form-item>
<el-form-item label="secret">
<el-input v-model="config.email.secret" />
</el-form-item>
<el-form-item label="测试邮件">
<el-button @click="email">测试邮件</el-button>
</el-form-item>
<!-- Email end -->
<el-collapse-item title="数据库配置" name="9">
<template v-if="config.system.dbType === 'mysql'">
<el-form-item label="username">
<el-input v-model="config.mysql.username" />
</el-form-item>
<el-form-item label="password">
<el-input v-model="config.mysql.password" />
</el-form-item>
<el-form-item label="path">
<el-input v-model="config.mysql.path" />
</el-form-item>
<el-form-item label="dbname">
<el-input v-model="config.mysql.dbname" />
</el-form-item>
<el-form-item label="maxIdleConns">
<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-form-item>
<el-form-item label="logMode">
<el-checkbox v-model="config.mysql.logMode" />
</el-form-item>
</template>
<template v-if="config.system.dbType === 'pgsql'">
<el-form-item label="username">
<el-input v-model="config.pgsql.username" />
</el-form-item>
<el-form-item label="password">
<el-input v-model="config.pgsql.password" />
</el-form-item>
<el-form-item label="path">
<el-input v-model="config.pgsql.path" />
</el-form-item>
<el-form-item label="dbname">
<el-input v-model="config.pgsql.dbname" />
</el-form-item>
<el-form-item label="maxIdleConns">
<el-input v-model.number="config.pgsql.maxIdleConns" />
</el-form-item>
<el-form-item label="maxOpenConns">
<el-input v-model.number="config.pgsql.maxOpenConns" />
</el-form-item>
<el-form-item label="logMode">
<el-checkbox v-model="config.pgsql.logMode" />
</el-form-item>
</template>
</el-collapse-item>
<!-- Casbin start -->
<h2>casbin配置</h2>
<el-form-item label="模型地址">
<el-input v-model="config.casbin.modelPath" />
</el-form-item>
<!-- Casbin end -->
<el-collapse-item title="oss配置" name="10">
<template v-if="config.system.ossType === 'local'">
<h2>本地文件配置</h2>
<el-form-item label="本地文件路径">
<el-input v-model="config.local.path" />
</el-form-item>
</template>
<template v-if="config.system.ossType === 'qiniu'">
<h2>qiniu上传配置</h2>
<el-form-item label="存储区域">
<el-input v-model="config.qiniu.zone" />
</el-form-item>
<el-form-item label="空间名称">
<el-input v-model="config.qiniu.bucket" />
</el-form-item>
<el-form-item label="CDN加速域名">
<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-form-item>
<el-form-item label="secretKey">
<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'">
<h2>腾讯云COS上传配置</h2>
<el-form-item label="bucket">
<el-input v-model="config.tencentCOS.bucket" />
</el-form-item>
<el-form-item label="region">
<el-input v-model="config.tencentCOS.region" />
</el-form-item>
<el-form-item label="secretID">
<el-input v-model="config.tencentCOS.secretID" />
</el-form-item>
<el-form-item label="secretKey">
<el-input v-model="config.tencentCOS.secretKey" />
</el-form-item>
<el-form-item label="pathPrefix">
<el-input v-model="config.tencentCOS.pathPrefix" />
</el-form-item>
<el-form-item label="baseURL">
<el-input v-model="config.tencentCOS.baseURL" />
</el-form-item>
</template>
<template v-if="config.system.ossType === 'aliyun-oss'">
<h2>阿里云OSS上传配置</h2>
<el-form-item label="endpoint">
<el-input v-model="config.aliyunOSS.endpoint" />
</el-form-item>
<el-form-item label="accessKeyId">
<el-input v-model="config.aliyunOSS.accessKeyId" />
</el-form-item>
<el-form-item label="accessKeySecret">
<el-input v-model="config.aliyunOSS.accessKeySecret" />
</el-form-item>
<el-form-item label="bucketName">
<el-input v-model="config.aliyunOSS.bucketName" />
</el-form-item>
<el-form-item label="bucketUrl">
<el-input v-model="config.aliyunOSS.bucketUrl" />
</el-form-item>
</template>
<!-- Captcha start -->
<h2>验证码配置</h2>
<el-form-item label="keyLong">
<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-form-item>
<el-form-item label="imgHeight">
<el-input v-model.number="config.captcha.imgHeight" />
</el-form-item>
<!-- Captcha end -->
</el-collapse-item>
<!-- dbType start -->
<template v-if="config.system.dbType === 'mysql'">
<h2>mysql admin数据库配置</h2>
<el-form-item label="username">
<el-input v-model="config.mysql.username" />
</el-form-item>
<el-form-item label="password">
<el-input v-model="config.mysql.password" />
</el-form-item>
<el-form-item label="path">
<el-input v-model="config.mysql.path" />
</el-form-item>
<el-form-item label="dbname">
<el-input v-model="config.mysql.dbname" />
</el-form-item>
<el-form-item label="maxIdleConns">
<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-form-item>
<el-form-item label="logMode">
<el-checkbox v-model="config.mysql.logMode" />
</el-form-item>
</template>
<template v-if="config.system.dbType === 'sqlite'">
<h2>sqlite admin数据库配置</h2>
<el-form-item label="path">
<el-input v-model="config.mysql.path" />
</el-form-item>
<el-form-item label="maxIdleConns">
<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-form-item>
<el-form-item label="logger">
<el-checkbox v-model="config.mysql.logger" />
</el-form-item>
</template>
<template v-if="config.system.dbType === 'sqlserver'">
<h2>sqlserver admin数据库配置</h2>
<el-form-item label="username">
<el-input v-model="config.sqlserver.username" />
</el-form-item>
<el-form-item label="password">
<el-input v-model="config.sqlserver.password" />
</el-form-item>
<el-form-item label="path">
<el-input v-model="config.sqlserver.path" />
</el-form-item>
<el-form-item label="dbname">
<el-input v-model="config.sqlserver.dbname" />
</el-form-item>
<el-form-item label="maxIdleConns">
<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-form-item>
<el-form-item label="logger">
<el-checkbox v-model="config.sqlserver.logger" />
</el-form-item>
</template>
<template v-if="config.system.dbType === 'postgresql'">
<h2>postgresql admin数据库配置</h2>
<el-form-item label="username">
<el-input v-model="config.mysql.username" />
</el-form-item>
<el-form-item label="password">
<el-input v-model="config.mysql.password" />
</el-form-item>
<el-form-item label="dbName">
<el-input v-model="config.mysql.dbName" />
</el-form-item>
<el-form-item label="port">
<el-input v-model="config.mysql.port" />
</el-form-item>
<el-form-item label="config">
<el-input v-model="config.mysql.config" />
</el-form-item>
<el-form-item label="maxIdleConns">
<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-form-item>
<el-form-item label="logger">
<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-form-item>
</template>
<!-- dbType end -->
<el-collapse-item title="Excel上传配置" name="11">
<el-form-item label="合成目标地址">
<el-input v-model="config.excel.dir" />
</el-form-item>
</el-collapse-item>
<!-- ossType start -->
<template v-if="config.system.ossType === 'local'">
<h2>本地上传配置</h2>
<el-form-item label="本地文件路径">
<el-input v-model="config.local.path" />
</el-form-item>
</template>
<template v-if="config.system.ossType === 'qiniu'">
<h2>qiniu上传配置</h2>
<el-form-item label="存储区域">
<el-input v-model="config.qiniu.zone" />
</el-form-item>
<el-form-item label="空间名称">
<el-input v-model="config.qiniu.bucket" />
</el-form-item>
<el-form-item label="CDN加速域名">
<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-form-item>
<el-form-item label="secretKey">
<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'">
<h2>腾讯云COS上传配置</h2>
<el-form-item label="bucket">
<el-input v-model="config.tencentCOS.bucket" />
</el-form-item>
<el-form-item label="region">
<el-input v-model="config.tencentCOS.region" />
</el-form-item>
<el-form-item label="secretID">
<el-input v-model="config.tencentCOS.secretID" />
</el-form-item>
<el-form-item label="secretKey">
<el-input v-model="config.tencentCOS.secretKey" />
</el-form-item>
<el-form-item label="pathPrefix">
<el-input v-model="config.tencentCOS.pathPrefix" />
</el-form-item>
<el-form-item label="baseURL">
<el-input v-model="config.tencentCOS.baseURL" />
</el-form-item>
</template>
<template v-if="config.system.ossType === 'aliyun-oss'">
<h2>阿里云OSS上传配置</h2>
<el-form-item label="endpoint">
<el-input v-model="config.aliyunOSS.endpoint" />
</el-form-item>
<el-form-item label="accessKeyId">
<el-input v-model="config.aliyunOSS.accessKeyId" />
</el-form-item>
<el-form-item label="accessKeySecret">
<el-input v-model="config.aliyunOSS.accessKeySecret" />
</el-form-item>
<el-form-item label="bucketName">
<el-input v-model="config.aliyunOSS.bucketName" />
</el-form-item>
<el-form-item label="bucketUrl">
<el-input v-model="config.aliyunOSS.bucketUrl" />
</el-form-item>
</template>
<!-- ossType end -->
<el-collapse-item title="自动化代码配置" name="12">
<el-form-item label="是否自动重启(linux)">
<el-checkbox v-model="config.autoCode.transferRestart" />
</el-form-item>
<el-form-item label="root(项目根路径)">
<el-input v-model="config.autoCode.root" disabled />
</el-form-item>
<el-form-item label="Server(后端代码地址)">
<el-input v-model="config.autoCode.transferRestart" />
</el-form-item>
<el-form-item label="SApi(后端api文件夹地址)">
<el-input v-model="config.autoCode.serverApi" />
</el-form-item>
<el-form-item label="SInitialize(后端Initialize文件夹)">
<el-input v-model="config.autoCode.serverInitialize" />
</el-form-item>
<el-form-item label="SModel(后端Model文件地址)">
<el-input v-model="config.autoCode.serverModel" />
</el-form-item>
<el-form-item label="SRequest(后端Request文件夹地址)">
<el-input v-model="config.autoCode.serverRequest" />
</el-form-item>
<el-form-item label="SRouter(后端Router文件夹地址)">
<el-input v-model="config.autoCode.serverRouter" />
</el-form-item>
<el-form-item label="SService(后端Service文件夹地址)">
<el-input v-model="config.autoCode.serverService" />
</el-form-item>
<el-form-item label="Web(前端文件夹地址)">
<el-input v-model="config.autoCode.web" />
</el-form-item>
<el-form-item label="WApi(后端WApi文件夹地址)">
<el-input v-model="config.autoCode.webApi" />
</el-form-item>
<el-form-item label="WForm(后端WForm文件夹地址)">
<el-input v-model="config.autoCode.webForm" />
</el-form-item>
<el-form-item label="WTable(后端WTable文件夹地址)">
<el-input v-model="config.autoCode.webTable" />
</el-form-item>
</el-collapse-item>
<el-collapse-item title="Timer(定时任务)" name="13">
<el-form-item label="Start(是否启用)">
<el-select v-model="config.timer.wTable" />
</el-form-item>
<el-form-item label="Spec(CRON表达式)">
<el-input v-model="config.timer.spec" />
</el-form-item>
<template v-for="(item,k) in config.timer.detail">
<div v-for="(key,k2) in item" :key="k2">
<el-form-item :key="k+k2" :label="k2">
<el-input v-model="item[k2]" />
</el-form-item>
</div>
</template>
</el-collapse-item>
</el-collapse>
</el-form>
<div class="gva-btn-list">
<el-button type="primary" size="mini" @click="update">立即更新</el-button>
@@ -319,7 +345,9 @@ export default {
jwt: {},
casbin: {},
mysql: {},
sqlite: {},
pgsql: {},
excel: {},
autoCode: {},
redis: {},
qiniu: {},
tencentCOS: {},
@@ -327,7 +355,10 @@ export default {
captcha: {},
zap: {},
local: {},
email: {}
email: {},
timer: {
detail: {}
}
}
}
},
@@ -373,11 +404,20 @@ export default {
<style lang="scss">
.system {
background: #fff;
padding:36px;
border-radius: 2px;
h2 {
padding: 10px;
margin: 10px 0;
font-size: 16px;
box-shadow: -4px 0px 0px 0px #e7e8e8;
}
::v-deep(.el-input-number__increase){
top:5px !important;
}
.gva-btn-list{
margin-top:16px;
}
}
</style>