后台用户

This commit is contained in:
TimSpan 2024-09-05 10:45:49 +08:00
parent 9eebc328c2
commit 3b11749c37
6 changed files with 248 additions and 5 deletions

View File

@ -6,7 +6,7 @@ VITE_DROP_CONSOLE=false
# axios # axios
VITE_APP_BASE_API=/api VITE_APP_BASE_API=/api
# VITE_APP_PROXY_URL=http://localhost:8765 # VITE_APP_PROXY_URL=http://localhost:8765
VITE_APP_PROXY_URL=http://172.10.10.151:8765 VITE_APP_PROXY_URL=http://172.10.10.93:8765
# rsa 公钥 # rsa 公钥

View File

@ -26,10 +26,16 @@ declare module 'vue' {
ALayoutSider: typeof import('ant-design-vue/es')['LayoutSider'] ALayoutSider: typeof import('ant-design-vue/es')['LayoutSider']
AMenu: typeof import('ant-design-vue/es')['Menu'] AMenu: typeof import('ant-design-vue/es')['Menu']
AMenuItem: typeof import('ant-design-vue/es')['MenuItem'] AMenuItem: typeof import('ant-design-vue/es')['MenuItem']
ASelect: typeof import('ant-design-vue/es')['Select']
ASelectOption: typeof import('ant-design-vue/es')['SelectOption']
ASpace: typeof import('ant-design-vue/es')['Space']
ASpin: typeof import('ant-design-vue/es')['Spin'] ASpin: typeof import('ant-design-vue/es')['Spin']
ASubMenu: typeof import('ant-design-vue/es')['SubMenu'] ASubMenu: typeof import('ant-design-vue/es')['SubMenu']
ATable: typeof import('ant-design-vue/es')['Table']
ATabPane: typeof import('ant-design-vue/es')['TabPane'] ATabPane: typeof import('ant-design-vue/es')['TabPane']
ATabs: typeof import('ant-design-vue/es')['Tabs'] ATabs: typeof import('ant-design-vue/es')['Tabs']
ATag: typeof import('ant-design-vue/es')['Tag']
ATooltip: typeof import('ant-design-vue/es')['Tooltip']
HelloWorld: typeof import('./src/components/HelloWorld.vue')['default'] HelloWorld: typeof import('./src/components/HelloWorld.vue')['default']
Layout: typeof import('./src/components/layout/layout.vue')['default'] Layout: typeof import('./src/components/layout/layout.vue')['default']
LayoutHeader: typeof import('./src/components/layout/header/LayoutHeader.vue')['default'] LayoutHeader: typeof import('./src/components/layout/header/LayoutHeader.vue')['default']

View File

@ -36,7 +36,8 @@
</a-menu-item> </a-menu-item>
<a-sub-menu v-if="route.children && route.children.length && route?.meta?.title" :key="route.path"> <a-sub-menu v-if="route.children && route.children.length && route?.meta?.title" :key="route.path">
<template #title> <template #title>
<MailOutlined /> <MailOutlined v-if="route.name === 'query-'" />
<UserOutlined v-if="route.name === 'user'" />
<span>{{ route.meta?.title }}</span> <span>{{ route.meta?.title }}</span>
</template> </template>
<a-menu-item v-for="child in route.children" :key="child.path"> <a-menu-item v-for="child in route.children" :key="child.path">
@ -68,7 +69,7 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { InsuranceOutlined, HomeOutlined, SoundOutlined, MailOutlined, ApartmentOutlined, InboxOutlined, AppstoreOutlined } from '@ant-design/icons-vue' import { InsuranceOutlined, HomeOutlined, SoundOutlined, MailOutlined, ApartmentOutlined, UserOutlined, AppstoreOutlined } from '@ant-design/icons-vue'
import LayoutHeader from '@/components/layout/header/LayoutHeader.vue' import LayoutHeader from '@/components/layout/header/LayoutHeader.vue'
import { computed } from 'vue' import { computed } from 'vue'
import { staticRouter } from '@/router/staticRouters' import { staticRouter } from '@/router/staticRouters'
@ -108,8 +109,8 @@ const keepAliveNames = ref<string[]>(['index', 'rindex'])
.layout-content { .layout-content {
margin: 10px; margin: 10px;
padding: 4px; // padding: 4px;
background: #f5f7fd; // background: #f5f7fd;
min-height: 280px; min-height: 280px;
border-radius: 5px; border-radius: 5px;
overflow: auto; overflow: auto;

View File

@ -1,5 +1,6 @@
// name 唯一
import { RouteRecordRaw } from "vue-router"; import { RouteRecordRaw } from "vue-router";
export const Layout = () => import("@/components/layout/layout.vue"); export const Layout = () => import("@/components/layout/layout.vue");
export const staticRouter: RouteRecordRaw[] = export const staticRouter: RouteRecordRaw[] =
@ -28,6 +29,38 @@ export const staticRouter: RouteRecordRaw[] =
] ]
}, },
{
path: '/user',
name: 'user',
meta: {
title: '用户管理',
keepalive: true
},
component: Layout,
children: [
{
path: 'index',
name: 'user-index',
meta: {
title: '后台用户',
keepalive: true
},
component: () => import('@/views/user/user.vue')
},
{
path: 'weapp',
name: 'weapp',
meta: {
title: '小程序用户',
keepalive: true
},
component: () => import('@/views/user/user-weapp.vue')
},
]
},
{ {
path: '/query-', path: '/query-',

View File

@ -0,0 +1,8 @@
<template>
<div>
<!-- 小程序用户 -->
小程序用户
</div>
</template>
<script setup lang="ts"></script>

View File

@ -0,0 +1,195 @@
<template>
<!-- 后台用户 -->
<div>
<div class="h-16 w-full bg-white rounded shadow-md py-5 px-10 flex items-center">
<div class="mr-5">关键字</div>
<a-input class="w-40 mr-5" v-model:value="searchUser" autocomplete="off" placeholder="请输入用户名搜索" />
<div class="mr-5">状态</div>
<a-space>
<a-select ref="select" v-model:value="selectValue" style="width: 120px" @focus="focus" @change="handleChange">
<a-select-option value="0">全部</a-select-option>
<a-select-option value="1">启用</a-select-option>
<a-select-option value="2">禁用</a-select-option>
</a-select>
</a-space>
<a-button class="ml-5 flex items-center" type="primary" @click="search"><SearchOutlined style="font-size: 16px" />搜索</a-button>
<a-button class="ml-5 flex items-center"><SyncOutlined style="font-size: 16px" />重置</a-button>
</div>
<div class="w-full h-full bg-white mt-5 rounded">
<div class="w-full h-16 py-5 px-10 flex items-center">
<a-button class="flex items-center" type="primary" @click="search"><PlusOutlined style="font-size: 16px" />新增</a-button>
<a-button :disabled="!hasSelected" class="ml-5 flex items-center" type="primary" danger @click="search"><DeleteOutlined style="font-size: 16px" />删除</a-button>
</div>
<div class="px-10">
<a-table :row-selection="{ selectedRowKeys: state.selectedRowKeys, onChange: onSelectChange }" :columns="columns" :data-source="tableData" />
</div>
</div>
</div>
</template>
<script setup lang="tsx">
import api from '@/axios/index.ts'
import { SearchOutlined, SyncOutlined, PlusOutlined, DeleteOutlined } from '@ant-design/icons-vue'
import { ref, h, computed, reactive, onMounted } from 'vue'
const searchUser = ref('')
const selectValue = ref('0')
const focus = () => {
console.log('focus')
}
const handleChange = (value: string) => {
console.log(`selected ${value}`)
}
const search = function name() {}
const obj = {
params: {
// name: '',
// telephone: '',
// sex: '',
},
page: {
// records: [
// {
// snowFlakeId: 0,
// name: '',
// sex: '',
// account: '',
// telephone: '',
// isEnable: '',
// isAdmin: '',
// createUserName: '',
// createTime: '',
// },
// ],
// total: 0,
// size: 0,
// current: 0,
size: 10,
current: 0,
// orders: [
// {
// column: '',
// asc: true,
// },
// ],
// optimizeCountSql: {},
// searchCount: {},
// optimizeJoinOfCountSql: true,
// maxLimit: 0,
// countId: '',
// pages: 0,
},
}
const getUserList = async function name() {
const res = await api.post<any>('/managementPoliceUnitUser/pager', obj)
tableData.value = res.data.records
}
onMounted(() => {
getUserList()
})
//
type Key = string | number
interface DataType {
key: Key
name: string
age: number
address: string
}
interface ResponseData {
params: {
name: string
telephone: string
sex: string
}
page: {
records: Array<RecordItem>
total: number
size: number
current: number
orders: Array<{
column: string
asc: boolean
}>
optimizeCountSql: any
searchCount: any
optimizeJoinOfCountSql: boolean
maxLimit: number
countId: string
pages: number
}
}
interface RecordItem {
account: string
createTime: string
createUserName: string | null
isAdmin: LabelValue //
isEnable: EnableStatus //
name: string
sex: LabelValue //
snowFlakeId: string // Snowflake ID
telephone: string
}
interface LabelValue {
value: number
label: string
}
interface EnableStatus {
value: number
label: string
extData: {
color: string
}
}
const columns = [
{
title: '账号',
dataIndex: 'account',
},
{
title: '名称',
dataIndex: 'name',
},
// {
// title: '',
// dataIndex: 'isAdmin',
// customRender: ({ record }: { record: RecordItem }) => {
// return record.isAdmin.value === 0 ? <a-tag color='green'>{record.isAdmin.label}</a-tag> : <a-tag color='#f50'>{record.isAdmin.label}</a-tag>
// },
// },
{
title: '是否启用',
dataIndex: 'isEnable',
customRender: ({ record }: { record: RecordItem }) => {
return record.isEnable.extData?.color === 'success' ? <a-tag color='green'>{record.isEnable.label}</a-tag> : <a-tag color='#f50'>{record.isEnable.label}</a-tag>
},
},
{
title: '创建时间',
dataIndex: 'createTime',
},
]
const tableData = ref<DataType[]>([])
const state = reactive<{
selectedRowKeys: Key[]
loading: boolean
}>({
selectedRowKeys: [], // Check here to configure the default column
loading: false,
})
const hasSelected = computed(() => state.selectedRowKeys.length > 0)
const onSelectChange = (selectedRowKeys: Key[]) => {
console.log('selectedRowKeys changed: ', selectedRowKeys)
state.selectedRowKeys = selectedRowKeys
}
</script>