This commit is contained in:
sc 2021-05-15 16:24:20 +08:00
parent 71f02ce4c3
commit 4004b81827
14 changed files with 398 additions and 59 deletions

View File

@ -15,6 +15,7 @@
"less": "^3.12.2", "less": "^3.12.2",
"less-loader": "^7.1.0", "less-loader": "^7.1.0",
"nprogress": "^0.2.0", "nprogress": "^0.2.0",
"sortablejs": "^1.13.0",
"vue": "^3.0.0", "vue": "^3.0.0",
"vue-router": "^4.0.0-0", "vue-router": "^4.0.0-0",
"vuedraggable": "^4.0.1", "vuedraggable": "^4.0.1",

23
public/json/app.json Normal file
View File

@ -0,0 +1,23 @@
{
"code": 200,
"count": 2,
"data": [
{
"id": "100",
"appName": "自助机",
"appId": "selfHelp",
"secret": "YuOju6lP3t4thLbZOhRSV4UZ79vdnwIC",
"type": "ALL",
"exp": "长期"
},
{
"id": "101",
"appName": "微信小程序",
"appId": "WechatApp",
"secret": "WgBbsRtCeXiNXIYkkShxxvqOGrAYKK2e",
"type": "",
"exp": "长期"
}
],
"message": ""
}

View File

@ -6,37 +6,22 @@
"id": "100", "id": "100",
"key": "1", "key": "1",
"name": "发布通知", "name": "发布通知",
"yx": 1 "dic": "1",
}, "yx": "1"
{
"id": "101",
"key": "2",
"name": "批转通知",
"yx": 1
}, },
{ {
"id": "102", "id": "102",
"key": "3", "key": "2",
"name": "转发通知", "name": "转发通知",
"yx": 1 "dic": "1",
}, "yx": "1"
{
"id": "103",
"key": "4",
"name": "指示通知",
"yx": 0
},
{
"id": "104",
"key": "5",
"name": "任免通知",
"yx": 0
}, },
{ {
"id": "105", "id": "105",
"key": "6", "key": "3",
"name": "事务通知", "name": "事务通知",
"yx": 1 "dic": "1",
"yx": "0"
} }
], ],
"message": "" "message": ""

View File

