master
parent
ad0fd2ab96
commit
183b44c83a
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<el-config-provider :button="buttonConfig" size="default">
|
<el-config-provider :button="buttonConfig" size="small">
|
||||||
<router-view #="{ Component }">
|
<router-view #="{ Component }">
|
||||||
<component :is="Component"/>
|
<component :is="Component"/>
|
||||||
</router-view>
|
</router-view>
|
||||||
|
|
|
||||||
|
|
@ -77,7 +77,7 @@ router.beforeEach((to, from) => {
|
||||||
} else {
|
} else {
|
||||||
return {
|
return {
|
||||||
replace: true,
|
replace: true,
|
||||||
name: 'menus',
|
name: 'role',
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -108,6 +108,8 @@ export function reloadRouter() {
|
||||||
.map((it) => it.routeName)
|
.map((it) => it.routeName)
|
||||||
|
|
||||||
routNames.push('menus')
|
routNames.push('menus')
|
||||||
|
routNames.push('user')
|
||||||
|
routNames.push('role')
|
||||||
|
|
||||||
if (Colls.isEmpty(routNames)) {
|
if (Colls.isEmpty(routNames)) {
|
||||||
return false
|
return false
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
export {}
|
export {}
|
||||||
declare global {
|
declare global {
|
||||||
const EffectScope: typeof import('vue').EffectScope
|
const EffectScope: typeof import('vue').EffectScope
|
||||||
|
const ElMessage: typeof import('element-plus/es').ElMessage
|
||||||
const acceptHMRUpdate: typeof import('pinia').acceptHMRUpdate
|
const acceptHMRUpdate: typeof import('pinia').acceptHMRUpdate
|
||||||
const computed: typeof import('vue').computed
|
const computed: typeof import('vue').computed
|
||||||
const createApp: typeof import('vue').createApp
|
const createApp: typeof import('vue').createApp
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@
|
||||||
// ------
|
// ------
|
||||||
// Generated by unplugin-vue-components
|
// Generated by unplugin-vue-components
|
||||||
// Read more: https://github.com/vuejs/core/pull/3399
|
// Read more: https://github.com/vuejs/core/pull/3399
|
||||||
import { GlobalComponents } from 'vue'
|
|
||||||
|
|
||||||
export {}
|
export {}
|
||||||
|
|
||||||
|
|
@ -15,25 +14,35 @@ declare module 'vue' {
|
||||||
ElAside: typeof import('element-plus/es')['ElAside']
|
ElAside: typeof import('element-plus/es')['ElAside']
|
||||||
ElAvatar: typeof import('element-plus/es')['ElAvatar']
|
ElAvatar: typeof import('element-plus/es')['ElAvatar']
|
||||||
ElButton: typeof import('element-plus/es')['ElButton']
|
ElButton: typeof import('element-plus/es')['ElButton']
|
||||||
|
ElButtonGroup: typeof import('element-plus/es')['ElButtonGroup']
|
||||||
|
ElCheckbox: typeof import('element-plus/es')['ElCheckbox']
|
||||||
|
ElCheckboxGroup: typeof import('element-plus/es')['ElCheckboxGroup']
|
||||||
ElConfigProvider: typeof import('element-plus/es')['ElConfigProvider']
|
ElConfigProvider: typeof import('element-plus/es')['ElConfigProvider']
|
||||||
ElContainer: typeof import('element-plus/es')['ElContainer']
|
ElContainer: typeof import('element-plus/es')['ElContainer']
|
||||||
ElDialog: typeof import('element-plus/es')['ElDialog']
|
ElDialog: typeof import('element-plus/es')['ElDialog']
|
||||||
ElDropdown: typeof import('element-plus/es')['ElDropdown']
|
ElDropdown: typeof import('element-plus/es')['ElDropdown']
|
||||||
|
ElEmpty: typeof import('element-plus/es')['ElEmpty']
|
||||||
ElForm: typeof import('element-plus/es')['ElForm']
|
ElForm: typeof import('element-plus/es')['ElForm']
|
||||||
ElFormItem: typeof import('element-plus/es')['ElFormItem']
|
ElFormItem: typeof import('element-plus/es')['ElFormItem']
|
||||||
ElHeader: typeof import('element-plus/es')['ElHeader']
|
ElHeader: typeof import('element-plus/es')['ElHeader']
|
||||||
ElIcon: typeof import('element-plus/es')['ElIcon']
|
ElIcon: typeof import('element-plus/es')['ElIcon']
|
||||||
ElIconFilter: typeof import('@element-plus/icons-vue')['Filter']
|
ElIconFilter: typeof import('@element-plus/icons-vue')['Filter']
|
||||||
|
ElIconPicture: typeof import('@element-plus/icons-vue')['Picture']
|
||||||
|
ElImage: typeof import('element-plus/es')['ElImage']
|
||||||
ElInput: typeof import('element-plus/es')['ElInput']
|
ElInput: typeof import('element-plus/es')['ElInput']
|
||||||
ElInputNumber: typeof import('element-plus/es')['ElInputNumber']
|
ElInputNumber: typeof import('element-plus/es')['ElInputNumber']
|
||||||
ElMain: typeof import('element-plus/es')['ElMain']
|
ElMain: typeof import('element-plus/es')['ElMain']
|
||||||
ElOption: typeof import('element-plus/es')['ElOption']
|
ElOption: typeof import('element-plus/es')['ElOption']
|
||||||
ElPagination: typeof import('element-plus/es')['ElPagination']
|
ElPagination: typeof import('element-plus/es')['ElPagination']
|
||||||
ElSelect: typeof import('element-plus/es')['ElSelect']
|
ElSelect: typeof import('element-plus/es')['ElSelect']
|
||||||
|
ElSwitch: typeof import('element-plus/es')['ElSwitch']
|
||||||
ElTable: typeof import('element-plus/es')['ElTable']
|
ElTable: typeof import('element-plus/es')['ElTable']
|
||||||
ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
|
ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
|
||||||
ElTabPane: typeof import('element-plus/es')['ElTabPane']
|
ElTabPane: typeof import('element-plus/es')['ElTabPane']
|
||||||
ElTabs: typeof import('element-plus/es')['ElTabs']
|
ElTabs: typeof import('element-plus/es')['ElTabs']
|
||||||
|
ElTag: typeof import('element-plus/es')['ElTag']
|
||||||
|
ElTooltip: typeof import('element-plus/es')['ElTooltip']
|
||||||
|
ElTransfer: typeof import('element-plus/es')['ElTransfer']
|
||||||
ElTreeSelect: typeof import('element-plus/es')['ElTreeSelect']
|
ElTreeSelect: typeof import('element-plus/es')['ElTreeSelect']
|
||||||
ElUpload: typeof import('element-plus/es')['ElUpload']
|
ElUpload: typeof import('element-plus/es')['ElUpload']
|
||||||
RouterLink: typeof import('vue-router')['RouterLink']
|
RouterLink: typeof import('vue-router')['RouterLink']
|
||||||
|
|
@ -49,27 +58,37 @@ declare global {
|
||||||
const ElAside: typeof import('element-plus/es')['ElAside']
|
const ElAside: typeof import('element-plus/es')['ElAside']
|
||||||
const ElAvatar: typeof import('element-plus/es')['ElAvatar']
|
const ElAvatar: typeof import('element-plus/es')['ElAvatar']
|
||||||
const ElButton: typeof import('element-plus/es')['ElButton']
|
const ElButton: typeof import('element-plus/es')['ElButton']
|
||||||
|
const ElButtonGroup: typeof import('element-plus/es')['ElButtonGroup']
|
||||||
|
const ElCheckbox: typeof import('element-plus/es')['ElCheckbox']
|
||||||
|
const ElCheckboxGroup: typeof import('element-plus/es')['ElCheckboxGroup']
|
||||||
const ElConfigProvider: typeof import('element-plus/es')['ElConfigProvider']
|
const ElConfigProvider: typeof import('element-plus/es')['ElConfigProvider']
|
||||||
const ElContainer: typeof import('element-plus/es')['ElContainer']
|
const ElContainer: typeof import('element-plus/es')['ElContainer']
|
||||||
const ElDialog: typeof import('element-plus/es')['ElDialog']
|
const ElDialog: typeof import('element-plus/es')['ElDialog']
|
||||||
const ElDropdown: typeof import('element-plus/es')['ElDropdown']
|
const ElDropdown: typeof import('element-plus/es')['ElDropdown']
|
||||||
|
const ElEmpty: typeof import('element-plus/es')['ElEmpty']
|
||||||
const ElForm: typeof import('element-plus/es')['ElForm']
|
const ElForm: typeof import('element-plus/es')['ElForm']
|
||||||
const ElFormItem: typeof import('element-plus/es')['ElFormItem']
|
const ElFormItem: typeof import('element-plus/es')['ElFormItem']
|
||||||
const ElHeader: typeof import('element-plus/es')['ElHeader']
|
const ElHeader: typeof import('element-plus/es')['ElHeader']
|
||||||
const ElIcon: typeof import('element-plus/es')['ElIcon']
|
const ElIcon: typeof import('element-plus/es')['ElIcon']
|
||||||
const ElIconFilter: typeof import('@element-plus/icons-vue')['Filter']
|
const ElIconFilter: typeof import('@element-plus/icons-vue')['Filter']
|
||||||
|
const ElIconPicture: typeof import('@element-plus/icons-vue')['Picture']
|
||||||
|
const ElImage: typeof import('element-plus/es')['ElImage']
|
||||||
const ElInput: typeof import('element-plus/es')['ElInput']
|
const ElInput: typeof import('element-plus/es')['ElInput']
|
||||||
const ElInputNumber: typeof import('element-plus/es')['ElInputNumber']
|
const ElInputNumber: typeof import('element-plus/es')['ElInputNumber']
|
||||||
const ElMain: typeof import('element-plus/es')['ElMain']
|
const ElMain: typeof import('element-plus/es')['ElMain']
|
||||||
const ElOption: typeof import('element-plus/es')['ElOption']
|
const ElOption: typeof import('element-plus/es')['ElOption']
|
||||||
const ElPagination: typeof import('element-plus/es')['ElPagination']
|
const ElPagination: typeof import('element-plus/es')['ElPagination']
|
||||||
const ElSelect: typeof import('element-plus/es')['ElSelect']
|
const ElSelect: typeof import('element-plus/es')['ElSelect']
|
||||||
|
const ElSwitch: typeof import('element-plus/es')['ElSwitch']
|
||||||
const ElTable: typeof import('element-plus/es')['ElTable']
|
const ElTable: typeof import('element-plus/es')['ElTable']
|
||||||
const ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
|
const ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
|
||||||
const ElTabPane: typeof import('element-plus/es')['ElTabPane']
|
const ElTabPane: typeof import('element-plus/es')['ElTabPane']
|
||||||
const ElTabs: typeof import('element-plus/es')['ElTabs']
|
const ElTabs: typeof import('element-plus/es')['ElTabs']
|
||||||
|
const ElTag: typeof import('element-plus/es')['ElTag']
|
||||||
|
const ElTooltip: typeof import('element-plus/es')['ElTooltip']
|
||||||
|
const ElTransfer: typeof import('element-plus/es')['ElTransfer']
|
||||||
const ElTreeSelect: typeof import('element-plus/es')['ElTreeSelect']
|
const ElTreeSelect: typeof import('element-plus/es')['ElTreeSelect']
|
||||||
const ElUpload: typeof import('element-plus/es')['ElUpload']
|
const ElUpload: typeof import('element-plus/es')['ElUpload']
|
||||||
const RouterLink: typeof import('vue-router')['RouterLink']
|
const RouterLink: typeof import('vue-router')['RouterLink']
|
||||||
const RouterView: typeof import('vue-router')['RouterView']
|
const RouterView: typeof import('vue-router')['RouterView']
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,8 +20,8 @@ declare global {
|
||||||
}
|
}
|
||||||
|
|
||||||
interface PageParam {
|
interface PageParam {
|
||||||
current: number
|
current?: number
|
||||||
size: number
|
size?: number
|
||||||
orders?: string
|
orders?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,13 @@
|
||||||
import {
|
import {
|
||||||
|
ElButton,
|
||||||
|
ElIcon,
|
||||||
ElMenu,
|
ElMenu,
|
||||||
ElMenuItem,
|
ElMenuItem,
|
||||||
ElMenuItemGroup,
|
ElMenuItemGroup,
|
||||||
ElSubMenu,
|
ElSubMenu,
|
||||||
type MenuItemRegistered,
|
type MenuItemRegistered,
|
||||||
} from 'element-plus'
|
} from 'element-plus'
|
||||||
|
import { elIcons } from '@/common/element/element.ts'
|
||||||
|
|
||||||
export interface Menu extends G.TreeNode {
|
export interface Menu extends G.TreeNode {
|
||||||
// Id
|
// Id
|
||||||
|
|
@ -72,10 +74,24 @@ export default defineComponent(
|
||||||
}
|
}
|
||||||
return currentNode
|
return currentNode
|
||||||
}
|
}
|
||||||
|
const isCollapse = ref(false)
|
||||||
|
|
||||||
return () => (<ElMenu>{{
|
return () => (<>
|
||||||
default: () => menus.map(renderMenu),
|
<ElMenu collapse={isCollapse.value} style={{height: '100%', overflow: 'auto', '--el-menu-base-level-padding': '10px'}} class={'menus'}>
|
||||||
}}</ElMenu>)
|
{{
|
||||||
|
default: () => menus.map(renderMenu),
|
||||||
|
}}
|
||||||
|
</ElMenu>
|
||||||
|
<ElButton style={{position: 'absolute', right: 0, bottom: 0, width: '32px', height: '32px'}} onClick={() => {
|
||||||
|
isCollapse.value = !isCollapse.value
|
||||||
|
}}>
|
||||||
|
<ElIcon style={{cursor: 'pointer'}}>
|
||||||
|
{
|
||||||
|
isCollapse.value ? <elIcons.Fold/> : <elIcons.Expand/>
|
||||||
|
}
|
||||||
|
</ElIcon>
|
||||||
|
</ElButton>
|
||||||
|
</>)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
props: {
|
props: {
|
||||||
|
|
|
||||||
|
|
@ -102,12 +102,8 @@ onUnmounted(() => {
|
||||||
|
|
||||||
& > aside {
|
& > aside {
|
||||||
height 100%;
|
height 100%;
|
||||||
width 300px;
|
width auto
|
||||||
|
position relative
|
||||||
& > ul {
|
|
||||||
height 100%
|
|
||||||
overflow auto
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
& > main {
|
& > main {
|
||||||
|
|
@ -120,4 +116,10 @@ onUnmounted(() => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
<style>
|
||||||
|
.menus:not(.el-menu--collapse) {
|
||||||
|
width: 230px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ const loginFormIns = ref<FormInstance>()
|
||||||
const loginForm = reactive<LoginTypes.LoginForm>({
|
const loginForm = reactive<LoginTypes.LoginForm>({
|
||||||
account: '',
|
account: '',
|
||||||
secret: '',
|
secret: '',
|
||||||
|
clientCode: 0,
|
||||||
})
|
})
|
||||||
const rules = reactive<FormRules<LoginTypes.LoginForm>>({
|
const rules = reactive<FormRules<LoginTypes.LoginForm>>({
|
||||||
account: [
|
account: [
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ declare global {
|
||||||
interface LoginForm {
|
interface LoginForm {
|
||||||
account: string
|
account: string
|
||||||
secret: string
|
secret: string
|
||||||
|
clientCode: 0 | 1
|
||||||
}
|
}
|
||||||
|
|
||||||
interface UserSetting {
|
interface UserSetting {
|
||||||
|
|
|
||||||
|
|
@ -133,10 +133,10 @@ onMounted(() => {
|
||||||
width 100%
|
width 100%
|
||||||
|
|
||||||
:deep(.table-header) {
|
:deep(.table-header) {
|
||||||
color black
|
color #454C59
|
||||||
|
|
||||||
th {
|
th {
|
||||||
background-color #E1E5EB
|
background-color #EDF1F7
|
||||||
font-weight 500
|
font-weight 500
|
||||||
position relative
|
position relative
|
||||||
|
|
||||||
|
|
@ -151,7 +151,7 @@ onMounted(() => {
|
||||||
top: 50%;
|
top: 50%;
|
||||||
left: 1px;
|
left: 1px;
|
||||||
width: 1px;
|
width: 1px;
|
||||||
background-color: #A6AFB5;
|
background-color: #D3D7DE;
|
||||||
transform: translateY(-50%);
|
transform: translateY(-50%);
|
||||||
content: "";
|
content: "";
|
||||||
height 50%
|
height 50%
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
import { get } from '@/common/utils/http-util.ts'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
list(data?: ResourceTypes.SearchResourceParam) {
|
||||||
|
return get<ResourceTypes.SearchResourceResult[]>('/resource/list', data)
|
||||||
|
},
|
||||||
|
listRoleRes(roleId: string) {
|
||||||
|
return get<ResourceTypes.SearchResourceResult[]>('/resource/list_role_res', {roleId})
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,57 @@
|
||||||
|
export {}
|
||||||
|
declare global {
|
||||||
|
namespace ResourceTypes {
|
||||||
|
interface SearchResourceParam extends G.PageParam {
|
||||||
|
// Id
|
||||||
|
id?: string
|
||||||
|
// 编号
|
||||||
|
sn?: string
|
||||||
|
// 表名称
|
||||||
|
tableName?: string
|
||||||
|
// 数据行 Id
|
||||||
|
dataId?: string
|
||||||
|
// 备注
|
||||||
|
memo?: string
|
||||||
|
keywords?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
interface SearchResourceResult {
|
||||||
|
// Id
|
||||||
|
id?: string
|
||||||
|
// 编号
|
||||||
|
sn?: string
|
||||||
|
// 表名称
|
||||||
|
tableName?: string
|
||||||
|
// 数据行 Id
|
||||||
|
dataId?: string
|
||||||
|
// 备注
|
||||||
|
memo?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
interface AddResourceParam {
|
||||||
|
// Id
|
||||||
|
id?: string
|
||||||
|
// 编号
|
||||||
|
sn?: string
|
||||||
|
// 表名称
|
||||||
|
tableName?: string
|
||||||
|
// 数据行 Id
|
||||||
|
dataId?: string
|
||||||
|
// 备注
|
||||||
|
memo?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ModifyResourceParam {
|
||||||
|
// Id
|
||||||
|
id?: string
|
||||||
|
// 编号
|
||||||
|
sn?: string
|
||||||
|
// 表名称
|
||||||
|
tableName?: string
|
||||||
|
// 数据行 Id
|
||||||
|
dataId?: string
|
||||||
|
// 备注
|
||||||
|
memo?: string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,101 @@
|
||||||
|
<template>
|
||||||
|
<ElDialog v-model="showDialog"
|
||||||
|
:close-on-click-modal="false"
|
||||||
|
destroy-on-close
|
||||||
|
width="900">
|
||||||
|
<ElTransfer
|
||||||
|
v-model="rightValue"
|
||||||
|
:button-texts="['解绑', '绑定']"
|
||||||
|
:data="allRes"
|
||||||
|
:filter-method="filterMethod"
|
||||||
|
:props="{
|
||||||
|
key: 'id',
|
||||||
|
label: 'roleName',
|
||||||
|
}"
|
||||||
|
:titles="['资源列表', '已有资源']"
|
||||||
|
class="transfer"
|
||||||
|
filter-placeholder="搜索"
|
||||||
|
filterable
|
||||||
|
>
|
||||||
|
<template #default="{ option }">
|
||||||
|
<ElTooltip
|
||||||
|
:content="option.sn"
|
||||||
|
placement="top">
|
||||||
|
<span> {{ option.memo }} </span>
|
||||||
|
</ElTooltip>
|
||||||
|
</template>
|
||||||
|
<template #left-empty>
|
||||||
|
<el-empty :image-size="60" description="暂无数据"/>
|
||||||
|
</template>
|
||||||
|
<template #right-empty>
|
||||||
|
<el-empty :image-size="60" description="暂无数据"/>
|
||||||
|
</template>
|
||||||
|
</ElTransfer>
|
||||||
|
<template #footer>
|
||||||
|
<ElButton @click="showDialog = false">取消</ElButton>
|
||||||
|
<ElButton :disabled="rightValue.length <= 0" :loading="submiting" type="primary" @click="submitHandler">提交</ElButton>
|
||||||
|
</template>
|
||||||
|
</ElDialog>
|
||||||
|
</template>
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import RoleApi from '@/pages/sys/role/role-api.ts'
|
||||||
|
import Strings from '@/common/utils/strings.ts'
|
||||||
|
import {
|
||||||
|
ElMessage,
|
||||||
|
type TransferDataItem,
|
||||||
|
} from 'element-plus'
|
||||||
|
import ResourceApi from '@/pages/sys/resource/resource-api.ts'
|
||||||
|
|
||||||
|
const showDialog = ref(false)
|
||||||
|
const submiting = ref(false)
|
||||||
|
const hadRes = ref<ResourceTypes.SearchResourceResult[]>([])
|
||||||
|
const allRes = ref<ResourceTypes.SearchResourceResult[]>([])
|
||||||
|
const rightValue = ref<string[]>([])
|
||||||
|
const currentUserId = ref<string>('')
|
||||||
|
|
||||||
|
function filterMethod(query: string, item: TransferDataItem) {
|
||||||
|
return Strings.isBlank(query) || (item as ResourceTypes.SearchResourceResult).memo!.includes(query) || (item as ResourceTypes.SearchResourceResult).memo!.includes(query)
|
||||||
|
}
|
||||||
|
|
||||||
|
function submitHandler() {
|
||||||
|
submiting.value = true
|
||||||
|
RoleApi.bindRes({
|
||||||
|
id: currentUserId.value,
|
||||||
|
res: rightValue.value,
|
||||||
|
}).then(() => {
|
||||||
|
ElMessage.success('修改成功')
|
||||||
|
showDialog.value = false
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
submiting.value = false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
open(roleId: string) {
|
||||||
|
currentUserId.value = roleId
|
||||||
|
showDialog.value = true
|
||||||
|
ResourceApi.listRoleRes(roleId)
|
||||||
|
.then(res => {
|
||||||
|
hadRes.value = res.data ?? []
|
||||||
|
rightValue.value = hadRes.value.map(it => it.id!)
|
||||||
|
})
|
||||||
|
ResourceApi.list()
|
||||||
|
.then(res => {
|
||||||
|
allRes.value = res.data ?? []
|
||||||
|
})
|
||||||
|
},
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
<style lang="stylus" scoped>
|
||||||
|
.transfer {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
:deep(.el-transfer-panel) {
|
||||||
|
flex 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
import {
|
||||||
|
get,
|
||||||
|
post,
|
||||||
|
} from '@/common/utils/http-util.ts'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
paging(data: RoleTypes.SearchRoleParam) {
|
||||||
|
return get<G.PageResult<RoleTypes.SearchRoleResult>>('/role/paging', data)
|
||||||
|
},
|
||||||
|
detail(id: string) {
|
||||||
|
return get<RoleTypes.SearchRoleResult>('/role/detail', {id})
|
||||||
|
},
|
||||||
|
add(data: RoleTypes.AddRoleParam) {
|
||||||
|
return post('/role/add', data)
|
||||||
|
},
|
||||||
|
modify(data: RoleTypes.ModifyRoleParam) {
|
||||||
|
return post('/role/modify', data)
|
||||||
|
},
|
||||||
|
del(ids: string[]) {
|
||||||
|
return post('/role/del', ids)
|
||||||
|
},
|
||||||
|
listUserRole(userId: string) {
|
||||||
|
return get<RoleTypes.SearchRoleResult[]>('/role/list_user_role', {userId})
|
||||||
|
},
|
||||||
|
list(data?: RoleTypes.SearchRoleParam) {
|
||||||
|
return get<RoleTypes.SearchRoleResult[]>('/role/list', data)
|
||||||
|
},
|
||||||
|
bindRes(data: RoleTypes.BindResParam) {
|
||||||
|
return post('/role/bind_res', data)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,54 @@
|
||||||
|
export {}
|
||||||
|
declare global {
|
||||||
|
namespace RoleTypes {
|
||||||
|
interface SearchRoleParam extends G.PageParam {
|
||||||
|
// Id
|
||||||
|
id?: string
|
||||||
|
// 角色代码
|
||||||
|
roleCode?: string
|
||||||
|
// 角色名称
|
||||||
|
roleName?: string
|
||||||
|
// 备注
|
||||||
|
memo?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
interface SearchRoleResult {
|
||||||
|
// Id
|
||||||
|
id?: string
|
||||||
|
// 角色代码
|
||||||
|
roleCode?: string
|
||||||
|
// 角色名称
|
||||||
|
roleName?: string
|
||||||
|
// 备注
|
||||||
|
memo?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
interface AddRoleParam {
|
||||||
|
// Id
|
||||||
|
id?: string
|
||||||
|
// 角色代码
|
||||||
|
roleCode?: string
|
||||||
|
// 角色名称
|
||||||
|
roleName?: string
|
||||||
|
// 备注
|
||||||
|
memo?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ModifyRoleParam {
|
||||||
|
// Id
|
||||||
|
id?: string
|
||||||
|
// 角色代码
|
||||||
|
roleCode?: string
|
||||||
|
// 角色名称
|
||||||
|
roleName?: string
|
||||||
|
// 备注
|
||||||
|
memo?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
interface BindResParam {
|
||||||
|
id?: string
|
||||||
|
res?: string[]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,97 @@
|
||||||
|
<template>
|
||||||
|
<ElDialog v-model="showDialog"
|
||||||
|
:close-on-click-modal="false"
|
||||||
|
destroy-on-close
|
||||||
|
width="700">
|
||||||
|
<ElTransfer
|
||||||
|
v-model="rightValue"
|
||||||
|
:button-texts="['解绑', '绑定']"
|
||||||
|
:data="allRoles"
|
||||||
|
:filter-method="filterMethod"
|
||||||
|
:props="{
|
||||||
|
key: 'id',
|
||||||
|
label: 'roleName',
|
||||||
|
}"
|
||||||
|
:titles="['角色列表', '已有角色']"
|
||||||
|
class="transfer"
|
||||||
|
filter-placeholder="搜索"
|
||||||
|
filterable
|
||||||
|
>
|
||||||
|
<template #default="{ option }">
|
||||||
|
<ElTooltip
|
||||||
|
:content="option.roleCode"
|
||||||
|
placement="top">
|
||||||
|
<span> {{ option.roleName }} </span>
|
||||||
|
</ElTooltip>
|
||||||
|
</template>
|
||||||
|
<template #left-empty>
|
||||||
|
<el-empty :image-size="60" description="暂无数据"/>
|
||||||
|
</template>
|
||||||
|
<template #right-empty>
|
||||||
|
<el-empty :image-size="60" description="暂无数据"/>
|
||||||
|
</template>
|
||||||
|
</ElTransfer>
|
||||||
|
<template #footer>
|
||||||
|
<ElButton @click="showDialog = false">取消</ElButton>
|
||||||
|
<ElButton :disabled="rightValue.length <= 0" :loading="submiting" type="primary" @click="submitHandler">提交</ElButton>
|
||||||
|
</template>
|
||||||
|
</ElDialog>
|
||||||
|
</template>
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import RoleApi from '@/pages/sys/role/role-api.ts'
|
||||||
|
import Strings from '@/common/utils/strings.ts'
|
||||||
|
import {
|
||||||
|
ElMessage,
|
||||||
|
type TransferDataItem,
|
||||||
|
} from 'element-plus'
|
||||||
|
import UserApi from '@/pages/sys/user/user-api.ts'
|
||||||
|
|
||||||
|
const showDialog = ref(false)
|
||||||
|
const submiting = ref(false)
|
||||||
|
const hadRoles = ref<RoleTypes.SearchRoleResult[]>([])
|
||||||
|
const allRoles = ref<RoleTypes.SearchRoleResult[]>([])
|
||||||
|
const rightValue = ref<string[]>([])
|
||||||
|
const currentUserId = ref<string>('')
|
||||||
|
|
||||||
|
function filterMethod(query: string, item: TransferDataItem) {
|
||||||
|
return Strings.isBlank(query) || (item as RoleTypes.SearchRoleResult).roleCode!.includes(query) || (item as RoleTypes.SearchRoleResult).roleName!.includes(query)
|
||||||
|
}
|
||||||
|
|
||||||
|
function submitHandler() {
|
||||||
|
submiting.value = true
|
||||||
|
UserApi.bindRole({
|
||||||
|
id: currentUserId.value,
|
||||||
|
roles: rightValue.value,
|
||||||
|
}).then(() => {
|
||||||
|
ElMessage.success('修改成功')
|
||||||
|
showDialog.value = false
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
submiting.value = false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
open(userId: string) {
|
||||||
|
currentUserId.value = userId
|
||||||
|
showDialog.value = true
|
||||||
|
RoleApi.listUserRole(userId)
|
||||||
|
.then(res => {
|
||||||
|
hadRoles.value = res.data ?? []
|
||||||
|
rightValue.value = hadRoles.value.map(it => it.id!)
|
||||||
|
})
|
||||||
|
RoleApi.list()
|
||||||
|
.then(res => {
|
||||||
|
allRoles.value = res.data ?? []
|
||||||
|
})
|
||||||
|
},
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
<style lang="stylus" scoped>
|
||||||
|
.transfer {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -1,22 +1,22 @@
|
||||||
<template>
|
<template>
|
||||||
<Page>
|
<Page>
|
||||||
<ElForm v-show="showSearchForm" inline @submit.prevent="paging">
|
<ElForm v-show="showSearchForm" inline @submit.prevent="paging">
|
||||||
<ElFormItem label="昵称">
|
<ElFormItem label="昵称">
|
||||||
<ElInput
|
<ElInput
|
||||||
v-model="searchForm.nickname"
|
v-model="searchForm.nickname"
|
||||||
placeholder="昵称"/>
|
placeholder="昵称"/>
|
||||||
</ElFormItem>
|
</ElFormItem>
|
||||||
<ElFormItem label="头像">
|
<ElFormItem label="头像">
|
||||||
<ElInput
|
<ElInput
|
||||||
v-model="searchForm.avatar"
|
v-model="searchForm.avatar"
|
||||||
placeholder="头像"/>
|
placeholder="头像"/>
|
||||||
</ElFormItem>
|
</ElFormItem>
|
||||||
<ElFormItem label="邮箱">
|
<ElFormItem label="邮箱">
|
||||||
<ElInput
|
<ElInput
|
||||||
v-model="searchForm.email"
|
v-model="searchForm.email"
|
||||||
placeholder="邮箱"/>
|
placeholder="邮箱"/>
|
||||||
</ElFormItem>
|
</ElFormItem>
|
||||||
<ElFormItem label="手机号">
|
<ElFormItem label="手机号">
|
||||||
<ElInput
|
<ElInput
|
||||||
v-model="searchForm.phone"
|
v-model="searchForm.phone"
|
||||||
placeholder="手机号"/>
|
placeholder="手机号"/>
|
||||||
|
|
@ -36,22 +36,50 @@
|
||||||
empty-text="暂无数据"
|
empty-text="暂无数据"
|
||||||
header-row-class-name="table-header"
|
header-row-class-name="table-header"
|
||||||
row-key="id">
|
row-key="id">
|
||||||
<ElTableColumn label="昵称" prop="nickname"/>
|
<ElTableColumn label="昵称" prop="nickname"/>
|
||||||
|
<ElTableColumn label="头像" prop="avatar" width="60">
|
||||||
<ElTableColumn label="头像" prop="avatar"/>
|
<template #default="{row}">
|
||||||
|
<ElImage :src="AppApi.fileUrl(row.avatar)" class="avatar">
|
||||||
<ElTableColumn label="邮箱" prop="email"/>
|
<template #error>
|
||||||
|
<ElIcon>
|
||||||
<ElTableColumn label="手机号" prop="phone"/>
|
<ElIconPicture/>
|
||||||
|
</ElIcon>
|
||||||
|
</template>
|
||||||
|
</ElImage>
|
||||||
|
</template>
|
||||||
|
</ElTableColumn>
|
||||||
|
<ElTableColumn label="联系电话" prop="phone"/>
|
||||||
|
<ElTableColumn label="登录手机号" prop="account.phone"/>
|
||||||
|
<ElTableColumn label="用户名" prop="account.username"/>
|
||||||
|
<ElTableColumn label="微信标识" prop="account.wechatOpenid"/>
|
||||||
|
<ElTableColumn label="已授权客户端" prop="account.clientCode">
|
||||||
|
<template #default="{row}">
|
||||||
|
<ElCheckboxGroup v-model="row.account.clients" :disabled="row.id == '1'" @change="clientChangeHandler($event,row)">
|
||||||
|
<ElCheckbox :value="0" label="电脑端"/>
|
||||||
|
<ElCheckbox :value="1" label="微信小程序"/>
|
||||||
|
</ElCheckboxGroup>
|
||||||
|
</template>
|
||||||
|
</ElTableColumn>
|
||||||
|
<ElTableColumn label="是否禁用" prop="account.disabled">
|
||||||
|
<template #default="{row}">
|
||||||
|
<ElSwitch v-model="row.account.disabled" :disabled="row.id == '1'" @change="disabledUserHandler($event,row.id)"/>
|
||||||
|
</template>
|
||||||
|
</ElTableColumn>
|
||||||
|
<ElTableColumn label="注册时间" prop="account.regdate" width="170"/>
|
||||||
|
|
||||||
<ElTableColumn label="操作" width="180">
|
<ElTableColumn label="操作" width="180">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<ElButton text type="danger" @click="delHandler(scope)">删除</ElButton>
|
<!-- <ElButton text type="danger" :loading="deling" @click="delHandler(scope)">删除</ElButton> -->
|
||||||
<ElButton text type="primary" @click="modifyHandler(scope)">修改</ElButton>
|
<div class="action-btn">
|
||||||
|
<ElButton text type="primary" @click="bindRoleHandler(scope)">权限</ElButton>
|
||||||
|
<ElButton v-if="scope.row.id != '1'" text type="primary" @click="modifyHandler(scope)">修改</ElButton>
|
||||||
|
<ElButton v-if="scope.row.id != '1'" text type="primary" @click="resetPasswd(scope)">重置密码</ElButton>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</ElTableColumn>
|
</ElTableColumn>
|
||||||
</ElTable>
|
</ElTable>
|
||||||
<UserForm ref="userForm"/>
|
<UserForm ref="userForm" @edit-succ="paging"/>
|
||||||
|
<BindRole ref="bindRole"/>
|
||||||
</Page>
|
</Page>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
|
@ -59,40 +87,117 @@ import UserApi from '@/pages/sys/user/user-api.ts'
|
||||||
import Page from '@/components/page/Page.vue'
|
import Page from '@/components/page/Page.vue'
|
||||||
import { elIcons } from '@/common/element/element.ts'
|
import { elIcons } from '@/common/element/element.ts'
|
||||||
import UserForm from '@/pages/sys/user/UserForm.vue'
|
import UserForm from '@/pages/sys/user/UserForm.vue'
|
||||||
|
import {
|
||||||
|
type CheckboxValueType,
|
||||||
|
ElMessage,
|
||||||
|
} from 'element-plus'
|
||||||
|
import AppApi from '@/common/app/app-api.ts'
|
||||||
|
import BindRole from '@/pages/sys/user/BindRole.vue'
|
||||||
|
|
||||||
const tableData = ref<UserTypes.SearchUserResult[]>([])
|
const tableData = ref<UserTypes.SearchUserResult[]>([])
|
||||||
const searchForm = reactive<UserTypes.SearchUserParam>({
|
const searchForm = reactive<UserTypes.SearchUserParam>({
|
||||||
current: 1,
|
current: 1,
|
||||||
size: 20,
|
size: 20,
|
||||||
})
|
})
|
||||||
const searching = ref(false)
|
const searching = ref(false)
|
||||||
|
// const deling = ref(false)
|
||||||
const showSearchForm = ref(true)
|
const showSearchForm = ref(true)
|
||||||
const userFormIns = useTemplateRef<InstanceType<typeof UserForm>>('userForm')
|
const userFormIns = useTemplateRef<InstanceType<typeof UserForm>>('userForm')
|
||||||
|
const bindRoleIns = useTemplateRef<InstanceType<typeof BindRole>>('bindRole')
|
||||||
|
|
||||||
function showDialog(data?: UserTypes.SearchUserResult) {
|
function showDialog(data?: UserTypes.SearchUserResult) {
|
||||||
userFormIns.value?.open(data)
|
userFormIns.value?.open(data)
|
||||||
}
|
}
|
||||||
function delHandler({row}: { row: UserTypes.SearchUserResult }) {
|
|
||||||
UserApi.del([ row.id! ])
|
/* function delHandler({row}: { row: UserTypes.SearchUserResult }) {
|
||||||
}
|
if (row.id == '1') {
|
||||||
|
ElMessage.error('不能删除管理员')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
deling.value = true
|
||||||
|
UserApi.del([ row.id! ])
|
||||||
|
.then(() => {
|
||||||
|
ElMessage.success('删除成功')
|
||||||
|
paging()
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
deling.value = false
|
||||||
|
})
|
||||||
|
} */
|
||||||
|
|
||||||
function modifyHandler({row}: { row: UserTypes.SearchUserResult }) {
|
function modifyHandler({row}: { row: UserTypes.SearchUserResult }) {
|
||||||
|
if (row.id == '1') {
|
||||||
|
ElMessage.error('不能修改管理员')
|
||||||
|
return
|
||||||
|
}
|
||||||
showDialog(row)
|
showDialog(row)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function resetPasswd({row}: { row: UserTypes.SearchUserResult }) {
|
||||||
|
if (row.id == '1') {
|
||||||
|
ElMessage.error('不能修改管理员')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
UserApi.resetPasswd(row.id!)
|
||||||
|
.then((res) => {
|
||||||
|
ElMessage.success(res.msg)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function bindRoleHandler({row}: { row: UserTypes.SearchUserResult }) {
|
||||||
|
bindRoleIns.value?.open(row.id!)
|
||||||
|
}
|
||||||
|
|
||||||
function addHandler() {
|
function addHandler() {
|
||||||
showDialog()
|
showDialog()
|
||||||
}
|
}
|
||||||
|
|
||||||
function reset() {
|
function reset() {
|
||||||
Object.assign(searchForm, {})
|
Object.assign(searchForm, {})
|
||||||
paging()
|
paging()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function clientChangeHandler(clients: CheckboxValueType[], data: UserTypes.SearchUserResult) {
|
||||||
|
if (data.id == '1') {
|
||||||
|
ElMessage.error('不能操作管理员')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
searching.value = true
|
||||||
|
UserApi.bindClient(data.id!, clients as number[])
|
||||||
|
.then(() => {
|
||||||
|
ElMessage.success('修改成功')
|
||||||
|
paging()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function disabledUserHandler(val: string | number | boolean, id: string) {
|
||||||
|
if (id == '1') {
|
||||||
|
ElMessage.error('不能操作管理员')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
searching.value = true
|
||||||
|
UserApi.disable(id, val as boolean)
|
||||||
|
.then(() => {
|
||||||
|
ElMessage.success(val ? '禁用成功' : '启用成功')
|
||||||
|
paging()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
function paging() {
|
function paging() {
|
||||||
searching.value = true
|
searching.value = true
|
||||||
UserApi.paging(searchForm)
|
UserApi.paging(searchForm)
|
||||||
.then(res => {
|
.then(res => {
|
||||||
tableData.value = res.data?.records ?? []
|
tableData.value = res.data?.records ?? []
|
||||||
|
tableData.value.map(it => {
|
||||||
|
it.account.clients = UserApi.clients(it.account.clientCode!).map(it => it.val)
|
||||||
|
return it
|
||||||
|
})
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
searching.value = false
|
searching.value = false
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
paging()
|
paging()
|
||||||
})
|
})
|
||||||
|
|
@ -101,36 +206,64 @@ onMounted(() => {
|
||||||
.table-list {
|
.table-list {
|
||||||
flex 1;
|
flex 1;
|
||||||
width 100%
|
width 100%
|
||||||
|
|
||||||
:deep(.table-header) {
|
:deep(.table-header) {
|
||||||
color black
|
color #454C59
|
||||||
|
|
||||||
th {
|
th {
|
||||||
background-color #E1E5EB
|
background-color #EDF1F7
|
||||||
font-weight 500
|
font-weight 500
|
||||||
position relative
|
position relative
|
||||||
|
|
||||||
& > div {
|
& > div {
|
||||||
display flex
|
display flex
|
||||||
gap 5px
|
gap 5px
|
||||||
align-items center
|
align-items center
|
||||||
}
|
}
|
||||||
|
|
||||||
&:not(:first-child) > div::before {
|
&:not(:first-child) > div::before {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 50%;
|
top: 50%;
|
||||||
left: 1px;
|
left: 1px;
|
||||||
width: 1px;
|
width: 1px;
|
||||||
background-color: #A6AFB5;
|
background-color: #D3D7DE;
|
||||||
transform: translateY(-50%);
|
transform: translateY(-50%);
|
||||||
content: "";
|
content: "";
|
||||||
height 50%
|
height 50%
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.table-cell) {
|
:deep(.table-cell) {
|
||||||
color #2F3540
|
color #2F3540
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.action-btn {
|
||||||
|
width 100%
|
||||||
|
display flex
|
||||||
|
flex-wrap wrap
|
||||||
|
|
||||||
|
& > button {
|
||||||
|
margin 0
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.tool-bar {
|
.tool-bar {
|
||||||
display flex
|
display flex
|
||||||
justify-content space-between
|
justify-content space-between
|
||||||
margin 0 0 20px 0
|
margin 0 0 20px 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.avatar {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
:deep(.el-icon) {
|
||||||
|
font-size 25px
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -6,29 +6,42 @@
|
||||||
<ElForm :model="userFormData"
|
<ElForm :model="userFormData"
|
||||||
class="sys_user-form"
|
class="sys_user-form"
|
||||||
label-width="auto">
|
label-width="auto">
|
||||||
<ElFormItem label="昵称">
|
<ElFormItem label="昵称">
|
||||||
<ElInput
|
<ElInput
|
||||||
v-model="userFormData.nickname"
|
v-model="userFormData.nickname"
|
||||||
:disabled="status === 'view'"
|
:disabled="status === 'view'"
|
||||||
placeholder="昵称"/>
|
placeholder="昵称"/>
|
||||||
</ElFormItem>
|
</ElFormItem>
|
||||||
<ElFormItem label="头像">
|
<ElFormItem label="头像">
|
||||||
<ElInput
|
<Uploader
|
||||||
v-model="userFormData.avatar"
|
v-model:file="userFormData.avatar"
|
||||||
:disabled="status === 'view'"
|
:disabled="status === 'view'"
|
||||||
placeholder="头像"/>
|
:limit="1"
|
||||||
|
:multiple="true"
|
||||||
|
accept="image/*"
|
||||||
|
class="avatar-uploader"
|
||||||
|
list-type="picture">
|
||||||
|
<ElButton>点击上传头像</ElButton>
|
||||||
|
</Uploader>
|
||||||
</ElFormItem>
|
</ElFormItem>
|
||||||
<ElFormItem label="邮箱">
|
<ElFormItem label="联系电话">
|
||||||
<ElInput
|
|
||||||
v-model="userFormData.email"
|
|
||||||
:disabled="status === 'view'"
|
|
||||||
placeholder="邮箱"/>
|
|
||||||
</ElFormItem>
|
|
||||||
<ElFormItem label="手机号">
|
|
||||||
<ElInput
|
<ElInput
|
||||||
v-model="userFormData.phone"
|
v-model="userFormData.phone"
|
||||||
:disabled="status === 'view'"
|
:disabled="status === 'view'"
|
||||||
placeholder="手机号"/>
|
placeholder="联系电话"/>
|
||||||
|
</ElFormItem>
|
||||||
|
<ElFormItem v-if="status === 'add'" label="用户名">
|
||||||
|
<ElInput
|
||||||
|
v-model="userFormData.account.username"
|
||||||
|
placeholder="用户名"/>
|
||||||
|
</ElFormItem>
|
||||||
|
<ElFormItem v-if="status === 'add'" label="密码">
|
||||||
|
<ElInput
|
||||||
|
v-model="userFormData.account.secret"
|
||||||
|
autocomplete="new-password"
|
||||||
|
placeholder="密码"
|
||||||
|
show-password
|
||||||
|
type="password"/>
|
||||||
</ElFormItem>
|
</ElFormItem>
|
||||||
</ElForm>
|
</ElForm>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
|
|
@ -41,17 +54,28 @@
|
||||||
import UserApi from '@/pages/sys/user/user-api.ts'
|
import UserApi from '@/pages/sys/user/user-api.ts'
|
||||||
import Strings from '@/common/utils/strings.ts'
|
import Strings from '@/common/utils/strings.ts'
|
||||||
import { ElMessage } from 'element-plus'
|
import { ElMessage } from 'element-plus'
|
||||||
|
import Uploader from '@/components/uploader/Uploader.vue'
|
||||||
|
|
||||||
|
const emits = defineEmits([ 'editSucc' ])
|
||||||
const showDialog = ref(false)
|
const showDialog = ref(false)
|
||||||
const submiting = ref(false)
|
const submiting = ref(false)
|
||||||
const status = ref<'add' | 'view' | 'modify'>('add')
|
const status = ref<'add' | 'view' | 'modify'>('add')
|
||||||
const userFormData = reactive<UserTypes.SearchUserResult>({})
|
const userFormData = reactive<UserTypes.SearchUserResult>({
|
||||||
|
account: {
|
||||||
|
username: '',
|
||||||
|
secret: '',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
function submitHandler() {
|
function submitHandler() {
|
||||||
if (status.value === 'view') return
|
if (status.value === 'view') return
|
||||||
submiting.value = true
|
submiting.value = true
|
||||||
if (userFormData.id != null) {
|
if (userFormData.id != null) {
|
||||||
UserApi.modify(userFormData)
|
UserApi.modify(userFormData)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
ElMessage.success('修改成功')
|
ElMessage.success('修改成功')
|
||||||
|
emits('editSucc')
|
||||||
|
showDialog.value = false
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
submiting.value = false
|
submiting.value = false
|
||||||
|
|
@ -60,30 +84,44 @@ function submitHandler() {
|
||||||
UserApi.add(userFormData)
|
UserApi.add(userFormData)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
ElMessage.success('添加成功')
|
ElMessage.success('添加成功')
|
||||||
|
emits('editSucc')
|
||||||
|
showDialog.value = false
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
submiting.value = false
|
submiting.value = false
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
defineExpose({
|
defineExpose({
|
||||||
open(data: UserTypes.SearchUserResult = {}) {
|
open(data?: UserTypes.SearchUserResult) {
|
||||||
showDialog.value = true
|
showDialog.value = true
|
||||||
if (!Strings.isBlank(data.id)) {
|
if (data != null && !Strings.isBlank(data.id)) {
|
||||||
status.value = 'modify'
|
status.value = 'modify'
|
||||||
UserApi.detail(data.id!)
|
UserApi.detail(data.id!)
|
||||||
.then(res => {
|
.then(res => {
|
||||||
Object.assign(userFormData, res.data)
|
Object.assign(userFormData, {
|
||||||
|
...res.data, account: {},
|
||||||
|
})
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
status.value = 'add'
|
status.value = 'add'
|
||||||
Object.assign(userFormData, {})
|
Object.assign(userFormData, {
|
||||||
|
account: {
|
||||||
|
username: '',
|
||||||
|
secret: '',
|
||||||
|
},
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
<style lang="stylus" scoped>
|
<style lang="stylus" scoped>
|
||||||
.sys_user-form {
|
.sys_user-form {
|
||||||
padding 20px
|
padding 20px
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.avatar-uploader {
|
||||||
|
width 100%
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -1,21 +1,57 @@
|
||||||
import {
|
import {
|
||||||
get,
|
get,
|
||||||
post
|
post,
|
||||||
} from '@/common/utils/http-util.ts'
|
} from '@/common/utils/http-util.ts'
|
||||||
|
|
||||||
|
const Clients = [ {
|
||||||
|
txt: '电脑端',
|
||||||
|
val: 0,
|
||||||
|
}, {
|
||||||
|
txt: '微信小程序',
|
||||||
|
val: 1,
|
||||||
|
} ]
|
||||||
export default {
|
export default {
|
||||||
paging(data: UserTypes.SearchUserParam) {
|
paging(data: UserTypes.SearchUserParam) {
|
||||||
return get<G.PageResult<UserTypes.SearchUserResult>>('/sys_user/paging', data)
|
return get<G.PageResult<UserTypes.SearchUserResult>>('/user/paging', data)
|
||||||
},
|
},
|
||||||
detail(id: string) {
|
detail(id: string) {
|
||||||
return get<UserTypes.SearchUserResult>('/sys_user/detail', {id})
|
return get<UserTypes.SearchUserResult>('/user/detail', {id})
|
||||||
|
},
|
||||||
|
disable(id: string, disable: boolean) {
|
||||||
|
return get('/user/disable', {id, disable})
|
||||||
},
|
},
|
||||||
add(data: UserTypes.AddUserParam) {
|
add(data: UserTypes.AddUserParam) {
|
||||||
return post('/sys_user/add', data)
|
return post('/user/add', data)
|
||||||
|
},
|
||||||
|
bindRole(data: UserTypes.BindRoleParam) {
|
||||||
|
return post('/user/bind_role', data)
|
||||||
},
|
},
|
||||||
modify(data: UserTypes.ModifyUserParam) {
|
modify(data: UserTypes.ModifyUserParam) {
|
||||||
return post('/sys_user/modify', data)
|
return post('/user/modify', data)
|
||||||
|
},
|
||||||
|
modifyInfo(data: { nickname?: string; avatar?: string; phone?: string }) {
|
||||||
|
return post('/user/modify_info', data)
|
||||||
|
},
|
||||||
|
modifyPasswd(data: { oldPasswd: string; newPasswd: string }) {
|
||||||
|
return post('/user/modify_passwd', data)
|
||||||
|
},
|
||||||
|
resetPasswd(id: string) {
|
||||||
|
return get('/user/reset_passwd', {id})
|
||||||
},
|
},
|
||||||
del(ids: string[]) {
|
del(ids: string[]) {
|
||||||
return post('/sys_user/del', ids)
|
return post('/user/del', ids)
|
||||||
|
},
|
||||||
|
clients(clientCode: number) {
|
||||||
|
return Clients.filter(it => {
|
||||||
|
const mask = 1 << it.val
|
||||||
|
return (clientCode & mask) === 0
|
||||||
|
})
|
||||||
|
},
|
||||||
|
bindClient(id: string, clients: number[]) {
|
||||||
|
let clientCode = (1 << Clients.length) - 1
|
||||||
|
for (let client of clients) {
|
||||||
|
clientCode = (1 << client) ^ clientCode
|
||||||
|
}
|
||||||
|
return get('/user/bind_client', {id, clientCode})
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,33 @@ declare global {
|
||||||
// 手机号
|
// 手机号
|
||||||
phone?: string
|
phone?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface SearchUserAccountResult {
|
||||||
|
// Id
|
||||||
|
id?: string
|
||||||
|
// 用户 Id
|
||||||
|
userId?: string
|
||||||
|
// 用户名
|
||||||
|
username?: string
|
||||||
|
// 手机号
|
||||||
|
phone?: string
|
||||||
|
// 密码
|
||||||
|
secret?: string
|
||||||
|
// 微信 openid
|
||||||
|
wechatOpenid?: string
|
||||||
|
// 微信 unionid
|
||||||
|
wechatUnionid?: string
|
||||||
|
// 注册时间
|
||||||
|
regdate?: string
|
||||||
|
// 允许登录的客户端
|
||||||
|
clientCode?: number
|
||||||
|
clients?: number[]
|
||||||
|
// 是否禁用
|
||||||
|
disabled?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
interface SearchUserResult {
|
interface SearchUserResult {
|
||||||
|
id?: string
|
||||||
// 昵称
|
// 昵称
|
||||||
nickname?: string
|
nickname?: string
|
||||||
// 头像
|
// 头像
|
||||||
|
|
@ -20,7 +46,10 @@ declare global {
|
||||||
email?: string
|
email?: string
|
||||||
// 手机号
|
// 手机号
|
||||||
phone?: string
|
phone?: string
|
||||||
|
|
||||||
|
account: SearchUserAccountResult
|
||||||
}
|
}
|
||||||
|
|
||||||
interface AddUserParam {
|
interface AddUserParam {
|
||||||
// 昵称
|
// 昵称
|
||||||
nickname?: string
|
nickname?: string
|
||||||
|
|
@ -31,6 +60,14 @@ declare global {
|
||||||
// 手机号
|
// 手机号
|
||||||
phone?: string
|
phone?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface BindRoleParam {
|
||||||
|
// 昵称
|
||||||
|
id?: string
|
||||||
|
// 头像
|
||||||
|
roles?: string[]
|
||||||
|
}
|
||||||
|
|
||||||
interface ModifyUserParam {
|
interface ModifyUserParam {
|
||||||
// 昵称
|
// 昵称
|
||||||
nickname?: string
|
nickname?: string
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue