6b967b6b69
- ItemType / ColumnItem / EleProTableDone 等纯类型改用 import type, 避免打包器把类型当运行时依赖处理 - 提交 pnpm-lock.yaml 与 pnpm-workspace.yaml 注:仓库里原有的 package-lock.json 与 yarn.lock 未动,三份锁文件并存。
232 lines
5.7 KiB
Vue
232 lines
5.7 KiB
Vue
<!-- 用户编辑弹窗 -->
|
|
<template>
|
|
<div class="page">
|
|
<div class="ele-body" style="padding-bottom: 60px;">
|
|
<!-- 表格 -->
|
|
<a-spin :spinning="loading">
|
|
<table class="ele-table ele-table-stripe ele-table-medium">
|
|
<tbody>
|
|
<tr v-for="(item,index) in notice" :key="index">
|
|
<td style="text-align: right; width: 360px; vertical-align: top;">
|
|
<div class="user-avatar">
|
|
<a-avatar v-if="item.channel === 0" :src="item.avatar" />
|
|
<a-avatar v-else class="openai" />
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<div class="content"><byte-md-viewer :value="item.content" ref="md-content" :plugins="plugins" /></div>
|
|
</td>
|
|
<td>
|
|
<a-button v-if="item.channel === 1" @click="copyText(item.content)">复制</a-button>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</a-spin>
|
|
<a-space class="action">
|
|
<a-popconfirm
|
|
title="确定要删除当前会话吗?"
|
|
@confirm="remove(item)"
|
|
>
|
|
<a-button class="ele-text-danger">清空当前会话</a-button>
|
|
</a-popconfirm>
|
|
</a-space>
|
|
</div>
|
|
<a-card class="foot">
|
|
<div class="send-box">
|
|
<a-space>
|
|
<a-input
|
|
v-model:value="content"
|
|
placeholder="我是AI机器人,你想和我聊点什么?"
|
|
size="large"
|
|
:disabled="loading"
|
|
style="width: 770px"
|
|
@pressEnter="onSend"
|
|
>
|
|
<template #suffix>
|
|
<send-outlined @click="onSend" />
|
|
</template>
|
|
</a-input>
|
|
</a-space>
|
|
</div>
|
|
</a-card>
|
|
<a-back-top />
|
|
</div>
|
|
</template>
|
|
|
|
<script lang="ts" setup>
|
|
import "bytemd/dist/index.min.css";
|
|
import { ref } from "vue";
|
|
import "github-markdown-css/github-markdown-light.css";
|
|
// // 链接、删除线、复选框、表格等的插件
|
|
import gfm from "@bytemd/plugin-gfm";
|
|
// // 插件的中文语言文件
|
|
import zh_HansGfm from "@bytemd/plugin-gfm/locales/zh_Hans.json";
|
|
// 中文语言文件
|
|
import "bytemd/dist/index.min.css";
|
|
import highlight from "@bytemd/plugin-highlight-ssr";
|
|
import "highlight.js/styles/default.css";
|
|
import { message} from "ant-design-vue";
|
|
import { storeToRefs } from "pinia";
|
|
import { useThemeStore } from "@/store/modules/theme";
|
|
import { uploadFile } from "@/api/system/file";
|
|
import type { Notice } from "@/api/oa/notice/model";
|
|
import { FILE_SERVER } from "@/config/setting";
|
|
import type { ItemType } from "ele-admin-pro/es/ele-image-upload/types";
|
|
import { listNotice, removeNotice } from "@/api/oa/notice";
|
|
import { chat, send } from "@/api/oa/chatgpt";
|
|
import {
|
|
SendOutlined
|
|
} from '@ant-design/icons-vue';
|
|
import { Message } from "@/api/user/message/model";
|
|
import { EquipmentFault } from "@/api/apps/equipment/fault/model";
|
|
import { removeEquipmentFault } from "@/api/apps/equipment/fault";
|
|
import { EleTableSelect } from "ele-admin-pro";
|
|
import { FormInstance } from "ant-design-vue/es/form";
|
|
import { copyText, isImage } from "@/utils/common";
|
|
|
|
// 插件
|
|
const plugins = ref([
|
|
gfm({
|
|
locale: zh_HansGfm
|
|
}),
|
|
highlight()
|
|
]);
|
|
|
|
// 是否开启响应式布局
|
|
const themeStore = useThemeStore();
|
|
const { styleResponsive } = storeToRefs(themeStore);
|
|
// 请求状态
|
|
const loading = ref(false);
|
|
const noticeId = ref(0);
|
|
const content = ref('');
|
|
const files = ref<ItemType[]>([]);
|
|
const notice = ref<Notice[]>([]);
|
|
|
|
/* 上传事件 */
|
|
const uploadHandler = (file: File) => {
|
|
const item: ItemType = {
|
|
file,
|
|
uid: (file as any).uid,
|
|
name: file.name
|
|
};
|
|
if (!file.type.startsWith("image")) {
|
|
message.error("只能选择图片");
|
|
return;
|
|
}
|
|
if (file.size / 1024 / 1024 > 2) {
|
|
message.error("大小不能超过 2MB");
|
|
return;
|
|
}
|
|
onUpload(item);
|
|
};
|
|
|
|
const onUpload = (d: ItemType) => {
|
|
uploadFile(<File>d.file)
|
|
.then((result) => {
|
|
files.value.push({
|
|
uid: result.id,
|
|
url: FILE_SERVER + result.path,
|
|
name: isImage(result.path) ? 'image' : result.name,
|
|
status: "done"
|
|
});
|
|
message.success("上传成功");
|
|
})
|
|
.catch((e) => {
|
|
message.error(e.message);
|
|
});
|
|
};
|
|
|
|
/* 向chatGPT提问 */
|
|
const onSend = () => {
|
|
send({
|
|
tenantId: Number(localStorage.getItem('tenantId')),
|
|
content: content.value
|
|
}).then((noticeId) => {
|
|
query();
|
|
onChat(noticeId);
|
|
})
|
|
}
|
|
|
|
const onChat = (noticeId) => {
|
|
chat({
|
|
tenantId: Number(localStorage.getItem('tenantId')),
|
|
content: content.value,
|
|
noticeId
|
|
}).then(() => {
|
|
query();
|
|
content.value = '';
|
|
})
|
|
}
|
|
|
|
/* 删除单个 */
|
|
const remove = (row: Notice) => {
|
|
console.log(row);
|
|
const hide = message.loading('请求中..', 0);
|
|
removeNotice(row.noticeId)
|
|
.then((msg) => {
|
|
hide();
|
|
message.success(msg);
|
|
query();
|
|
})
|
|
.catch((e) => {
|
|
hide();
|
|
message.error(e.message);
|
|
});
|
|
};
|
|
|
|
const query = () => {
|
|
listNotice({limit: 2})
|
|
.then((response) => {
|
|
notice.value = response
|
|
})
|
|
.catch((e) => {
|
|
message.error(e.message);
|
|
});
|
|
};
|
|
|
|
query();
|
|
</script>
|
|
<script lang="ts">
|
|
export default {
|
|
name: "ChatGPT"
|
|
};
|
|
</script>
|
|
<style lang="less" scoped>
|
|
.content {
|
|
max-width: 1000px;
|
|
padding: 20px 0;
|
|
.edit-md {
|
|
margin-top: 50px;
|
|
}
|
|
}
|
|
.foot{
|
|
position: fixed;
|
|
width: 100%;
|
|
background-color: #f3f9ff;
|
|
bottom: 0;
|
|
height: 100px;
|
|
//display: flex;
|
|
//justify-content: center;
|
|
.send-box{
|
|
margin-left: 360px;
|
|
}
|
|
}
|
|
.user-avatar{
|
|
padding: 20px 0;
|
|
}
|
|
.openai{
|
|
background-image: url("@/assets/icon/openai-avatar.jpeg");
|
|
background-size: 100%;
|
|
}
|
|
.markdown-body{
|
|
background: none;
|
|
}
|
|
.action{
|
|
padding: 20px 0;
|
|
display: flex;
|
|
justify-content: flex-end;
|
|
}
|
|
.copy-btn{display: flex; justify-content: flex-end;}
|
|
</style>
|