@ -5,6 +5,7 @@
{ {
"id": "100", "id": "100",
"userName": "81883387", "userName": "81883387",
"avatar": "images/avatar.jpg",
"mail": "81883387@qq.com", "mail": "81883387@qq.com",
"name": "sakuya", "name": "sakuya",
"group": ["1"], "group": ["1"],
@ -14,6 +15,7 @@
{ {
"id": "101", "id": "101",
"userName": "luhkpev", "userName": "luhkpev",
"avatar": "images/avatar3.gif",
"mail": "k.luhkpev@zdgtfd.ma", "mail": "k.luhkpev@zdgtfd.ma",
"name": "John Martinez", "name": "John Martinez",
"group": ["22", "23"], "group": ["22", "23"],

View File

@ -72,6 +72,15 @@ const api = {
} }
} }
}, },
app: {
list: {
url: `${config.API_URL}/json/app.json`,
name: "应用列表",
get: async function(){
return await http.get(this.url);
}
}
},
demo: { demo: {
select: { select: {
url: `${config.API_URL}/json/select.json`, url: `${config.API_URL}/json/select.json`,

View File

@ -0,0 +1,82 @@
<template>
<div class="sc-upload">
<div v-show="img!=''" class="sc-upload-file">
<div class="mask">
<span class="del" @click.stop="del"><i class="el-icon-delete"></i></span>
</div>
<el-image class="file" :src="img" :preview-src-list="[img]" hide-on-click-modal append-to-body></el-image>
</div>
<div v-show="img==''" 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">
<div class="file-empty">
上传
</div>
</el-upload>
</div>
<el-input v-model="img" style="display:none"></el-input>
</div>
</template>
<script>
export default {
props: {
modelValue: { type: String, default: "" }
},
data() {
return {
loading: false,
img: ""
}
},
watch:{
modelValue(){
this.img = this.modelValue;
},
img(){
this.$emit('update:modelValue', this.img);
}
},
mounted() {
},
methods: {
before(file){
this.img = URL.createObjectURL(file);
this.loading = true;
},
success(res){
this.loading = false;
this.img = res.data.src;
},
error(err){
console.log(err.message);
this.loading = false;
this.img = ""
},
del(){
this.img = ""
}
}
}
</script>
<style scoped>
.el-form-item.is-error .sc-upload {border: 1px solid #F56C6C;}
.sc-upload {width: 100px;height: 100px;}
.sc-upload-file {position: relative;width: 100px;height: 100px;}
.sc-upload-file .mask {display: none;position: absolute;top:0px;right:0px;line-height: 1;z-index: 1;}
.sc-upload-file .mask span {display: inline-block;width: 25px;height:25px;line-height: 23px;text-align: center;cursor: pointer;color: #fff;}
.sc-upload-file .mask span i {font-size: 12px;}
.sc-upload-file .mask .del {background: #F56C6C;}
.sc-upload-file .file {width: 100px;height: 100px;}
.sc-upload-file .file img {vertical-align: bottom;}
.sc-upload-file:hover .mask {display: inline-block;}
.sc-upload-uploader {}
.sc-upload-uploader .file-empty {width: 100px;height: 100px;background: #f5f5f5;}
</style>

View File

@ -13,6 +13,7 @@ import http from "./utils/request"
import permission from './utils/permission' import permission from './utils/permission'
import scTable from './components/scTable' import scTable from './components/scTable'
import scFilterBar from './components/scFilterBar' import scFilterBar from './components/scFilterBar'
import scUpload from './components/scUpload'
const app = createApp(App); const app = createApp(App);
@ -28,5 +29,6 @@ app.use(ElementPlus, {size: 'small', zIndex: 3000 ,locale: locale});
app.component('scTable', scTable); app.component('scTable', scTable);
app.component('scFilterBar', scFilterBar); app.component('scFilterBar', scFilterBar);
app.component('scUpload', scUpload);
app.mount('#app'); app.mount('#app');

View File

@ -0,0 +1,48 @@
<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">
<scTable ref="table" :apiObj="apiObj" row-key="id">
<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="秘钥" 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="操作" fixed="right" align="right" width="120">
<template #default="scope">
<el-button type="text" size="small" @click="table_edit(scope.row, scope.$index)">编辑</el-button>
<el-popconfirm title="确定删除吗?" @confirm="table_del(scope.row, scope.$index)">
<template #reference>
<el-button type="text" size="small">删除</el-button>
</template>
</el-popconfirm>
</template>
</el-table-column>
</scTable>
</el-main>
</el-container>
</template>
<script>
export default {
name: "client",
data(){
return {
apiObj: this.$API.app.list
}
},
methods: {
add(){
}
}
}
</script>
<style>
</style>

View File

@ -1,24 +1,14 @@
<template> <template>
<el-form :model="form" :rules="rules" ref="dialogForm" label-width="80px" label-position="left"> <el-form :model="form" :rules="rules" ref="dialogForm" label-width="80px" label-position="left">
<el-row :gutter="20"> <el-form-item label="编码" prop="code">
<el-col :span="24"> <el-input v-model="form.code" clearable></el-input>
<el-form-item label="编码" prop="code"> </el-form-item>
<el-input v-model="form.code" clearable></el-input> <el-form-item label="字典名称" prop="name">
</el-form-item> <el-input v-model="form.name" clearable></el-input>
</el-col> </el-form-item>
</el-row> <el-form-item label="父路径" prop="parentId">
<el-row :gutter="20"> <el-cascader v-model="form.parentId" :options="dic" :props="dicProps" :show-all-levels="false" clearable></el-cascader>
<el-col :span="12"> </el-form-item>
<el-form-item label="字典名称" prop="name">
<el-input v-model="form.name" clearable></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="父路径" prop="parentId">
<el-cascader v-model="form.parentId" :options="dic" :props="dicProps" :show-all-levels="false" clearable></el-cascader>
</el-form-item>
</el-col>
</el-row>
</el-form> </el-form>
</template> </template>

View File

@ -28,24 +28,32 @@
<el-header> <el-header>
<div class="left-panel"> <div class="left-panel">
<el-button type="primary" icon="el-icon-plus" @click="addInfo"></el-button> <el-button type="primary" icon="el-icon-plus" @click="addInfo"></el-button>
<el-button type="danger" plain icon="el-icon-delete" disabled></el-button> <el-button type="danger" plain icon="el-icon-delete" :disabled="selection.length==0" @click="batch_del"></el-button>
</div> </div>
</el-header> </el-header>
<el-main class="nopadding"> <el-main class="nopadding">
<scTable ref="table" :apiObj="listApi" :params="listApiParams" stripe :paginationLayout="'prev, pager, next'"> <scTable ref="table" :apiObj="listApi" row-key="id" :params="listApiParams" @selection-change="selectionChange" stripe :paginationLayout="'prev, pager, next'">
<el-table-column type="selection" width="50"></el-table-column> <el-table-column type="selection" width="50"></el-table-column>
<el-table-column label="#" type="index" width="50"></el-table-column>
<el-table-column label="" width="50"> <el-table-column label="" width="50">
<template #default> <template #default>
<el-tag type="info" style="cursor: move;"><i class="el-icon-d-caret"></i></el-tag> <el-tag class="move" style="cursor: move;"><i class="el-icon-d-caret"></i></el-tag>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="名称" prop="name" width="150"></el-table-column> <el-table-column label="名称" prop="name" width="150"></el-table-column>
<el-table-column label="键值" prop="key" width="150"></el-table-column> <el-table-column label="键值" prop="key" width="150"></el-table-column>
<el-table-column label="是否有效" prop="yx" width="100"> <el-table-column label="是否有效" prop="yx" width="100">
<template #default="scope"> <template #default="scope">
<i v-if="scope.row.yx==1" class="el-icon-success" style="color: #67C23A;"></i> <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>
<i v-if="scope.row.yx==0" class="el-icon-remove" style="color: #DCDFE6;"></i> </template>
</el-table-column>
<el-table-column label="操作" fixed="right" align="right" width="140">
<template #default="scope">
<el-button type="text" size="small" @click="table_edit(scope.row, scope.$index)">编辑</el-button>
<el-popconfirm title="确定删除吗?" @confirm="table_del(scope.row, scope.$index)">
<template #reference>
<el-button type="text" size="small">删除</el-button>
</template>
</el-popconfirm>
</template> </template>
</el-table-column> </el-table-column>
</scTable> </scTable>
@ -53,7 +61,7 @@
</el-container> </el-container>
</el-container> </el-container>
<el-dialog :title="titleMap[dicMode]" v-model="dicDialogVisible" :width="600" destroy-on-close> <el-dialog :title="titleMap[dicMode]" v-model="dicDialogVisible" :width="330" destroy-on-close>
<dic-dialog ref="dicDialog" :mode="dicMode"></dic-dialog> <dic-dialog ref="dicDialog" :mode="dicMode"></dic-dialog>
<template #footer> <template #footer>
<el-button @click="dicDialogVisible=false" > </el-button> <el-button @click="dicDialogVisible=false" > </el-button>
@ -61,7 +69,7 @@
</template> </template>
</el-dialog> </el-dialog>
<el-dialog :title="titleMap[listMode]" v-model="listDialogVisible" :width="600" destroy-on-close> <el-dialog :title="titleMap[listMode]" v-model="listDialogVisible" :width="330" destroy-on-close>
<list-dialog ref="listDialog" :mode="listMode" :params="listDialogParams"></list-dialog> <list-dialog ref="listDialog" :mode="listMode" :params="listDialogParams"></list-dialog>
<template #footer> <template #footer>
<el-button @click="listDialogVisible=false" > </el-button> <el-button @click="listDialogVisible=false" > </el-button>
@ -74,6 +82,7 @@
<script> <script>
import dicDialog from './dic' import dicDialog from './dic'
import listDialog from './list' import listDialog from './list'
import Sortable from 'sortablejs'
export default { export default {
name: 'dic', name: 'dic',
@ -103,6 +112,7 @@
listDialogParams: {}, listDialogParams: {},
isListSaveing: false, isListSaveing: false,
listMode: 'add', listMode: 'add',
selection: []
} }
}, },
watch: { watch: {
@ -112,6 +122,7 @@
}, },
mounted() { mounted() {
this.getDic() this.getDic()
this.rowDrop()
}, },
methods: { methods: {
// //
@ -226,15 +237,98 @@
}) })
}, },
//
rowDrop(){
const _this = this
const tbody = this.$refs.table.$el.querySelector('.el-table__body-wrapper tbody')
Sortable.create(tbody, {
handle: ".move",
animation: 300,
ghostClass: "ghost",
onEnd({ newIndex, oldIndex }) {
const tableData = _this.$refs.table.tableData
const currRow = tableData.splice(oldIndex, 1)[0]
tableData.splice(newIndex, 0, currRow)
_this.$message.success("排序成功")
}
})
},
// //
addInfo(){ addInfo(){
var dicCurrentKey = this.$refs.dic.getCurrentKey(); var dicCurrentKey = this.$refs.dic.getCurrentKey();
this.listDialogParams = {code: dicCurrentKey}; this.listDialogParams = {code: dicCurrentKey};
this.listMode = 'add';
this.listDialogVisible = true; this.listDialogVisible = true;
}, },
// //
saveList(){ table_edit(row){
this.listMode = 'edit';
this.listDialogVisible = true;
this.$nextTick(() => {
this.$refs.listDialog.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){
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(() => {
})
},
//
saveList(){
this.$refs.listDialog.submit(async (formData) => {
this.isListSaveing = true;
var res = await this.$API.user.save.post(formData);
this.isListSaveing = false;
if(res.code == 200){
// OR /
this.listDialogVisible = false;
this.$message.success("操作成功")
}else{
this.$alert(res.message, "提示", {type: 'error'})
}
})
},
//
selectionChange(selection){
this.selection = selection;
},
//
changeSwitch(val, row){
//1.
row.yx = row.yx == '1'?'0':'1'
//2.
row.$switch_yx = true;
//3.
setTimeout(()=>{
delete row.$switch_yx;
row.yx = val;
this.$message.success(`操作成功id:${row.id} val:${val}`)
}, 500)
} }
} }
} }

