mirror of
https://github.com/yangjian102621/geekai.git
synced 2025-09-18 09:16:39 +08:00
feat(ui): 新增系统管理员
This commit is contained in:
parent
d9558f13ad
commit
b2ff49ee94
@ -3,7 +3,7 @@ import tokenHandler from "./token";
|
||||
|
||||
const { _tokenData, refreshToken, setCurRequest } = tokenHandler();
|
||||
|
||||
const createInstance = (baseURL: string = (import.meta as any).env.VITE_PROXY_BASE_URL) => {
|
||||
const createInstance = (baseURL: string) => {
|
||||
|
||||
const instance = axios.create({
|
||||
baseURL,
|
||||
|
@ -127,110 +127,6 @@ importers:
|
||||
specifier: ^1.8.27
|
||||
version: 1.8.27(typescript@5.3.3)
|
||||
|
||||
projects/vue-mobile:
|
||||
dependencies:
|
||||
pinia:
|
||||
specifier: ^2.1.7
|
||||
version: 2.1.7(typescript@5.3.3)(vue@3.4.21)
|
||||
vue:
|
||||
specifier: ^3.4.15
|
||||
version: 3.4.21(typescript@5.3.3)
|
||||
vue-router:
|
||||
specifier: ^4.2.5
|
||||
version: 4.3.0(vue@3.4.21)
|
||||
devDependencies:
|
||||
'@rushstack/eslint-patch':
|
||||
specifier: ^1.3.3
|
||||
version: 1.7.2
|
||||
'@tsconfig/node20':
|
||||
specifier: ^20.1.2
|
||||
version: 20.1.2
|
||||
'@types/node':
|
||||
specifier: ^20.11.10
|
||||
version: 20.11.24
|
||||
'@vitejs/plugin-vue':
|
||||
specifier: ^5.0.3
|
||||
version: 5.0.4(vite@5.1.5)(vue@3.4.21)
|
||||
'@vitejs/plugin-vue-jsx':
|
||||
specifier: ^3.1.0
|
||||
version: 3.1.0(vite@5.1.5)(vue@3.4.21)
|
||||
'@vue/eslint-config-typescript':
|
||||
specifier: ^12.0.0
|
||||
version: 12.0.0(eslint-plugin-vue@9.22.0)(eslint@8.57.0)(typescript@5.3.3)
|
||||
'@vue/tsconfig':
|
||||
specifier: ^0.5.1
|
||||
version: 0.5.1
|
||||
eslint:
|
||||
specifier: ^8.49.0
|
||||
version: 8.57.0
|
||||
eslint-plugin-vue:
|
||||
specifier: ^9.17.0
|
||||
version: 9.22.0(eslint@8.57.0)
|
||||
npm-run-all2:
|
||||
specifier: ^6.1.1
|
||||
version: 6.1.2
|
||||
typescript:
|
||||
specifier: ~5.3.0
|
||||
version: 5.3.3
|
||||
vite:
|
||||
specifier: ^5.0.11
|
||||
version: 5.1.5(@types/node@20.11.24)(less@4.2.0)
|
||||
vue-tsc:
|
||||
specifier: ^1.8.27
|
||||
version: 1.8.27(typescript@5.3.3)
|
||||
|
||||
projects/vue-web:
|
||||
dependencies:
|
||||
pinia:
|
||||
specifier: ^2.1.7
|
||||
version: 2.1.7(typescript@5.3.3)(vue@3.4.21)
|
||||
vue:
|
||||
specifier: ^3.4.15
|
||||
version: 3.4.21(typescript@5.3.3)
|
||||
vue-router:
|
||||
specifier: ^4.2.5
|
||||
version: 4.3.0(vue@3.4.21)
|
||||
devDependencies:
|
||||
'@rushstack/eslint-patch':
|
||||
specifier: ^1.3.3
|
||||
version: 1.7.2
|
||||
'@tsconfig/node20':
|
||||
specifier: ^20.1.2
|
||||
version: 20.1.2
|
||||
'@types/node':
|
||||
specifier: ^20.11.10
|
||||
version: 20.11.24
|
||||
'@vitejs/plugin-vue':
|
||||
specifier: ^5.0.3
|
||||
version: 5.0.4(vite@5.1.5)(vue@3.4.21)
|
||||
'@vitejs/plugin-vue-jsx':
|
||||
specifier: ^3.1.0
|
||||
version: 3.1.0(vite@5.1.5)(vue@3.4.21)
|
||||
'@vue/eslint-config-typescript':
|
||||
specifier: ^12.0.0
|
||||
version: 12.0.0(eslint-plugin-vue@9.22.0)(eslint@8.57.0)(typescript@5.3.3)
|
||||
'@vue/tsconfig':
|
||||
specifier: ^0.5.1
|
||||
version: 0.5.1
|
||||
eslint:
|
||||
specifier: ^8.49.0
|
||||
version: 8.57.0
|
||||
eslint-plugin-vue:
|
||||
specifier: ^9.17.0
|
||||
version: 9.22.0(eslint@8.57.0)
|
||||
npm-run-all2:
|
||||
specifier: ^6.1.1
|
||||
version: 6.1.2
|
||||
typescript:
|
||||
specifier: ~5.3.0
|
||||
version: 5.3.3
|
||||
vite:
|
||||
specifier: ^5.0.11
|
||||
version: 5.1.5(@types/node@20.11.24)(less@4.2.0)
|
||||
vue-tsc:
|
||||
specifier: ^1.8.27
|
||||
version: 1.8.27(typescript@5.3.3)
|
||||
|
||||
packages:
|
||||
|
||||
/@aashutoshrathi/word-wrap@1.2.6:
|
||||
|
@ -1,3 +1,2 @@
|
||||
VITE_PROXY_BASE_URL="/api"
|
||||
VITE_TARGET_URL="http://172.22.11.2:5678"
|
||||
VITE_SOCKET_IO_URL="http://172.28.1.3:8899"
|
||||
|
@ -1,3 +1,2 @@
|
||||
VITE_PROXY_BASE_URL=""
|
||||
VITE_TARGET_URL="/"
|
||||
VITE_SOCKET_IO_URL="/"
|
||||
|
@ -8,6 +8,7 @@ type OriginProps = SwitchInstance["$props"];
|
||||
interface Props extends /* @vue-ignore */ OriginProps {
|
||||
modelValue: boolean | string | number;
|
||||
api: (params?: any) => Promise<BaseResponse<any>>;
|
||||
onSuccess?: (res?: any) => void;
|
||||
}
|
||||
|
||||
const props = defineProps<Props>();
|
||||
@ -23,8 +24,9 @@ const _value = computed({
|
||||
|
||||
const onBeforeChange = async (params) => {
|
||||
try {
|
||||
await props.api({ ...params, value: !_value.value });
|
||||
const res = await props.api({ ...params, value: !_value.value });
|
||||
Message.success("操作成功");
|
||||
props?.onSuccess?.(res);
|
||||
return true;
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
|
@ -5,7 +5,7 @@ import type { BaseResponse } from "@gpt-vue/packages/type";
|
||||
|
||||
export const uploadUrl = import.meta.env.VITE_PROXY_BASE_URL + "/api/admin/upload";
|
||||
|
||||
export const instance = createInstance()
|
||||
export const instance = createInstance(import.meta.env.VITE_PROXY_BASE_URL)
|
||||
|
||||
instance.interceptors.request.use((config) => {
|
||||
config.headers[__AUTH_KEY] = localStorage.getItem(__AUTH_KEY);
|
||||
|
@ -11,6 +11,7 @@ import {
|
||||
IconLock,
|
||||
IconCodepen,
|
||||
IconWechatpay,
|
||||
IconRobot,
|
||||
} from "@arco-design/web-vue/es/icon";
|
||||
|
||||
const menu = [
|
||||
@ -123,6 +124,15 @@ const menu = [
|
||||
},
|
||||
component: () => import("@/views/LoginLog.vue"),
|
||||
},
|
||||
{
|
||||
path: "/sysAdmin",
|
||||
name: "SysAdmin",
|
||||
meta: {
|
||||
title: "系统管理员",
|
||||
icon: IconRobot,
|
||||
},
|
||||
component: () => import("@/views/SysAdmin/SysAdminContainer.vue"),
|
||||
},
|
||||
];
|
||||
|
||||
export default menu;
|
||||
|
@ -0,0 +1,115 @@
|
||||
<script lang="ts" setup>
|
||||
import { Message } from "@arco-design/web-vue";
|
||||
import { dateFormat } from "@gpt-vue/packages/utils";
|
||||
import SearchTable from "@/components/SearchTable/SearchTable.vue";
|
||||
import type { SearchTableColumns } from "@/components/SearchTable/type";
|
||||
import ConfirmSwitch from "@/components/ConfirmSwitch.vue";
|
||||
import usePopup from "@/composables/usePopup";
|
||||
import SysAdminForm from "./SysAdminForm.vue";
|
||||
import SysAdminResetPWD from "./SysAdminResetPWD.vue";
|
||||
import { getList, save, remove, resetPass } from "./api";
|
||||
|
||||
const columns: SearchTableColumns[] = [
|
||||
{
|
||||
dataIndex: "username",
|
||||
title: "账号",
|
||||
search: {
|
||||
valueType: "input",
|
||||
},
|
||||
},
|
||||
{
|
||||
dataIndex: "last_login_ip",
|
||||
title: "最后登录IP",
|
||||
},
|
||||
{
|
||||
dataIndex: "last_login_at",
|
||||
title: "最后登录时间",
|
||||
render: ({ record }) => dateFormat(record.last_login_at),
|
||||
},
|
||||
{
|
||||
dataIndex: "created_at",
|
||||
title: "创建时间",
|
||||
render: ({ record }) => dateFormat(record.created_at),
|
||||
},
|
||||
{
|
||||
dataIndex: "updated_at",
|
||||
title: "更新时间",
|
||||
render: ({ record }) => dateFormat(record.updated_at),
|
||||
},
|
||||
{
|
||||
dataIndex: "status",
|
||||
title: "状态",
|
||||
slotName: "switch",
|
||||
width: 80,
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
slotName: "actions",
|
||||
fixed: "right",
|
||||
width: 180,
|
||||
},
|
||||
];
|
||||
|
||||
const openFormModal = usePopup(SysAdminForm, {
|
||||
nodeProps: ([_, record]) => ({ record }),
|
||||
popupProps: ([reload, record], exposed) => ({
|
||||
title: `${record?.id ? "编辑" : "新增"}系统管理员`,
|
||||
onBeforeOk: async (done) => {
|
||||
await exposed()?.handleSubmit(save, {
|
||||
id: record?.id,
|
||||
});
|
||||
await reload();
|
||||
done(true);
|
||||
},
|
||||
}),
|
||||
});
|
||||
|
||||
const openResetPWDModal = usePopup(SysAdminResetPWD, {
|
||||
popupProps: ([reload, record], exposed) => ({
|
||||
title: `修改密码`,
|
||||
onBeforeOk: async (done) => {
|
||||
await exposed()?.handleSubmit(resetPass, {
|
||||
id: record?.id,
|
||||
});
|
||||
Message.success("修改成功");
|
||||
await reload();
|
||||
done(true);
|
||||
},
|
||||
}),
|
||||
});
|
||||
|
||||
const handleRemove = async (id, reload) => {
|
||||
await remove({ id });
|
||||
Message.success("删除成功");
|
||||
await reload();
|
||||
return true;
|
||||
};
|
||||
</script>
|
||||
<template>
|
||||
<SearchTable :request="getList" :columns="columns">
|
||||
<template #header-option="{ reload }">
|
||||
<a-button type="primary" @click="openFormModal(reload, {})">
|
||||
<template #icon> <icon-plus /> </template>
|
||||
新增
|
||||
</a-button>
|
||||
</template>
|
||||
<template #switch="{ record, column }">
|
||||
<ConfirmSwitch
|
||||
v-model="record[column.dataIndex]"
|
||||
:api="async () => save({ ...record, status: !record.status })"
|
||||
/>
|
||||
</template>
|
||||
<template #actions="{ record, reload }">
|
||||
<a-link @click="openFormModal(reload, record)">编辑</a-link>
|
||||
<a-link @click="openResetPWDModal(reload, record)">修改密码</a-link>
|
||||
<a-popconfirm
|
||||
content="是否删除?"
|
||||
position="left"
|
||||
type="warning"
|
||||
:on-before-ok="() => handleRemove(record.id, reload)"
|
||||
>
|
||||
<a-link status="danger">删除</a-link>
|
||||
</a-popconfirm>
|
||||
</template>
|
||||
</SearchTable>
|
||||
</template>
|
@ -0,0 +1,39 @@
|
||||
<template>
|
||||
<a-form ref="formRef" :model="formData" auto-label-width>
|
||||
<a-form-item field="username" label="账号" :rules="[{ required: true, message: '请输入账号' }]">
|
||||
<a-input v-model="formData.username" placeholder="请输入账号" />
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
v-if="!props.record?.id"
|
||||
field="password"
|
||||
label="密码"
|
||||
:rules="[{ required: true, message: '请输入密码' }]"
|
||||
>
|
||||
<a-input-password
|
||||
v-model="formData.password"
|
||||
placeholder="请输入密码"
|
||||
autocomplete="new-password"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item field="status" label="启用状态">
|
||||
<a-switch v-model="formData.status" />
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import useSubmit from "@/composables/useSubmit";
|
||||
const props = defineProps({
|
||||
record: Object,
|
||||
});
|
||||
|
||||
const { formRef, formData, handleSubmit } = useSubmit({
|
||||
username: "",
|
||||
password: "",
|
||||
status: true,
|
||||
});
|
||||
|
||||
defineExpose({
|
||||
handleSubmit,
|
||||
});
|
||||
</script>
|
@ -0,0 +1,28 @@
|
||||
<template>
|
||||
<a-form ref="formRef" :model="formData" auto-label-width>
|
||||
<a-form-item
|
||||
field="password"
|
||||
label="密码"
|
||||
:rules="[{ required: true, message: '请输入密码' }]"
|
||||
showable
|
||||
>
|
||||
<a-input-password
|
||||
v-model="formData.password"
|
||||
placeholder="请输入密码"
|
||||
autocomplete="new-password"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import useSubmit from "@/composables/useSubmit";
|
||||
|
||||
const { formRef, formData, handleSubmit } = useSubmit({
|
||||
password: "",
|
||||
});
|
||||
|
||||
defineExpose({
|
||||
handleSubmit,
|
||||
});
|
||||
</script>
|
33
gpt-vue/projects/vue-admin/src/views/SysAdmin/api.ts
Normal file
33
gpt-vue/projects/vue-admin/src/views/SysAdmin/api.ts
Normal file
@ -0,0 +1,33 @@
|
||||
import http from "@/http/config";
|
||||
|
||||
export const getList = (params) => {
|
||||
return http({
|
||||
url: "/api/admin/sysUser/list",
|
||||
method: "get",
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
export const save = (data) => {
|
||||
return http({
|
||||
url: "/api/admin/sysUser/save",
|
||||
method: "post",
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export const remove = (data) => {
|
||||
return http({
|
||||
url: "/api/admin/sysUser/remove",
|
||||
method: "post",
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export const resetPass = (data) => {
|
||||
return http({
|
||||
url: "/api/admin/sysUser/resetPass",
|
||||
method: "post",
|
||||
data
|
||||
})
|
||||
}
|
@ -36,12 +36,9 @@ export default defineConfig(({ mode }) => {
|
||||
output: {
|
||||
manualChunks: (id) => {
|
||||
if (id.includes("node_modules")) {
|
||||
if (id.includes("arco")) {
|
||||
return `arco`;
|
||||
}
|
||||
if (id.includes("vue") && !id.includes("arco")) {
|
||||
return `vue`;
|
||||
}
|
||||
if (id.includes("echats")) return `echats`;
|
||||
if (id.includes("arco")) return `arco`;
|
||||
if (id.includes("vue") && !id.includes("arco")) return `vue`;
|
||||
return `vendor`;
|
||||
}
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user