mirror of
https://github.com/yangjian102621/geekai.git
synced 2025-09-18 01:06:39 +08:00
Merge branch 'ui' of 172.28.1.6:yangjian/chatgpt-plus into ui
This commit is contained in:
commit
9796a841d9
@ -18,7 +18,7 @@ export default function (
|
|||||||
|
|
||||||
const popupProps = (arg: Arg[], getExposed) => {
|
const popupProps = (arg: Arg[], getExposed) => {
|
||||||
return {
|
return {
|
||||||
width: 700,
|
width: 800,
|
||||||
onBeforeOk: async () => {
|
onBeforeOk: async () => {
|
||||||
const exposed = getExposed();
|
const exposed = getExposed();
|
||||||
const validateRes = await exposed?.formRef.value.validate();
|
const validateRes = await exposed?.formRef.value.validate();
|
||||||
|
@ -4,80 +4,112 @@ import {
|
|||||||
IconOrderedList,
|
IconOrderedList,
|
||||||
IconCalendar,
|
IconCalendar,
|
||||||
IconSettings,
|
IconSettings,
|
||||||
|
IconUserGroup,
|
||||||
|
IconLock,
|
||||||
|
IconCodepen,
|
||||||
|
IconWechatpay,
|
||||||
} from "@arco-design/web-vue/es/icon";
|
} from "@arco-design/web-vue/es/icon";
|
||||||
|
|
||||||
const menu = [
|
const menu = [
|
||||||
{
|
{
|
||||||
path: '/dashboard',
|
path: "/dashboard",
|
||||||
name: 'Dashboard',
|
name: "Dashboard",
|
||||||
meta: {
|
meta: {
|
||||||
title: "仪表盘",
|
title: "仪表盘",
|
||||||
icon: IconDashboard
|
icon: IconDashboard,
|
||||||
},
|
},
|
||||||
component: () => import('@/views/DashboardView.vue')
|
component: () => import("@/views/DashboardView.vue"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/user',
|
path: "/user",
|
||||||
name: 'User',
|
name: "User",
|
||||||
meta: {
|
meta: {
|
||||||
title: "用户管理",
|
title: "用户管理",
|
||||||
icon: IconUser,
|
icon: IconUser,
|
||||||
},
|
},
|
||||||
component: () => import('@/views/User/UserContainer.vue')
|
component: () => import("@/views/User/UserContainer.vue"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/order',
|
path: "/Role",
|
||||||
name: 'Order',
|
name: "Role",
|
||||||
|
meta: {
|
||||||
|
title: "角色管理",
|
||||||
|
icon: IconUserGroup,
|
||||||
|
},
|
||||||
|
component: () => import("@/views/Role/RoleContainer.vue"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "/ChatModel",
|
||||||
|
name: "ChatModel",
|
||||||
|
meta: {
|
||||||
|
title: "语言模型",
|
||||||
|
icon: IconCodepen,
|
||||||
|
},
|
||||||
|
component: () => import("@/views/ChatModel/ChatModelContainer.vue"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "/Product",
|
||||||
|
name: "Product",
|
||||||
|
meta: {
|
||||||
|
title: "充值产品",
|
||||||
|
icon: IconWechatpay,
|
||||||
|
},
|
||||||
|
component: () => import("@/views/Product/ProductContainer.vue"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "/ApiKey",
|
||||||
|
name: "ApiKey",
|
||||||
|
meta: {
|
||||||
|
title: "APIKEY",
|
||||||
|
icon: IconLock,
|
||||||
|
},
|
||||||
|
component: () => import("@/views/ApiKey/ApiKeyContainer.vue"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "/order",
|
||||||
|
name: "Order",
|
||||||
meta: {
|
meta: {
|
||||||
title: "充值订单",
|
title: "充值订单",
|
||||||
icon: IconOrderedList,
|
icon: IconOrderedList,
|
||||||
},
|
},
|
||||||
component: () => import('@/views/Order/OrderContainer.vue')
|
component: () => import("@/views/Order/OrderContainer.vue"),
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
path: '/reward',
|
path: "/reward",
|
||||||
name: 'Reward',
|
name: "Reward",
|
||||||
meta: {
|
meta: {
|
||||||
title: "众筹管理",
|
title: "众筹管理",
|
||||||
icon: IconCalendar,
|
icon: IconCalendar,
|
||||||
},
|
},
|
||||||
component: () => import('@/views/Reward/RewardContainer.vue')
|
component: () => import("@/views/Reward/RewardContainer.vue"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/functions',
|
path: "/chats",
|
||||||
name: 'Functions',
|
name: "Chats",
|
||||||
meta: {
|
|
||||||
title: "函数管理",
|
|
||||||
icon: IconCalendar,
|
|
||||||
},
|
|
||||||
component: () => import('@/views/Functions/FunctionsContainer.vue')
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/chats',
|
|
||||||
name: 'Chats',
|
|
||||||
meta: {
|
meta: {
|
||||||
title: "对话管理",
|
title: "对话管理",
|
||||||
icon: IconCalendar,
|
icon: IconCalendar,
|
||||||
},
|
},
|
||||||
component: () => import('@/views/Chats/ChatsContainer.vue')
|
component: () => import("@/views/Chats/ChatsContainer.vue"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/system',
|
path: "/system",
|
||||||
name: 'System',
|
name: "System",
|
||||||
meta: {
|
meta: {
|
||||||
title: "系统设置",
|
title: "系统设置",
|
||||||
icon: IconSettings,
|
icon: IconSettings,
|
||||||
},
|
},
|
||||||
component: () => import('@/views/System/SystemContainer.vue')
|
component: () => import("@/views/System/SystemContainer.vue"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/loginLog',
|
path: "/loginLog",
|
||||||
name: 'LoginLog',
|
name: "LoginLog",
|
||||||
meta: {
|
meta: {
|
||||||
title: "登录日志",
|
title: "登录日志",
|
||||||
icon: IconCalendar,
|
icon: IconCalendar,
|
||||||
},
|
},
|
||||||
component: () => import('@/views/LoginLog.vue')
|
component: () => import("@/views/LoginLog.vue"),
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -1,4 +1,120 @@
|
|||||||
<script lang="ts" setup></script>
|
<script lang="ts" setup>
|
||||||
|
import { getList, save, deleting, setStatus } from "./api";
|
||||||
|
import { ref } from "vue";
|
||||||
|
import ApiKeyForm from "./ApiKeyForm.vue";
|
||||||
|
import useCustomFormPopup from "@/composables/useCustomFormPopup";
|
||||||
|
import { Message } from "@arco-design/web-vue";
|
||||||
|
import SimpleTable from "@/components/SimpleTable/SimpleTable.vue";
|
||||||
|
import { dateFormat } from "@gpt-vue/packages/utils";
|
||||||
|
// table 配置
|
||||||
|
const columns = [
|
||||||
|
{
|
||||||
|
title: "所属平台",
|
||||||
|
dataIndex: "platform",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "名称",
|
||||||
|
dataIndex: "name",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "key",
|
||||||
|
dataIndex: "value",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "用途",
|
||||||
|
dataIndex: "type",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "使用代理",
|
||||||
|
dataIndex: "use_proxy",
|
||||||
|
slotName: "proxy",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "最后使用时间",
|
||||||
|
dataIndex: "last_used_at",
|
||||||
|
render: ({ record }) => {
|
||||||
|
return dateFormat(record.last_used_at);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "启用状态",
|
||||||
|
dataIndex: "enabled",
|
||||||
|
slotName: "status",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "操作",
|
||||||
|
slotName: "action",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
// 数据
|
||||||
|
const tableData = ref([]);
|
||||||
|
const getData = () => {
|
||||||
|
getList().then(({ code, data }) => {
|
||||||
|
if (code === 0) {
|
||||||
|
tableData.value = data;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
getData();
|
||||||
|
|
||||||
|
// 新增编辑
|
||||||
|
const popup = useCustomFormPopup(ApiKeyForm, save);
|
||||||
|
|
||||||
|
// 删除
|
||||||
|
const handleDelete = ({ id }, reload) => {
|
||||||
|
deleting(id).then(({ code }) => {
|
||||||
|
if (code === 0) {
|
||||||
|
Message.success("操作成功");
|
||||||
|
reload();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 状态
|
||||||
|
const handleStatusChange = ({ filed, value, record, reload }) => {
|
||||||
|
setStatus({
|
||||||
|
id: record.id,
|
||||||
|
value,
|
||||||
|
filed,
|
||||||
|
}).then(({ code }) => {
|
||||||
|
if (code === 0) {
|
||||||
|
Message.success("操作成功");
|
||||||
|
reload();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<div></div>
|
<SimpleTable :columns="columns" :request="getList">
|
||||||
|
<template #action="{ record, reload }">
|
||||||
|
<a-link @click="popup({ record, reload })">编辑</a-link>
|
||||||
|
<a-popconfirm content="确定删除?" @ok="handleDelete(record, reload)">
|
||||||
|
<a-link>删除</a-link>
|
||||||
|
</a-popconfirm>
|
||||||
|
</template>
|
||||||
|
<template #header="{ reload }">
|
||||||
|
<a-button @click="popup({ reload })" size="small"><icon-plus />新增</a-button>
|
||||||
|
</template>
|
||||||
|
<template #status="{ record, reload }">
|
||||||
|
<a-switch
|
||||||
|
v-model="record.enabled"
|
||||||
|
@change="
|
||||||
|
(value) => {
|
||||||
|
handleStatusChange({ filed: 'enabled', value, record, reload });
|
||||||
|
}
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<template #proxy="{ record, reload }">
|
||||||
|
<a-switch
|
||||||
|
v-model="record.use_proxy"
|
||||||
|
@change="
|
||||||
|
(value) => {
|
||||||
|
handleStatusChange({ filed: 'use_proxy', value, record, reload });
|
||||||
|
}
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</SimpleTable>
|
||||||
</template>
|
</template>
|
||||||
|
97
gpt-vue/projects/vue-admin/src/views/ApiKey/ApiKeyForm.vue
Normal file
97
gpt-vue/projects/vue-admin/src/views/ApiKey/ApiKeyForm.vue
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
<template>
|
||||||
|
<a-form ref="formRef" :model="form" :style="{ width: '600px' }" @submit="handleSubmit">
|
||||||
|
<a-form-item
|
||||||
|
field="platform"
|
||||||
|
label="所属平台"
|
||||||
|
:rules="[{ required: true, message: '请输入所属平台' }]"
|
||||||
|
:validate-trigger="['change', 'input']"
|
||||||
|
>
|
||||||
|
<a-input v-model="form.platform" placeholder="请输入所属平台" />
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item
|
||||||
|
field="name"
|
||||||
|
label="名称"
|
||||||
|
:rules="[{ required: true, message: '请输入名称' }]"
|
||||||
|
:validate-trigger="['change', 'input']"
|
||||||
|
showable
|
||||||
|
>
|
||||||
|
<a-input v-model="form.name" placeholder="请输入名称" />
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item
|
||||||
|
field="type"
|
||||||
|
label="用途"
|
||||||
|
:rules="[{ required: true, message: '请输入用途' }]"
|
||||||
|
:validate-trigger="['change', 'input']"
|
||||||
|
>
|
||||||
|
<a-select v-model="form.type" placeholder="请输入用途" :options="typeOPtions"> </a-select>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item
|
||||||
|
field="value"
|
||||||
|
label="API KEY"
|
||||||
|
:rules="[{ required: true, message: '请输入API KEY' }]"
|
||||||
|
:validate-trigger="['change', 'input']"
|
||||||
|
>
|
||||||
|
<a-input v-model="form.value" placeholder="请输入API KEY" />
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item
|
||||||
|
field="api_url"
|
||||||
|
label="API URL"
|
||||||
|
:rules="[{ required: true, message: '请输入API URL' }]"
|
||||||
|
:validate-trigger="['change', 'input']"
|
||||||
|
>
|
||||||
|
<a-input v-model="form.api_url" placeholder="请输入API URL" />
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<a-form-item field="use_proxy" label="使用代理">
|
||||||
|
<a-switch v-model="form.use_proxy" />
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item field="enable" label="启用状态">
|
||||||
|
<a-switch v-model="form.enable" />
|
||||||
|
</a-form-item>
|
||||||
|
</a-form>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, defineExpose, defineProps } from "vue";
|
||||||
|
const props = defineProps({
|
||||||
|
data: {},
|
||||||
|
});
|
||||||
|
|
||||||
|
const formRef = ref();
|
||||||
|
const form = ref({});
|
||||||
|
if (props.data?.id) {
|
||||||
|
form.value = Object.assign({}, props.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
formRef,
|
||||||
|
form,
|
||||||
|
});
|
||||||
|
|
||||||
|
const typeOPtions = [
|
||||||
|
{
|
||||||
|
label: "聊天",
|
||||||
|
value: "chart",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "绘图",
|
||||||
|
value: "img",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
</script>
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.content-title {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
width: 350px;
|
||||||
|
}
|
||||||
|
.content-cell {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
width: 350px;
|
||||||
|
svg {
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
29
gpt-vue/projects/vue-admin/src/views/ApiKey/api.ts
Normal file
29
gpt-vue/projects/vue-admin/src/views/ApiKey/api.ts
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
import http from "@/http/config";
|
||||||
|
|
||||||
|
export const getList = (params?: Record<string, unknown>) => {
|
||||||
|
return http({
|
||||||
|
url: "/api/admin/apikey/list",
|
||||||
|
method: "get",
|
||||||
|
params,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
export const save = (data?: Record<string, unknown>) => {
|
||||||
|
return http({
|
||||||
|
url: "/api/admin/apikey/save",
|
||||||
|
method: "post",
|
||||||
|
data,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
export const deleting = (id: string | number) => {
|
||||||
|
return http({
|
||||||
|
url: `/api/admin/apikey/remove?id=${id}`,
|
||||||
|
method: "get",
|
||||||
|
});
|
||||||
|
};
|
||||||
|
export const setStatus = (data) => {
|
||||||
|
return http({
|
||||||
|
url: `/api/admin/apikey/set`,
|
||||||
|
method: "post",
|
||||||
|
data,
|
||||||
|
});
|
||||||
|
};
|
@ -1,4 +1,120 @@
|
|||||||
<script lang="ts" setup></script>
|
<script lang="ts" setup>
|
||||||
|
import { getList, save, deleting, setStatus } from "./api";
|
||||||
|
import { ref } from "vue";
|
||||||
|
import ChatModelForm from "./ChatModelForm.vue";
|
||||||
|
import useCustomFormPopup from "@/composables/useCustomFormPopup";
|
||||||
|
import { Message } from "@arco-design/web-vue";
|
||||||
|
import SimpleTable from "@/components/SimpleTable/SimpleTable.vue";
|
||||||
|
import { dateFormat } from "@gpt-vue/packages/utils";
|
||||||
|
// table 配置
|
||||||
|
const columns = [
|
||||||
|
{
|
||||||
|
title: "所属平台",
|
||||||
|
dataIndex: "platform",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "模型名称",
|
||||||
|
dataIndex: "name",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "模型值",
|
||||||
|
dataIndex: "value",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "对话权重",
|
||||||
|
dataIndex: "weight",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "启用状态",
|
||||||
|
dataIndex: "enabled",
|
||||||
|
slotName: "status",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "开放状态",
|
||||||
|
dataIndex: "open",
|
||||||
|
slotName: "open",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "创建时间",
|
||||||
|
dataIndex: "created_at",
|
||||||
|
render: ({ record }) => {
|
||||||
|
return dateFormat(record.created_at);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "操作",
|
||||||
|
slotName: "action",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
// 数据
|
||||||
|
const tableData = ref([]);
|
||||||
|
const getData = () => {
|
||||||
|
getList().then(({ code, data }) => {
|
||||||
|
if (code === 0) {
|
||||||
|
tableData.value = data;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
getData();
|
||||||
|
|
||||||
|
// 新增编辑
|
||||||
|
const popup = useCustomFormPopup(ChatModelForm, save);
|
||||||
|
|
||||||
|
// 删除
|
||||||
|
const handleDelete = ({ id }, reload) => {
|
||||||
|
deleting(id).then(({ code }) => {
|
||||||
|
if (code === 0) {
|
||||||
|
Message.success("操作成功");
|
||||||
|
reload();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 状态
|
||||||
|
const handleStatusChange = ({ filed, value, record, reload }) => {
|
||||||
|
setStatus({
|
||||||
|
id: record.id,
|
||||||
|
value,
|
||||||
|
filed,
|
||||||
|
}).then(({ code }) => {
|
||||||
|
if (code === 0) {
|
||||||
|
Message.success("操作成功");
|
||||||
|
reload();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<div></div>
|
<SimpleTable :columns="columns" :request="getList">
|
||||||
|
<template #action="{ record, reload }">
|
||||||
|
<a-link @click="popup({ record, reload })">编辑</a-link>
|
||||||
|
<a-popconfirm content="确定删除?" @ok="handleDelete(record, reload)">
|
||||||
|
<a-link>删除</a-link>
|
||||||
|
</a-popconfirm>
|
||||||
|
</template>
|
||||||
|
<template #header="{ reload }">
|
||||||
|
<a-button @click="popup({ reload })" size="small"><icon-plus />新增</a-button>
|
||||||
|
</template>
|
||||||
|
<template #status="{ record, reload }">
|
||||||
|
<a-switch
|
||||||
|
v-model="record.enabled"
|
||||||
|
@change="
|
||||||
|
(value) => {
|
||||||
|
handleStatusChange({ filed: 'enabled', value, record, reload });
|
||||||
|
}
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<template #open="{ record, reload }">
|
||||||
|
<a-switch
|
||||||
|
v-model="record.open"
|
||||||
|
@change="
|
||||||
|
(value) => {
|
||||||
|
handleStatusChange({ filed: 'open', value, record, reload });
|
||||||
|
}
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</SimpleTable>
|
||||||
</template>
|
</template>
|
||||||
|
@ -0,0 +1,91 @@
|
|||||||
|
<template>
|
||||||
|
<a-form ref="formRef" :model="form" :style="{ width: '600px' }" @submit="handleSubmit">
|
||||||
|
<a-form-item
|
||||||
|
field="platform"
|
||||||
|
label="所属平台"
|
||||||
|
:rules="[{ required: true, message: '请输入所属平台' }]"
|
||||||
|
:validate-trigger="['change', 'input']"
|
||||||
|
>
|
||||||
|
<a-input v-model="form.platform" placeholder="请输入所属平台" />
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item
|
||||||
|
field="name"
|
||||||
|
label="名称"
|
||||||
|
:rules="[{ required: true, message: '请输入名称' }]"
|
||||||
|
:validate-trigger="['change', 'input']"
|
||||||
|
showable
|
||||||
|
>
|
||||||
|
<a-input v-model="form.name" placeholder="请输入名称" />
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item
|
||||||
|
field="value"
|
||||||
|
label="模型值"
|
||||||
|
:rules="[{ required: true, message: '请输入名称' }]"
|
||||||
|
:validate-trigger="['change', 'input']"
|
||||||
|
showable
|
||||||
|
>
|
||||||
|
<a-input v-model="form.value" placeholder="请输入名称" />
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item
|
||||||
|
field="weight"
|
||||||
|
label="对话权重"
|
||||||
|
:rules="[{ required: true, message: '请输入对话权重' }]"
|
||||||
|
:validate-trigger="['change', 'input']"
|
||||||
|
showable
|
||||||
|
>
|
||||||
|
<a-input-number v-model="form.weight" placeholder="请输入对话权重" />
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<a-form-item field="open" label="开放状态代理">
|
||||||
|
<a-switch v-model="form.open" />
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item field="enabled" label="启用状态">
|
||||||
|
<a-switch v-model="form.enabled" />
|
||||||
|
</a-form-item>
|
||||||
|
</a-form>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, defineExpose, defineProps } from "vue";
|
||||||
|
const props = defineProps({
|
||||||
|
data: {},
|
||||||
|
});
|
||||||
|
|
||||||
|
const formRef = ref();
|
||||||
|
const form = ref({});
|
||||||
|
if (props.data?.id) {
|
||||||
|
form.value = Object.assign({}, props.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
formRef,
|
||||||
|
form,
|
||||||
|
});
|
||||||
|
|
||||||
|
const typeOPtions = [
|
||||||
|
{
|
||||||
|
label: "聊天",
|
||||||
|
value: "chart",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "绘图",
|
||||||
|
value: "img",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
</script>
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.content-title {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
width: 350px;
|
||||||
|
}
|
||||||
|
.content-cell {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
width: 350px;
|
||||||
|
svg {
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
29
gpt-vue/projects/vue-admin/src/views/ChatModel/api.ts
Normal file
29
gpt-vue/projects/vue-admin/src/views/ChatModel/api.ts
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
import http from "@/http/config";
|
||||||
|
|
||||||
|
export const getList = (params?: Record<string, unknown>) => {
|
||||||
|
return http({
|
||||||
|
url: "/api/admin/model/list",
|
||||||
|
method: "get",
|
||||||
|
params,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
export const save = (data?: Record<string, unknown>) => {
|
||||||
|
return http({
|
||||||
|
url: "/api/admin/model/save",
|
||||||
|
method: "post",
|
||||||
|
data,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
export const deleting = (id: string | number) => {
|
||||||
|
return http({
|
||||||
|
url: `/api/admin/model/remove?id=${id}`,
|
||||||
|
method: "get",
|
||||||
|
});
|
||||||
|
};
|
||||||
|
export const setStatus = (data) => {
|
||||||
|
return http({
|
||||||
|
url: `/api/admin/model/set`,
|
||||||
|
method: "post",
|
||||||
|
data,
|
||||||
|
});
|
||||||
|
};
|
@ -1,4 +1,69 @@
|
|||||||
<script lang="ts" setup></script>
|
<script lang="ts" setup>
|
||||||
|
import http from "@/http/config";
|
||||||
|
import { ref } from "vue";
|
||||||
|
const dataSet = {
|
||||||
|
users: "今日新增用户",
|
||||||
|
chats: "今日新增对话",
|
||||||
|
tokens: "今日消耗 Tokens",
|
||||||
|
income: "今日入账",
|
||||||
|
};
|
||||||
|
const data = ref<Record<string, number>>({});
|
||||||
|
const getData = () => {
|
||||||
|
http({
|
||||||
|
url: "api/admin/dashboard/stats",
|
||||||
|
method: "get",
|
||||||
|
}).then((res) => {
|
||||||
|
data.value = res.data;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
getData();
|
||||||
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<div></div>
|
<div class="dashboard">
|
||||||
|
<div class="data-card" v-for="(value, key) in dataSet" :key="key">
|
||||||
|
<span :class="key" class="icon"><icon-user /></span>
|
||||||
|
<span class="count"
|
||||||
|
><a-statistic :extra="value" :value="data[key]" :precision="0"
|
||||||
|
/></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.dashboard {
|
||||||
|
display: flex;
|
||||||
|
text-align: center;
|
||||||
|
.data-card {
|
||||||
|
display: flex;
|
||||||
|
flex: 0 0 25%;
|
||||||
|
padding: 0 10px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
.icon {
|
||||||
|
display: inline-block;
|
||||||
|
font-size: 50px;
|
||||||
|
width: 100px;
|
||||||
|
height: 100px;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 100px;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
.users {
|
||||||
|
background: #2d8cf0;
|
||||||
|
}
|
||||||
|
.chats {
|
||||||
|
background: #64d572;
|
||||||
|
}
|
||||||
|
.tokens {
|
||||||
|
background: #f25e43;
|
||||||
|
}
|
||||||
|
.income {
|
||||||
|
background: #f25e43;
|
||||||
|
}
|
||||||
|
.count {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
@ -1,4 +1,116 @@
|
|||||||
<script lang="ts" setup></script>
|
<script lang="ts" setup>
|
||||||
|
import { getList, save, deleting, setStatus } from "./api";
|
||||||
|
import { ref } from "vue";
|
||||||
|
import ProductForm from "./ProductForm.vue";
|
||||||
|
import useCustomFormPopup from "@/composables/useCustomFormPopup";
|
||||||
|
import { Message } from "@arco-design/web-vue";
|
||||||
|
import SimpleTable from "@/components/SimpleTable/SimpleTable.vue";
|
||||||
|
import { dateFormat } from "@gpt-vue/packages/utils";
|
||||||
|
// table 配置
|
||||||
|
const columns = [
|
||||||
|
{
|
||||||
|
title: "产品名称",
|
||||||
|
dataIndex: "name",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "产品价格",
|
||||||
|
dataIndex: "price",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "优惠金额",
|
||||||
|
dataIndex: "discount",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "有效期(天)",
|
||||||
|
dataIndex: "days",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "对话次数",
|
||||||
|
dataIndex: "calls",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "绘图次数",
|
||||||
|
dataIndex: "img_calls",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "销量",
|
||||||
|
dataIndex: "sales",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "启用状态",
|
||||||
|
dataIndex: "enabled",
|
||||||
|
slotName: "status",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "更新时间",
|
||||||
|
dataIndex: "updated_at",
|
||||||
|
render: ({ record }) => {
|
||||||
|
return dateFormat(record.updated_at);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "操作",
|
||||||
|
slotName: "action",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
// 数据
|
||||||
|
const tableData = ref([]);
|
||||||
|
const getData = () => {
|
||||||
|
getList().then(({ code, data }) => {
|
||||||
|
if (code === 0) {
|
||||||
|
tableData.value = data;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
getData();
|
||||||
|
|
||||||
|
// 新增编辑
|
||||||
|
const popup = useCustomFormPopup(ProductForm, save);
|
||||||
|
|
||||||
|
// 删除
|
||||||
|
const handleDelete = ({ id }, reload) => {
|
||||||
|
deleting(id).then(({ code }) => {
|
||||||
|
if (code === 0) {
|
||||||
|
Message.success("操作成功");
|
||||||
|
reload();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 状态
|
||||||
|
const handleStatusChange = ({ value, record, reload }) => {
|
||||||
|
setStatus({
|
||||||
|
id: record.id,
|
||||||
|
enabled: value,
|
||||||
|
}).then(({ code }) => {
|
||||||
|
if (code === 0) {
|
||||||
|
Message.success("操作成功");
|
||||||
|
reload();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<div></div>
|
<SimpleTable :columns="columns" :request="getList">
|
||||||
|
<template #action="{ record, reload }">
|
||||||
|
<a-link @click="popup({ record, reload })">编辑</a-link>
|
||||||
|
<a-popconfirm content="确定删除?" @ok="handleDelete(record, reload)">
|
||||||
|
<a-link>删除</a-link>
|
||||||
|
</a-popconfirm>
|
||||||
|
</template>
|
||||||
|
<template #header="{ reload }">
|
||||||
|
<a-button @click="popup({ reload })" size="small"><icon-plus />新增</a-button>
|
||||||
|
</template>
|
||||||
|
<template #status="{ record, reload }">
|
||||||
|
<a-switch
|
||||||
|
v-model="record.enabled"
|
||||||
|
@change="
|
||||||
|
(value) => {
|
||||||
|
handleStatusChange({ value, record, reload });
|
||||||
|
}
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</SimpleTable>
|
||||||
</template>
|
</template>
|
||||||
|
87
gpt-vue/projects/vue-admin/src/views/Product/ProductForm.vue
Normal file
87
gpt-vue/projects/vue-admin/src/views/Product/ProductForm.vue
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
<template>
|
||||||
|
<a-form ref="formRef" :model="form" :style="{ width: '600px' }" @submit="handleSubmit">
|
||||||
|
<a-form-item
|
||||||
|
field="name"
|
||||||
|
label="产品名称"
|
||||||
|
:rules="[{ required: true, message: '请输入产品名称' }]"
|
||||||
|
:validate-trigger="['change', 'input']"
|
||||||
|
>
|
||||||
|
<a-input v-model="form.name" placeholder="请输入产品名称" />
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item
|
||||||
|
field="price"
|
||||||
|
label="产品价格"
|
||||||
|
:rules="[{ required: true, message: '请输入产品价格' }]"
|
||||||
|
:validate-trigger="['change', 'input']"
|
||||||
|
showable
|
||||||
|
>
|
||||||
|
<a-input-number v-model="form.price" placeholder="请输入产品价格" />
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item
|
||||||
|
field="discount"
|
||||||
|
label="优惠金额"
|
||||||
|
:rules="[{ required: true, message: '请输入优惠金额' }]"
|
||||||
|
:validate-trigger="['change', 'input']"
|
||||||
|
showable
|
||||||
|
>
|
||||||
|
<a-input-number v-model="form.discount" placeholder="请输入优惠金额" />
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item
|
||||||
|
field="days"
|
||||||
|
label="有效期(天)"
|
||||||
|
:rules="[{ required: true, message: '请输入有效期(天)' }]"
|
||||||
|
:validate-trigger="['change', 'input']"
|
||||||
|
showable
|
||||||
|
>
|
||||||
|
<a-input-number v-model="form.days" placeholder="请输入有效期(天)" />
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item field="calls" label="对话次数" :validate-trigger="['change', 'input']" showable>
|
||||||
|
<a-input-number v-model="form.calls" placeholder="请输入对话次数" />
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item
|
||||||
|
field="img_calls"
|
||||||
|
label="绘图次数"
|
||||||
|
:validate-trigger="['change', 'input']"
|
||||||
|
showable
|
||||||
|
>
|
||||||
|
<a-input-number v-model="form.img_calls" placeholder="请输入绘图次数" />
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item field="enabled" label="启用状态">
|
||||||
|
<a-switch v-model="form.enabled" />
|
||||||
|
</a-form-item>
|
||||||
|
</a-form>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, defineExpose, defineProps } from "vue";
|
||||||
|
const props = defineProps({
|
||||||
|
data: {},
|
||||||
|
});
|
||||||
|
|
||||||
|
const formRef = ref();
|
||||||
|
const form = ref({});
|
||||||
|
if (props.data?.id) {
|
||||||
|
form.value = Object.assign({}, props.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
formRef,
|
||||||
|
form,
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.content-title {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
width: 350px;
|
||||||
|
}
|
||||||
|
.content-cell {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
width: 350px;
|
||||||
|
svg {
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
29
gpt-vue/projects/vue-admin/src/views/Product/api.ts
Normal file
29
gpt-vue/projects/vue-admin/src/views/Product/api.ts
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
import http from "@/http/config";
|
||||||
|
|
||||||
|
export const getList = (params?: Record<string, unknown>) => {
|
||||||
|
return http({
|
||||||
|
url: "/api/admin/product/list",
|
||||||
|
method: "get",
|
||||||
|
params,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
export const save = (data?: Record<string, unknown>) => {
|
||||||
|
return http({
|
||||||
|
url: "/api/admin/product/save",
|
||||||
|
method: "post",
|
||||||
|
data,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
export const deleting = (id: string | number) => {
|
||||||
|
return http({
|
||||||
|
url: `/api/admin/product/remove?id=${id}`,
|
||||||
|
method: "get",
|
||||||
|
});
|
||||||
|
};
|
||||||
|
export const setStatus = (data) => {
|
||||||
|
return http({
|
||||||
|
url: `/api/admin/product/enable`,
|
||||||
|
method: "post",
|
||||||
|
data,
|
||||||
|
});
|
||||||
|
};
|
@ -1,4 +1,118 @@
|
|||||||
<script lang="ts" setup></script>
|
<script lang="ts" setup>
|
||||||
|
import { getList, save, deleting, setStatus } from "./api";
|
||||||
|
import { reactive, ref } from "vue";
|
||||||
|
import RoleForm from "./RoleForm.vue";
|
||||||
|
import useCustomFormPopup from "@/composables/useCustomFormPopup";
|
||||||
|
import { Message } from "@arco-design/web-vue";
|
||||||
|
import SimpleTable from "@/components/SimpleTable/SimpleTable.vue";
|
||||||
|
// table 配置
|
||||||
|
const columns = [
|
||||||
|
{
|
||||||
|
title: "角色名称",
|
||||||
|
dataIndex: "name",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "角色标识",
|
||||||
|
dataIndex: "key",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "启用状态",
|
||||||
|
dataIndex: "enable",
|
||||||
|
slotName: "status",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "角色图标",
|
||||||
|
dataIndex: "icon",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "打招呼信息",
|
||||||
|
dataIndex: "hello_msg",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "操作",
|
||||||
|
slotName: "action",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const expandable = reactive({
|
||||||
|
title: "",
|
||||||
|
width: 80,
|
||||||
|
});
|
||||||
|
|
||||||
|
// 数据
|
||||||
|
const tableData = ref([]);
|
||||||
|
const getData = () => {
|
||||||
|
getList().then(({ code, data }) => {
|
||||||
|
if (code === 0) {
|
||||||
|
tableData.value = data;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
getData();
|
||||||
|
|
||||||
|
//展开行table
|
||||||
|
const expandColumns = [
|
||||||
|
{
|
||||||
|
dataIndex: "role",
|
||||||
|
title: "对话角色",
|
||||||
|
width: 120,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: "content",
|
||||||
|
title: "对话内容",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
// 新增编辑
|
||||||
|
const popup = useCustomFormPopup(RoleForm, save);
|
||||||
|
|
||||||
|
// 删除
|
||||||
|
const handleDelete = ({ id }, reload) => {
|
||||||
|
deleting(id).then(({ code }) => {
|
||||||
|
if (code === 0) {
|
||||||
|
Message.success("操作成功");
|
||||||
|
reload();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 状态
|
||||||
|
const handleStatusChange = ({ value, record, reload }) => {
|
||||||
|
setStatus({
|
||||||
|
id: record.id,
|
||||||
|
value,
|
||||||
|
filed: "enable",
|
||||||
|
}).then(({ code }) => {
|
||||||
|
if (code === 0) {
|
||||||
|
Message.success("操作成功");
|
||||||
|
reload();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<div></div>
|
<SimpleTable :columns="columns" :request="getList" :expandable="expandable">
|
||||||
|
<template #expand-row="{ record }">
|
||||||
|
<a-table :columns="expandColumns" :data="record.context || []" :pagination="false"></a-table>
|
||||||
|
</template>
|
||||||
|
<template #action="{ record, reload }">
|
||||||
|
<a-link @click="popup({ record, reload })">编辑</a-link>
|
||||||
|
<a-popconfirm content="确定删除?" @ok="handleDelete(record, reload)">
|
||||||
|
<a-link>删除</a-link>
|
||||||
|
</a-popconfirm>
|
||||||
|
</template>
|
||||||
|
<template #header="{ reload }">
|
||||||
|
<a-button @click="popup({ reload })" size="small"><icon-plus />新增</a-button>
|
||||||
|
</template>
|
||||||
|
<template #status="{ record, reload }">
|
||||||
|
<a-switch
|
||||||
|
v-model="record.enable"
|
||||||
|
@change="
|
||||||
|
(value) => {
|
||||||
|
handleStatusChange({ value, record, reload });
|
||||||
|
}
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</SimpleTable>
|
||||||
</template>
|
</template>
|
||||||
|
116
gpt-vue/projects/vue-admin/src/views/Role/RoleForm.vue
Normal file
116
gpt-vue/projects/vue-admin/src/views/Role/RoleForm.vue
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
<template>
|
||||||
|
<a-form ref="formRef" :model="form" :style="{ width: '600px' }" @submit="handleSubmit">
|
||||||
|
<a-form-item
|
||||||
|
field="name"
|
||||||
|
label="角色名称"
|
||||||
|
:rules="[{ required: true, message: '请输入角色名称' }]"
|
||||||
|
:validate-trigger="['change', 'input']"
|
||||||
|
>
|
||||||
|
<a-input v-model="form.name" placeholder="请输入角色名称" />
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item
|
||||||
|
field="key"
|
||||||
|
label="角色标志"
|
||||||
|
:rules="[{ required: true, message: '请输入角色标志' }]"
|
||||||
|
:validate-trigger="['change', 'input']"
|
||||||
|
showable
|
||||||
|
>
|
||||||
|
<a-input v-model="form.key" placeholder="请输入角色标志" />
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item
|
||||||
|
field="icon"
|
||||||
|
label="角色图标"
|
||||||
|
:rules="[{ required: true, message: '请输入角色图标' }]"
|
||||||
|
:validate-trigger="['change', 'input']"
|
||||||
|
>
|
||||||
|
<a-input v-model="form.icon" placeholder="请输入角色图标" />
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item
|
||||||
|
field="hello_msg"
|
||||||
|
label="打招呼信息"
|
||||||
|
:rules="[{ required: true, message: '请输入打招呼信息' }]"
|
||||||
|
:validate-trigger="['change', 'input']"
|
||||||
|
>
|
||||||
|
<a-input v-model="form.hello_msg" placeholder="请输入打招呼信息" />
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item field="username" label="上下文信息" :validate-trigger="['change', 'input']">
|
||||||
|
<a-table :data="form.context || []" :pagination="false">
|
||||||
|
<template #columns>
|
||||||
|
<a-table-column title="对话角色">
|
||||||
|
<template #cell="{ record }">
|
||||||
|
<a-input v-model="record.role" />
|
||||||
|
</template>
|
||||||
|
</a-table-column>
|
||||||
|
<a-table-column width="350">
|
||||||
|
<template #title>
|
||||||
|
<div class="content-title">
|
||||||
|
<span>对话内容</span>
|
||||||
|
<a-button @click="addContext" type="primary">增加一行</a-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template #cell="{ record }">
|
||||||
|
<div class="content-cell">
|
||||||
|
<a-input v-model="record.content" /><icon-minus-circle
|
||||||
|
@click="removeContext(record)"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</a-table-column>
|
||||||
|
</template>
|
||||||
|
</a-table>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item field="enable" label="启用状态">
|
||||||
|
<a-switch v-model="form.enable" />
|
||||||
|
</a-form-item>
|
||||||
|
</a-form>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, defineExpose, defineProps } from "vue";
|
||||||
|
const props = defineProps({
|
||||||
|
data: {},
|
||||||
|
});
|
||||||
|
|
||||||
|
const formRef = ref();
|
||||||
|
const form = ref({});
|
||||||
|
if (props.data?.id) {
|
||||||
|
form.value = Object.assign({}, props.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
const addContext = () => {
|
||||||
|
form.value.context = form.value.context || [];
|
||||||
|
form.value.context.push({
|
||||||
|
role: "",
|
||||||
|
content: "",
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const removeContext = (record) => {
|
||||||
|
const index = form.value.context.findIndex((item) => {
|
||||||
|
return item === record;
|
||||||
|
});
|
||||||
|
if (index > -1) {
|
||||||
|
form.value.context.splice(index, 1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
defineExpose({
|
||||||
|
formRef,
|
||||||
|
form,
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.content-title {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
width: 350px;
|
||||||
|
}
|
||||||
|
.content-cell {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
width: 350px;
|
||||||
|
svg {
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
29
gpt-vue/projects/vue-admin/src/views/Role/api.ts
Normal file
29
gpt-vue/projects/vue-admin/src/views/Role/api.ts
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
import http from "@/http/config";
|
||||||
|
|
||||||
|
export const getList = (params?: Record<string, unknown>) => {
|
||||||
|
return http({
|
||||||
|
url: "/api/admin/role/list",
|
||||||
|
method: "get",
|
||||||
|
params,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
export const save = (data?: Record<string, unknown>) => {
|
||||||
|
return http({
|
||||||
|
url: "/api/admin/role/save",
|
||||||
|
method: "post",
|
||||||
|
data,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
export const deleting = (id: string | number) => {
|
||||||
|
return http({
|
||||||
|
url: `/api/admin/role/remove?id=${id}`,
|
||||||
|
method: "get",
|
||||||
|
});
|
||||||
|
};
|
||||||
|
export const setStatus = (data) => {
|
||||||
|
return http({
|
||||||
|
url: `/api/admin/role/set`,
|
||||||
|
method: "post",
|
||||||
|
data,
|
||||||
|
});
|
||||||
|
};
|
Loading…
Reference in New Issue
Block a user