View File

@ -1,6 +1,18 @@
<template> <template>
LIST <el-form :model="form" :rules="rules" ref="dialogForm" label-width="100px" label-position="left">
{{params}} <el-form-item label="所属字典" prop="dic">
<el-cascader v-model="form.dic" :options="dic" :props="dicProps" :show-all-levels="false" clearable></el-cascader>
</el-form-item>
<el-form-item label="项名称" prop="name">
<el-input v-model="form.name" clearable></el-input>
</el-form-item>
<el-form-item label="键值" prop="key">
<el-input v-model="form.key" clearable></el-input>
</el-form-item>
<el-form-item label="是否有效" prop="yx">
<el-switch v-model="form.yx" active-value="1" inactive-value="0"></el-switch>
</el-form-item>
</el-form>
</template> </template>
<script> <script>
@ -11,7 +23,61 @@
}, },
data() { data() {
return { return {
form: {
id: "",
dic: "",
name: "",
key: "",
yx: "1"
},
rules: {
dic: [
{required: true, message: '请选择所属字典'}
],
name: [
{required: true, message: '请输入项名称'}
],
key: [
{required: true, message: '请输入键值'}
]
},
dic: [],
dicProps: {
value: "id",
label: "name",
checkStrictly: true
}
}
},
mounted() {
if(this.params){
this.form.dic = this.params.code
}
this.getDic()
},
methods: {
//
async getDic(){
var res = await this.$API.dic.list.get();
this.dic = res.data;
},
//
submit(callback){
this.$refs.dialogForm.validate((valid) => {
if (valid) {
callback(this.form)
}else{
return false;
}
})
},
//
setData(data){
this.form.id = data.id
this.form.name = data.name
this.form.key = data.key
this.form.yx = data.yx
this.form.dic = data.dic
} }
} }
} }

