Files
tuanwei-admin/src/views/oa/chatgpt/index.bak.vue
T
weicw1996 6b967b6b69 修正类型导入写法,补上 pnpm 锁文件
- ItemType / ColumnItem / EleProTableDone 等纯类型改用 import type,
  避免打包器把类型当运行时依赖处理
- 提交 pnpm-lock.yaml 与 pnpm-workspace.yaml

注:仓库里原有的 package-lock.json 与 yarn.lock 未动,三份锁文件并存。
2026-09-18 23:30:55 +08:00

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>