liyongli 1 سال پیش
والد
کامیت
e59d40ff62

+ 16 - 0
src/api/aleditor.js

@@ -87,3 +87,19 @@ export function advertisement(params) {
     method: 'POST',
   });
 }
+
+/**
+ * 文献推荐
+ * @param {object} params 
+ * @returns 
+ */
+export function recommendation(params) {
+    return ajax({
+        api: '/html/literature-recommendation?isSampleDocument=false',
+        data: params.data,
+        noload: params.noload,
+        base: 'xzMao',
+        noJY: true,
+        method: 'POST',
+    })
+}

+ 13 - 7
src/view/allMedia/AIeditor/components/advertisement.vue

@@ -56,19 +56,17 @@
         </div>
       </div>
     </div>
-
-    <template v-if="form.list.length">
+    <template v-if="form.list.length && form.page > 0">
       <el-pagination
         :page-size="form.count"
         layout="prev, pager, next"
-        :total="form.list.length"
+        :total="total()"
         :current-page="form.page"
       />
       <div class="item" v-for="(item, i) in form.list[form.page - 1]" :key="i">
         <div class="content" v-text="item.text"></div>
         <div class="btn_div">
           <el-tooltip
-            class="box-item"
             effect="dark"
             content="左侧导入"
             placement="top"
@@ -88,7 +86,6 @@
         </div>
         <div class="btn_div">
           <el-tooltip
-            class="box-item"
             effect="dark"
             content="复制"
             placement="top"
@@ -125,11 +122,19 @@ const form = ref({
   title: '',
   long: 'short',
   list: [],
-  page: 1,
+  page: 0,
   count: 5,
 });
 const load = ref(false);
 