View File

@ -0,0 +1,20 @@
<template>
<el-container>
<el-header>
</el-header>
<el-main class="nopadding">
</el-main>
</el-container>
</template>
<script>
export default {
name: "menu",
data(){
return {}
}
}
</script>
<style>
</style>

View File

@ -28,7 +28,12 @@
<el-main class="nopadding"> <el-main class="nopadding">
<scTable ref="table" :apiObj="apiObj" @selection-change="selectionChange" stripe> <scTable ref="table" :apiObj="apiObj" @selection-change="selectionChange" stripe>
<el-table-column type="selection" width="50"></el-table-column> <el-table-column type="selection" width="50"></el-table-column>
<el-table-column label="ID" prop="id" width="50"></el-table-column> <el-table-column label="ID" prop="id" width="80"></el-table-column>
<el-table-column label="头像" width="80">
<template #default="scope">
<el-avatar :src="scope.row.avatar" size="small"></el-avatar>
</template>
</el-table-column>
<el-table-column label="登录账号" prop="userName" width="150"></el-table-column> <el-table-column label="登录账号" prop="userName" width="150"></el-table-column>
<el-table-column label="姓名" prop="name" width="150"></el-table-column> <el-table-column label="姓名" prop="name" width="150"></el-table-column>
<el-table-column label="所属角色" prop="groupName" width="200"></el-table-column> <el-table-column label="所属角色" prop="groupName" width="200"></el-table-column>
@ -149,7 +154,7 @@
loading.close(); loading.close();
this.$message.success("操作成功") this.$message.success("操作成功")
}).catch(() => { }).catch(() => {
}) })
}, },
// //

