mirror of
				https://github.com/yangjian102621/geekai.git
				synced 2025-11-04 08:13:43 +08:00 
			
		
		
		
	feat(ui):细节调整
This commit is contained in:
		@@ -1,4 +1,4 @@
 | 
			
		||||
import usePopup from "./usePopup";
 | 
			
		||||
import usePopup, { type Config } from "./usePopup";
 | 
			
		||||
import { Message } from "@arco-design/web-vue";
 | 
			
		||||
import type { Component } from "vue";
 | 
			
		||||
import type { BaseResponse } from "@gpt-vue/packages/type";
 | 
			
		||||
@@ -6,19 +6,23 @@ interface Arg {
 | 
			
		||||
  reload?: () => void;
 | 
			
		||||
  record?: Record<string, any>;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default function (
 | 
			
		||||
  node: Component,
 | 
			
		||||
  api: (params?: any) => Promise<BaseResponse<any>>
 | 
			
		||||
  api: (params?: any) => Promise<BaseResponse<any>>,
 | 
			
		||||
  config?: Config
 | 
			
		||||
): (arg: Arg) => void {
 | 
			
		||||
  const nodeProps = (arg: Arg[]) => {
 | 
			
		||||
    return {
 | 
			
		||||
      data: arg[0].record || {},
 | 
			
		||||
      ...config.nodeProps?.(arg),
 | 
			
		||||
    };
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  const popupProps = (arg: Arg[], getExposed) => {
 | 
			
		||||
    return {
 | 
			
		||||
      width: 800,
 | 
			
		||||
      width: 750,
 | 
			
		||||
      maskClosable: false,
 | 
			
		||||
      onBeforeOk: async () => {
 | 
			
		||||
        const exposed = getExposed();
 | 
			
		||||
        const validateRes = await exposed?.formRef.value.validate();
 | 
			
		||||
@@ -32,6 +36,7 @@ export default function (
 | 
			
		||||
        arg[0]?.reload?.();
 | 
			
		||||
        return code === 0;
 | 
			
		||||
      },
 | 
			
		||||
      ...config.popupProps?.(arg, getExposed),
 | 
			
		||||
    };
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,7 @@ import { Modal, Drawer } from "@arco-design/web-vue";
 | 
			
		||||
import type { ModalConfig, DrawerConfig } from "@arco-design/web-vue";
 | 
			
		||||
import app from "@/main";
 | 
			
		||||
 | 
			
		||||
interface Config {
 | 
			
		||||
export interface Config {
 | 
			
		||||
  nodeProps?: (...arg: any) => Record<string, any>;
 | 
			
		||||
  popupProps?: (
 | 
			
		||||
    arg: any[],
 | 
			
		||||
 
 | 
			
		||||
@@ -59,7 +59,9 @@ const getData = () => {
 | 
			
		||||
getData();
 | 
			
		||||
 | 
			
		||||
//  新增编辑
 | 
			
		||||
const popup = useCustomFormPopup(ApiKeyForm, save);
 | 
			
		||||
const popup = useCustomFormPopup(ApiKeyForm, save, {
 | 
			
		||||
  popupProps: (arg) => ({ title: arg[0].record ? "编辑ApiKey" : "新增ApiKey" }),
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
// 删除
 | 
			
		||||
const handleDelete = ({ id }, reload) => {
 | 
			
		||||
@@ -90,7 +92,7 @@ const handleStatusChange = ({ filed, value, record, reload }) => {
 | 
			
		||||
    <template #action="{ record, reload }">
 | 
			
		||||
      <a-link @click="popup({ record, reload })">编辑</a-link>
 | 
			
		||||
      <a-popconfirm content="确定删除?" @ok="handleDelete(record, reload)">
 | 
			
		||||
        <a-link>删除</a-link>
 | 
			
		||||
        <a-link status="danger">删除</a-link>
 | 
			
		||||
      </a-popconfirm>
 | 
			
		||||
    </template>
 | 
			
		||||
    <template #header="{ reload }">
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,17 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <a-form ref="formRef" :model="form" :style="{ width: '600px' }" @submit="handleSubmit">
 | 
			
		||||
  <a-alert type="warning">
 | 
			
		||||
    <div class="warning">
 | 
			
		||||
      {{
 | 
			
		||||
        `注意:如果是百度文心一言平台,API-KEY 为 APIKey|SecretKey,中间用竖线(|)连接\n注意:如果是讯飞星火大模型,API-KEY 为 AppId|APIKey|APISecret,中间用竖线(|)连接`
 | 
			
		||||
      }}
 | 
			
		||||
    </div>
 | 
			
		||||
  </a-alert>
 | 
			
		||||
  <a-form
 | 
			
		||||
    ref="formRef"
 | 
			
		||||
    :model="form"
 | 
			
		||||
    :style="{ width: '600px', 'margin-top': '10px' }"
 | 
			
		||||
    @submit="handleSubmit"
 | 
			
		||||
  >
 | 
			
		||||
    <a-form-item
 | 
			
		||||
      field="platform"
 | 
			
		||||
      label="所属平台"
 | 
			
		||||
@@ -44,6 +56,12 @@
 | 
			
		||||
 | 
			
		||||
    <a-form-item field="use_proxy" label="使用代理">
 | 
			
		||||
      <a-switch v-model="form.use_proxy" />
 | 
			
		||||
      <a-tooltip
 | 
			
		||||
        content="是否使用代理访问 API URL,OpenAI 官方API需要开启代理访问"
 | 
			
		||||
        position="right"
 | 
			
		||||
      >
 | 
			
		||||
        <icon-info-circle-fill />
 | 
			
		||||
      </a-tooltip>
 | 
			
		||||
    </a-form-item>
 | 
			
		||||
    <a-form-item field="enable" label="启用状态">
 | 
			
		||||
      <a-switch v-model="form.enable" />
 | 
			
		||||
@@ -94,4 +112,8 @@ const typeOPtions = [
 | 
			
		||||
    margin-left: 10px;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
.warning {
 | 
			
		||||
  color: #e6a23c;
 | 
			
		||||
  white-space: pre;
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
 
 | 
			
		||||
@@ -59,7 +59,9 @@ const getData = () => {
 | 
			
		||||
getData();
 | 
			
		||||
 | 
			
		||||
//  新增编辑
 | 
			
		||||
const popup = useCustomFormPopup(ChatModelForm, save);
 | 
			
		||||
const popup = useCustomFormPopup(ChatModelForm, save, {
 | 
			
		||||
  popupProps: (arg) => ({ title: arg[0].record ? "编辑ApiKey" : "新增ApiKey" }),
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
// 删除
 | 
			
		||||
const handleDelete = ({ id }, reload) => {
 | 
			
		||||
@@ -90,7 +92,7 @@ const handleStatusChange = ({ filed, value, record, reload }) => {
 | 
			
		||||
    <template #action="{ record, reload }">
 | 
			
		||||
      <a-link @click="popup({ record, reload })">编辑</a-link>
 | 
			
		||||
      <a-popconfirm content="确定删除?" @ok="handleDelete(record, reload)">
 | 
			
		||||
        <a-link>删除</a-link>
 | 
			
		||||
        <a-link status="danger">删除</a-link>
 | 
			
		||||
      </a-popconfirm>
 | 
			
		||||
    </template>
 | 
			
		||||
    <template #header="{ reload }">
 | 
			
		||||
 
 | 
			
		||||
@@ -34,6 +34,9 @@
 | 
			
		||||
      showable
 | 
			
		||||
    >
 | 
			
		||||
      <a-input-number v-model="form.weight" placeholder="请输入对话权重" />
 | 
			
		||||
      <a-tooltip content="对话权重,每次对话扣减多少次对话额度" position="right">
 | 
			
		||||
        <icon-info-circle-fill />
 | 
			
		||||
      </a-tooltip>
 | 
			
		||||
    </a-form-item>
 | 
			
		||||
 | 
			
		||||
    <a-form-item field="open" label="开放状态代理">
 | 
			
		||||
 
 | 
			
		||||
@@ -1,12 +1,21 @@
 | 
			
		||||
<script lang="ts" setup>
 | 
			
		||||
import http from "@/http/config";
 | 
			
		||||
import { ref } from "vue";
 | 
			
		||||
 | 
			
		||||
const dataSet = {
 | 
			
		||||
  users: "今日新增用户",
 | 
			
		||||
  chats: "今日新增对话",
 | 
			
		||||
  tokens: "今日消耗 Tokens",
 | 
			
		||||
  income: "今日入账",
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const icons = {
 | 
			
		||||
  users: "icon-user",
 | 
			
		||||
  chats: "icon-wechat",
 | 
			
		||||
  tokens: "icon-computer",
 | 
			
		||||
  income: "icon-wechatpay",
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const data = ref<Record<string, number>>({});
 | 
			
		||||
const getData = () => {
 | 
			
		||||
  http({
 | 
			
		||||
@@ -20,19 +29,27 @@ getData();
 | 
			
		||||
</script>
 | 
			
		||||
<template>
 | 
			
		||||
  <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>
 | 
			
		||||
    <a-grid :cols="{ xs: 1, sm: 1, md: 2, lg: 3, xl: 4 }" :colGap="12" :rowGap="16" class="grid">
 | 
			
		||||
      <a-grid-item v-for="(value, key) in dataSet" :key="key">
 | 
			
		||||
        <div class="data-card">
 | 
			
		||||
          <span :class="key" class="icon"><icon-user /></span>
 | 
			
		||||
          <span class="count"
 | 
			
		||||
            ><a-statistic :extra="value" :value="data[key]" :precision="0"
 | 
			
		||||
          /></span>
 | 
			
		||||
        </div>
 | 
			
		||||
      </a-grid-item>
 | 
			
		||||
    </a-grid>
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
<style lang="less" scoped>
 | 
			
		||||
.dashboard {
 | 
			
		||||
  display: flex;
 | 
			
		||||
  text-align: center;
 | 
			
		||||
  .grid {
 | 
			
		||||
    width: 100%;
 | 
			
		||||
  }
 | 
			
		||||
  .data-card {
 | 
			
		||||
    width: 100%;
 | 
			
		||||
    display: flex;
 | 
			
		||||
    flex: 0 0 25%;
 | 
			
		||||
    padding: 0 10px;
 | 
			
		||||
 
 | 
			
		||||
@@ -66,7 +66,9 @@ const getData = () => {
 | 
			
		||||
getData();
 | 
			
		||||
 | 
			
		||||
//  新增编辑
 | 
			
		||||
const popup = useCustomFormPopup(ProductForm, save);
 | 
			
		||||
const popup = useCustomFormPopup(ProductForm, save, {
 | 
			
		||||
  popupProps: (arg) => ({ title: arg[0].record ? "编辑产品" : "新增产品" }),
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
// 删除
 | 
			
		||||
const handleDelete = ({ id }, reload) => {
 | 
			
		||||
@@ -96,7 +98,7 @@ const handleStatusChange = ({ value, record, reload }) => {
 | 
			
		||||
    <template #action="{ record, reload }">
 | 
			
		||||
      <a-link @click="popup({ record, reload })">编辑</a-link>
 | 
			
		||||
      <a-popconfirm content="确定删除?" @ok="handleDelete(record, reload)">
 | 
			
		||||
        <a-link>删除</a-link>
 | 
			
		||||
        <a-link status="danger">删除</a-link>
 | 
			
		||||
      </a-popconfirm>
 | 
			
		||||
    </template>
 | 
			
		||||
    <template #header="{ reload }">
 | 
			
		||||
 
 | 
			
		||||
@@ -23,6 +23,7 @@ const columns = [
 | 
			
		||||
  {
 | 
			
		||||
    title: "角色图标",
 | 
			
		||||
    dataIndex: "icon",
 | 
			
		||||
    slotName: "icon",
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    title: "打招呼信息",
 | 
			
		||||
@@ -64,7 +65,9 @@ const expandColumns = [
 | 
			
		||||
];
 | 
			
		||||
 | 
			
		||||
//  新增编辑
 | 
			
		||||
const popup = useCustomFormPopup(RoleForm, save);
 | 
			
		||||
const popup = useCustomFormPopup(RoleForm, save, {
 | 
			
		||||
  popupProps: (arg) => ({ title: arg[0].record ? "编辑角色" : "新增角色" }),
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
// 删除
 | 
			
		||||
const handleDelete = ({ id }, reload) => {
 | 
			
		||||
@@ -98,7 +101,7 @@ const handleStatusChange = ({ value, record, reload }) => {
 | 
			
		||||
    <template #action="{ record, reload }">
 | 
			
		||||
      <a-link @click="popup({ record, reload })">编辑</a-link>
 | 
			
		||||
      <a-popconfirm content="确定删除?" @ok="handleDelete(record, reload)">
 | 
			
		||||
        <a-link>删除</a-link>
 | 
			
		||||
        <a-link status="danger">删除</a-link>
 | 
			
		||||
      </a-popconfirm>
 | 
			
		||||
    </template>
 | 
			
		||||
    <template #header="{ reload }">
 | 
			
		||||
@@ -114,5 +117,11 @@ const handleStatusChange = ({ value, record, reload }) => {
 | 
			
		||||
        "
 | 
			
		||||
      />
 | 
			
		||||
    </template>
 | 
			
		||||
 | 
			
		||||
    <template #icon="{ record }">
 | 
			
		||||
      <a-avatar>
 | 
			
		||||
        <img alt="avatar" :src="record.icon" />
 | 
			
		||||
      </a-avatar>
 | 
			
		||||
    </template>
 | 
			
		||||
  </SimpleTable>
 | 
			
		||||
</template>
 | 
			
		||||
 
 | 
			
		||||
@@ -55,8 +55,12 @@ const columns: SearchTableColumns[] = [
 | 
			
		||||
];
 | 
			
		||||
 | 
			
		||||
//弹窗
 | 
			
		||||
const editModal = useCustomFormPopup(UserForm, saveApi);
 | 
			
		||||
const password = useCustomFormPopup(UserPassword, resetPassword);
 | 
			
		||||
const editModal = useCustomFormPopup(UserForm, saveApi, {
 | 
			
		||||
  popupProps: (arg) => ({ title: arg[0].record ? "编辑用户" : "新增用户" }),
 | 
			
		||||
});
 | 
			
		||||
const password = useCustomFormPopup(UserPassword, resetPassword, {
 | 
			
		||||
  popupProps: (arg) => ({ title: "重置密码" }),
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const handleDelete = async ({ id }: { id: string }, reload) => {
 | 
			
		||||
  const res = await deletApi(id);
 | 
			
		||||
@@ -71,7 +75,7 @@ const handleDelete = async ({ id }: { id: string }, reload) => {
 | 
			
		||||
    <template #actions="{ record, reload }">
 | 
			
		||||
      <a-link @click="editModal({ record, reload })">编辑</a-link>
 | 
			
		||||
      <a-popconfirm content="确定删除?" @ok="handleDelete(record, reload)">
 | 
			
		||||
        <a-link>删除</a-link>
 | 
			
		||||
        <a-link status="danger">删除</a-link>
 | 
			
		||||
      </a-popconfirm>
 | 
			
		||||
      <a-link @click="password({ record, reload })">重置密码</a-link>
 | 
			
		||||
    </template>
 | 
			
		||||
 
 | 
			
		||||
@@ -3,7 +3,7 @@
 | 
			
		||||
    <a-form-item
 | 
			
		||||
      field="username"
 | 
			
		||||
      label="账号"
 | 
			
		||||
      :rules="[{ required: true, message: 'name is required' }]"
 | 
			
		||||
      :rules="[{ required: true, message: '请输入账号' }]"
 | 
			
		||||
      :validate-trigger="['change', 'input']"
 | 
			
		||||
    >
 | 
			
		||||
      <a-input v-model="form.username" placeholder="请输入账号" />
 | 
			
		||||
@@ -12,7 +12,7 @@
 | 
			
		||||
      v-if="!props.data.id"
 | 
			
		||||
      field="password"
 | 
			
		||||
      label="密码"
 | 
			
		||||
      :rules="[{ required: true, message: 'password is required' }]"
 | 
			
		||||
      :rules="[{ required: true, message: '请输入密码' }]"
 | 
			
		||||
      :validate-trigger="['change', 'input']"
 | 
			
		||||
      showable
 | 
			
		||||
    >
 | 
			
		||||
@@ -21,20 +21,14 @@
 | 
			
		||||
    <a-form-item
 | 
			
		||||
      field="calls"
 | 
			
		||||
      label="对话次数"
 | 
			
		||||
      :rules="[
 | 
			
		||||
        { required: true, message: 'count is required' },
 | 
			
		||||
        { type: 'number', message: 'age is max than 200' },
 | 
			
		||||
      ]"
 | 
			
		||||
      :rules="[{ required: true, message: '请输入对话次数' }]"
 | 
			
		||||
    >
 | 
			
		||||
      <a-input-number v-model="form.calls" placeholder="请输入对话次数" />
 | 
			
		||||
    </a-form-item>
 | 
			
		||||
    <a-form-item
 | 
			
		||||
      field="img_calls"
 | 
			
		||||
      label="绘图次数"
 | 
			
		||||
      :rules="[
 | 
			
		||||
        { required: true, message: 'count is required' },
 | 
			
		||||
        { type: 'number', message: 'age is max than 200' },
 | 
			
		||||
      ]"
 | 
			
		||||
      :rules="[{ required: true, message: '请输入绘图次数' }]"
 | 
			
		||||
    >
 | 
			
		||||
      <a-input-number v-model="form.img_calls" placeholder="请输入绘图次数" />
 | 
			
		||||
    </a-form-item>
 | 
			
		||||
@@ -48,6 +42,7 @@
 | 
			
		||||
        placeholder="请选择聊天角色"
 | 
			
		||||
        multiple
 | 
			
		||||
        :options="roleOption"
 | 
			
		||||
        :rules="[{ required: true, message: '请选择聊天角色' }]"
 | 
			
		||||
      >
 | 
			
		||||
      </a-select>
 | 
			
		||||
    </a-form-item>
 | 
			
		||||
@@ -58,6 +53,7 @@
 | 
			
		||||
        placeholder="请选择模型角色"
 | 
			
		||||
        multiple
 | 
			
		||||
        :options="modalOption"
 | 
			
		||||
        :rules="[{ required: true, message: '请选择模型角色' }]"
 | 
			
		||||
      >
 | 
			
		||||
      </a-select>
 | 
			
		||||
    </a-form-item>
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user