CzRger преди 1 седмица
родител
ревизия
72cf284a48

+ 1 - 1
src/types/chat.ts

@@ -16,5 +16,5 @@ export type AnswerStruct = {
   taskId?: string //  回答的任务ID,停止回答使用
   ask?: string //  回答的问题
   mock?: boolean //  是否为自己模拟的回答,不需要回答后的额外功能
-  com?: any //  自定义组件
+  teleport?: any //  自定义组件的ID,通過<teleport/>传送,降低耦合度
 }

+ 20 - 0
src/views/business/doing-with-chat/chat/form-list.vue

@@ -0,0 +1,20 @@
+<template>
+  <div>
+    <template v-for="item in data">
+      <div class="flex items-center" @click="$emit('ddd')">
+        <SvgIcon name="document" :active="true" />{{ item }}
+      </div>
+    </template>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { reactive } from 'vue'
+
+const props = defineProps({
+  data: { default: () => [] },
+})
+const state: any = reactive({})
+</script>
+
+<style lang="scss" scoped></style>

+ 68 - 20
src/views/business/doing-with-chat/index.vue

@@ -22,16 +22,18 @@
             <div
               class="flex items-center text-base"
               :class="`${
-                state.step.index >= index
-                  ? 'font-bold text-[#2E3238]'
-                  : 'text-[#A7ADB9]'
-              } ${item.finish ? '__hover' : 'cursor-no-drop'}`"
-              @click="item.finish ? (state.step.index = index) : undefined"
+                item.finish ? 'font-bold text-[#2E3238]' : 'text-[#A7ADB9]'
+              } ${item.finish || state.step.index <= index ? '__hover' : 'cursor-no-drop'}`"
+              @click="
+                item.finish || state.step.index <= index
+                  ? (state.step.index = index)
+                  : undefined
+              "
             >
               <div
                 class="mr-2.5 flex size-8 items-center justify-center rounded-full border-1 border-[#A7ADB9]"
                 :class="
-                  state.step.index >= index
+                  item.finish
                     ? 'border-[var(--czr-main-color)] bg-[var(--czr-main-color)] text-[#ffffff]'
                     : 'border-[#A7ADB9]'
                 "
@@ -105,19 +107,23 @@
       </div>
     </div>
   </div>
-  <!--  <div class="flex size-full flex-col">-->
-  <!--    <div>-->
-  <!--      <el-button @click="getAnswer">获取答案</el-button>-->
-  <!--      <template v-for="item in state.answers">-->
-  <!--        <div>{{ item }}</div>-->
-  <!--      </template>-->
-  <!--    </div>-->
-  <!--    <div class="flex-1 overflow-y-auto">-->
-  <!--  </div>-->
+  <!--  <template v-for="item in state.components">-->
+  <!--    <teleport :to="'#' + item.id">-->
+  <!--      <component :is="item.is" v-bind="item.props" />-->
+  <!--    </teleport>-->
+  <!--  </template>-->
 </template>
 
 <script setup lang="ts">
-import { nextTick, onMounted, provide, reactive, ref } from 'vue'
+import {
+  defineAsyncComponent,
+  markRaw,
+  nextTick,
+  onMounted,
+  provide,
+  reactive,
+  ref,
+} from 'vue'
 import { mockQuestion, sxOnethingInfo } from './mock'
 import treeNode from './tree-node.vue'
 import toBackCom from '@/views/manage/components/to-back.vue'
@@ -125,6 +131,7 @@ import { useRoute, useRouter } from 'vue-router'
 import { appDetail } from '@/api/modules/app'
 import chat from '@/views/chat/index.vue'
 import { isValue } from '@/utils/czr-util'
+import { v4 } from 'uuid'
 
 const route = useRoute()
 const router = useRouter()