View File

@ -1,5 +1,12 @@
<template> <template>
<el-form :model="form" :rules="rules" :disabled="mode=='show'" ref="dialogForm" label-width="80px" label-position="top"> <el-form :model="form" :rules="rules" :disabled="mode=='show'" ref="dialogForm" label-width="80px" label-position="top">
<el-row :gutter="20">
<el-col :span="24">
<el-form-item label="头像" prop="avatar">
<sc-upload v-model="form.avatar"></sc-upload>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20"> <el-row :gutter="20">
<el-col :span="12"> <el-col :span="12">
<el-form-item label="登录账号" prop="userName"> <el-form-item label="登录账号" prop="userName">
@ -26,7 +33,7 @@
</el-col> </el-col>
</el-row> </el-row>
<el-row :gutter="20"> <el-row :gutter="20">
<el-col :span="24"> <el-col :span="12">
<el-form-item label="所属角色" prop="group"> <el-form-item label="所属角色" prop="group">
<el-cascader v-model="form.group" :options="groups" :props="groupsProps" :show-all-levels="false" clearable></el-cascader> <el-cascader v-model="form.group" :options="groups" :props="groupsProps" :show-all-levels="false" clearable></el-cascader>
</el-form-item> </el-form-item>
@ -46,11 +53,15 @@
form: { form: {
id:"", id:"",
userName: "", userName: "",
avatar: "",
name: "", name: "",
group: "" group: ""
}, },
// //
rules: { rules: {
avatar:[
{required: true, message: '请上传头像'}
],
userName: [ userName: [
{required: true, message: '请输入登录账号'} {required: true, message: '请输入登录账号'}
], ],
@ -113,9 +124,10 @@
setData(data){ setData(data){
this.form.id = data.id this.form.id = data.id
this.form.userName = data.userName this.form.userName = data.userName
this.form.avatar = data.avatar
this.form.name = data.name this.form.name = data.name
this.form.group = data.group this.form.group = data.group
// //
//Object.assign(this.form, data) //Object.assign(this.form, data)
} }