feat(ui): web移动端初始化

This commit is contained in:
廖彦棋 2024-03-13 17:30:24 +08:00
parent d3fbb8c19e
commit 4cb4b145f9
277 changed files with 50840 additions and 668 deletions

View File

@ -1,12 +1,12 @@
{ {
"name": "gpt-vue", "name": "chatgpt-plus",
"version": "1.0.0", "version": "1.0.0",
"description": "", "description": "",
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {
"clear": "rimraf node_modules projects/vue-admin/node_modules", "clear": "rimraf node_modules rimraf -g */node_modules rimraf -g */*/node_modules",
"dev": "pnpm --filter=@gpt-vue-projects/* run dev", "dev": "pnpm --filter=@chatgpt-plus-projects/* run dev",
"build": "pnpm --filter=@gpt-vue-projects/* run build" "build": "pnpm --filter=@chatgpt-plus-projects/* run build"
}, },
"keywords": [], "keywords": [],
"author": "", "author": "",

View File

@ -1,5 +1,5 @@
{ {
"name": "@gpt-vue/packages", "name": "@chatgpt-plus/packages",
"version": "1.0.0", "version": "1.0.0",
"description": "", "description": "",
"main": "index.js", "main": "index.js",

File diff suppressed because it is too large Load Diff

View File

@ -4,7 +4,7 @@
<meta charset="UTF-8"> <meta charset="UTF-8">
<link rel="icon" href="/favicon.ico"> <link rel="icon" href="/favicon.ico">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ChatPlus-Ai</title> <title>chatgpt-plus-Ai</title>
</head> </head>
<body> <body>
<div id="app"></div> <div id="app"></div>

View File

@ -1,5 +1,5 @@
{ {
"name": "@gpt-vue-projects/vue-admin", "name": "@chatgpt-plus-projects/admin",
"version": "0.0.0", "version": "0.0.0",
"private": true, "private": true,
"type": "module", "type": "module",
@ -13,7 +13,7 @@
}, },
"dependencies": { "dependencies": {
"@arco-design/web-vue": "^2.54.6", "@arco-design/web-vue": "^2.54.6",
"@gpt-vue/packages": "workspace:^1.0.0", "@chatgpt-plus/packages": "workspace:^1.0.0",
"echarts": "^5.5.0", "echarts": "^5.5.0",
"md-editor-v3": "^2.2.1", "md-editor-v3": "^2.2.1",
"pinia": "^2.1.7", "pinia": "^2.1.7",

View File

Before

Width:  |  Height:  |  Size: 66 KiB

After

Width:  |  Height:  |  Size: 66 KiB

View File

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

Before

Width:  |  Height:  |  Size: 46 KiB

After

Width:  |  Height:  |  Size: 46 KiB

View File

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 23 KiB

View File

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

View File

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 27 KiB

View File

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 32 KiB

View File

Before

Width:  |  Height:  |  Size: 5.8 KiB

After

Width:  |  Height:  |  Size: 5.8 KiB

View File

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 40 KiB

View File

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 27 KiB

View File

Before

Width:  |  Height:  |  Size: 5.6 KiB

After

Width:  |  Height:  |  Size: 5.6 KiB

View File

Before

Width:  |  Height:  |  Size: 41 KiB

After

Width:  |  Height:  |  Size: 41 KiB

View File

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

View File

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View File

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

View File

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

View File

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

View File

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 24 KiB

View File

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

View File

Before

Width:  |  Height:  |  Size: 5.0 KiB

After

Width:  |  Height:  |  Size: 5.0 KiB

View File

Before

Width:  |  Height:  |  Size: 5.1 KiB

After

Width:  |  Height:  |  Size: 5.1 KiB

View File

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 KiB

View File

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 38 KiB

View File

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

View File

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 44 KiB

View File

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

Before

Width:  |  Height:  |  Size: 8.4 KiB

After

Width:  |  Height:  |  Size: 8.4 KiB

View File

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

Before

Width:  |  Height:  |  Size: 48 KiB

After

Width:  |  Height:  |  Size: 48 KiB

View File

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 36 KiB

View File

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 31 KiB

View File

Before

Width:  |  Height:  |  Size: 276 B

After

Width:  |  Height:  |  Size: 276 B

View File

@ -1,7 +1,7 @@
<script lang="ts" setup> <script lang="ts" setup>
import { computed } from "vue"; import { computed } from "vue";
import { Message, type SwitchInstance } from "@arco-design/web-vue"; import { Message, type SwitchInstance } from "@arco-design/web-vue";
import type { BaseResponse } from "@gpt-vue/packages/type"; import type { BaseResponse } from "@chatgpt-plus/packages/type";
type OriginProps = SwitchInstance["$props"]; type OriginProps = SwitchInstance["$props"];

View File

@ -18,7 +18,7 @@ const [visible, setVisible] = useState(false);
<ALayoutHeader class="custom-layout-header"> <ALayoutHeader class="custom-layout-header">
<div class="logo"> <div class="logo">
<img :src="Logo" alt="logo" /> <img :src="Logo" alt="logo" />
<span>ChatPlus 控制台</span> <span>chatgpt-plus 控制台</span>
</div> </div>
<div class="action"> <div class="action">
<ADropdown> <ADropdown>
@ -38,7 +38,7 @@ const [visible, setVisible] = useState(false);
<template #icon> <template #icon>
<icon-github /> <icon-github />
</template> </template>
<span>ChatPlus-AI 创作系统</span> <span>chatgpt-plus-AI 创作系统</span>
</ADoption> </ADoption>
</a> </a>
<ADoption value="2" @click="setVisible(true)"> <ADoption value="2" @click="setVisible(true)">

View File

@ -1,6 +1,6 @@
import { computed, onMounted, reactive, unref, type Ref } from "vue"; import { computed, onMounted, reactive, unref, type Ref } from "vue";
import type { TableInstance } from "@arco-design/web-vue"; import type { TableInstance } from "@arco-design/web-vue";
import type { BaseResponse, ListResponse } from "@gpt-vue/packages/type"; import type { BaseResponse, ListResponse } from "@chatgpt-plus/packages/type";
export type TableOriginalProps = TableInstance["$props"]; export type TableOriginalProps = TableInstance["$props"];
export type TableRequest<T extends Record<string, unknown>> = (params?: any) => Promise<BaseResponse<ListResponse<T>>> export type TableRequest<T extends Record<string, unknown>> = (params?: any) => Promise<BaseResponse<ListResponse<T>>>

View File

@ -1,6 +1,6 @@
import { computed, onMounted, reactive, unref } from "vue"; import { computed, onMounted, reactive, unref } from "vue";
import type { TableInstance } from "@arco-design/web-vue"; import type { TableInstance } from "@arco-design/web-vue";
import type { BaseResponse } from "@gpt-vue/packages/type"; import type { BaseResponse } from "@chatgpt-plus/packages/type";
export type TableOriginalProps = TableInstance["$props"]; export type TableOriginalProps = TableInstance["$props"];
export type TableRequest<T extends Record<string, unknown>> = ( export type TableRequest<T extends Record<string, unknown>> = (

View File

@ -1,44 +1,44 @@
import usePopup, { type Config } from "./usePopup"; import usePopup, { type Config } from "./usePopup";
import { Message } from "@arco-design/web-vue"; import { Message } from "@arco-design/web-vue";
import type { Component } from "vue"; import type { Component } from "vue";
import type { BaseResponse } from "@gpt-vue/packages/type"; import type { BaseResponse } from "@chatgpt-plus/packages/type";
interface Arg { interface Arg {
reload?: () => void; reload?: () => void;
record?: Record<string, any>; record?: Record<string, any>;
} }
export default function ( export default function (
node: Component, node: Component,
api: (params?: any) => Promise<BaseResponse<any>>, api: (params?: any) => Promise<BaseResponse<any>>,
config?: Config config?: Config
): (arg: Arg) => void { ): (arg: Arg) => void {
const nodeProps = (arg: Arg[]) => { const nodeProps = (arg: Arg[]) => {
return { return {
data: arg[0].record || {}, data: arg[0].record || {},
...config.nodeProps?.(arg), ...config.nodeProps?.(arg),
}; };
}; };
const popupProps = (arg: Arg[], getExposed) => { const popupProps = (arg: Arg[], getExposed) => {
return { return {
width: 750, width: 750,
maskClosable: false, maskClosable: false,
onBeforeOk: async () => { onBeforeOk: async () => {
const exposed = getExposed(); const exposed = getExposed();
const validateRes = await exposed?.formRef.value.validate(); const validateRes = await exposed?.formRef.value.validate();
if (validateRes) { if (validateRes) {
return false; return false;
} }
const { code } = await api(exposed?.form.value); const { code } = await api(exposed?.form.value);
if (code === 0) { if (code === 0) {
Message.success("操作成功"); Message.success("操作成功");
} }
arg[0]?.reload?.(); arg[0]?.reload?.();
return code === 0; return code === 0;
}, },
...config.popupProps?.(arg, getExposed), ...config.popupProps?.(arg, getExposed),
}; };
}; };
return usePopup(node, { nodeProps, popupProps }); return usePopup(node, { nodeProps, popupProps });
} }

View File

@ -1,6 +1,6 @@
import { ref } from "vue"; import { ref } from "vue";
import type { Ref } from "vue"; import type { Ref } from "vue";
import type { BaseResponse } from "@gpt-vue/packages/type"; import type { BaseResponse } from "@chatgpt-plus/packages/type";
type Request<T> = (params?: any) => Promise<BaseResponse<T>> type Request<T> = (params?: any) => Promise<BaseResponse<T>>
function useRequest<T>(request: Request<T>) { function useRequest<T>(request: Request<T>) {

View File

@ -1,6 +1,6 @@
import { ref, reactive, unref } from "vue"; import { ref, reactive, unref } from "vue";
import { Message } from "@arco-design/web-vue"; import { Message } from "@arco-design/web-vue";
import type { BaseResponse } from "@gpt-vue/packages/type"; import type { BaseResponse } from "@chatgpt-plus/packages/type";
function useSubmit<T extends Record<string, any> = Record<string, any>, R = any>(defaultData?: T) { function useSubmit<T extends Record<string, any> = Record<string, any>, R = any>(defaultData?: T) {
const formRef = ref(); const formRef = ref();
const formData = reactive<T | Record<string, any>>({ ...defaultData ?? {} }); const formData = reactive<T | Record<string, any>>({ ...defaultData ?? {} });

View File

@ -1,7 +1,7 @@
import router from "@/router"; import router from "@/router";
import { Notification } from "@arco-design/web-vue"; import { Notification } from "@arco-design/web-vue";
import createInstance from "@gpt-vue/packages/request" import createInstance from "@chatgpt-plus/packages/request"
import type { BaseResponse } from "@gpt-vue/packages/type"; import type { BaseResponse } from "@chatgpt-plus/packages/type";
export const uploadUrl = import.meta.env.VITE_PROXY_BASE_URL + "/api/admin/upload"; export const uploadUrl = import.meta.env.VITE_PROXY_BASE_URL + "/api/admin/upload";

View File

@ -5,7 +5,7 @@ import ApiKeyForm from "./ApiKeyForm.vue";
import useCustomFormPopup from "@/composables/useCustomFormPopup"; import useCustomFormPopup from "@/composables/useCustomFormPopup";
import { Message } from "@arco-design/web-vue"; import { Message } from "@arco-design/web-vue";
import SimpleTable from "@/components/SimpleTable/SimpleTable.vue"; import SimpleTable from "@/components/SimpleTable/SimpleTable.vue";
import { dateFormat } from "@gpt-vue/packages/utils"; import { dateFormat } from "@chatgpt-plus/packages/utils";
// table // table
const columns = [ const columns = [
{ {
@ -30,7 +30,7 @@ const columns = [
dataIndex: "use_proxy", dataIndex: "use_proxy",
slotName: "proxy", slotName: "proxy",
align: "center", align: "center",
width: 100 width: 100,
}, },
{ {
title: "最后使用时间", title: "最后使用时间",
@ -45,7 +45,7 @@ const columns = [
dataIndex: "enabled", dataIndex: "enabled",
slotName: "status", slotName: "status",
align: "center", align: "center",
width: 100 width: 100,
}, },
{ {
title: "操作", title: "操作",

View File

@ -1,119 +1,119 @@
<template> <template>
<a-alert type="warning"> <a-alert type="warning">
<div class="warning"> <div class="warning">
{{ {{
`注意如果是百度文心一言平台API-KEY 为 APIKey|SecretKey中间用竖线|)连接\n注意如果是讯飞星火大模型API-KEY 为 AppId|APIKey|APISecret中间用竖线|)连接` `注意如果是百度文心一言平台API-KEY 为 APIKey|SecretKey中间用竖线|)连接\n注意如果是讯飞星火大模型API-KEY 为 AppId|APIKey|APISecret中间用竖线|)连接`
}} }}
</div> </div>
</a-alert> </a-alert>
<a-form <a-form
ref="formRef" ref="formRef"
:model="form" :model="form"
:style="{ width: '600px', 'margin-top': '10px' }" :style="{ width: '600px', 'margin-top': '10px' }"
@submit="handleSubmit" @submit="handleSubmit"
> >
<a-form-item <a-form-item
field="platform" field="platform"
label="所属平台" label="所属平台"
:rules="[{ required: true, message: '请输入所属平台' }]" :rules="[{ required: true, message: '请输入所属平台' }]"
:validate-trigger="['change', 'input']" :validate-trigger="['change', 'input']"
> >
<a-input v-model="form.platform" placeholder="请输入所属平台" /> <a-input v-model="form.platform" placeholder="请输入所属平台" />
</a-form-item> </a-form-item>
<a-form-item <a-form-item
field="name" field="name"
label="名称" label="名称"
:rules="[{ required: true, message: '请输入名称' }]" :rules="[{ required: true, message: '请输入名称' }]"
:validate-trigger="['change', 'input']" :validate-trigger="['change', 'input']"
showable showable
> >
<a-input v-model="form.name" placeholder="请输入名称" /> <a-input v-model="form.name" placeholder="请输入名称" />
</a-form-item> </a-form-item>
<a-form-item <a-form-item
field="type" field="type"
label="用途" label="用途"
:rules="[{ required: true, message: '请输入用途' }]" :rules="[{ required: true, message: '请输入用途' }]"
:validate-trigger="['change', 'input']" :validate-trigger="['change', 'input']"
> >
<a-select v-model="form.type" placeholder="请输入用途" :options="typeOPtions"> </a-select> <a-select v-model="form.type" placeholder="请输入用途" :options="typeOPtions"> </a-select>
</a-form-item> </a-form-item>
<a-form-item <a-form-item
field="value" field="value"
label="API KEY" label="API KEY"
:rules="[{ required: true, message: '请输入API KEY' }]" :rules="[{ required: true, message: '请输入API KEY' }]"
:validate-trigger="['change', 'input']" :validate-trigger="['change', 'input']"
> >
<a-input v-model="form.value" placeholder="请输入API KEY" /> <a-input v-model="form.value" placeholder="请输入API KEY" />
</a-form-item> </a-form-item>
<a-form-item <a-form-item
field="api_url" field="api_url"
label="API URL" label="API URL"
:rules="[{ required: true, message: '请输入API URL' }]" :rules="[{ required: true, message: '请输入API URL' }]"
:validate-trigger="['change', 'input']" :validate-trigger="['change', 'input']"
> >
<a-input v-model="form.api_url" placeholder="请输入API URL" /> <a-input v-model="form.api_url" placeholder="请输入API URL" />
</a-form-item> </a-form-item>
<a-form-item field="use_proxy" label="使用代理"> <a-form-item field="use_proxy" label="使用代理">
<a-switch v-model="form.use_proxy" /> <a-switch v-model="form.use_proxy" />
<a-tooltip <a-tooltip
content="是否使用代理访问 API URLOpenAI 官方API需要开启代理访问" content="是否使用代理访问 API URLOpenAI 官方API需要开启代理访问"
position="right" position="right"
> >
<icon-info-circle-fill /> <icon-info-circle-fill />
</a-tooltip> </a-tooltip>
</a-form-item> </a-form-item>
<a-form-item field="enable" label="启用状态"> <a-form-item field="enable" label="启用状态">
<a-switch v-model="form.enable" /> <a-switch v-model="form.enable" />
</a-form-item> </a-form-item>
</a-form> </a-form>
</template> </template>
<script setup> <script setup>
import { ref, defineExpose, defineProps } from "vue"; import { ref, defineExpose, defineProps } from "vue";
const props = defineProps({ const props = defineProps({
data: {}, data: {},
}); });
const formRef = ref(); const formRef = ref();
const form = ref({}); const form = ref({});
if (props.data?.id) { if (props.data?.id) {
form.value = Object.assign({}, props.data); form.value = Object.assign({}, props.data);
} }
defineExpose({ defineExpose({
formRef, formRef,
form, form,
}); });
const typeOPtions = [ const typeOPtions = [
{ {
label: "聊天", label: "聊天",
value: "chart", value: "chart",
}, },
{ {
label: "绘图", label: "绘图",
value: "img", value: "img",
}, },
]; ];
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
.content-title { .content-title {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
width: 350px; width: 350px;
} }
.content-cell { .content-cell {
display: flex; display: flex;
align-items: center; align-items: center;
width: 350px; width: 350px;
svg { svg {
margin-left: 10px; margin-left: 10px;
} }
} }
.warning { .warning {
color: #e6a23c; color: #e6a23c;
white-space: pre; white-space: pre;
} }
</style> </style>

View File

@ -5,7 +5,7 @@ import ChatModelForm from "./ChatModelForm.vue";
import useCustomFormPopup from "@/composables/useCustomFormPopup"; import useCustomFormPopup from "@/composables/useCustomFormPopup";
import { Message } from "@arco-design/web-vue"; import { Message } from "@arco-design/web-vue";
import SimpleTable from "@/components/SimpleTable/SimpleTable.vue"; import SimpleTable from "@/components/SimpleTable/SimpleTable.vue";
import { dateFormat } from "@gpt-vue/packages/utils"; import { dateFormat } from "@chatgpt-plus/packages/utils";
// table // table
const columns = [ const columns = [
{ {

View File

@ -1,94 +1,94 @@
<template> <template>
<a-form ref="formRef" :model="form" :style="{ width: '600px' }" @submit="handleSubmit"> <a-form ref="formRef" :model="form" :style="{ width: '600px' }" @submit="handleSubmit">
<a-form-item <a-form-item
field="platform" field="platform"
label="所属平台" label="所属平台"
:rules="[{ required: true, message: '请输入所属平台' }]" :rules="[{ required: true, message: '请输入所属平台' }]"
:validate-trigger="['change', 'input']" :validate-trigger="['change', 'input']"
> >
<a-input v-model="form.platform" placeholder="请输入所属平台" /> <a-input v-model="form.platform" placeholder="请输入所属平台" />
</a-form-item> </a-form-item>
<a-form-item <a-form-item
field="name" field="name"
label="名称" label="名称"
:rules="[{ required: true, message: '请输入名称' }]" :rules="[{ required: true, message: '请输入名称' }]"
:validate-trigger="['change', 'input']" :validate-trigger="['change', 'input']"
showable showable
> >
<a-input v-model="form.name" placeholder="请输入名称" /> <a-input v-model="form.name" placeholder="请输入名称" />
</a-form-item> </a-form-item>
<a-form-item <a-form-item
field="value" field="value"
label="模型值" label="模型值"
:rules="[{ required: true, message: '请输入名称' }]" :rules="[{ required: true, message: '请输入名称' }]"
:validate-trigger="['change', 'input']" :validate-trigger="['change', 'input']"
showable showable
> >
<a-input v-model="form.value" placeholder="请输入名称" /> <a-input v-model="form.value" placeholder="请输入名称" />
</a-form-item> </a-form-item>
<a-form-item <a-form-item
field="weight" field="weight"
label="对话权重" label="对话权重"
:rules="[{ required: true, message: '请输入对话权重' }]" :rules="[{ required: true, message: '请输入对话权重' }]"
:validate-trigger="['change', 'input']" :validate-trigger="['change', 'input']"
showable showable
> >
<a-input-number v-model="form.weight" placeholder="请输入对话权重" /> <a-input-number v-model="form.weight" placeholder="请输入对话权重" />
<a-tooltip content="对话权重,每次对话扣减多少次对话额度" position="right"> <a-tooltip content="对话权重,每次对话扣减多少次对话额度" position="right">
<icon-info-circle-fill /> <icon-info-circle-fill />
</a-tooltip> </a-tooltip>
</a-form-item> </a-form-item>
<a-form-item field="open" label="开放状态代理"> <a-form-item field="open" label="开放状态代理">
<a-switch v-model="form.open" /> <a-switch v-model="form.open" />
</a-form-item> </a-form-item>
<a-form-item field="enabled" label="启用状态"> <a-form-item field="enabled" label="启用状态">
<a-switch v-model="form.enabled" /> <a-switch v-model="form.enabled" />
</a-form-item> </a-form-item>
</a-form> </a-form>
</template> </template>
<script setup> <script setup>
import { ref, defineExpose, defineProps } from "vue"; import { ref, defineExpose, defineProps } from "vue";
const props = defineProps({ const props = defineProps({
data: {}, data: {},
}); });
const formRef = ref(); const formRef = ref();
const form = ref({}); const form = ref({});
if (props.data?.id) { if (props.data?.id) {
form.value = Object.assign({}, props.data); form.value = Object.assign({}, props.data);
} }
defineExpose({ defineExpose({
formRef, formRef,
form, form,
}); });
const typeOPtions = [ const typeOPtions = [
{ {
label: "聊天", label: "聊天",
value: "chart", value: "chart",
}, },
{ {
label: "绘图", label: "绘图",
value: "img", value: "img",
}, },
]; ];
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
.content-title { .content-title {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
width: 350px; width: 350px;
} }
.content-cell { .content-cell {
display: flex; display: flex;
align-items: center; align-items: center;
width: 350px; width: 350px;
svg { svg {
margin-left: 10px; margin-left: 10px;
} }
} }
</style> </style>

View File

@ -1,7 +1,7 @@
<script lang="ts" setup> <script lang="ts" setup>
import { ref, h } from "vue"; import { ref, h } from "vue";
import { Message, Modal } from "@arco-design/web-vue"; import { Message, Modal } from "@arco-design/web-vue";
import { dateFormat } from "@gpt-vue/packages/utils"; import { dateFormat } from "@chatgpt-plus/packages/utils";
import SearchTable from "@/components/SearchTable/SearchTable.vue"; import SearchTable from "@/components/SearchTable/SearchTable.vue";
import type { SearchTableColumns } from "@/components/SearchTable/type"; import type { SearchTableColumns } from "@/components/SearchTable/type";
import app from "@/main"; import app from "@/main";

View File

@ -1,7 +1,7 @@
<script lang="ts" setup> <script lang="ts" setup>
import { onMounted } from "vue"; import { onMounted } from "vue";
import { Message } from "@arco-design/web-vue"; import { Message } from "@arco-design/web-vue";
import { dateFormat } from "@gpt-vue/packages/utils"; import { dateFormat } from "@chatgpt-plus/packages/utils";
import useRequest from "@/composables/useRequest"; import useRequest from "@/composables/useRequest";
import { history } from "./api"; import { history } from "./api";

View File

@ -1,5 +1,5 @@
<script lang="ts" setup> <script lang="ts" setup>
import { dateFormat } from "@gpt-vue/packages/utils"; import { dateFormat } from "@chatgpt-plus/packages/utils";
import SearchTable from "@/components/SearchTable/SearchTable.vue"; import SearchTable from "@/components/SearchTable/SearchTable.vue";
import type { SearchTableColumns } from "@/components/SearchTable/type"; import type { SearchTableColumns } from "@/components/SearchTable/type";
import { loginLog } from "@/http/login"; import { loginLog } from "@/http/login";

View File

@ -1,7 +1,7 @@
<script lang="ts" setup> <script lang="ts" setup>
import SearchTable from "@/components/SearchTable/SearchTable.vue"; import SearchTable from "@/components/SearchTable/SearchTable.vue";
import type { SearchTableColumns } from "@/components/SearchTable/type"; import type { SearchTableColumns } from "@/components/SearchTable/type";
import { dateFormat } from "@gpt-vue/packages/utils"; import { dateFormat } from "@chatgpt-plus/packages/utils";
import { getList } from "./api"; import { getList } from "./api";
const columns: SearchTableColumns[] = [ const columns: SearchTableColumns[] = [

View File

@ -5,7 +5,7 @@ import ProductForm from "./ProductForm.vue";
import useCustomFormPopup from "@/composables/useCustomFormPopup"; import useCustomFormPopup from "@/composables/useCustomFormPopup";
import { Message } from "@arco-design/web-vue"; import { Message } from "@arco-design/web-vue";
import SimpleTable from "@/components/SimpleTable/SimpleTable.vue"; import SimpleTable from "@/components/SimpleTable/SimpleTable.vue";
import { dateFormat } from "@gpt-vue/packages/utils"; import { dateFormat } from "@chatgpt-plus/packages/utils";
// table // table
const columns = [ const columns = [
{ {
@ -41,7 +41,7 @@ const columns = [
dataIndex: "enabled", dataIndex: "enabled",
slotName: "status", slotName: "status",
align: "center", align: "center",
width: 100 width: 100,
}, },
{ {
title: "更新时间", title: "更新时间",
@ -55,7 +55,7 @@ const columns = [
title: "操作", title: "操作",
slotName: "action", slotName: "action",
width: 120, width: 120,
fixed: "right" fixed: "right",
}, },
]; ];

View File

@ -1,87 +1,87 @@
<template> <template>
<a-form ref="formRef" :model="form" :style="{ width: '600px' }" @submit="handleSubmit"> <a-form ref="formRef" :model="form" :style="{ width: '600px' }" @submit="handleSubmit">
<a-form-item <a-form-item
field="name" field="name"
label="产品名称" label="产品名称"
:rules="[{ required: true, message: '请输入产品名称' }]" :rules="[{ required: true, message: '请输入产品名称' }]"
:validate-trigger="['change', 'input']" :validate-trigger="['change', 'input']"
> >
<a-input v-model="form.name" placeholder="请输入产品名称" /> <a-input v-model="form.name" placeholder="请输入产品名称" />
</a-form-item> </a-form-item>
<a-form-item <a-form-item
field="price" field="price"
label="产品价格" label="产品价格"
:rules="[{ required: true, message: '请输入产品价格' }]" :rules="[{ required: true, message: '请输入产品价格' }]"
:validate-trigger="['change', 'input']" :validate-trigger="['change', 'input']"
showable showable
> >
<a-input-number v-model="form.price" placeholder="请输入产品价格" /> <a-input-number v-model="form.price" placeholder="请输入产品价格" />
</a-form-item> </a-form-item>
<a-form-item <a-form-item
field="discount" field="discount"
label="优惠金额" label="优惠金额"
:rules="[{ required: true, message: '请输入优惠金额' }]" :rules="[{ required: true, message: '请输入优惠金额' }]"
:validate-trigger="['change', 'input']" :validate-trigger="['change', 'input']"
showable showable
> >
<a-input-number v-model="form.discount" placeholder="请输入优惠金额" /> <a-input-number v-model="form.discount" placeholder="请输入优惠金额" />
</a-form-item> </a-form-item>
<a-form-item <a-form-item
field="days" field="days"
label="有效期(天)" label="有效期(天)"
:rules="[{ required: true, message: '请输入有效期(天)' }]" :rules="[{ required: true, message: '请输入有效期(天)' }]"
:validate-trigger="['change', 'input']" :validate-trigger="['change', 'input']"
showable showable
> >
<a-input-number v-model="form.days" placeholder="请输入有效期(天)" /> <a-input-number v-model="form.days" placeholder="请输入有效期(天)" />
</a-form-item> </a-form-item>
<a-form-item field="calls" label="对话次数" :validate-trigger="['change', 'input']" showable> <a-form-item field="calls" label="对话次数" :validate-trigger="['change', 'input']" showable>
<a-input-number v-model="form.calls" placeholder="请输入对话次数" /> <a-input-number v-model="form.calls" placeholder="请输入对话次数" />
</a-form-item> </a-form-item>
<a-form-item <a-form-item
field="img_calls" field="img_calls"
label="绘图次数" label="绘图次数"
:validate-trigger="['change', 'input']" :validate-trigger="['change', 'input']"
showable showable
> >
<a-input-number v-model="form.img_calls" placeholder="请输入绘图次数" /> <a-input-number v-model="form.img_calls" placeholder="请输入绘图次数" />
</a-form-item> </a-form-item>
<a-form-item field="enabled" label="启用状态"> <a-form-item field="enabled" label="启用状态">
<a-switch v-model="form.enabled" /> <a-switch v-model="form.enabled" />
</a-form-item> </a-form-item>
</a-form> </a-form>
</template> </template>
<script setup> <script setup>
import { ref, defineExpose, defineProps } from "vue"; import { ref, defineExpose, defineProps } from "vue";
const props = defineProps({ const props = defineProps({
data: {}, data: {},
}); });
const formRef = ref(); const formRef = ref();
const form = ref({}); const form = ref({});
if (props.data?.id) { if (props.data?.id) {
form.value = Object.assign({}, props.data); form.value = Object.assign({}, props.data);
} }
defineExpose({ defineExpose({
formRef, formRef,
form, form,
}); });
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
.content-title { .content-title {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
width: 350px; width: 350px;
} }
.content-cell { .content-cell {
display: flex; display: flex;
align-items: center; align-items: center;
width: 350px; width: 350px;
svg { svg {
margin-left: 10px; margin-left: 10px;
} }
} }
</style> </style>

View File

@ -1,6 +1,6 @@
<script lang="ts" setup> <script lang="ts" setup>
import { Message, type TableColumnData } from "@arco-design/web-vue"; import { Message, type TableColumnData } from "@arco-design/web-vue";
import { dateFormat } from "@gpt-vue/packages/utils"; import { dateFormat } from "@chatgpt-plus/packages/utils";
import SimpleTable from "@/components/SimpleTable/SimpleTable.vue"; import SimpleTable from "@/components/SimpleTable/SimpleTable.vue";
import { getList, remove } from "./api"; import { getList, remove } from "./api";

View File

@ -1,116 +1,116 @@
<template> <template>
<a-form ref="formRef" :model="form" :style="{ width: '600px' }" @submit="handleSubmit"> <a-form ref="formRef" :model="form" :style="{ width: '600px' }" @submit="handleSubmit">
<a-form-item <a-form-item
field="name" field="name"
label="角色名称" label="角色名称"
:rules="[{ required: true, message: '请输入角色名称' }]" :rules="[{ required: true, message: '请输入角色名称' }]"
:validate-trigger="['change', 'input']" :validate-trigger="['change', 'input']"
> >
<a-input v-model="form.name" placeholder="请输入角色名称" /> <a-input v-model="form.name" placeholder="请输入角色名称" />
</a-form-item> </a-form-item>
<a-form-item <a-form-item
field="key" field="key"
label="角色标志" label="角色标志"
:rules="[{ required: true, message: '请输入角色标志' }]" :rules="[{ required: true, message: '请输入角色标志' }]"
:validate-trigger="['change', 'input']" :validate-trigger="['change', 'input']"
showable showable
> >
<a-input v-model="form.key" placeholder="请输入角色标志" /> <a-input v-model="form.key" placeholder="请输入角色标志" />
</a-form-item> </a-form-item>
<a-form-item <a-form-item
field="icon" field="icon"
label="角色图标" label="角色图标"
:rules="[{ required: true, message: '请输入角色图标' }]" :rules="[{ required: true, message: '请输入角色图标' }]"
:validate-trigger="['change', 'input']" :validate-trigger="['change', 'input']"
> >
<a-input v-model="form.icon" placeholder="请输入角色图标" /> <a-input v-model="form.icon" placeholder="请输入角色图标" />
</a-form-item> </a-form-item>
<a-form-item <a-form-item
field="hello_msg" field="hello_msg"
label="打招呼信息" label="打招呼信息"
:rules="[{ required: true, message: '请输入打招呼信息' }]" :rules="[{ required: true, message: '请输入打招呼信息' }]"
:validate-trigger="['change', 'input']" :validate-trigger="['change', 'input']"
> >
<a-input v-model="form.hello_msg" placeholder="请输入打招呼信息" /> <a-input v-model="form.hello_msg" placeholder="请输入打招呼信息" />
</a-form-item> </a-form-item>
<a-form-item field="username" label="上下文信息" :validate-trigger="['change', 'input']"> <a-form-item field="username" label="上下文信息" :validate-trigger="['change', 'input']">
<a-table :data="form.context || []" :pagination="false"> <a-table :data="form.context || []" :pagination="false">
<template #columns> <template #columns>
<a-table-column title="对话角色"> <a-table-column title="对话角色">
<template #cell="{ record }"> <template #cell="{ record }">
<a-input v-model="record.role" /> <a-input v-model="record.role" />
</template> </template>
</a-table-column> </a-table-column>
<a-table-column width="350"> <a-table-column width="350">
<template #title> <template #title>
<div class="content-title"> <div class="content-title">
<span>对话内容</span> <span>对话内容</span>
<a-button @click="addContext" type="primary">增加一行</a-button> <a-button @click="addContext" type="primary">增加一行</a-button>
</div> </div>
</template> </template>
<template #cell="{ record }"> <template #cell="{ record }">
<div class="content-cell"> <div class="content-cell">
<a-input v-model="record.content" /><icon-minus-circle <a-input v-model="record.content" /><icon-minus-circle
@click="removeContext(record)" @click="removeContext(record)"
/> />
</div> </div>
</template> </template>
</a-table-column> </a-table-column>
</template> </template>
</a-table> </a-table>
</a-form-item> </a-form-item>
<a-form-item field="enable" label="启用状态"> <a-form-item field="enable" label="启用状态">
<a-switch v-model="form.enable" /> <a-switch v-model="form.enable" />
</a-form-item> </a-form-item>
</a-form> </a-form>
</template> </template>
<script setup> <script setup>
import { ref, defineExpose, defineProps } from "vue"; import { ref, defineExpose, defineProps } from "vue";
const props = defineProps({ const props = defineProps({
data: {}, data: {},
}); });
const formRef = ref(); const formRef = ref();
const form = ref({}); const form = ref({});
if (props.data?.id) { if (props.data?.id) {
form.value = Object.assign({}, props.data); form.value = Object.assign({}, props.data);
} }
const addContext = () => { const addContext = () => {
form.value.context = form.value.context || []; form.value.context = form.value.context || [];
form.value.context.push({ form.value.context.push({
role: "", role: "",
content: "", content: "",
}); });
}; };
const removeContext = (record) => { const removeContext = (record) => {
const index = form.value.context.findIndex((item) => { const index = form.value.context.findIndex((item) => {
return item === record; return item === record;
}); });
if (index > -1) { if (index > -1) {
form.value.context.splice(index, 1); form.value.context.splice(index, 1);
} }
}; };
defineExpose({ defineExpose({
formRef, formRef,
form, form,
}); });
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
.content-title { .content-title {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
width: 350px; width: 350px;
} }
.content-cell { .content-cell {
display: flex; display: flex;
align-items: center; align-items: center;
width: 350px; width: 350px;
svg { svg {
margin-left: 10px; margin-left: 10px;
} }
} }
</style> </style>

Some files were not shown because too many files have changed in this diff Show More