@@ -134,7 +141,7 @@ const state: any = reactive({
   answers: [],
   step: {
     options: [
-      { label: '用户须知', finish: false, time: 3 },
+      { label: '用户须知', finish: false, time: 0 },
       {
         label: '情形选择',
         finish: false,
@@ -146,8 +153,9 @@ const state: any = reactive({
       { label: '材料上传', finish: false },
       { label: '结果领取', finish: false },
     ],
-    index: 1,
+    index: 0,
   },
+  // components: [],
 })
 const ref_chat = ref()
 const ref_treeNode = ref()
@@ -156,7 +164,6 @@ const getAnswer = () => {
   state.step.options[state.step.index].complete = state.step.options[
     state.step.index
   ].answers.every((a) => a.every((b) => isValue(b)))
-  console.log(state.step.options[state.step.index].answers)
 }
 const onStep = (index) => {
   const current = state.step.options[index - 1]
@@ -167,12 +174,53 @@ const onStep = (index) => {
           current.finish = true
           ref_chat.value.mockAnswer({
             text: '欢迎进入事项网办阶段!请选择情形',
-            com: true,
           })
         }
         state.step.index = index
       }
       break
+    case 2:
+      {
+        if (current.complete) {
+          if (!current.finish) {
+            current.finish = true
+            const id = v4()
+            const ddd = () => {
+              console.log(123123)
+            }
+            ref_chat.value.mockAnswer({
+              text: '欢迎进入表单填写阶段!为了让您的体验更加顺畅,我已经贴心地为您预先填写了部分内容。接下来,请在左侧补充剩余的信息,感谢您的配合!',
+              teleport: id,
+              com: {
+                is: defineAsyncComponent(
+                  () =>
+                    import(
+                      '@/views/business/doing-with-chat/chat/form-list.vue'
+                    ),
+                ),
+                binds: {
+                  data: ['asdasd', 'zxvzxvzxv'],
+                  ddd,
+                },
+              },
+            })
+            // state.components.push({
+            //   id,
+            //   is: defineAsyncComponent(
+            //     () =>
+            //       import(
+            //         '@/views/business/doing-with-chat/chat/form-list.vue'
+            //         ),
+            //   ),
+            //   props: {
+            //     data: ['asdasda', 'faszxcszczxc'],
+            //   },
+            // })
+          }
+          state.step.index = index
+        }
+      }
+      break
   }
 }
 onMounted(() => {

Файловите разлики са ограничени, защото са твърде много
+ 6884 - 6884
src/views/business/doing-with-chat/mock.ts


+ 18 - 7
src/views/business/doing-with-chat/tree-node.vue

@@ -1,31 +1,42 @@
 <template>
   <div :style="{ marginLeft: level * 20 + 'px' }">
     <template v-for="(question, questionIndex) in data">
-      <div>{{ questionIndex + 1 }}、{{ question.conditionname }}</div>
+      <div class="my-2 text-sm font-bold text-[#2E3238]">
+        {{ questionIndex + 1 }}、{{ question.conditionname }}
+      </div>
       <template v-if="question.optiontype === 'single'">
         <template v-for="(answer, answerIndex) in question.children">
           <div
-            class="__hover flex w-fit items-center px-2"
+            class="__hover flex w-fit items-center px-2 text-sm text-[#576275]"
             @click="
               ((question.__answer = answer.id),
               $nextTick(() => $emit('onChange')))
             "
           >
             <div
-              class="my-2 mr-2 size-5 rounded-full border"
+              class="my-2 mr-1 flex size-3 items-center justify-center rounded-full border"
               :class="
                 answer.id === question.__answer
-                  ? 'bg-[var(--czr-main-color)]'
+                  ? 'border-[var(--czr-main-color)]'
                   : ''
               "
-            />
+            >
+              <div
+                class="size-2 rounded-full"
+                :class="
+                  answer.id === question.__answer
+                    ? 'bg-[var(--czr-main-color)]'
+                    : ''
+                "
+              />
+            </div>
             {{ answer.conditionname }}
             <template v-if="answer.conditiondesc">
               <el-tooltip :content="answer.conditiondesc" placement="top">
                 <SvgIcon
-                  class="__hover"
+                  class="__hover ml-2"
                   name="czr_tip"
-                  size="20"
+                  size="16"
                   :active="true"
                 />
               </el-tooltip>

+ 4 - 2
src/views/chat/answer/index.vue

@@ -66,7 +66,7 @@
         </div>
         <div
           class="mt-2 flex items-center gap-2.5 px-2.5 text-[0.63rem] text-[#909399]"
-          v-if="item.finished && !item.com"
+          v-if="item.finished && !item.mock"
         >
           <div v-if="item.time">{{ formatTimeDuration(item.time) }}</div>
           <div v-if="item.tokens">{{ item.tokens }} Tokens</div>
@@ -138,7 +138,9 @@
             />
           </el-tooltip>
         </div>
-        <template v-if="item.com"></template>
+        <!--        <template v-if="item.com">-->
+        <!--          <component :is="item.com.is" />-->
+        <!--        </template>-->
         <template v-if="item.adviseLoading">
           <div class="mt-2 ml-2.5 text-sm text-[var(--czr-main-color)]">
             问题建议生成中……

+ 4 - 3
src/views/chat/normal.vue

@@ -322,15 +322,16 @@ const mockAnswer = (answer) => {
     type: 'answer',
     loading: false,
     finished: true,
+    mock: true,
   })
 }
 onMounted(() => {
   initTextHandle()
 })
 defineExpose({
-  init: () => initChat(),
-  history: (conversationId) => initHistory(conversationId),
-  mockAnswer: (answer) => mockAnswer(answer),
+  init: initChat,
+  history: initHistory,
+  mockAnswer,
 })
 </script>