fix conflicts

This commit is contained in:
RockYang
2024-03-12 18:07:19 +08:00
74 changed files with 249 additions and 1630 deletions

View File

@@ -0,0 +1,2 @@
VITE_PROXY_BASE_URL="/api"
VITE_TARGET_URL="http://172.22.11.2:5678"

View File

@@ -1,3 +1,2 @@
VITE_PROXY_BASE_URL=""
VITE_TARGET_URL="/"
VITE_SOCKET_IO_URL="/"

View File

@@ -6,7 +6,7 @@
"scripts": {
"dev": "vite",
"build": "run-p type-check \"build-only {@}\" --",
"preview": "vite preview",
"preview": "vite preview --mode preview",
"build-only": "vite build",
"type-check": "vue-tsc --build --force",
"lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore"

View File

@@ -18,14 +18,4 @@
border-radius: 1px;
background: #fafafa;
}
.public-bg {
display: flex;
width: 100vw;
height: 100vh;
align-items: center;
justify-content: center;
background: linear-gradient(133deg, #ffffff 0%, #dde8fe 100%);
overflow: hidden;
}
</style>

View File

@@ -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);

View File

@@ -49,11 +49,13 @@ const [visible, setVisible] = useState(false);
</ADoption>
</template>
<template #footer>
<APopconfirm content="确认退出?" position="br" @ok="authStore.logout">
<ASpace align="center" class="logout-area">
<IconExport size="16" />
<span>退出</span>
</ASpace>
<APopconfirm content="确认退出?" position="bl" @ok="authStore.logout">
<AButton status="warning" class="logout-area">
<ASpace align="center">
<IconExport size="16" />
<span>退出登录</span>
</ASpace>
</AButton>
</APopconfirm>
</template>
</ADropdown>
@@ -125,7 +127,8 @@ const [visible, setVisible] = useState(false);
.logout-area {
padding: 8px 0;
display: flex;
width: 80px;
min-width: 80px;
width: 100%;
align-items: center;
justify-content: center;
}

View File

@@ -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);

View File

@@ -11,6 +11,7 @@ import {
IconLock,
IconCodepen,
IconWechatpay,
IconRobot,
} from "@arco-design/web-vue/es/icon";
const menu = [
@@ -33,7 +34,7 @@ const menu = [
component: () => import("@/views/User/UserContainer.vue"),
},
{
path: "/Role",
path: "/role",
name: "Role",
meta: {
title: "角色管理",
@@ -42,7 +43,7 @@ const menu = [
component: () => import("@/views/Role/RoleContainer.vue"),
},
{
path: "/ChatModel",
path: "/chatModel",
name: "ChatModel",
meta: {
title: "语言模型",
@@ -51,7 +52,7 @@ const menu = [
component: () => import("@/views/ChatModel/ChatModelContainer.vue"),
},
{
path: "/Product",
path: "/product",
name: "Product",
meta: {
title: "充值产品",
@@ -60,7 +61,7 @@ const menu = [
component: () => import("@/views/Product/ProductContainer.vue"),
},
{
path: "/ApiKey",
path: "/apiKey",
name: "ApiKey",
meta: {
title: "APIKEY",
@@ -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;

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View 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
})
}