This commit is contained in:
sakuya 2021-05-15 23:35:24 +08:00
parent 2a4cf90586
commit cbbd57511b
15 changed files with 330 additions and 27 deletions

View File

@ -7,16 +7,16 @@
"appName": "自助机",
"appId": "selfHelp",
"secret": "YuOju6lP3t4thLbZOhRSV4UZ79vdnwIC",
"type": "ALL",
"exp": "长期"
"type": ["ALL"],
"exp": "2035-01-01 00:00:00"
},
{
"id": "101",
"appName": "微信小程序",
"appId": "WechatApp",
"secret": "WgBbsRtCeXiNXIYkkShxxvqOGrAYKK2e",
"type": "",
"exp": "长期"
"type": ["UPDATA", "QUERY"],
"exp": "2023-06-01 00:00:00"
}
],
"message": ""

View File

@ -209,7 +209,7 @@
},
{
"path": "/setting/menu",
"name": "menu",
"name": "settingMenu",
"meta": {
"title": "菜单管理"
},
@ -222,6 +222,14 @@
"title": "应用管理"
},
"component": "setting/client"
},
{
"path": "/setting/log",
"name": "log",
"meta": {
"title": "系统日志"
},
"component": "setting/log"
}
]
}

View File

@ -81,7 +81,20 @@ const api = {
}
}
},
log: {
list: {
url: `${config.API_URL}/json/log.json`,
name: "日志列表",
get: async function(){
return await http.get(this.url);
}
}
},
demo: {
upload: {
url: `https://www.fastmock.site/mock/44c807475f7eeba73409792255781935/api/upload`,
name: "文件上传接口"
},
select: {
url: `${config.API_URL}/json/select.json`,
name: "下拉菜单数据",

View File

@ -4,10 +4,10 @@
<div class="mask">
<span class="del" @click.stop="del"><i class="el-icon-delete"></i></span>
</div>
<el-image class="file" :src="tempImg || img" :preview-src-list="[img]" hide-on-click-modal append-to-body></el-image>
<el-image class="file" :src="tempImg || img" :preview-src-list="[img]" fit="cover" hide-on-click-modal append-to-body></el-image>
</div>
<div v-else class="sc-upload-uploader">
<el-upload ref="upload" v-loading="loading" class="uploader" accept=".JPG, .PNG, .JPEG,.jpg, .png, .jpeg" action="https://www.fastmock.site/mock/44c807475f7eeba73409792255781935/api/upload" :show-file-list="false" :before-upload="before" :on-success="success" :on-error="error">
<el-upload ref="upload" v-loading="loading" class="uploader" :accept="accept" :action="action" :show-file-list="false" :before-upload="before" :on-success="success" :on-error="error">
<div class="file-empty">
<i class="el-icon-plus"></i>
<h4>{{title}}</h4>
@ -22,6 +22,9 @@
export default {
props: {
modelValue: { type: String, default: "" },
action: { type: String, default: "#" },
accept: { type: String, default: ".jpg, .png, .jpeg, .gif" },
maxSize: { type: Number, default: 10 },
title: { type: String, default: "上传" },
},
data() {
@ -45,6 +48,11 @@
},
methods: {
before(file){
const maxSize = file.size / 1024 / 1024 < this.maxSize;
if (!maxSize) {
this.$message.warning('上传文件大小不能超过 10MB!');
return false;
}
this.tempImg = URL.createObjectURL(file);
this.loading = true;
},
@ -56,6 +64,7 @@
}else{
this.img = res.data.src;
}
this.$emit('on-success', res)
},
error(err){
this.$notify.error({
@ -74,11 +83,9 @@
</script>
<style scoped>
.el-form-item.is-error .sc-upload-uploader {border: 1px dashed #F56C6C;}
.sc-upload {width: 120px;height: 120px;}
.sc-upload:hover {}
.sc-upload-file {position: relative;width: 100%;height: 100%;}
.sc-upload-file .mask {display: none;position: absolute;top:0px;right:0px;line-height: 1;z-index: 1;}
@ -89,7 +96,6 @@
.sc-upload-file .file img {vertical-align: bottom;}
.sc-upload-file:hover .mask {display: inline-block;}
.sc-upload-uploader {border: 1px dashed #d9d9d9;}
.sc-upload-uploader:hover {border: 1px dashed #409eff;}
.sc-upload-uploader .file-empty {width: 118px;height: 118px;line-height: 1;display: flex;flex-direction: column;align-items: center;justify-content: center;}

View File

@ -25,7 +25,7 @@ app.config.globalProperties.$HAS = permission;
app.use(store);
app.use(router);
app.use(ElementPlus, {size: 'small', zIndex: 3000 ,locale: locale});
app.use(ElementPlus, {size: 'small', zIndex: 1000 ,locale: locale});
app.component('scTable', scTable);
app.component('scFilterBar', scFilterBar);

View File

@ -3,16 +3,22 @@
<el-header>
<div class="left-panel">
<el-button type="primary" icon="el-icon-plus" @click="add"></el-button>
<el-button type="danger" plain icon="el-icon-delete" :disabled="selection.length==0" @click="batch_del"></el-button>
</div>
</el-header>
<el-main class="nopadding">
<scTable ref="table" :apiObj="apiObj" row-key="id">
<scTable ref="table" :apiObj="apiObj" row-key="id" @selection-change="selectionChange" stripe>
<el-table-column type="selection" width="50"></el-table-column>
<el-table-column label="应用ID" prop="appId" width="150"></el-table-column>
<el-table-column label="应用名称" prop="appName" width="250"></el-table-column>
<el-table-column label="状态" width="50">
<template #default>
<i class="el-icon-success" style="color: #67C23A;"></i>
</template>
</el-table-column>
<el-table-column label="秘钥" prop="secret" show-overflow-tooltip width="150"></el-table-column>
<el-table-column label="类型" prop="type" width="150"></el-table-column>
<el-table-column label="授权到期" prop="tokenExp" width="150"></el-table-column>
<el-table-column label="类型" prop="type" width="250"></el-table-column>
<el-table-column label="授权到期" prop="exp" width="150"></el-table-column>
<el-table-column label="操作" fixed="right" align="right" width="120">
<template #default="scope">
<el-button type="text" size="small" @click="table_edit(scope.row, scope.$index)">编辑</el-button>
@ -26,20 +32,113 @@
</scTable>
</el-main>
</el-container>
<el-dialog :title="titleMap[saveMode]" v-model="saveDialogVisible" :width="500" destroy-on-close>
<save-dialog ref="saveDialog" :mode="saveMode"></save-dialog>
<template #footer>
<el-button @click="saveDialogVisible=false" > </el-button>
<el-button v-if="saveMode!='show'" type="primary" @click="saveForm()" :loading="isSaveing"> </el-button>
</template>
</el-dialog>
</template>
<script>
import saveDialog from './save'
export default {
name: "client",
components: {
saveDialog
},
data(){
return {
apiObj: this.$API.app.list
apiObj: this.$API.app.list,
selection: [],
saveDialogVisible: false,
saveMode: 'add',
titleMap: {
add: "新增",
edit: "编辑",
show: "查看"
},
isSaveing: false,
}
},
methods: {
add(){
this.saveMode = 'add';
this.saveDialogVisible = true;
},
//
table_edit(row){
this.saveMode = 'edit';
this.saveDialogVisible = true;
this.$nextTick(() => {
//ID
this.$refs.saveDialog.setData(row)
})
},
//
table_show(row){
this.saveMode = 'show';
this.saveDialogVisible = true;
this.$nextTick(() => {
//ID
this.$refs.saveDialog.setData(row)
})
},
//
async table_del(row, index){
var reqData = {id: row.id}
var res = await this.$API.user.del.post(reqData);
if(res.code == 200){
// OR /
this.$refs.table.tableData.splice(index, 1);
this.$message.success("删除成功")
}else{
this.$alert(res.message, "提示", {type: 'error'})
}
},
//
async batch_del(){
this.$confirm(`确定删除选中的 ${this.selection.length} 项吗?`, '提示', {
type: 'warning'
}).then(() => {
const loading = this.$loading();
this.selection.forEach(item => {
this.$refs.table.tableData.forEach((itemI, indexI) => {
if (item.id === itemI.id) {
this.$refs.table.tableData.splice(indexI, 1)
}
})
})
loading.close();
this.$message.success("操作成功")
}).catch(() => {
})
},
//
saveForm(){
this.$refs.saveDialog.submit(async (formData) => {
this.isSaveing = true;
var res = await this.$API.user.save.post(formData);
this.isSaveing = false;
if(res.code == 200){
// OR /
this.saveDialogVisible = false;
this.$message.success("操作成功")
}else{
this.$alert(res.message, "提示", {type: 'error'})
}
})
},
//
selectionChange(selection){
this.selection = selection;
},
}
}
</script>

View File

@ -0,0 +1,90 @@
<template>
<el-form :model="form" :rules="rules" :disabled="mode=='show'" ref="dialogForm" label-width="100px" label-position="left">
<el-form-item label="应用标识" prop="appId">
<el-input v-model="form.appId" clearable></el-input>
</el-form-item>
<el-form-item label="应用名称" prop="appName">
<el-input v-model="form.appName" clearable></el-input>
</el-form-item>
<el-form-item label="秘钥" prop="secret">
<el-input v-model="form.secret" clearable></el-input>
</el-form-item>
<el-form-item label="类型范围" prop="type">
<el-checkbox-group v-model="form.type">
<el-checkbox-button label="ALL"></el-checkbox-button>
<el-checkbox-button label="UPDATA"></el-checkbox-button>
<el-checkbox-button label="QUERY"></el-checkbox-button>
<el-checkbox-button label="INSERT"></el-checkbox-button>
</el-checkbox-group>
</el-form-item>
<el-form-item label="授权至" prop="exp">
<el-date-picker v-model="form.exp" type="datetime" placeholder="选择日期时间"></el-date-picker>
</el-form-item>
</el-form>
</template>
<script>
export default {
props: {
mode: { type: String, default: "add" }
},
data() {
return {
//
form: {
id:"",
appId: "",
appName: "",
secret: "",
type: [],
exp: ""
},
//
rules: {
appId:[
{required: true, message: '请输入应用标识'}
],
appName:[
{required: true, message: '请输入应用名称'}
],
secret:[
{required: true, message: '请输入秘钥'}
],
type:[
{required: true, message: '请选择类型范围'}
],
exp:[
{required: true, message: '请选择授权到期日期'}
]
},
}
},
methods: {
//
submit(callback){
this.$refs.dialogForm.validate((valid) => {
if (valid) {
callback(this.form)
}else{
return false;
}
})
},
//
setData(data){
this.form.id = data.id
this.form.appId = data.appId
this.form.appName = data.appName
this.form.secret = data.secret
this.form.type = data.type
this.form.exp = data.exp
//
//Object.assign(this.form, data)
}
}
}
</script>
<style>
</style>

View File

@ -43,7 +43,7 @@
<el-table-column label="键值" prop="key" width="150"></el-table-column>
<el-table-column label="是否有效" prop="yx" width="100">
<template #default="scope">
<el-switch v-model="scope.row.yx" @change="changeSwitch($event, scope.row)" :loading="scope.row.$switch_yx" active-value="1" inactive-value="0"></el-switch>
<el-switch v-if="scope.row.yx" v-model="scope.row.yx" @change="changeSwitch($event, scope.row)" :loading="scope.row.$switch_yx" active-value="1" inactive-value="0"></el-switch>
</template>
</el-table-column>
<el-table-column label="操作" fixed="right" align="right" width="140">
@ -158,6 +158,9 @@
this.dicMode = 'edit';
this.dicDialogVisible = true;
this.$nextTick(() => {
var editNode = this.$refs.dic.getNode(data.id);
var editNodeParentId = editNode.level==1?undefined:editNode.parent.data.id
data.parentId = editNodeParentId
this.$refs.dicDialog.setData(data)
})
},

View File

@ -0,0 +1,73 @@
<template>
<el-container>
<el-container>
<el-header>
<div class="left-panel">
</div>
<div class="right-panel">
<div class="right-panel-search">
<el-input v-model="search.keyword" placeholder="关键词" clearable></el-input>
<el-button type="primary" icon="el-icon-search" @click="upsearch"></el-button>
</div>
</div>
</el-header>
<el-main class="nopadding">
<scTable ref="table" :apiObj="apiObj" stripe>
<el-table-column label="#" type="index" width="50"></el-table-column>
<el-table-column label="ID" prop="id" width="80"></el-table-column>
<el-table-column label="日志名" prop="id" width="150"></el-table-column>
<el-table-column label="请求接口" prop="id" width="150"></el-table-column>
<el-table-column label="请求方法" prop="id" width="150"></el-table-column>
<el-table-column label="客户端IP" prop="id" width="150"></el-table-column>
<el-table-column label="日志时间" prop="id" width="150"></el-table-column>
</scTable>
</el-main>
</el-container>
<el-aside width="340px" style="border-left: 1px solid #e6e6e6;border-right: 0;padding:20px;">
<el-descriptions title="基础信息" :column="1" size="small">
<el-descriptions-item label="请求接口">/oauth/token</el-descriptions-item>
<el-descriptions-item label="请求方法">POST</el-descriptions-item>
<el-descriptions-item label="状态代码">200</el-descriptions-item>
<el-descriptions-item label="日志名">登录用户验证</el-descriptions-item>
<el-descriptions-item label="日志时间">2021-05-15 22:15:35</el-descriptions-item>
</el-descriptions>
<el-collapse>
<el-collapse-item title="Request" name="1">
<div>
Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198
Safari/537.36
</div>
</el-collapse-item>
<el-collapse-item title="Response" name="2">
<div>
id=100
</div>
</el-collapse-item>
</el-collapse>
</el-aside>
</el-container>
</template>
<script>
export default {
name: 'log',
data() {
return {
apiObj: this.$API.log.list,
search: {
keyword: ""
}
}
},
methods: {
upsearch(){
}
}
}
</script>
<style>
</style>

View File

@ -1,6 +1,9 @@
<template>
<el-container>
<el-header>
<div class="left-panel">
<el-button type="primary" icon="el-icon-plus" @click="add"></el-button>
</div>
</el-header>
<el-main class="nopadding">
</el-main>
@ -9,9 +12,14 @@
<script>
export default {
name: "menu",
name: "settingMenu",
data(){
return {}
},
methods: {
add(){
}
}
}
</script>

View File

@ -35,7 +35,7 @@
</el-main>
</el-container>
<el-dialog :title="titleMap[saveMode]" v-model="saveDialogVisible" :width="600" destroy-on-close>
<el-dialog :title="titleMap[saveMode]" v-model="saveDialogVisible" :width="500" destroy-on-close>
<save-dialog ref="saveDialog" :mode="saveMode"></save-dialog>
<template #footer>
<el-button @click="saveDialogVisible=false" > </el-button>

View File

@ -4,7 +4,6 @@
<el-col :span="12">
<el-form-item label="上级角色" prop="parentId">
<el-cascader v-model="form.parentId" :options="groups" :props="groupsProps" :show-all-levels="false" clearable></el-cascader>
<div class="el-form-item-msg">如不选择任意上级系统默认为最顶级角色</div>
</el-form-item>
</el-col>
<el-col :span="12">

View File

@ -2,10 +2,11 @@
<el-main>
<el-card shadow="never">
<el-tabs tab-position="top">
<el-tab-pane label="用户管理">用户管理</el-tab-pane>
<el-tab-pane label="配置管理">配置管理</el-tab-pane>
<el-tab-pane label="角色管理">角色管理</el-tab-pane>
<el-tab-pane label="定时任务补偿">定时任务补偿</el-tab-pane>
<el-tab-pane label="系统设置">
</el-tab-pane>
<el-tab-pane label="业务配置">业务配置</el-tab-pane>
<el-tab-pane label="扩展配置">扩展配置</el-tab-pane>
</el-tabs>
</el-card>
</el-main>
@ -16,7 +17,9 @@
name: 'system',
data() {
return {
sys: {
name: ""
}
}
}
}

View File

@ -55,7 +55,7 @@
</el-container>
</el-container>
<el-dialog :title="titleMap[saveMode]" v-model="saveDialogVisible" :width="600" destroy-on-close>
<el-dialog :title="titleMap[saveMode]" v-model="saveDialogVisible" :width="500" destroy-on-close>
<save-dialog ref="saveDialog" :mode="saveMode"></save-dialog>
<template #footer>
<el-button @click="saveDialogVisible=false" > </el-button>

View File

@ -3,7 +3,7 @@
<el-row :gutter="20">
<el-col :span="24">
<el-form-item label="头像" prop="avatar">
<sc-upload v-model="form.avatar" title="上传头像"></sc-upload>
<sc-upload v-model="form.avatar" title="上传头像" :action="uploadUrl"></sc-upload>
</el-form-item>
</el-col>
</el-row>
@ -49,6 +49,7 @@
},
data() {
return {
uploadUrl: this.$API.demo.upload.url,
//
form: {
id:"",