|
@@ -1,58 +1,87 @@
|
|
|
<script setup lang="ts">
|
|
|
-import { ref } from 'vue';
|
|
|
-import { PlusOutlined, LoadingOutlined, DeleteOutlined } from '@ant-design/icons-vue';
|
|
|
-import { message } from 'ant-design-vue';
|
|
|
-import type { UploadChangeParam } from 'ant-design-vue';
|
|
|
+import { ChapterType, ChapterTypeLabels } from "@/types/report.types";
|
|
|
+import { ref } from "vue";
|
|
|
+import type { PropType } from "vue";
|
|
|
+import { PlusOutlined, LoadingOutlined, DeleteOutlined } from "@ant-design/icons-vue";
|
|
|
+import * as aiService from "@/services/ai.service";
|
|
|
+import { marked } from "marked";
|
|
|
+import { message } from "ant-design-vue";
|
|
|
+import type { UploadChangeParam } from "ant-design-vue";
|
|
|
+import { Item } from "ant-design-vue/lib/menu";
|
|
|
+import { iteratee } from "lodash";
|
|
|
+import type { Chapter } from "@/types/report.types";
|
|
|
|
|
|
-defineProps({
|
|
|
+const props = defineProps({
|
|
|
url: {
|
|
|
type: String,
|
|
|
required: false,
|
|
|
- }
|
|
|
-})
|
|
|
+ },
|
|
|
+ title: {
|
|
|
+ type: String,
|
|
|
+ required: true,
|
|
|
+ },
|
|
|
+ list: {
|
|
|
+ type: Array as PropType<Chapter[]>,
|
|
|
+ default() {
|
|
|
+ return [];
|
|
|
+ },
|
|
|
+ },
|
|
|
+});
|
|
|
|
|
|
const emits = defineEmits<{
|
|
|
(e: "change", file: File): void;
|
|
|
(e: "delete"): void;
|
|
|
+ (e: "ok", vaule: ChapterType[]): void;
|
|
|
+ (e: "one-touch", data: Chapter): void;
|
|
|
}>();
|
|
|
|
|
|
+const categoryOptions = ChapterTypeLabels.map((item) => ({
|
|
|
+ label: item.label,
|
|
|
+ value: item.key,
|
|
|
+}));
|
|
|
+
|
|
|
function getBase64(img: Blob, callback: (base64Url: string) => void) {
|
|
|
const reader = new FileReader();
|
|
|
- reader.addEventListener('load', () => callback(reader.result as string));
|
|
|
+ reader.addEventListener("load", () => callback(reader.result as string));
|
|
|
reader.readAsDataURL(img);
|
|
|
}
|
|
|
|
|
|
const fileList = ref([]);
|
|
|
const loading = ref<boolean>(false);
|
|
|
-const imageUrl = ref<string>('');
|
|
|
+const imageUrl = ref<string>("");
|
|
|
+const checkedCategories = ref<ChapterType[]>([
|
|
|
+ ChapterType.BACKGROUND,
|
|
|
+ ChapterType.RESEARCH_STATUS,
|
|
|
+ ChapterType.RESEARCH,
|
|
|
+]);
|
|
|
|
|
|
const handleChange = (info: UploadChangeParam) => {
|
|
|
- if (info.file.status === 'uploading') {
|
|
|
+ if (info.file.status === "uploading") {
|
|
|
loading.value = true;
|
|
|
return;
|
|
|
}
|
|
|
- if (info.file.status === 'done') {
|
|
|
+ if (info.file.status === "done") {
|
|
|
// Get this url from response in real world.
|
|
|
getBase64(info.file.originFileObj as Blob, (base64Url: string) => {
|
|
|
imageUrl.value = base64Url;
|
|
|
loading.value = false;
|
|
|
});
|
|
|
}
|
|
|
- if (info.file.status === 'error') {
|
|
|
+ if (info.file.status === "error") {
|
|
|
loading.value = false;
|
|
|
- message.error('upload error');
|
|
|
+ message.error("upload error");
|
|
|
}
|
|
|
};
|
|
|
|
|
|
const beforeUpload = (file: File) => {
|
|
|
- const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png';
|
|
|
+ const isJpgOrPng = file.type === "image/jpeg" || file.type === "image/png";
|
|
|
if (!isJpgOrPng) {
|
|
|
- message.error('仅支持JPG和PNG格式的图片');
|
|
|
+ message.error("仅支持JPG和PNG格式的图片");
|
|
|
}
|
|
|
|
|
|
const isLt2M = file.size / 1024 / 1024 < 2;
|
|
|
if (!isLt2M) {
|
|
|
- message.error('仅支持小于2MB的图片');
|
|
|
+ message.error("仅支持小于2MB的图片");
|
|
|
}
|
|
|
if (!isJpgOrPng || !isLt2M) {
|
|
|
return false;
|
|
@@ -64,7 +93,105 @@ const beforeUpload = (file: File) => {
|
|
|
};
|
|
|
|
|
|
function onDelete() {
|
|
|
- emits("delete")
|
|
|
+ emits("delete");
|
|
|
+}
|
|
|
+
|
|
|
+function onContentChange(data: any) {
|
|
|
+ emits("one-touch", data);
|
|
|
+}
|
|
|
+
|
|
|
+function test1() {
|
|
|
+ let values: ChapterType[] = [];
|
|
|
+ let chapterTitle: string = "";
|
|
|
+ if(!props.title){
|
|
|
+ message.warning("项目名称不能为空")
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if (props.list.length == 0) {
|
|
|
+ for (let item of categoryOptions) {
|
|
|
+ if (checkedCategories.value.find((x) => x == item.value)) {
|
|
|
+ values.push(item.value);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ emits("ok", values);
|
|
|
+ } else {
|
|
|
+ let arr = [];
|
|
|
+ let dataList = props.list;
|
|
|
+ for (let item of dataList) {
|
|
|
+ if(item.title.includes(',')){
|
|
|
+ message.warning("章节类型中不能存在英文逗号!!!")
|
|
|
+ return
|
|
|
+ }
|
|
|
+ arr.push(item.title);
|
|
|
+ }
|
|
|
+ chapterTitle = arr.toString();
|
|
|
+ }
|
|
|
+ const loadingHandler = message.loading({
|
|
|
+ content: "AI正在撰写章节内容,请稍等……",
|
|
|
+ duration: 0,
|
|
|
+ });
|
|
|
+ aiService
|
|
|
+ .generatePlus(props.title, chapterTitle)
|
|
|
+ .then((resp) => {
|
|
|
+ // return;
|
|
|
+ const obj: any = resp;
|
|
|
+ if (props.list.length == 0) {
|
|
|
+ let list: any = [
|
|
|
+ {
|
|
|
+ title: "立项背景与意义",
|
|
|
+ fullTitle: "",
|
|
|
+ content: "",
|
|
|
+ chapterType: "BACKGROUND",
|
|
|
+ keywords: [],
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: "国内外研究现状与发展趋势",
|
|
|
+ fullTitle: "",
|
|
|
+ content: "",
|
|
|
+ chapterType: "RESEARCH_STATUS",
|
|
|
+ keywords: [],
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: "项目主要研究内容",
|
|
|
+ fullTitle: "",
|
|
|
+ content: "",
|
|
|
+ chapterType: "RESEARCH",
|
|
|
+ keywords: [],
|
|
|
+ },
|
|
|
+ ];
|
|
|
+ for (let item of list) {
|
|
|
+ const key: string = item.title;
|
|
|
+ onContentChange({
|
|
|
+ title: "",
|
|
|
+ fullTitle: "",
|
|
|
+ content: marked.parse(obj[key]),
|
|
|
+ chapterType: item.chapterType,
|
|
|
+ keywords: [],
|
|
|
+ });
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ for (let item of props.list) {
|
|
|
+ const key: string = item.title;
|
|
|
+ onContentChange({
|
|
|
+ title: item.title,
|
|
|
+ fullTitle: item.fullTitle,
|
|
|
+ content: marked.parse(obj[key]),
|
|
|
+ chapterType: item.chapterType,
|
|
|
+ keywords: item.keywords,
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // onContentChange(marked.parse(resp));
|
|
|
+ if (loadingHandler) {
|
|
|
+ loadingHandler();
|
|
|
+ }
|
|
|
+ })
|
|
|
+ .catch((err) => {
|
|
|
+ console.log("err", err);
|
|
|
+ if (loadingHandler) {
|
|
|
+ loadingHandler();
|
|
|
+ }
|
|
|
+ });
|
|
|
}
|
|
|
</script>
|
|
|
|
|
@@ -91,9 +218,7 @@ function onDelete() {
|
|
|
</a-col>
|
|
|
<a-col class="description-wrap">
|
|
|
<div class="description">
|
|
|
- <div style="flex: 1;">
|
|
|
- 请按需上传企业logo<br />仅支持 jpg. png. 格式图片
|
|
|
- </div>
|
|
|
+ <div style="flex: 1">请按需上传企业logo<br />仅支持 jpg. png. 格式图片</div>
|
|
|
<div>
|
|
|
<a-popconfirm
|
|
|
title="确定删除此Logoo?"
|
|
@@ -108,6 +233,13 @@ function onDelete() {
|
|
|
</div>
|
|
|
</a-col>
|
|
|
</a-row>
|
|
|
+ <a-row>
|
|
|
+ <a-col>
|
|
|
+ <a-button class="generate-project" type="primary" @click="test1">
|
|
|
+ 一键生成
|
|
|
+ </a-button>
|
|
|
+ </a-col>
|
|
|
+ </a-row>
|
|
|
</template>
|
|
|
|
|
|
<style scoped lang="scss">
|
|
@@ -129,4 +261,9 @@ function onDelete() {
|
|
|
align-content: space-between;
|
|
|
}
|
|
|
}
|
|
|
-</style>
|
|
|
+
|
|
|
+.generate-project {
|
|
|
+ margin: 43px 0 0 20px;
|
|
|
+ background: green;
|
|
|
+}
|
|
|
+</style>
|