+const total = () => {
+  let n = 0;
+  for (let i = 0; i < form.value.list.length; i++) {
+    const v = form.value.list[i];
+    n += v.length;
+  }
+  return n;
+};
 const createContent = () => {
   if (!form.value.title) return;
   const p = {
@@ -141,7 +146,7 @@ const createContent = () => {
     query_type: 'slogan',
   };
   load.value = true;
-  form.value.page = 1;
+  form.value.page = 0;
   advertisement({
     data: p,
     noload: true,
@@ -179,6 +184,7 @@ const get = p => {
         });
       }
       form.value.list.push(l);
+      form.value.page++;
     })
     .catch(() => {
       load.value = false;

+ 7 - 1
src/view/allMedia/AIeditor/components/full_text.vue

@@ -170,7 +170,13 @@ const get = p => {
     noload: true,
   })
     .then(res => {
-      if (res.errCode !== 0 && res.data.status === 'RUNNING') return get(p);
+      if (res.errCode !== 0 && res.data.status === 'RUNNING') {
+        let t = setTimeout(() => {
+            clearTimeout(t);
+            get();
+        }, 200);
+        return
+      }
       emits('closeType');
       emits('setHtml', res.data.result.intro);
       load.value = false;

+ 183 - 34
src/view/allMedia/AIeditor/components/inspiration.vue

@@ -15,7 +15,11 @@
               }"
               v-text="status.step < i ? i + 1 : ''"
             ></div>
-            <div class="item-child-label active" style="width: 50px" v-text="item.text"></div>
+            <div
+              class="item-child-label active"
+              style="width: 50px"
+              v-text="item.text"
+            ></div>
           </div>
           <div class="c_right c_right_grey"></div>
         </div>
@@ -32,22 +36,29 @@
       </el-form-item>
       <el-form-item label="文章长度">
         <div style="text-align: right; width: 100%">
-          <el-button plain :class="{ act: form.long === 'small' }">
+          <el-button
+            @click="form.long = 'short'"
+            plain
+            :class="{ act: form.long === 'short' }"
+          >
           </el-button>
-          <el-button plain :class="{ act: form.long === 'middle' }">
+          <el-button
+            @click="form.long = 'default'"
+            plain
+            :class="{ act: form.long === 'default' }"
+          >
           </el-button>
-          <el-button plain :class="{ act: form.long === 'long' }">
+          <el-button
+            @click="form.long = 'long'"
+            plain
+            :class="{ act: form.long === 'long' }"
+          >
           </el-button>
         </div>
       </el-form-item>
-      <el-form-item label="自动配图">
-        <div style="text-align: right; width: 100%">
-          <el-switch v-model="form.isImg" />
-        </div>
-      </el-form-item>
       <el-form-item label="摘要条数">
         <div style="text-align: right; width: 100%">
           <el-input-number v-model="form.num" :min="1" />
@@ -62,9 +73,28 @@
       label-position="top"
     >
       <el-form-item label="您可以选择/编辑摘要:">
-        <el-input v-model="form.title1" type="textarea" :rows="6" />
+        <div
+          style="
+            position: relative;
+            margin-top: 1em;
+            border: 1px solid #fff;
+            border-radius: 4px;
+          "
+          :style="{ borderColor: form.radio === i ? '#3b82f6' : '#fff' }"
+          v-for="(_, i) in form.intro_list"
+          :key="i"
+        >
+          <el-icon
+            class="select"
+            :color="form.radio === i ? '#3b82f6' : '#333'"
+            @click="form.radio = i"
+            ><Check
+          /></el-icon>
+          <el-input v-model="form.intro_list[i]" type="textarea" :rows="6" />
+        </div>
       </el-form-item>
     </el-form>
+
     <el-form
       label-width="100px"
       v-if="status.step === 2"
@@ -75,28 +105,45 @@
         label="您可以选择编辑/增删/重组大纲:"
         style="display: block"
       >
-        <div class="dagang">
+        <div
+          class="dagang"
+          v-for="(item, i) in form.contents_list"
+          :key="'dg' + i"
+        >
           <el-icon :size="20" class="add"><CirclePlus /></el-icon>
           <el-icon :size="20" class="close"><CircleClose /></el-icon>
-          <el-input v-model="form.title2" style="width: 100%" class="no_border" />
-        </div>
-        <div class="dagang">
-          <el-icon :size="20" class="add"><CirclePlus /></el-icon>
-          <el-icon :size="20" class="close"><CircleClose /></el-icon>
-          <el-input v-model="form.title2" style="width: 100%" class="no_border" />
+          <el-input
+            v-model="item.title"
+            style="width: 100%"
+            class="no_border"
+          />
         </div>
       </el-form-item>
     </el-form>
 
+    <div class="step4" v-if="status.step === 3">
+      <b>标题:</b>
+      {{ form.title }}
+      <p
+        style="padding: 5px 10px"
+        v-for="(item, i) in form.contents_list"
+        :key="item + i"
+        v-text="item.title"
+      ></p>
+    </div>
+
     <div class="btn_group">
       <el-button
         type="primary"
         v-if="status.step > 0"
         plain
         @click="status.step--"
-        >上一步</el-button
       >
-      <el-button type="primary" @click="status.step++">下一步</el-button>
+        上一步
+      </el-button>
+      <el-button type="primary" :loading="load" @click="createEdior">
+        下一步
+      </el-button>
       <div class="bottom-content-safe-tip">
         <img :src="image_base64.tanhao" class="content-safe-tip-icon" />
         <div class="content-safe-tip-text">
@@ -108,9 +155,10 @@
 </template>
 
 <script setup>
-import { ref } from 'vue';
+import { ref, defineEmits } from 'vue';
 import { image_base64 } from './data.js';
-// import {commit} from "@/api/aleditor.js";
+import { commit, generate_pc_get } from '@/api/aleditor.js';
+const emits = defineEmits(['closeType', 'setHtml', 'setImage', 'setTitle']);
 const steps = [
   {
     text: '标题',
@@ -126,18 +174,17 @@ const steps = [
   },
 ];
 const form = ref({
-  title1:
-    '《旅游科学》(双月刊)自创刊以来,以服务于各级旅游管理部门、旅游企事业单位、旅游研究者、旅游者为宗旨,坚持以学术为本,为繁荣我国的旅游业,为我国的旅游业走向世界而服务。本刊将以更好的办刊质量和更高的学术水平来回报广大读者,进一步推动我国旅游业的发展。本刊将继续举办"专家笔会"、"学者讲座"和"专题研讨会"等活动,并在此基础上推出系列学术专栏,以推动学术研究和学科建设。',
+  intro_list: [],
+  contents_list: [],
   title: '',
-  title2: '一、问题的提出',
+  title2: '',
   num: 1,
-  isImg: false,
-  long: 'small',
+  long: 'short',
+  radio: 0,
 });
-
+const load = ref(false);
 const status = ref({
   step: 0,
-  progress: 0,
 });
 
 const getBG = i => {
@@ -145,6 +192,89 @@ const getBG = i => {
   if (status.value.step > i) return 'url(' + image_base64.duigou + ')';
   return undefined;
 };
+
+// 第一步
+const createEdior = () => {
+  load.value = true;
+  let generateType = undefined;
+  let query_type = undefined;
+  // 如果是大纲到内容则清空intro_list
+  if (status.value.step === 2) form.value.intro_list = [];
+  if (form.value.intro_list.length) {
+    generateType = 7;
+    query_type = 'title';
+  } else if (!form.value.intro_list.length && form.value.long === 'short') {
+    generateType = 8;
+    query_type = 'all';
+  } else {
+    generateType = 6;
+    query_type = 'intro';
+  }
+  const p = {
+    data: {
+      title: form.value.title,
+      intro: form.value.intro_list.length
+        ? form.value.intro_list[form.value.radio]
+        : undefined,
+    },
+    outLineCnt: status.value.step === 1 ? 5 : undefined,
+    domain: 'paper',
+    generateType,
+    intro_count: form.value.long === 'short' ? undefined : form.value.num,
+    length: form.value.long,
+    query_type,
+  };
+  status.value.step++;
+  commit({
+    data: p,
+    noload: true,
+  })
+    .then(r => {
+      if (!r.data) return;
+      p.req = {
+        doc_id: r.data.doc_id,
+      };
+      get(p);
+    })
+    .catch(() => {
+      load.value = false;
+    });
+};
+
+const get = p => {
+  generate_pc_get({
+    data: p,
+    noload: true,
+  })
+    .then(res => {
+      if (res.errCode !== 0 && res.data.status === 'RUNNING') {
+        let t = setTimeout(() => {
+          clearTimeout(t);
+          get(p);
+        }, 800);
+        return;
+      }
+      load.value = false;
+      if (status.value.step === 1) {
+        const intro = res.data.result.introList.length
+          ? res.data.result.introList
+          : [res.data.result.intro || ''];
+        form.value.intro_list = intro;
+      }
+      if (status.value.step === 2) {
+        console.log(res.data.result.contents);
+        form.value.contents_list = res.data.result.contents || [];
+      }
+      if (status.value.step === 3) {
+        emits('setTitle', res.data.result.title);
+        emits('setHtml', res.data.result.intro);
+        emits('closeType');
+      }
+    })
+    .catch(() => {
+      load.value = false;
+    });
+};
 </script>
 
 <style scoped>
@@ -289,7 +419,7 @@ const getBG = i => {
   top: 5px;
   display: none;
 }
-.no_border .el-input__wrapper{
+.no_border .el-input__wrapper {
   box-shadow: none;
 }
 
@@ -299,17 +429,36 @@ const getBG = i => {
   cursor: pointer;
 }
 
-.dagang:hover .no_border .el-input__wrapper{
-    box-shadow: 0 0 0 1px var(--el-input-border-color, var(--el-border-color))
+.dagang:hover .no_border .el-input__wrapper {
+  box-shadow: 0 0 0 1px var(--el-input-border-color, var(--el-border-color))
     inset;
 }
-
-
-
+.select {
+  position: absolute;
+  right: 5px;
+  top: 50%;
+  transform: translateY(-50%);
+  z-index: 1;
+  cursor: pointer;
+}
+.step4 {
+  padding: 40px;
+  text-align: left;
+  color: #8e8e8e;
+  background-color: #f5f5f5;
+  line-height: 1.1em;
+}
+.step4 * {
+  vertical-align: middle;
+}
 </style>
 
 <style>
 .model-item-container .el-form-item__content {
   display: block;
 }
+
+.model-item-container .el-textarea__inner {
+  padding-top: 1em;
+}
 </style>

+ 139 - 4
src/view/allMedia/AIeditor/components/literature.vue

@@ -18,19 +18,119 @@
     </el-form>
 
     <div class="btn_group">
-      <el-button type="primary" style="width: 100%" :disabled="form.title"
-        >检索</el-button
+      <el-button
+        type="primary"
+        style="width: 100%"
+        :disabled="!form.title"
+        @click="getRec"
+        :loading="load"
       >
+        检索
+      </el-button>
     </div>
+
+    <div style="text-align: left" v-if="form.list.length">
+      <div style="padding: 5px">
+        <el-checkbox @change="e => chagne(e)" label="全选" size="large" />
+        <el-button
+          type="primary"
+          text
+          bg
+          style="float: right"
+          @click="exportsText"
+          >全部导出</el-button
+        >
+      </div>
+      <div class="item" v-for="(item, i) in form.list" :key="i">
+        <div class="son sonLeft">
+          <el-checkbox v-model="select[i]" size="large" />
+        </div>
+        <div class="son">
+          <div class="title" v-text="item.title"></div>
+          <div class="author" v-text="author(item.authors)"></div>
+          <div class="author">
+            <span v-text="item.publication" style="padding-right: 16px"></span>
+            <span v-text="item.publish_date" style="padding-right: 16px"></span>
+            <el-button
+              @click="
+                yinyongShow = true;
+                yinyong = item.cite;
+              "
+              type="primary"
+              link
+            >
+              引用
+            </el-button>
+            <el-button
+              text
+              bg
+              type="primary"
+              plain
+              @click="() => see(item.url)"
+            >
+              查看
+            </el-button>
+          </div>
+        </div>
+      </div>
+    </div>
+
+    <el-dialog v-model="yinyongShow" title="引用">
+      <div v-html="yinyong" style="text-align: left"></div>
+    </el-dialog>
   </div>
 </template>
 
 <script setup>
-import { ref } from 'vue';
-// import {commit} from "@/api/aleditor.js";
+import { ref, defineEmits } from 'vue';
+import { recommendation } from '@/api/aleditor.js';
+const emits = defineEmits(['closeType', 'setHtml', 'setImage', 'setTitle']);
 const form = ref({
   title: '',
+  list: [],
 });
+
+const yinyong = ref('');
+const yinyongShow = ref(false);
+const load = ref(false);
+
+const select = ref([]);
+
+const chagne = e => {
+  for (let i = 0; i < form.value.list.length; i++) {
+    select.value[i] = e;
+  }
+};
+
+const see = url => {
+  window.open(url);
+};
+
+const author = list => {
+  return list.join(',');
+};
+
+const getRec = () => {
+  load.value = true;
+  recommendation({
+    data: {
+      text: form.value.title,
+    },
+    noload: true,
+  }).then(r => {
+    load.value = false;
+    if (r.errCode !== 0) return;
+    form.value.list = r.data || [];
+  }).catch(() => {
+    load.value = false;
+  });
+};
+
+const exportsText = () => {
+  for (let i = 0; i < form.value.list.length; i++) {
+    select.value[i] && emits('setHtml', form.value.list[i].cite);
+  }
+};
 </script>
 
 <style scoped>
@@ -61,4 +161,39 @@ const form = ref({
 .btn_group {
   padding-right: 1em;
 }
+
+.item {
+  border-top: 1px solid #dcdfe6;
+  margin-top: 24px;
+  padding-top: 24px;
+}
+
+.son {
+  width: calc(100% - 20px);
+  display: inline-block;
+}
+.sonLeft {
+  width: 20px;
+}
+
+.son .title {
+  font-weight: 700;
+  font-size: 14px;
+  line-height: 22px;
+  color: #4b4b4b;
+  white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
+}
+
+.son .author {
+  font-weight: 400;
+  font-size: 10px;
+  line-height: 18px;
+  color: #8e8e8e;
+  margin-top: 2px;
+  white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
+}
 </style>

+ 162 - 11
src/view/allMedia/AIeditor/components/little_red_book.vue

@@ -3,10 +3,16 @@
     <br />
     <el-form label-width="100px" :model="form" label-position="left">
       <el-form-item label="产品名称">
-        <el-input v-model="form.title" :maxlength="100" show-word-limit />
+        <el-input v-model="form.name" :maxlength="100" show-word-limit />
       </el-form-item>
       <el-form-item label="产品描述">
-        <el-input v-model="form.desc" type="textarea" :rows="5" :maxlength="1000" show-word-limit />
+        <el-input
+          v-model="form.desc"
+          type="textarea"
+          :rows="5"
+          :maxlength="1000"
+          show-word-limit
+        />
       </el-form-item>
       <el-form-item label="自动生成标题">
         <div style="text-align: right; width: 100%">
@@ -23,15 +29,27 @@
           </el-select>
         </div>
       </el-form-item>
-      <el-form-item label="文长度">
+      <el-form-item label="文长度">
         <div style="text-align: right; width: 100%">
-          <el-button plain :class="{ act: form.long === 'small' }">
+          <el-button
+            @click="form.long = 'short'"
+            plain
+            :class="{ act: form.long === 'short' }"
+          >
           </el-button>
-          <el-button plain :class="{ act: form.long === 'middle' }">
+          <el-button
+            @click="form.long = 'default'"
+            plain
+            :class="{ act: form.long === 'default' }"
+          >
           </el-button>
-          <el-button plain :class="{ act: form.long === 'long' }">
+          <el-button
+            @click="form.long = 'long'"
+            plain
+            :class="{ act: form.long === 'long' }"
+          >
           </el-button>
         </div>
@@ -44,7 +62,13 @@
     </el-form>
 
     <div class="btn_group">
-      <el-button type="primary" style="width: 100%;">生成内容</el-button>
+      <el-button
+        type="primary"
+        style="width: 100%"
+        @click="create"
+        :loading="load"
+        >生成内容</el-button
+      >
       <div class="bottom-content-safe-tip">
         <img :src="image_base64.tanhao" class="content-safe-tip-icon" />
         <div class="content-safe-tip-text">
@@ -52,22 +76,112 @@
         </div>
       </div>
     </div>
+
+    <template v-if="form.list.length">
+      <div class="item" v-for="(item, i) in form.list" :key="i">
+        <div class="content" v-text="item.text"></div>
+        <div class="btn_div">
+          <el-tooltip effect="dark" content="左侧导入" placement="top">
+            <el-icon
+              @click="() => inputText(item.text)"
+              style="
+                left: 50;
+                top: 50%;
+                transform: translate(-50%, -50%);
+                cursor: pointer;
+              "
+              color="#cacaca"
+              ><DArrowLeft
+            /></el-icon>
+          </el-tooltip>
+        </div>
+        <div class="btn_div">
+          <el-tooltip effect="dark" content="复制" placement="top">
+            <el-icon
+              style="
+                left: 50;
+                top: 50%;
+                transform: translate(-50%, -50%);
+                cursor: pointer;
+              "
+              color="#cacaca"
+              ><CopyDocument
+            /></el-icon>
+          </el-tooltip>
+        </div>
+      </div>
+    </template>
   </div>
 </template>
 
 <script setup>
-import { ref } from 'vue';
+import { ref, defineEmits } from 'vue';
 import { image_base64 } from './data.js';
-// import {commit} from "@/api/aleditor.js";
+import { advertisement, generate_pc_get } from '@/api/aleditor.js';
+const emits = defineEmits(['closeType', 'setHtml', 'getImage']);
+const load = ref(false);
 const form = ref({
-  title: '',
+  name: '',
   isTitle: false,
   isTalk: false,
-  long: 'small',
+  long: 'short',
   desc: '',
   region: '默认',
+  list: [],
 });
 
+const inputText = text => {
+  emits('setHtml', text);
+};
+
+const create = () => {
+  load.value = true;
+  const p = {
+    count: 5,
+    data: { title: form.value.name, prev: form.value.desc },
+    generateType: 4,
+    length: form.value.long,
+    noblock: true,
+    query_type: 'zhongcao_title',
+  };
+  advertisement({
+    data: p,
+    noload: true,
+  }).then(r => {
+    if (r.errCode !== 0) return (load.value = false);
+    p.req = { doc_id: r.data.doc_id };
+    get(p);
+  });
+};
+
+const get = p => {
+  generate_pc_get({
+    data: p,
+    noload: true,
+  })
+    .then(res => {
+      load.value = false;
+      if (res.errCode !== 0 && res.data.status === 'RUNNING') {
+        let t = setTimeout(() => {
+          get(p);
+          clearTimeout(t);
+        }, 200);
+        return;
+      }
+      const list = res.data.result.content;
+      const l = [];
+      for (let i = 0; i < list.length; i++) {
+        const v = list[i];
+        l.push({
+          text: v,
+        });
+      }
+      form.value.list.push(...l);
+    })
+    .catch(() => {
+      load.value = false;
+    });
+};
 </script>
 
 <style scoped>
@@ -129,4 +243,41 @@ const form = ref({
   line-height: 15px;
   color: #cacaca;
 }
+.item {
+  width: 100%;
+  min-height: 45px;
+  -webkit-box-sizing: border-box;
+  box-sizing: border-box;
+  margin-bottom: 20px;
+  text-align: left;
+  position: relative;
+  padding: 10px 10px 10px 0;
+  display: flex;
+  -webkit-box-align: center;
+  -ms-flex-align: center;
+  align-items: center;
+  border-bottom: 1px solid #eee;
+}
+
+.content {
+  -webkit-box-flex: 1;
+  -ms-flex: 1;
+  flex: 1;
+  outline: none;
+  line-height: 28px;
+  text-align: justify;
+  overflow-y: auto;
+}
+
+.hover_class,
+.item:hover {
+  background-color: #f5f5f5;
+  border-bottom: 1px solid #f8f8f8;
+}
+
+.btn_div {
+  height: 30px;
+  width: 30px;
+  position: relative;
+}
 </style>

+ 16 - 3
src/view/allMedia/AIeditor/index.vue

@@ -9,9 +9,12 @@
     <div class="main">
       <div class="bgeditor">
         <div class="editor">
-          <h1 contenteditable style="padding: 100px 100px 0; outline: none">
-            无标题
-          </h1>
+          <h1
+            v-html="title"
+            @input="e => seaveTitle(e)"
+            contenteditable
+            style="padding: 100px 100px 0; outline: none"
+          ></h1>
           <Editor
             :defaultConfig="editorConfig"
             style="padding: 0 90px; height: calc(100% - 150px)"
@@ -170,6 +173,7 @@
             <component
               @closeType="closeType"
               @setHtml="setHtml"
+              @setTitle="setTitle"
               @setImage="setImage"
               :is="component_2_list[select_right_2_btn_type]"
             ></component>
@@ -211,6 +215,8 @@ import composition from './components/composition.vue';
 // 右侧头部数据
 const right_head = ref({});
 
+const title = ref('无标题');
+
 const componment_list = [pen_ink, review, image, dictionary, comment];
 // index对应ai里的功能
 const component_2_list = [
@@ -325,6 +331,10 @@ const editorConfig = {
   },
 };
 
+const seaveTitle = e => {
+  title.value = e.target.innerHTML;
+};
+
 // 组件销毁时,也及时销毁编辑器
 onBeforeUnmount(() => {
   if (editorRef.value != null) editorRef.value.destroy();
@@ -385,6 +395,9 @@ const setHtml = html => {
 const setImage = imgs => {
   console.log(imgs);
 };
+const setTitle = text => {
+  title.value = text;
+};
 </script>
 
 <style scoped>