vue3版本初版上线 自测已可用

This commit is contained in:
piexlmax
2021-08-26 12:45:41 +08:00
parent adc7f567f9
commit 265e42f513
81 changed files with 4478 additions and 18639 deletions
+17 -13
View File
@@ -3,7 +3,9 @@
<el-row :gutter="10">
<el-col :span="12">
<el-card>
<div slot="header">gin-vue-admin</div>
<template #header>
<el-divider>gin-vue-admin</el-divider>
</template>
<div>
<el-row>
<el-col :span="8" :offset="8">
@@ -48,7 +50,9 @@
</div>
</el-card>
<el-card style="margin-top: 20px">
<div slot="header">flipped-aurora团队</div>
<template #header>
<div>flipped-aurora团队</div>
</template>
<div>
<el-row>
<el-col :span="8" :offset="8">
@@ -62,23 +66,23 @@
</el-col>
</el-row>
<el-row style="margin-left: 40px" :gutter="20">
<template v-for="(item, index) in members">
<el-col :key="index" :span="8">
<a :href="item.html_url">
<img class="avatar-img" :src="item.avatar_url">
<a class="author-name" style="">{{ item.login }}</a>
</a>
</el-col>
</template>
<el-col v-for="(item, index) in members" :key="index" :span="8">
<a :href="item.html_url">
<img class="avatar-img" :src="item.avatar_url">
<a class="author-name" style="">{{ item.login }}</a>
</a>
</el-col>
</el-row>
</div>
</el-card>
</el-col>
<el-col :span="12">
<el-card>
<div slot="header">
提交记录
</div>
<template #header>
<div>
提交记录
</div>
</template>
<div>
<Timeline
:timeline-items="dataTimeline"
@@ -1,44 +0,0 @@
<template>
<div>
<div style="width: 100%">
<APlayer :audio="audio" />
</div>
</div>
</template>
<script>
import { APlayer } from '@moefe/vue-aplayer'
export default {
name: 'MusicPlayer',
components: {
APlayer
},
data() {
return {
audio: [
{
name: '东西(Cover:林俊呈)',
artist: '纳豆',
url: 'http://music.163.com/song/media/outer/url?id=1321594530.mp3',
cover: 'https://p1.music.126.net/5zs7IvmLv7KahY3BFzUmrg==/109951163635241613.jpg?param=300y300', // prettier-ignore
lrc: 'https://cdn.moefe.org/music/lrc/thing.lrc'
},
{
name: '响喜乱舞(Cover:MARiA)',
artist: '泠鸢yousa',
url: 'http://music.163.com/song/media/outer/url?id=1318962459.mp3',
cover: 'https://p1.music.126.net/AUGVPQ_rVrngDH9ocQrn3Q==/109951163613037822.jpg?param=300y300', // prettier-ignore
lrc: 'https://cdn.moefe.org/music/lrc/kyoukiranbu.lrc'
},
{
name: '啵唧',
artist: 'Hanser',
url: 'http://music.163.com/song/media/outer/url?id=1321424246.mp3',
cover: 'https://p1.music.126.net/K0-IPcIQ9QFvA0jXTBqoWQ==/109951163636756693.jpg?param=300y300', // prettier-ignore
lrc: 'https://cdn.moefe.org/music/lrc/kiss.lrc'
}
]
}
}
}
</script>
@@ -1,81 +0,0 @@
<template>
<li :class="{ completed: todo.done, editing: editing }" class="todo">
<div class="view">
<input
:checked="todo.done"
class="toggle"
type="checkbox"
@change="toggleTodo( todo)"
>
<label @dblclick="editing = true" v-text="todo.text" />
<button class="destroy" @click="deleteTodo( todo )" />
</div>
<input
v-show="editing"
v-focus="editing"
:value="todo.text"
class="edit"
@keyup.enter="doneEdit"
@keyup.esc="cancelEdit"
@blur="doneEdit"
>
</li>
</template>
<script>
export default {
name: 'Todo',
directives: {
focus(el, { value }, { context }) {
if (value) {
context.$nextTick(() => {
el.focus()
})
}
}
},
props: {
todo: {
type: Object,
default: function() {
return {}
}
}
},
data() {
return {
editing: false
}
},
methods: {
deleteTodo(todo) {
this.$emit('deleteTodo', todo)
},
editTodo({ todo, value }) {
this.$emit('editTodo', { todo, value })
},
toggleTodo(todo) {
this.$emit('toggleTodo', todo)
},
doneEdit(e) {
const value = e.target.value.trim()
const { todo } = this
if (!value) {
this.deleteTodo({
todo
})
} else if (this.editing) {
this.editTodo({
todo,
value
})
this.editing = false
}
},
cancelEdit(e) {
e.target.value = this.todo.text
this.editing = false
}
}
}
</script>
@@ -1,320 +0,0 @@
.todoapp {
font: 14px 'Helvetica Neue', Helvetica, Arial, sans-serif;
line-height: 1.4em;
color: #4d4d4d;
min-width: 230px;
max-width: 666px;
margin: 0 auto ;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
font-weight: 300;
background: #fff;
z-index: 1;
position: relative;
button {
margin: 0;
padding: 0;
border: 0;
background: none;
font-size: 100%;
vertical-align: baseline;
font-family: inherit;
font-weight: inherit;
color: inherit;
-webkit-appearance: none;
appearance: none;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
:focus {
outline: 0;
}
.hidden {
display: none;
}
.todoapp {
background: #fff;
margin: 130px 0 40px 0;
position: relative;
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2), 0 25px 50px 0 rgba(0, 0, 0, 0.1);
}
.todoapp input::-webkit-input-placeholder {
font-style: italic;
font-weight: 300;
color: #e6e6e6;
}
.todoapp input::-moz-placeholder {
font-style: italic;
font-weight: 300;
color: #e6e6e6;
}
.todoapp input::input-placeholder {
font-style: italic;
font-weight: 300;
color: #e6e6e6;
}
.todoapp h1 {
position: absolute;
top: -155px;
width: 100%;
font-size: 100px;
font-weight: 100;
text-align: center;
color: rgba(175, 47, 47, 0.15);
-webkit-text-rendering: optimizeLegibility;
-moz-text-rendering: optimizeLegibility;
text-rendering: optimizeLegibility;
}
.new-todo,
.edit {
position: relative;
margin: 0;
width: 100%;
font-size: 18px;
font-family: inherit;
font-weight: inherit;
line-height: 1.4em;
border: 0;
color: inherit;
padding: 6px;
border: 1px solid #999;
box-shadow: inset 0 -1px 5px 0 rgba(0, 0, 0, 0.2);
box-sizing: border-box;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.new-todo {
padding: 10px 16px 16px 60px;
border: none;
background: rgba(0, 0, 0, 0.003);
box-shadow: inset 0 -2px 1px rgba(0, 0, 0, 0.03);
}
.main {
position: relative;
z-index: 2;
border-top: 1px solid #e6e6e6;
}
.toggle-all {
text-align: center;
border: none;
/* Mobile Safari */
opacity: 0;
position: absolute;
}
.toggle-all+label {
width: 60px;
height: 34px;
font-size: 0;
position: absolute;
top: -52px;
left: -13px;
-webkit-transform: rotate(90deg);
transform: rotate(90deg);
}
.toggle-all+label:before {
content: '❯';
font-size: 22px;
color: #e6e6e6;
padding: 10px 27px 10px 27px;
}
.toggle-all:checked+label:before {
color: #737373;
}
.todo-list {
margin: 0;
padding: 0;
list-style: none;
}
.todo-list li {
position: relative;
font-size: 24px;
border-bottom: 1px solid #ededed;
}
.todo-list li:last-child {
border-bottom: none;
}
.todo-list li.editing {
border-bottom: none;
padding: 0;
}
.todo-list li.editing .edit {
display: block;
width: 506px;
padding: 12px 16px;
margin: 0 0 0 43px;
}
.todo-list li.editing .view {
display: none;
}
.todo-list li .toggle {
text-align: center;
width: 40px;
/* auto, since non-WebKit browsers doesn't support input styling */
height: auto;
position: absolute;
top: 0;
bottom: 0;
margin: auto 0;
border: none;
/* Mobile Safari */
-webkit-appearance: none;
appearance: none;
}
.todo-list li .toggle {
opacity: 0;
}
.todo-list li .toggle+label {
/*
Firefox requires `#` to be escaped - https://bugzilla.mozilla.org/show_bug.cgi?id=922433
IE and Edge requires *everything* to be escaped to render, so we do that instead of just the `#` - https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/7157459/
*/
background-image: url('data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2240%22%20height%3D%2240%22%20viewBox%3D%22-10%20-18%20100%20135%22%3E%3Ccircle%20cx%3D%2250%22%20cy%3D%2250%22%20r%3D%2250%22%20fill%3D%22none%22%20stroke%3D%22%23ededed%22%20stroke-width%3D%223%22/%3E%3C/svg%3E');
background-repeat: no-repeat;
background-position: center left;
background-size: 36px;
}
.todo-list li .toggle:checked+label {
background-size: 36px;
background-image: url('data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2240%22%20height%3D%2240%22%20viewBox%3D%22-10%20-18%20100%20135%22%3E%3Ccircle%20cx%3D%2250%22%20cy%3D%2250%22%20r%3D%2250%22%20fill%3D%22none%22%20stroke%3D%22%23bddad5%22%20stroke-width%3D%223%22/%3E%3Cpath%20fill%3D%22%235dc2af%22%20d%3D%22M72%2025L42%2071%2027%2056l-4%204%2020%2020%2034-52z%22/%3E%3C/svg%3E');
}
.todo-list li label {
word-break: break-all;
padding: 15px 15px 15px 50px;
display: block;
line-height: 1.0;
font-size: 14px;
transition: color 0.4s;
}
.todo-list li.completed label {
color: #d9d9d9;
text-decoration: line-through;
}
.todo-list li .destroy {
display: none;
position: absolute;
top: 0;
right: 10px;
bottom: 0;
width: 40px;
height: 40px;
margin: auto 0;
font-size: 30px;
color: #cc9a9a;
transition: color 0.2s ease-out;
cursor: pointer;
}
.todo-list li .destroy:hover {
color: #af5b5e;
}
.todo-list li .destroy:after {
content: '×';
}
.todo-list li:hover .destroy {
display: block;
}
.todo-list li .edit {
display: none;
}
.todo-list li.editing:last-child {
margin-bottom: -1px;
}
.footer {
color: #777;
position: relative;
padding: 10px 15px;
height: 40px;
text-align: center;
border-top: 1px solid #e6e6e6;
}
.footer:before {
content: '';
position: absolute;
right: 0;
bottom: 0;
left: 0;
height: 40px;
overflow: hidden;
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2), 0 8px 0 -3px #f6f6f6, 0 9px 1px -3px rgba(0, 0, 0, 0.2), 0 16px 0 -6px #f6f6f6, 0 17px 2px -6px rgba(0, 0, 0, 0.2);
}
.todo-count {
float: left;
text-align: left;
}
.todo-count strong {
font-weight: 300;
}
.filters {
margin: 0;
padding: 0;
position: relative;
z-index: 1;
list-style: none;
}
.filters li {
display: inline;
}
.filters li a {
color: inherit;
font-size: 12px;
padding: 3px 7px;
text-decoration: none;
border: 1px solid transparent;
border-radius: 3px;
}
.filters li a:hover {
border-color: rgba(175, 47, 47, 0.1);
}
.filters li a.selected {
border-color: rgba(175, 47, 47, 0.2);
}
.clear-completed,
html .clear-completed:active {
float: right;
position: relative;
line-height: 20px;
text-decoration: none;
cursor: pointer;
}
.clear-completed:hover {
text-decoration: underline;
}
.info {
margin: 65px auto 0;
color: #bfbfbf;
font-size: 10px;
text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);
text-align: center;
}
.info p {
line-height: 1;
}
.info a {
color: inherit;
text-decoration: none;
font-weight: 400;
}
.info a:hover {
text-decoration: underline;
}
/*
Hack to remove background from Mobile Safari.
Can't use it globally since it destroys checkboxes in Firefox
*/
@media screen and (-webkit-min-device-pixel-ratio:0) {
.toggle-all,
.todo-list li .toggle {
background: none;
}
.todo-list li .toggle {
height: 40px;
}
}
@media (max-width: 430px) {
.footer {
height: 50px;
}
.filters {
bottom: 10px;
}
}
}
@@ -1,122 +0,0 @@
<template>
<section class="todoapp">
<!-- header -->
<header class="header">
<input class="new-todo" autocomplete="off" placeholder="Todo List" @keyup.enter="addTodo">
</header>
<!-- main section -->
<section v-show="todos.length" class="main">
<input id="toggle-all" :checked="allChecked" class="toggle-all" type="checkbox" @change="toggleAll({ done: !allChecked })">
<label for="toggle-all" />
<ul class="todo-list">
<todo
v-for="(todo, index) in filteredTodos"
:key="index"
:todo="todo"
@toggleTodo="toggleTodo"
@editTodo="editTodo"
@deleteTodo="deleteTodo"
/>
</ul>
</section>
<!-- footer -->
<footer v-show="todos.length" class="footer">
<span class="todo-count">
<strong>{{ remaining }}</strong>
{{ remaining | pluralize('item') }} left
</span>
<ul class="filters">
<li v-for="(val, key) in filters" :key="key">
<a :class="{ selected: visibility === key }" @click.prevent="visibility = key">{{ key | capitalize }}</a>
</li>
</ul>
<!-- <button class="clear-completed" v-show="todos.length > remaining" @click="clearCompleted">
Clear completed
</button> -->
</footer>
</section>
</template>
<script>
import Todo from './Todo.vue'
const STORAGE_KEY = 'todos'
const filters = {
all: todos => todos,
active: todos => todos.filter(todo => !todo.done),
completed: todos => todos.filter(todo => todo.done)
}
const defaultList = [
{ text: '工作流功能绘制工具', done: false },
{ text: '工作流流转方法', done: false },
{ text: '自动化代码优化', done: false }
]
export default {
components: { Todo },
filters: {
pluralize: (n, w) => n === 1 ? w : w + 's',
capitalize: s => s.charAt(0).toUpperCase() + s.slice(1)
},
data() {
return {
visibility: 'all',
filters,
// todos: JSON.parse(window.localStorage.getItem(STORAGE_KEY)) || defaultList
todos: defaultList
}
},
computed: {
allChecked() {
return this.todos.every(todo => todo.done)
},
filteredTodos() {
return filters[this.visibility](this.todos)
},
remaining() {
return this.todos.filter(todo => !todo.done).length
}
},
methods: {
setLocalStorage() {
window.localStorage.setItem(STORAGE_KEY, JSON.stringify(this.todos))
},
addTodo(e) {
const text = e.target.value
if (text.trim()) {
this.todos.push({
text,
done: false
})
this.setLocalStorage()
}
e.target.value = ''
},
toggleTodo(val) {
val.done = !val.done
this.setLocalStorage()
},
deleteTodo(todo) {
this.todos.splice(this.todos.indexOf(todo), 1)
this.setLocalStorage()
},
editTodo({ todo, value }) {
todo.text = value
this.setLocalStorage()
},
clearCompleted() {
this.todos = this.todos.filter(todo => !todo.done)
this.setLocalStorage()
},
toggleAll({ done }) {
this.todos.forEach(todo => {
todo.done = done
this.setLocalStorage()
})
}
}
}
</script>
<style lang="scss">
@import './index.scss';
</style>
+69 -80
View File
@@ -1,73 +1,71 @@
<template>
<div class="big">
<el-row>
<div class="card">
<el-col :xs="24" :lg="16" :md="16">
<div class="car-left">
<el-row>
<div>
<el-col :xs="4" :md="3" :lg="3">
<span class="card-img">
<img :src="userInfo.headerImg" alt="">
</span>
</el-col>
<el-col :xs="20" :lg="12" :md="12">
<div class="text">
<h4>早安,管理员, 请开始您一天的工作吧!</h4>
<p class="tips-text">
<i class="el-icon-sunny el-icon" />
<span>今日晴,0℃ - 10℃,天气寒冷,注意添加衣物。</span>
</p>
</div>
</el-col>
<el-row class="card">
<el-col :xs="24" :lg="16" :md="16" style="height:90px">
<div class="car-left">
<el-row>
<el-col :xs="4" :md="3" :lg="3">
<span class="card-img">
<img :src="userInfo.headerImg" alt="">
</span>
</el-col>
<el-col :xs="20" :lg="12" :md="12">
<div class="text">
<h4>早安,管理员, 请开始您一天的工作吧!</h4>
<p class="tips-text">
<i class="el-icon-sunny el-icon" />
<span>今日晴,0℃ - 10℃,天气寒冷,注意添加衣物。</span>
</p>
</div>
</el-row>
</div>
</el-col>
<el-col :xs="24" :lg="8" :md="8">
<div class="car-right">
<el-row>
<el-col :span="8">
<div class="car-item">
<span class="flow"><i class="el-icon-s-grid" /></span>
<span>今日流量 </span>
<b>13260</b>
</div>
</el-col>
<el-col :span="8">
<div class="car-item">
<span class="user-number">
<i class="el-icon-s-custom" />
</span>
<span>总用户 </span>
<b>48286</b>
</div>
</el-col>
<el-col :span="8">
<div class="car-item">
<span class="feedback">
<i class="el-icon-star-on" />
</span>
<span>好评率 </span>
<b>98%</b>
</div>
</el-col>
</el-row>
</div>
</el-col>
</div>
</el-col>
</el-row>
</div>
</el-col>
<el-col :xs="24" :lg="8" :md="8">
<div class="car-right">
<el-row>
<el-col :span="8">
<div class="card-item">
<span class="flow"><i class="el-icon-s-grid" /></span>
<span>今日流量 </span>
<b>13260</b>
</div>
</el-col>
<el-col :span="8">
<div class="card-item">
<span class="user-number">
<i class="el-icon-s-custom" />
</span>
<span>总用户 </span>
<b>48286</b>
</div>
</el-col>
<el-col :span="8">
<div class="card-item">
<span class="feedback">
<i class="el-icon-star-on" />
</span>
<span>好评率 </span>
<b>98%</b>
</div>
</el-col>
</el-row>
</div>
</el-col>
</el-row>
<el-row>
<el-card shadow="hover">
<h2>
使用教学:<a style="color:#409EFF" target="view_window" href="https://www.bilibili.com/video/BV1fV411y7dT/">https://www.bilibili.com/video/BV1fV411y7dT/</a>
</h2>
<br>
<h2>
工作流教学:<a style="color:#409EFF" target="view_window" href="https://www.bilibili.com/video/BV1Ka411F7Ji/">https://www.bilibili.com/video/BV1Ka411F7Ji/</a>
</h2>
<div />
</el-card>
<el-col>
<el-card shadow="hover">
<h2>
使用教学:<a style="color:#409EFF" target="view_window" href="https://www.bilibili.com/video/BV1fV411y7dT/">https://www.bilibili.com/video/BV1fV411y7dT/</a>
</h2>
<br>
<h2>
工作流教学:<a style="color:#409EFF" target="view_window" href="https://www.bilibili.com/video/BV1Ka411F7Ji/">https://www.bilibili.com/video/BV1Ka411F7Ji/</a>
</h2>
<div />
</el-card>
</el-col>
</el-row>
<div class="shadow">
<el-row :gutter="20">
@@ -76,7 +74,7 @@
:key="key"
:span="4"
:xs="8"
@click.native="toTarget(card.name)"
@click="toTarget(card.name)"
>
<el-card shadow="hover" class="grid-content">
<i :class="card.icon" :style="{ color: card.color }" />
@@ -88,14 +86,10 @@
<div class="bottom">
<el-row :gutter="32">
<el-col :xs="24" :sm="24" :lg="12">
<div class="chart-player">
<music-player />
</div>
<div class="chart-player" />
</el-col>
<el-col :xs="24" :sm="24" :lg="12">
<div class="chart-player">
<todo-list />
</div>
<div class="chart-player" />
</el-col>
</el-row>
</div>
@@ -103,17 +97,12 @@
</template>
<script>
import musicPlayer from './component/musicPlayer'
import TodoList from './component/todoList'
import { mapGetters } from 'vuex'
export default {
name: 'Dashboard',
components: {
musicPlayer, // 音乐播放器
TodoList // TodoList
// RaddarChart, //雷达图
// stackMap, //堆叠图
// Sunburst, //旭日图
},
data() {
return {
@@ -171,7 +160,7 @@ export default {
<style lang="scss" scoped>
.big {
margin: 100px 0 0 0;
padding-top: 0;
padding-top: 10px;
background-color: rgb(243, 243, 243);
.top {
width: 100%;
+15 -20
View File
@@ -17,21 +17,25 @@
>
<el-table-column type="selection" width="55" />
<el-table-column label="接入日期" width="180">
<template slot-scope="scope">{{ scope.row.CreatedAt|formatDate }}</template>
<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 slot-scope="scope">
<template #default="scope">
<el-button size="small" type="text" @click="updateCustomer(scope.row)">变更</el-button>
<el-popover v-model="scope.row.visible" placement="top" width="160">
<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>
<el-button slot="reference" type="danger" icon="el-icon-delete" size="mini">删除</el-button>
<template #reference>
<el-button type="danger" icon="el-icon-delete" size="mini">删除</el-button>
</template>
</el-popover>
</template>
</el-table-column>
@@ -48,7 +52,7 @@
@size-change="handleSizeChange"
/>
<el-dialog :before-close="closeDialog" :visible.sync="dialogFormVisible" title="客户">
<el-dialog v-model="dialogFormVisible" :before-close="closeDialog" title="客户">
<el-form :inline="true" :model="form" label-width="80px">
<el-form-item label="客户名">
<el-input v-model="form.customerName" autocomplete="off" />
@@ -57,10 +61,12 @@
<el-input v-model="form.customerPhoneData" autocomplete="off" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="closeDialog">取 消</el-button>
<el-button type="primary" @click="enterDialog">确 定</el-button>
</div>
<template #footer>
<div class="dialog-footer">
<el-button @click="closeDialog">取 消</el-button>
<el-button type="primary" @click="enterDialog">确 定</el-button>
</div>
</template>
</el-dialog>
<div class="tips">在资源权限中将此角色的资源权限清空 或者不包含创建者的角色 即可屏蔽此客户资源的显示</div>
</div>
@@ -74,21 +80,10 @@ import {
getExaCustomer,
getExaCustomerList
} from '@/api/customer'
import { formatTimeToStr } from '@/utils/date'
import infoList from '@/mixins/infoList'
export default {
name: 'Customer',
filters: {
formatDate: function(time) {
if (time !== null && time !== '') {
var date = new Date(time)
return formatTimeToStr(date, 'yyyy-MM-dd hh:mm:ss')
} else {
return ''
}
}
},
mixins: [infoList],
data() {
return {
+2 -1
View File
@@ -18,7 +18,8 @@
<el-table-column label="路由Name" min-width="160" prop="name" />
<el-table-column label="路由Path" min-width="160" prop="path" />
<el-table-column label="是否隐藏" min-width="100" prop="hidden">
<template slot-scope="scope">
<template #default="scope">
<span>{{ scope.row.hidden?"隐藏":"显示" }}</span>
</template>
</el-table-column>
+12 -4
View File
@@ -1,9 +1,17 @@
<template>
<div>
<keep-alive>
<router-view v-if="$route.meta.keepAlive" />
</keep-alive>
<router-view v-if="!$route.meta.keepAlive" />
<router-view v-if="$route.meta.keepAlive" v-slot="{ Component }">
<transition mode="out-in" name="el-fade-in-linear">
<keep-alive>
<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>
@@ -1,161 +0,0 @@
<template>
<uploader
:options="options"
:file-status-text="statusText"
:auto-start="false"
class="uploader-example"
@file-added="fileAdded"
@file-progress="onFileProgress"
@file-success="onFileSuccess"
@file-error="onFileError"
>
<uploader-unsupport />
<uploader-drop>
<p>拖拽文件至此或点击</p>
<uploader-btn>选择文件</uploader-btn>
</uploader-drop>
<uploader-list />
</uploader>
</template>
<script>
var notUploadedChunks = [] // 已经上传过的文件chunkNumber数组
var isUploaded = false // 文件已经上传成功了
import { mapGetters } from 'vuex'
import { checkFileMd5, mergeFileMd5 } from '@/api/simpleUploader'
import SparkMD5 from 'spark-md5'
const path = process.env.VUE_APP_BASE_API
export default {
name: 'SimpleUploader',
data() {
return {
md5: ''
}
},
computed: {
...mapGetters('user', ['userInfo', 'token']),
statusText() {
return {
success: '成功了',
error: '出错了',
uploading: '上传中',
paused: '暂停中',
waiting: '等待中'
}
},
options() {
return {
target: path + '/simpleUploader/upload',
testChunks: false,
simultaneousUploads: 5,
chunkSize: 2 * 1024 * 1024,
headers: {
'x-token': this.token,
'x-user-id': this.userInfo.ID
},
checkChunkUploadedByResponse(chunk) {
if (isUploaded) {
return true // return true 会忽略当前文件,不会再发送给后台
} else {
// 根据已经上传过的切片来进行忽略
return (
notUploadedChunks &&
notUploadedChunks.some(
item => item.chunkNumber === chunk.offset + 1
)
)
}
}
}
}
},
methods: {
// 上传单个文件
fileAdded(file) {
this.computeMD5(file) // 生成MD5
},
// 计算MD5值
computeMD5(file) {
var that = this
isUploaded = false // 这个文件是否已经上传成功过
notUploadedChunks = [] // 未成功的chunkNumber
var fileReader = new FileReader()
var md5 = ''
file.pause()
fileReader.readAsArrayBuffer(file.file)
fileReader.onload = async function(e) {
if (file.size !== e.target.result.byteLength) {
this.error(
'Browser reported success but could not read the file until the end.'
)
return false
}
md5 = SparkMD5.ArrayBuffer.hash(e.target.result, false)
file.uniqueIdentifier = md5
if (md5 !== '') {
const res = await checkFileMd5({ md5: md5 })
if (res.code === 0) {
if (res.data.isDone) {
// 上传成功过
isUploaded = true
that.$message({
message: '该文件已经上传成功过了,秒传成功。',
type: 'success'
})
file.cancel()
} else {
isUploaded = false
notUploadedChunks = res.data.chunks
if (notUploadedChunks.length) {
file.resume()
}
}
}
}
}
fileReader.onerror = function() {
this.error(
'generater md5 时FileReader异步读取文件出错了,FileReader onerror was triggered, maybe the browser aborted due to high memory usage.'
)
return false
}
},
// 上传进度
onFileProgress() {},
// 上传成功
async onFileSuccess(rootFile, file) {
await mergeFileMd5({ md5: file.uniqueIdentifier, fileName: file.name })
},
onFileError(rootFile, file, response) {
this.$message({
message: response,
type: 'error'
})
}
}
}
</script>
<style>
.uploader-example {
width: 880px;
padding: 15px;
margin: 15px 15px 20px;
font-size: 12px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.4);
}
.uploader-example .uploader-btn {
margin-right: 4px;
}
.uploader-example .uploader-list {
max-height: 440px;
overflow: auto;
overflow-x: hidden;
overflow-y: auto;
}
</style>
+8 -17
View File
@@ -12,7 +12,9 @@
:show-file-list="false"
>
<el-button size="small" type="primary">点击上传</el-button>
<div slot="tip" class="el-upload__tip">只能上传jpg/png文件,且不超过500kb</div>
<template #tip>
<div class="el-upload__tip">只能上传jpg/png文件,且不超过500kb</div>
</template>
</el-upload>
</el-col>
<el-col :span="12">
@@ -24,19 +26,19 @@
<el-table :data="tableData" border stripe>
<el-table-column label="预览" width="100">
<template slot-scope="scope">
<template #default="scope">
<CustomPic pic-type="file" :pic-src="scope.row.url" />
</template>
</el-table-column>
<el-table-column label="日期" prop="UpdatedAt" width="180">
<template slot-scope="scope">
<div>{{ scope.row.UpdatedAt | formatDate }}</div>
<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">
<template slot-scope="scope">
<template #default="scope">
<el-tag
:type="scope.row.tag === 'jpg' ? 'primary' : 'success'"
disable-transitions
@@ -44,7 +46,7 @@
</template>
</el-table-column>
<el-table-column label="操作" width="160">
<template slot-scope="scope">
<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>
</template>
@@ -70,7 +72,6 @@ import { mapGetters } from 'vuex'
import infoList from '@/mixins/infoList'
import { getFileList, deleteFile } from '@/api/fileUploadAndDownload'
import { downloadImage } from '@/utils/downloadImg'
import { formatTimeToStr } from '@/utils/date'
import CustomPic from '@/components/customPic'
import UploadImage from '@/components/upload/image.vue'
export default {
@@ -79,16 +80,6 @@ export default {
CustomPic,
UploadImage
},
filters: {
formatDate: function(time) {
if (time !== null && time !== '') {
var date = new Date(time)
return formatTimeToStr(date, 'yyyy-MM-dd hh:mm:ss')
} else {
return ''
}
}
},
mixins: [infoList],
data() {
return {
-1
View File
@@ -82,7 +82,6 @@ export default {
methods: {
showNext() {
this.hello = this.hello + 1
console.log(this.hello)
},
goDoc() {
window.open('https://www.gin-vue-admin.com/docs/first_master#3-init')
@@ -1,11 +1,11 @@
<template>
<el-submenu ref="subMenu" :popper-append-to-body="false" :index="routerInfo.name">
<template slot="title">
<el-sub-menu ref="subMenu" :index="routerInfo.name">
<template #title>
<i :class="'el-icon-'+routerInfo.meta.icon" />
<span slot="title">{{ routerInfo.meta.title }}</span>
<span>{{ routerInfo.meta.title }}</span>
</template>
<slot />
</el-submenu>
</el-sub-menu>
</template>
<script>
@@ -1,7 +1,9 @@
<template>
<el-menu-item :index="routerInfo.name" :route="{parameters:routerInfo.parameters}">
<i :class="'el-icon-'+routerInfo.meta.icon" />
<span slot="title">{{ routerInfo.meta.title }}</span>
<template #title>
<span>{{ routerInfo.meta.title }}</span>
</template>
</el-menu-item>
</template>
@@ -2,9 +2,9 @@
<div class="router-history">
<el-tabs
v-model="activeValue"
:closable="!(historys.length===1&&this.$route.name===defaultRouter)"
:closable="!(historys.length===1&&$route.name===defaultRouter)"
type="card"
@contextmenu.prevent.native="openContextMenu($event)"
@contextmenu.prevent="openContextMenu($event)"
@tab-click="changeTab"
@tab-remove="removeTab"
>
@@ -16,7 +16,9 @@
:tab="item"
class="gva-tab"
>
<span slot="label" :style="{color: activeValue===name(item)?activeColor:'#333'}"><i class="dot" :style="{backgroundColor:activeValue===name(item)?activeColor:'#ddd'}" /> {{ item.meta.title }}</span>
<template #label>
<span :style="{color: activeValue===name(item)?activeColor:'#333'}"><i class="dot" :style="{backgroundColor:activeValue===name(item)?activeColor:'#ddd'}" /> {{ item.meta.title }}</span>
</template>
</el-tab-pane>
</el-tabs>
@@ -32,6 +34,8 @@
<script>
import { mapGetters } from 'vuex'
import { emitter } from '@/utils/bus.js'
const getFmtString = (item) => {
return item.name +
JSON.stringify(item.query) +
@@ -75,15 +79,15 @@ export default {
sessionStorage.setItem('historys', JSON.stringify(this.historys))
this.activeValue = window.sessionStorage.getItem('activeValue')
if (now && to && now.name === to.name) {
this.$bus.$emit('reload')
emitter.emit('reload')
}
}
},
created() {
this.$bus.on('mobile', isMobile => {
emitter.on('mobile', isMobile => {
this.isMobile = isMobile
})
this.$bus.on('collapse', isCollapse => {
emitter.on('collapse', isCollapse => {
this.isCollapse = isCollapse
})
const initHistorys = [
@@ -107,8 +111,8 @@ export default {
},
beforeDestroy() {
this.$bus.off('collapse')
this.$bus.off('mobile')
emitter.off('collapse')
emitter.off('mobile')
},
methods: {
name(item) {
@@ -120,7 +124,6 @@ export default {
}
let id = ''
if (e.srcElement.nodeName === 'SPAN') {
console.log(e)
id = e.srcElement.offsetParent.id
} else {
id = e.srcElement.id
@@ -236,7 +239,7 @@ export default {
)
},
changeTab(component) {
const tab = component.$attrs.tab
const tab = component.instance.attrs.tab
this.$router.push({
name: tab.name,
query: tab.query,
+7 -5
View File
@@ -4,7 +4,7 @@
<transition :duration="{ enter: 800, leave: 100 }" mode="out-in" name="el-fade-in-linear">
<el-menu
:collapse="isCollapse"
:collapse-transition="true"
:collapse-transition="false"
:default-active="active"
:background-color="sideMode"
:active-text-color="activeColor"
@@ -25,6 +25,8 @@
<script>
import { mapGetters, mapMutations } from 'vuex'
import AsideComponent from '@/view/layout/aside/asideComponent'
import { emitter } from '@/utils/bus.js'
export default {
name: 'Aside',
components: {
@@ -52,12 +54,12 @@ export default {
this.isCollapse = !this.isCollapse
}
this.$bus.on('collapse', item => {
emitter.on('collapse', item => {
this.isCollapse = item
})
},
beforeDestroy() {
this.$bus.off('collapse')
emitter.off('collapse')
},
methods: {
...mapMutations('history', ['addHistory']),
@@ -84,13 +86,13 @@ export default {
</script>
<style lang="scss">
.el-submenu__title,.el-menu-item{
.el-sub-menu__title,.el-menu-item{
i{
color: inherit !important;
}
}
.el-submenu__title:hover,.el-menu-item:hover{
.el-sub-menu__title:hover,.el-menu-item:hover{
i{
color: inherit !important;
}
+75 -62
View File
@@ -1,7 +1,7 @@
<template>
<el-container class="layout-cont">
<el-container :class="[isSider?'openside':'hideside',isMobile ? 'mobile': '']">
<el-row :class="[isShadowBg?'shadowBg':'']" @click.native="changeShadow()" />
<el-row :class="[isShadowBg?'shadowBg':'']" @click="changeShadow()" />
<el-aside class="main-cont main-left">
<div class="tilte" :style="{background: backgroundColor}">
<img alt class="logoimg" :src="$GIN_VUE_ADMIN.appLogo">
@@ -18,52 +18,59 @@
>
<el-row>
<!-- :xs="8" :sm="6" :md="4" :lg="3" :xl="1" -->
<el-header class="header-cont">
<el-col :xs="2" :lg="1" :md="1" :sm="1" :xl="1">
<div class="menu-total" @click="totalCollapse">
<i v-if="isCollapse" class="el-icon-s-unfold" />
<i v-else class="el-icon-s-fold" />
</div>
</el-col>
<el-col :xs="10" :lg="14" :md="14" :sm="9" :xl="14">
<el-breadcrumb class="breadcrumb" separator-class="el-icon-arrow-right">
<el-breadcrumb-item
v-for="item in matched.slice(1,matched.length)"
:key="item.path"
>{{ item.meta.title }}</el-breadcrumb-item>
</el-breadcrumb>
</el-col>
<el-col :xs="12" :lg="9" :md="9" :sm="14" :xl="9">
<div class="fl-right right-box">
<Search />
<Screenfull class="screenfull" :style="{cursor:'pointer'}" />
<el-dropdown>
<span class="header-avatar" style="cursor: pointer">
<CustomPic />
<span style="margin-left: 5px">{{ userInfo.nickName }}</span>
<i class="el-icon-arrow-down" />
</span>
<el-dropdown-menu slot="dropdown" class="dropdown-group">
<el-dropdown-item>
<span style="font-weight: 600;">
当前角色:{{ userInfo.authority.authorityName }}
</span>
</el-dropdown-item>
<template v-if="userInfo.authorities">
<el-dropdown-item v-for="item in userInfo.authorities.filter(i=>i.authorityId!==userInfo.authorityId)" :key="item.authorityId" @click.native="changeUserAuth(item.authorityId)">
<span>
切换为:{{ item.authorityName }}
<el-col>
<el-header class="header-cont">
<el-row class="pd-0">
<el-col :xs="2" :lg="1" :md="1" :sm="1" :xl="1">
<div class="menu-total" @click="totalCollapse">
<i v-if="isCollapse" class="el-icon-s-unfold" />
<i v-else class="el-icon-s-fold" />
</div>
</el-col>
<el-col :xs="10" :lg="14" :md="14" :sm="9" :xl="14">
<el-breadcrumb class="breadcrumb" separator-class="el-icon-arrow-right">
<el-breadcrumb-item
v-for="item in matched.slice(1,matched.length)"
:key="item.path"
>{{ item.meta.title }}</el-breadcrumb-item>
</el-breadcrumb>
</el-col>
<el-col :xs="12" :lg="9" :md="9" :sm="14" :xl="9">
<div class="fl-right right-box">
<Search />
<Screenfull class="screenfull" :style="{cursor:'pointer'}" />
<el-dropdown>
<div class="dp-flex justify-content-center align-items height-full width-full">
<span class="header-avatar" style="cursor: pointer">
<CustomPic />
<span style="margin-left: 5px">{{ userInfo.nickName }}</span>
<i class="el-icon-arrow-down" />
</span>
</el-dropdown-item>
</template>
<el-dropdown-item icon="el-icon-s-custom" @click.native="toPerson">个人信息</el-dropdown-item>
<el-dropdown-item icon="el-icon-table-lamp" @click.native="LoginOut">登 出</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
</el-col>
</el-header>
</div>
<template #dropdown>
<el-dropdown-menu class="dropdown-group">
<el-dropdown-item>
<span style="font-weight: 600;">
当前角色:{{ userInfo.authority.authorityName }}
</span>
</el-dropdown-item>
<template v-if="userInfo.authorities">
<el-dropdown-item v-for="item in userInfo.authorities.filter(i=>i.authorityId!==userInfo.authorityId)" :key="item.authorityId" @click="changeUserAuth(item.authorityId)">
<span>
切换为:{{ item.authorityName }}
</span>
</el-dropdown-item>
</template>
<el-dropdown-item icon="el-icon-s-custom" @click="toPerson">个人信息</el-dropdown-item>
<el-dropdown-item icon="el-icon-table-lamp" @click="LoginOut">登 出</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</div>
</el-col>
</el-row>
</el-header>
</el-col>
</el-row>
<!-- 当前面包屑用路由自动生成可根据需求修改 -->
<!--
@@ -71,14 +78,19 @@
<HistoryComponent />
</div>
</transition>
<transition mode="out-in" name="el-fade-in-linear">
<keep-alive>
<router-view v-if="$route.meta.keepAlive && reloadFlag" v-loading="loadingFlag" element-loading-text="正在加载中" class="admin-box" />
</keep-alive>
</transition>
<transition mode="out-in" name="el-fade-in-linear">
<router-view v-if="!$route.meta.keepAlive && reloadFlag" v-loading="loadingFlag" element-loading-text="正在加载中" class="admin-box" />
</transition>
<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">
<keep-alive>
<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>
@@ -97,6 +109,7 @@ import { mapGetters, mapActions } from 'vuex'
import CustomPic from '@/components/customPic'
import Setting from './setting'
import { setUserAuthority } from '@/api/user'
import { emitter } from '@/utils/bus.js'
export default {
name: 'Layout',
components: {
@@ -162,13 +175,13 @@ export default {
this.isSider = true
this.isCollapse = false
}
this.$bus.emit('collapse', this.isCollapse)
this.$bus.emit('mobile', this.isMobile)
this.$bus.on('reload', this.reload)
this.$bus.on('showLoading', () => {
emitter.emit('collapse', this.isCollapse)
emitter.emit('mobile', this.isMobile)
emitter.on('reload', this.reload)
emitter.on('showLoading', () => {
this.loadingFlag = true
})
this.$bus.on('closeLoading', () => {
emitter.on('closeLoading', () => {
this.loadingFlag = false
})
window.onresize = () => {
@@ -187,8 +200,8 @@ export default {
this.isSider = true
this.isCollapse = false
}
this.$bus.emit('collapse', this.isCollapse)
this.$bus.emit('mobile', this.isMobile)
emitter.emit('collapse', this.isCollapse)
emitter.emit('mobile', this.isMobile)
})()
}
},
@@ -212,7 +225,7 @@ export default {
this.isCollapse = !this.isCollapse
this.isSider = !this.isCollapse
this.isShadowBg = !this.isCollapse
this.$bus.emit('collapse', this.isCollapse)
emitter.emit('collapse', this.isCollapse)
},
toPerson() {
this.$router.push({ name: 'person' })
+4 -2
View File
@@ -33,6 +33,7 @@
<script>
import { mapGetters } from 'vuex'
import { emitter } from '@/utils/bus.js'
export default {
name: 'SearchComponent',
@@ -44,8 +45,9 @@ export default {
}
},
computed: {
...mapGetters('router', ['routerList'])
...mapGetters('router', ['routerList']),
},
methods: {
changeRouter() {
this.$router.push({ name: this.value })
@@ -62,7 +64,7 @@ export default {
},
handleReload() {
this.reload = true
this.$bus.$emit('reload')
emitter.emit('reload')
setTimeout(() => {
this.reload = false
}, 500)
+1 -1
View File
@@ -2,8 +2,8 @@
<div>
<el-button type="primary" class="drawer-container" icon="el-icon-setting" @click="showSettingDrawer" />
<el-drawer
v-model="drawer"
title="系统配置"
:visible.sync="drawer"
:direction="direction"
:before-close="handleClose"
>
+10 -10
View File
@@ -9,11 +9,13 @@
ref="loginForm"
:model="loginForm"
:rules="rules"
@keyup.enter.native="submitForm"
@keyup.enter="submitForm"
>
<el-form-item prop="username">
<el-input v-model="loginForm.username" placeholder="请输入用户名">
<i slot="suffix" class="el-input__icon el-icon-user" />
<template #suffix>
<i class="el-input__icon el-icon-user" />
</template>
</el-input>
</el-form-item>
<el-form-item prop="password">
@@ -22,11 +24,12 @@
:type="lock === 'lock' ? 'password' : 'text'"
placeholder="请输入密码"
>
<i
slot="suffix"
:class="'el-input__icon el-icon-' + lock"
@click="changeLock"
/>
<template #suffix>
<i
:class="'el-input__icon el-icon-' + lock"
@click="changeLock"
/>
</template>
</el-input>
</el-form-item>
<el-form-item style="position: relative">
@@ -40,14 +43,11 @@
<img
v-if="picPath"
:src="picPath"
width="100%"
height="100%"
alt="请输入验证码"
@click="loginVerify()"
>
</div>
</el-form-item>
<div />
<el-form-item>
<el-button
type="primary"
+7 -5
View File
@@ -79,7 +79,7 @@
<ChooseImg ref="chooseImg" @enter-img="enterImg" />
<el-dialog :visible.sync="showPassword" title="修改密码" width="360px" @close="clearPassword">
<el-dialog v-model="showPassword" title="修改密码" width="360px" @close="clearPassword">
<el-form ref="modifyPwdForm" :model="pwdModify" :rules="rules" label-width="80px">
<el-form-item :minlength="6" label="原密码" prop="password">
<el-input v-model="pwdModify.password" show-password />
@@ -91,10 +91,12 @@
<el-input v-model="pwdModify.confirmPassword" show-password />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="showPassword=false">取 消</el-button>
<el-button type="primary" @click="savePassword">确 定</el-button>
</div>
<template #footer>
<div class="dialog-footer">
<el-button @click="showPassword=false">取 消</el-button>
<el-button type="primary" @click="savePassword">确 定</el-button>
</div>
</template>
</el-dialog>
</div>
</template>
+12 -4
View File
@@ -1,10 +1,18 @@
<template>
<!-- 此路由可作为父类路由通用路由页面使用 如需自定义父类路由页面 请参考 @/view/superAdmin/index.vue -->
<div>
<keep-alive>
<router-view v-if="$route.meta.keepAlive" />
</keep-alive>
<router-view v-if="!$route.meta.keepAlive" />
<router-view v-if="$route.meta.keepAlive" v-slot="{ Component }">
<transition mode="out-in" name="el-fade-in-linear">
<keep-alive>
<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>
+23 -23
View File
@@ -24,13 +24,15 @@
<el-form-item>
<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="deleteVisible" placement="top" width="160">
<el-popover v-model:visible="deleteVisible" placement="top" width="160">
<p>确定要删除吗?</p>
<div style="text-align: right; margin: 0">
<el-button size="mini" type="text" @click="deleteVisible = false">取消</el-button>
<el-button size="mini" type="primary" @click="onDelete">确定</el-button>
</div>
<el-button slot="reference" icon="el-icon-delete" size="mini" type="danger" style="margin-left: 10px;">批量删除</el-button>
<template #reference>
<el-button icon="el-icon-delete" size="mini" type="danger" style="margin-left: 10px;">批量删除</el-button>
</template>
</el-popover>
</el-form-item>
</el-form>
@@ -45,22 +47,21 @@
<el-table-column label="api分组" min-width="150" prop="apiGroup" sortable="custom" />
<el-table-column label="api简介" min-width="150" prop="description" sortable="custom" />
<el-table-column label="请求" min-width="150" prop="method" sortable="custom">
<template slot-scope="scope">
<template #default="scope">
<div>
{{ scope.row.method }}
<el-tag
:key="scope.row.methodFiletr"
:type="scope.row.method|tagTypeFiletr"
:type="tagTypeFiletr(scope.row.method)"
effect="dark"
size="mini"
>{{ scope.row.method|methodFiletr }}</el-tag>
<!-- {{scope.row.method|methodFiletr}} -->
>{{ methodFiletr(scope.row.method) }}</el-tag>
</div>
</template>
</el-table-column>
<el-table-column fixed="right" label="操作" width="200">
<template slot-scope="scope">
<template #default="scope">
<el-button size="small" type="primary" icon="el-icon-edit" @click="editApi(scope.row)">编辑</el-button>
<el-button
size="small"
@@ -82,7 +83,7 @@
@size-change="handleSizeChange"
/>
<el-dialog :before-close="closeDialog" :title="dialogTitle" :visible.sync="dialogFormVisible">
<el-dialog v-model="dialogFormVisible" :before-close="closeDialog" :title="dialogTitle">
<el-form ref="apiForm" :inline="true" :model="form" :rules="rules" label-width="80px">
<el-form-item label="路径" prop="path">
<el-input v-model="form.path" autocomplete="off" />
@@ -105,10 +106,12 @@
</el-form-item>
</el-form>
<div class="warning">新增Api需要在角色管理内配置权限才可使用</div>
<div slot="footer" class="dialog-footer">
<el-button @click="closeDialog">取 消</el-button>
<el-button type="primary" @click="enterDialog">确 定</el-button>
</div>
<template #footer>
<div class="dialog-footer">
<el-button @click="closeDialog">取 消</el-button>
<el-button type="primary" @click="enterDialog">确 定</el-button>
</div>
</template>
</el-dialog>
</div>
</template>
@@ -151,17 +154,6 @@ const methodOptions = [
export default {
name: 'Api',
filters: {
methodFiletr(value) {
const target = methodOptions.filter(item => item.value === value)[0]
// return target && `${target.label}(${target.value})`
return target && `${target.label}`
},
tagTypeFiletr(value) {
const target = methodOptions.filter(item => item.value === value)[0]
return target && `${target.type}`
}
},
mixins: [infoList],
data() {
return {
@@ -196,6 +188,14 @@ export default {
this.getTableData()
},
methods: {
methodFiletr(value) {
const target = methodOptions.filter(item => item.value === value)[0]
return target && `${target.label}`
},
tagTypeFiletr(value) {
const target = methodOptions.filter(item => item.value === value)[0]
return target && `${target.type}`
},
// 选中api
handleSelectionChange(val) {
this.apis = val
+15 -10
View File
@@ -14,7 +14,7 @@
<el-table-column label="角色id" min-width="180" prop="authorityId" />
<el-table-column label="角色名称" min-width="180" prop="authorityName" />
<el-table-column fixed="right" label="操作" width="460">
<template slot-scope="scope">
<template #default="scope">
<el-button size="mini" type="primary" @click="opdendrawer(scope.row)">设置权限</el-button>
<el-button
icon="el-icon-plus"
@@ -45,7 +45,7 @@
</el-table>
<span style="color: red;font-size: 12px">注:右上角头像下拉可切换角色</span>
<!-- 新增角色弹窗 -->
<el-dialog :title="dialogTitle" :visible.sync="dialogFormVisible">
<el-dialog v-model="dialogFormVisible" :title="dialogTitle">
<el-form ref="authorityForm" :model="form" :rules="rules">
<el-form-item label="父级角色" prop="parentId">
<el-cascader
@@ -64,22 +64,24 @@
<el-input v-model="form.authorityName" autocomplete="off" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="closeDialog">取 消</el-button>
<el-button type="primary" @click="enterDialog">确 定</el-button>
</div>
<template #footer>
<div class="dialog-footer">
<el-button @click="closeDialog">取 消</el-button>
<el-button type="primary" @click="enterDialog">确 定</el-button>
</div>
</template>
</el-dialog>
<el-drawer v-if="drawer" :visible.sync="drawer" :with-header="false" size="40%" title="角色配置">
<el-drawer v-if="drawer" v-model="drawer" :with-header="false" size="40%" title="角色配置">
<el-tabs :before-leave="autoEnter" class="role-box" type="border-card">
<el-tab-pane label="角色菜单">
<Menus ref="menus" :row="activeRow" />
<Menus ref="menus" :row="activeRow" @changeRow="changeRow" />
</el-tab-pane>
<el-tab-pane label="角色api">
<apis ref="apis" :row="activeRow" />
<Apis ref="apis" :row="activeRow" @changeRow="changeRow" />
</el-tab-pane>
<el-tab-pane label="资源权限">
<Datas ref="datas" :authority="tableData" :row="activeRow" />
<Datas ref="datas" :authority="tableData" :row="activeRow" @changeRow="changeRow" />
</el-tab-pane>
</el-tabs>
</el-drawer>
@@ -158,6 +160,9 @@ export default {
await this.getTableData()
},
methods: {
changeRow(key, value) {
this.activeRow[key] = value
},
autoEnter(activeName, oldActiveName) {
const paneArr = ['menus', 'apis', 'datas']
if (oldActiveName) {
@@ -25,7 +25,7 @@ export default {
},
authority: {
default: function() {
return {}
return []
},
type: Array
}
@@ -53,19 +53,19 @@ export default {
},
all() {
this.dataAuthorityId = [...this.authoritys]
this.row.dataAuthorityId = this.dataAuthorityId
this.$emit('changeRow', 'dataAuthorityId', this.dataAuthorityId)
this.needConfirm = true
},
self() {
this.dataAuthorityId = this.authoritys.filter(item => item.authorityId === this.row.authorityId)
this.row.dataAuthorityId = this.dataAuthorityId
this.$emit('changeRow', 'dataAuthorityId', this.dataAuthorityId)
this.needConfirm = true
},
selfAndChildren() {
const arrBox = []
this.getChildrenId(this.row, arrBox)
this.dataAuthorityId = this.authoritys.filter(item => arrBox.indexOf(item.authorityId) > -1)
this.row.dataAuthorityId = this.dataAuthorityId
this.$emit('changeRow', 'dataAuthorityId', this.dataAuthorityId)
this.needConfirm = true
},
getChildrenId(row, arrBox) {
@@ -95,7 +95,7 @@ export default {
},
// 选择
selectAuthority() {
this.row.dataAuthorityId = this.dataAuthorityId
this.$emit('changeRow', 'dataAuthorityId', this.dataAuthorityId)
this.needConfirm = true
}
}
@@ -14,20 +14,22 @@
show-checkbox
@check="nodeChange"
>
<span slot-scope="{ node , data }" class="custom-tree-node">
<span>{{ node.label }}</span>
<span>
<el-button
type="text"
size="mini"
:style="{color:row.defaultRouter === data.name?'#E6A23C':'#85ce61'}"
:disabled="!node.checked"
@click="() => setDefault(data)"
>
{{ row.defaultRouter === data.name?"首页":"设为首页" }}
</el-button>
<template #default="{ node , data }">
<span class="custom-tree-node">
<span>{{ node.label }}</span>
<span>
<el-button
type="text"
size="mini"
:style="{color:row.defaultRouter === data.name?'#E6A23C':'#85ce61'}"
:disabled="!node.checked"
@click="() => setDefault(data)"
>
{{ row.defaultRouter === data.name?"首页":"设为首页" }}
</el-button>
</span>
</span>
</span>
</template>
</el-tree>
</div>
</template>
@@ -81,7 +83,7 @@ export default {
const res = await updateAuthority({ authorityId: this.row.authorityId, AuthorityName: this.row.authorityName, parentId: this.row.parentId, defaultRouter: data.name })
if (res.code === 0) {
this.$message({ type: 'success', message: '设置成功' })
this.row.defaultRouter = res.data.authority.defaultRouter
this.$emit('changeRow', 'defaultRouter', res.data.authority.defaultRouter)
}
},
nodeChange() {
@@ -33,7 +33,7 @@
>
<el-table-column type="selection" width="55" />
<el-table-column label="日期" width="180">
<template slot-scope="scope">{{ scope.row.CreatedAt|formatDate }}</template>
<template #default="scope">{{ formatDate(scope.row.CreatedAt) }}</template>
</el-table-column>
<el-table-column label="字典名(中)" prop="name" width="120" />
@@ -41,22 +41,24 @@
<el-table-column label="字典名(英)" prop="type" width="120" />
<el-table-column label="状态" prop="status" width="120">
<template slot-scope="scope">{{ scope.row.status|formatBoolean }}</template>
<template #default="scope">{{ formatBoolean(scope.row.status) }}</template>
</el-table-column>
<el-table-column label="描述" prop="desc" width="280" />
<el-table-column label="按钮组">
<template slot-scope="scope">
<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="scope.row.visible" placement="top" width="160">
<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>
<el-button slot="reference" type="danger" icon="el-icon-delete" size="mini" style="margin-left:10px">删除</el-button>
<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>
@@ -73,7 +75,7 @@
@size-change="handleSizeChange"
/>
<el-dialog :before-close="closeDialog" :visible.sync="dialogFormVisible" title="弹窗操作">
<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">
<el-input
@@ -98,11 +100,13 @@
<el-input v-model="formData.desc" placeholder="请输入描述" clearable :style="{width: '100%'}" />
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button @click="closeDialog">取 消</el-button>
<el-button type="primary" @click="enterDialog">确 定</el-button>
</div>
</template>
<div slot="footer" class="dialog-footer">
<el-button @click="closeDialog">取 消</el-button>
<el-button type="primary" @click="enterDialog">确 定</el-button>
</div>
</el-dialog>
<div style="margin-top:40px;color:red">获取字典且缓存方法已在前端utils/dictionary 已经封装完成 不必自己书写 使用方法查看文件内注释</div>
@@ -117,27 +121,9 @@ import {
findSysDictionary,
getSysDictionaryList
} from '@/api/sysDictionary' // 此处请自行替换地址
import { formatTimeToStr } from '@/utils/date'
import infoList from '@/mixins/infoList'
export default {
name: 'SysDictionary',
filters: {
formatDate: function(time) {
if (time !== null && time !== '') {
var date = new Date(time)
return formatTimeToStr(date, 'yyyy-MM-dd hh:mm:ss')
} else {
return ''
}
},
formatBoolean: function(bool) {
if (bool !== null) {
return bool ? '是' : '否'
} else {
return ''
}
}
},
mixins: [infoList],
data() {
return {
@@ -32,7 +32,7 @@
>
<el-table-column type="selection" width="55" />
<el-table-column label="日期" width="180">
<template slot-scope="scope">{{ scope.row.CreatedAt|formatDate }}</template>
<template #default="scope">{{ formatDate(scope.row.CreatedAt) }}</template>
</el-table-column>
<el-table-column label="展示值" prop="label" width="120" />
@@ -40,21 +40,23 @@
<el-table-column label="字典值" prop="value" width="120" />
<el-table-column label="启用状态" prop="status" width="120">
<template slot-scope="scope">{{ scope.row.status|formatBoolean }}</template>
<template #default="scope">{{ formatBoolean(scope.row.status) }}</template>
</el-table-column>
<el-table-column label="排序标记" prop="sort" width="120" />
<el-table-column label="按钮组">
<template slot-scope="scope">
<template #default="scope">
<el-button size="small" type="primary" @click="updateSysDictionaryDetail(scope.row)">变更</el-button>
<el-popover v-model="scope.row.visible" placement="top" width="160">
<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>
<el-button slot="reference" type="danger" icon="el-icon-delete" size="mini">删除</el-button>
<template #reference>
<el-button type="danger" icon="el-icon-delete" size="mini">删除</el-button>
</template>
</el-popover>
</template>
</el-table-column>
@@ -71,7 +73,7 @@
@size-change="handleSizeChange"
/>
<el-dialog :before-close="closeDialog" :visible.sync="dialogFormVisible" title="弹窗操作">
<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="label">
<el-input
@@ -98,10 +100,12 @@
<el-input-number v-model.number="formData.sort" placeholder="排序标记" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="closeDialog">取 消</el-button>
<el-button type="primary" @click="enterDialog">确 定</el-button>
</div>
<template #footer>
<div class="dialog-footer">
<el-button @click="closeDialog">取 消</el-button>
<el-button type="primary" @click="enterDialog">确 定</el-button>
</div>
</template>
</el-dialog>
</div>
</template>
@@ -114,28 +118,10 @@ import {
findSysDictionaryDetail,
getSysDictionaryDetailList
} from '@/api/sysDictionaryDetail' // 此处请自行替换地址
import { formatTimeToStr } from '@/utils/date'
import infoList from '@/mixins/infoList'
export default {
name: 'SysDictionaryDetail',
filters: {
formatDate: function(time) {
if (time !== null && time !== '') {
var date = new Date(time)
return formatTimeToStr(date, 'yyyy-MM-dd hh:mm:ss')
} else {
return ''
}
},
formatBoolean: function(bool) {
if (bool !== null) {
return bool ? '是' : '否'
} else {
return ''
}
}
},
mixins: [infoList],
data() {
return {
+12 -4
View File
@@ -1,9 +1,17 @@
<template>
<div>
<keep-alive>
<router-view v-if="$route.meta.keepAlive" />
</keep-alive>
<router-view v-if="!$route.meta.keepAlive" />
<router-view v-if="$route.meta.keepAlive" v-slot="{ Component }">
<transition mode="out-in" name="el-fade-in-linear">
<keep-alive>
<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>
+6 -2
View File
@@ -9,10 +9,10 @@
<el-form-item prop="icon" style="width:100%">
<i
class="icon"
:class="'el-icon-'+ meta.icon"
:class="'el-icon-'+ metaData.icon"
style="position: absolute; z-index: 9999; padding: 5px 10px; "
/>
<el-select v-model="meta.icon" clearable filterable class="gva-select" placeholder="请选择">
<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>
@@ -37,6 +37,7 @@ export default {
data() {
return {
input: '',
metaData: {},
options: [
{ key: 'platform-eleme', label: 'el-icon-platform-eleme' },
{ key: 'eleme', label: 'el-icon-eleme' },
@@ -324,6 +325,9 @@ export default {
value: ''
}
},
created() {
this.metaData = this.meta
},
methods: {}
}
</script>
+25 -21
View File
@@ -10,7 +10,7 @@
<el-table-column label="路由Name" min-width="160" prop="name" />
<el-table-column label="路由Path" min-width="160" prop="path" />
<el-table-column label="是否隐藏" min-width="100" prop="hidden">
<template slot-scope="scope">
<template #default="scope">
<span>{{ scope.row.hidden?"隐藏":"显示" }}</span>
</template>
</el-table-column>
@@ -18,18 +18,18 @@
<el-table-column label="排序" min-width="70" prop="sort" />
<el-table-column label="文件路径" min-width="360" prop="component" />
<el-table-column label="展示名称" min-width="120" prop="authorityName">
<template slot-scope="scope">
<template #default="scope">
<span>{{ scope.row.meta.title }}</span>
</template>
</el-table-column>
<el-table-column label="图标" min-width="140" prop="authorityName">
<template slot-scope="scope">
<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 slot-scope="scope">
<template #default="scope">
<el-button
size="mini"
type="primary"
@@ -52,8 +52,9 @@
</el-table-column>
</el-table>
<el-dialog :before-close="handleClose" :title="dialogTitle" :visible.sync="dialogFormVisible">
<el-dialog v-model="dialogFormVisible" :before-close="handleClose" :title="dialogTitle">
<el-form
v-if="dialogFormVisible"
ref="menuForm"
:inline="true"
:model="form"
@@ -70,10 +71,13 @@
/>
</el-form-item>
<el-form-item prop="path" style="width:30%">
<div slot="label" style="display:inline-block">
路由path
<el-checkbox v-model="checkFlag" style="float:right;margin-left:20px;">添加参数</el-checkbox>
</div>
<template #label>
<div style="display:inline-flex">
路由path
<el-checkbox v-model="checkFlag" style="float:right;margin-left:20px;">添加参数</el-checkbox>
</div>
</template>
<el-input
v-model="form.path"
:disabled="!checkFlag"
@@ -105,9 +109,7 @@
<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">
<template slot="prepend">el-icon-</template>
</icon>
<icon :meta="form.meta" />
</el-form-item>
<el-form-item label="排序标记" prop="sort" style="width:30%">
<el-input v-model.number="form.sort" autocomplete="off" />
@@ -135,7 +137,7 @@
>新增菜单参数</el-button>
<el-table :data="form.parameters" stripe style="width: 100%">
<el-table-column prop="type" label="参数类型" width="180">
<template slot-scope="scope">
<template #default="scope">
<el-select v-model="scope.row.type" placeholder="请选择">
<el-option key="query" value="query" label="query" />
<el-option key="params" value="params" label="params" />
@@ -143,21 +145,21 @@
</template>
</el-table-column>
<el-table-column prop="key" label="参数key" width="180">
<template slot-scope="scope">
<template #default="scope">
<div>
<el-input v-model="scope.row.key" />
</div>
</template>
</el-table-column>
<el-table-column prop="value" label="参数值">
<template slot-scope="scope">
<template #default="scope">
<div>
<el-input v-model="scope.row.value" />
</div>
</template>
</el-table-column>
<el-table-column>
<template slot-scope="scope">
<template #default="scope">
<div>
<el-button
type="danger"
@@ -170,10 +172,12 @@
</el-table-column>
</el-table>
</div>
<div slot="footer" class="dialog-footer">
<el-button @click="closeDialog">取 消</el-button>
<el-button type="primary" @click="enterDialog">确 定</el-button>
</div>
<template #footer>
<div class="dialog-footer">
<el-button @click="closeDialog">取 消</el-button>
<el-button type="primary" @click="enterDialog">确 定</el-button>
</div>
</template>
</el-dialog>
</div>
</template>
@@ -244,7 +248,7 @@ export default {
methods: {
addParameter(form) {
if (!form.parameters) {
this.$set(form, 'parameters', [])
this.form.parameters = []
}
form.parameters.push({
type: 'query',
@@ -13,13 +13,15 @@
</el-form-item>
<el-form-item>
<el-button size="mini" type="primary" icon="el-icon-search" @click="onSubmit">查询</el-button>
<el-popover v-model="deleteVisible" placement="top" width="160">
<el-popover v-model:visible="deleteVisible" placement="top" width="160">
<p>确定要删除吗?</p>
<div style="text-align: right; margin: 0">
<el-button size="mini" type="text" @click="deleteVisible = false">取消</el-button>
<el-button size="mini" type="primary" @click="onDelete">确定</el-button>
</div>
<el-button slot="reference" icon="el-icon-delete" size="mini" type="danger" style="margin-left: 10px;">批量删除</el-button>
<template #reference>
<el-button icon="el-icon-delete" size="mini" type="danger" style="margin-left: 10px;">批量删除</el-button>
</template>
</el-popover>
</el-form-item>
</el-form>
@@ -35,15 +37,15 @@
>
<el-table-column type="selection" width="55" />
<el-table-column label="操作人" width="140">
<template slot-scope="scope">
<template #default="scope">
<div>{{ scope.row.user.userName }}({{ scope.row.user.nickName }})</div>
</template>
</el-table-column>
<el-table-column label="日期" width="180">
<template slot-scope="scope">{{ scope.row.CreatedAt|formatDate }}</template>
<template #default="scope">{{ formatDate(scope.row.CreatedAt) }}</template>
</el-table-column>
<el-table-column label="状态码" prop="status" width="120">
<template slot-scope="scope">
<template #default="scope">
<div>
<el-tag type="success">{{ scope.row.status }}</el-tag>
</div>
@@ -53,13 +55,15 @@
<el-table-column label="请求方法" prop="method" width="120" />
<el-table-column label="请求路径" prop="path" width="240" />
<el-table-column label="请求" prop="path" width="80">
<template slot-scope="scope">
<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>
<i slot="reference" class="el-icon-view" />
<template #reference>
<i class="el-icon-view" />
</template>
</el-popover>
<span v-else>无</span>
@@ -67,27 +71,31 @@
</template>
</el-table-column>
<el-table-column label="响应" prop="path" width="80">
<template slot-scope="scope">
<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>
<i slot="reference" class="el-icon-view" />
<template #reference>
<i class="el-icon-view" />
</template>
</el-popover>
<span v-else>无</span>
</div>
</template>
</el-table-column>
<el-table-column label="按钮组">
<template slot-scope="scope">
<el-popover v-model="scope.row.visible" placement="top" width="160">
<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>
</div>
<el-button slot="reference" icon="el-icon-delete" size="mini" type="danger">删除</el-button>
<template #reference>
<el-button icon="el-icon-delete" size="mini" type="danger">删除</el-button>
</template>
</el-popover>
</template>
</el-table-column>
@@ -111,28 +119,10 @@ import {
getSysOperationRecordList,
deleteSysOperationRecordByIds
} from '@/api/sysOperationRecord' // 此处请自行替换地址
import { formatTimeToStr } from '@/utils/date'
import infoList from '@/mixins/infoList'
export default {
name: 'SysOperationRecord',
filters: {
formatDate: function(time) {
if (time !== null && time !== '') {
var date = new Date(time)
return formatTimeToStr(date, 'yyyy-MM-dd hh:mm:ss')
} else {
return ''
}
},
formatBoolean: function(bool) {
if (bool !== null) {
return bool ? '是' : '否'
} else {
return ''
}
}
},
mixins: [infoList],
data() {
return {
+17 -12
View File
@@ -5,7 +5,7 @@
</div>
<el-table :data="tableData" border stripe>
<el-table-column label="头像" min-width="50">
<template slot-scope="scope">
<template #default="scope">
<div :style="{'textAlign':'center'}">
<CustomPic :pic-src="scope.row.headerImg" />
</div>
@@ -15,7 +15,7 @@
<el-table-column label="用户名" min-width="150" prop="userName" />
<el-table-column label="昵称" min-width="150" prop="nickName" />
<el-table-column label="用户角色" min-width="150">
<template slot-scope="scope">
<template #default="scope">
<el-cascader
v-model="scope.row.authorityIds"
:options="authOptions"
@@ -29,14 +29,16 @@
</template>
</el-table-column>
<el-table-column label="操作" min-width="150">
<template slot-scope="scope">
<el-popover v-model="scope.row.visible" placement="top" width="160">
<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>
<el-button slot="reference" type="danger" icon="el-icon-delete" size="mini">删除</el-button>
<template #reference>
<el-button type="danger" icon="el-icon-delete" size="mini">删除</el-button>
</template>
</el-popover>
</template>
</el-table-column>
@@ -53,7 +55,7 @@
@size-change="handleSizeChange"
/>
<el-dialog :visible.sync="addUserDialog" custom-class="user-dialog" title="新增用户">
<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" />
@@ -72,7 +74,8 @@
</el-form-item>
<el-form-item label="用户角色" label-width="80px" prop="authorityId">
<el-cascader
v-model="userInfo.authorityIds"
v-if="userInfo"
v-model:visible="userInfo.authorityIds"
:options="authOptions"
:show-all-levels="false"
:props="{ multiple:true,checkStrictly: true,label:'authorityName',value:'authorityId',disabled:'disabled',emitPath:false}"
@@ -81,10 +84,12 @@
/>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="closeAddUserDialog">取 消</el-button>
<el-button type="primary" @click="enterAddUserDialog">确 定</el-button>
</div>
<template #footer>
<div class="dialog-footer">
<el-button @click="closeAddUserDialog">取 消</el-button>
<el-button type="primary" @click="enterAddUserDialog">确 定</el-button>
</div>
</template>
</el-dialog>
<ChooseImg ref="chooseImg" :target="userInfo" :target-key="`headerImg`" />
</div>
@@ -155,7 +160,7 @@ export default {
const authorityIds = user.authorities && user.authorities.map(i => {
return i.authorityId
})
this.$set(user, 'authorityIds', authorityIds)
user.authorityIds = authorityIds
})
},
openHeaderChange() {
+22 -16
View File
@@ -3,7 +3,9 @@
<el-row :gutter="15" class="system_state">
<el-col :span="12">
<el-card v-if="state.os" class="card_item">
<div slot="header">Runtime</div>
<template #header>
<div>Runtime</div>
</template>
<div>
<el-row :gutter="10">
<el-col :span="12">os:</el-col>
@@ -30,7 +32,9 @@
</el-col>
<el-col :span="12">
<el-card v-if="state.disk" class="card_item">
<div slot="header">Disk</div>
<template #header>
<div>Disk</div>
</template>
<div>
<el-row :gutter="10">
<el-col :span="12">
@@ -70,30 +74,32 @@
class="card_item"
:body-style="{ height: '180px', 'overflow-y': 'scroll' }"
>
<div slot="header">CPU</div>
<template #header>
<div>CPU</div>
</template>
<div>
<el-row :gutter="10">
<el-col :span="12">physical number of cores:</el-col>
<el-col :span="12" v-text="state.cpu.cores" />
</el-row>
<template v-for="(item, index) in state.cpu.cpus">
<el-row :key="index" :gutter="10">
<el-col :span="12">core {{ index }}:</el-col>
<el-col
:span="12"
><el-progress
type="line"
:percentage="+item.toFixed(0)"
:color="colors"
/></el-col>
</el-row>
</template>
<el-row v-for="(item, index) in state.cpu.cpus" :key="index" :gutter="10">
<el-col :span="12">core {{ index }}:</el-col>
<el-col
:span="12"
><el-progress
type="line"
:percentage="+item.toFixed(0)"
:color="colors"
/></el-col>
</el-row>
</div>
</el-card>
</el-col>
<el-col :span="12">
<el-card v-if="state.ram" class="card_item">
<div slot="header">Ram</div>
<template #header>
<div>Ram</div>
</template>
<div>
<el-row :gutter="10">
<el-col :span="12">
@@ -3,14 +3,14 @@
<span style="color:red">搜索时如果条件为LIKE只支持字符串</span>
<el-form
ref="fieldDialogFrom"
:model="dialogMiddle"
:model="middleDate"
label-width="120px"
label-position="left"
:rules="rules"
>
<el-form-item label="Field名称" prop="fieldName">
<el-col :span="6">
<el-input v-model="dialogMiddle.fieldName" autocomplete="off" />
<el-input v-model="middleDate.fieldName" autocomplete="off" />
</el-col>
<el-col :offset="1" :span="2">
<el-button size="mini" @click="autoFill">自动填充</el-button>
@@ -18,28 +18,28 @@
</el-form-item>
<el-form-item label="Field中文名" prop="fieldDesc">
<el-col :span="6">
<el-input v-model="dialogMiddle.fieldDesc" autocomplete="off" />
<el-input v-model="middleDate.fieldDesc" autocomplete="off" />
</el-col>
</el-form-item>
<el-form-item label="FieldJSON" prop="fieldJson">
<el-col :span="6">
<el-input v-model="dialogMiddle.fieldJson" autocomplete="off" />
<el-input v-model="middleDate.fieldJson" autocomplete="off" />
</el-col>
</el-form-item>
<el-form-item label="数据库字段名" prop="columnName">
<el-col :span="6">
<el-input v-model="dialogMiddle.columnName" autocomplete="off" />
<el-input v-model="middleDate.columnName" autocomplete="off" />
</el-col>
</el-form-item>
<el-form-item label="数据库字段描述" prop="comment">
<el-col :span="6">
<el-input v-model="dialogMiddle.comment" autocomplete="off" />
<el-input v-model="middleDate.comment" autocomplete="off" />
</el-col>
</el-form-item>
<el-form-item label="Field数据类型" prop="fieldType">
<el-col :span="8">
<el-select
v-model="dialogMiddle.fieldType"
v-model="middleDate.fieldType"
placeholder="请选择field数据类型"
clearable
@change="getDbfdOptions"
@@ -57,8 +57,8 @@
<el-form-item label="数据库字段类型" prop="dataType">
<el-col :span="8">
<el-select
v-model="dialogMiddle.dataType"
:disabled="!dialogMiddle.fieldType"
v-model="middleDate.dataType"
:disabled="!middleDate.fieldType"
placeholder="请选择数据库字段类型"
clearable
>
@@ -73,12 +73,12 @@
</el-form-item>
<el-form-item label="数据库字段长度" prop="dataTypeLong">
<el-col :span="8">
<el-input v-model="dialogMiddle.dataTypeLong" placeholder="自定义类型必须指定长度" :disabled="!dialogMiddle.dataType" />
<el-input v-model="middleDate.dataTypeLong" placeholder="自定义类型必须指定长度" :disabled="!middleDate.dataType" />
</el-col>
</el-form-item>
<el-form-item label="Field查询条件" prop="fieldSearchType">
<el-col :span="8">
<el-select v-model="dialogMiddle.fieldSearchType" placeholder="请选择Field查询条件" clearable>
<el-select v-model="middleDate.fieldSearchType" placeholder="请选择Field查询条件" clearable>
<el-option
v-for="item in typeSearchOptions"
:key="item.value"
@@ -91,7 +91,7 @@
<el-form-item label="关联字典" prop="dictType">
<el-col :span="8">
<el-select v-model="dialogMiddle.dictType" :disabled="dialogMiddle.fieldType!=='int'" placeholder="请选择字典" clearable>
<el-select v-model="middleDate.dictType" :disabled="middleDate.fieldType!=='int'" placeholder="请选择字典" clearable>
<el-option
v-for="item in dictOptions"
:key="item.type"
@@ -122,6 +122,7 @@ export default {
},
data() {
return {
middleDate: {},
dbfdOptions: [],
dictOptions: [],
typeSearchOptions: [
@@ -188,6 +189,7 @@ export default {
}
},
async created() {
this.middleDate = this.dialogMiddle
const dictRes = await getSysDictionaryList({
page: 1,
pageSize: 999999
@@ -197,16 +199,16 @@ export default {
},
methods: {
autoFill() {
this.dialogMiddle.fieldJson = toLowerCase(this.dialogMiddle.fieldName)
this.dialogMiddle.columnName = toSQLLine(this.dialogMiddle.fieldJson)
this.middleDate.fieldJson = toLowerCase(this.middleDate.fieldName)
this.middleDate.columnName = toSQLLine(this.middleDate.fieldJson)
},
async getDbfdOptions() {
this.dialogMiddle.dataType = ''
this.dialogMiddle.dataTypeLong = ''
this.dialogMiddle.fieldSearchType = ''
this.dialogMiddle.dictType = ''
if (this.dialogMiddle.fieldType) {
this.dbfdOptions = await getDict(this.dialogMiddle.fieldType)
this.middleDate.dataType = ''
this.middleDate.dataTypeLong = ''
this.middleDate.fieldSearchType = ''
this.middleDate.dictType = ''
if (this.middleDate.fieldType) {
this.dbfdOptions = await getDict(this.middleDate.fieldType)
}
}
}
+21 -15
View File
@@ -3,7 +3,7 @@
<!-- 从数据库直接获取字段 -->
<el-collapse v-model="activeNames">
<el-collapse-item name="1">
<template slot="title">
<template #title>
<div :style="{fontSize:'16px',paddingLeft:'20px'}">
点这里从现有数据库创建代码
<i class="header-icon el-icon-thumb" />
@@ -61,7 +61,7 @@
<el-input v-model="form.packageName" placeholder="生成文件的默认名称(建议为驼峰格式,首字母小写,如sysXxxXxxx)" />
</el-form-item>
<el-form-item>
<template slot="label">
<template #label>
<el-tooltip content="注:把自动生成的API注册进数据库" placement="bottom" effect="light">
<div> 自动创建API </div>
</el-tooltip>
@@ -69,7 +69,7 @@
<el-checkbox v-model="form.autoCreateApiToSql" />
</el-form-item>
<el-form-item>
<template slot="label">
<template #label>
<el-tooltip content="注:自动迁移生成的文件到ymal配置的对应位置" placement="bottom" effect="light">
<div> 自动移动文件 </div>
</el-tooltip>
@@ -94,7 +94,7 @@
<el-table-column prop="fieldSearchType" label="搜索条件" width="130" />
<el-table-column prop="dictType" label="字典" width="130" />
<el-table-column label="操作" width="300">
<template slot-scope="scope">
<template #default="scope">
<el-button
size="mini"
type="primary"
@@ -113,13 +113,15 @@
:disabled="(scope.$index + 1) === form.fields.length"
@click="moveDownField(scope.$index)"
>下移</el-button>
<el-popover v-model="scope.row.visible" placement="top">
<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>
<el-button slot="reference" size="mini" type="danger" icon="el-icon-delete">删除</el-button>
<template #reference>
<el-button size="mini" type="danger" icon="el-icon-delete">删除</el-button>
</template>
</el-popover>
</template>
</el-table-column>
@@ -131,19 +133,23 @@
<el-button size="mini" type="primary" @click="enterForm(false)">生成代码</el-button>
</div>
<!-- 组件弹窗 -->
<el-dialog title="组件内容" :visible.sync="dialogFlag">
<el-dialog v-model="dialogFlag" title="组件内容">
<FieldDialog v-if="dialogFlag" ref="fieldDialog" :dialog-middle="dialogMiddle" />
<div slot="footer" class="dialog-footer">
<el-button size="mini" @click="closeDialog">取 消</el-button>
<el-button size="mini" type="primary" @click="enterDialog">确 定</el-button>
</div>
<template #footer>
<div class="dialog-footer">
<el-button size="mini" @click="closeDialog">取 消</el-button>
<el-button size="mini" type="primary" @click="enterDialog">确 定</el-button>
</div>
</template>
</el-dialog>
<el-dialog :visible.sync="previewFlag">
<el-dialog v-model="previewFlag">
<PreviewCodeDialg v-if="previewFlag" :preview-code="preViewCode" />
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="previewFlag = false">确 定</el-button>
</div>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="previewFlag = false">确 定</el-button>
</div>
</template>
</el-dialog>
</div>
</template>
@@ -20,13 +20,13 @@
/>
<el-table-column label="id" width="60" prop="ID" />
<el-table-column label="日期" width="180">
<template slot-scope="scope">{{ scope.row.CreatedAt|formatDate }}</template>
<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 slot-scope="scope">
<template #default="scope">
<el-tag
v-if="scope.row.flag"
type="danger"
@@ -46,7 +46,7 @@
</template>
</el-table-column>
<el-table-column label="操作" min-width="180">
<template slot-scope="scope">
<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>
@@ -72,28 +72,10 @@
<script>
// 获取列表内容封装在mixins内部 getTableData方法 初始化已封装完成 条件搜索时候 请把条件安好后台定制的结构体字段 放到 this.searchInfo 中即可实现条件搜索
import { getSysHistory, rollback, delSysHistory } from '@/api/autoCode.js'
import { formatTimeToStr } from '@/utils/date'
import infoList from '@/mixins/infoList'
export default {
name: 'Api',
filters: {
formatDate: function(time) {
if (time !== null && time !== '') {
var date = new Date(time)
return formatTimeToStr(date, 'yyyy-MM-dd hh:mm:ss')
} else {
return ''
}
},
formatBoolean: function(bool) {
if (bool !== null) {
return bool ? '是' : '否'
} else {
return ''
}
}
},
mixins: [infoList],
data() {
return {
+12 -4
View File
@@ -1,9 +1,17 @@
<template>
<div>
<keep-alive>
<router-view v-if="$route.meta.keepAlive" />
</keep-alive>
<router-view v-if="!$route.meta.keepAlive" />
<router-view v-if="$route.meta.keepAlive" v-slot="{ Component }">
<transition mode="out-in" name="el-fade-in-linear">
<keep-alive>
<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>