Browse Source

集成费用审查智能体

han_v3
han2015 3 months ago
parent
commit
a4752d24a2
  1. 3
      src/api/DesignForm/fieldUnit.ts
  2. 22
      src/api/DesignForm/filterUnit.ts
  3. 17
      src/api/doc/space.ts
  4. 3
      src/components/DesignForm/public/expand/digitpage.vue
  5. 52
      src/components/DesignForm/public/form/aiassist.vue
  6. 34
      src/components/DesignForm/public/form/form.vue
  7. 44
      src/components/DesignForm/public/form/formItem.vue

3
src/api/DesignForm/fieldUnit.ts

@ -5,4 +5,5 @@ export const choiceUnit = ["radio"]
export const switchUnit = ["switch"]
export const checkboxUnit = ["checkbox"]
export const orgDeptUnit = ["deptOrg"]
export const layoutUnit = ["grid","card","flex","div","tabs","divider","title","button","lowcodeImage","videoUpAndPlay","table","baidumap","lowcodeCarsusel","signaturemap","component"]
//edit by han2015: layoutUnit删掉了table字段,因为ai触发条件要支持子表字段
export const layoutUnit = ["grid","card","flex","div","tabs","divider","title","button","lowcodeImage","videoUpAndPlay","baidumap","lowcodeCarsusel","signaturemap","component"]

22
src/api/DesignForm/filterUnit.ts

@ -13,7 +13,27 @@ const analysisFromUnit = (unitInfo:formStruct) => {
// console.log("解析出表单可作为AI变量的元素------1---1--->",item.label?1:2)
if(!layoutUnit.includes(item.type)){
//by han2015: 暂时只支持普通类型字段
if (item.type!='input' && item.type!='digitpage') return;
//if (item.type!='input' && item.type!='digitpage') return;
//显示子表单字段
if(item.type=="table"){
item.list.forEach(eles => {
let labelName = ""
if(eles.label){
labelName = eles.label
}else if(eles.item && eles.item.label){
labelName = eles.item.label
}else{
labelName = eles.unitName
}
optionsInfo.push({
label:labelName,
value:eles.name
})
});
return;//退出该字段
}
let labelName = ""
if(item.label){
labelName = item.label

17
src/api/doc/space.ts

@ -106,7 +106,7 @@ export function doAiTraining(_url:string,data?: any){
export interface aiChatData{
inputs:object;
query:string;
query?:string;
response_mode:string;
conversation_id?:string;
user:string,
@ -129,6 +129,21 @@ export function doAiChat(_url:string,data: aiChatData,sig?:AbortSignal){
}
)
}
/**
*
*/
export function doAiWorkflow(_url:string,data: aiChatData){
return fetch(
_url,{
method: 'post',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
}
)
}
/**
* userid获取记录列表
* @requires userid

3
src/components/DesignForm/public/expand/digitpage.vue

@ -23,6 +23,7 @@ const props = withDefaults(
data?: Object;
modelValue?: string;
disabled?: boolean;
rowIndex:number;
}>(),
{}
);
@ -46,7 +47,7 @@ const config = computed(() => {
const changeEvent = inject(constAiEffect, '') as any
function onValueChange(){
changeEvent &&
changeEvent({key:props.data.name,value:props.modelValue, field:props.data.item.label})
changeEvent({key:props.data.name,value:props.modelValue, field:props.data.item.label,rowdex:props.rowIndex})
}
//--------------------------------------
/**

52
src/components/DesignForm/public/form/aiassist.vue

@ -6,24 +6,17 @@
<script lang="ts" setup>
import { doAiChat,aiChatData} from "@/api/doc/space"
import {ElText,ElInput, ButtonInstance} from "element-plus";
import { VueMarkdown } from '@crazydos/vue-markdown'
import rehypeRaw from 'rehype-raw'
import remarkGfm from 'remark-gfm'
import { useUserStore } from "@/store/modules/user";
//
const checkedModel = ref([])
const userStore = useUserStore();
const userid="p0"+userStore.userInfoCont.userId;
const baseURL=import.meta.env.VITE_APP_BASE_API
const conversation=ref("") //uuid
const myquestion=ref('')
const controller = ref<AbortController | null>(null)
const interact_msg=ref<{ask:boolean,think:string,content:string}[]>([])
const props = withDefaults(defineProps<{
//closefunc:()=>void,
//agent:{model:boolean,name:string,uuid:string[]}
}>(),{})
//
@ -40,22 +33,15 @@ interface chatRecord{
messages:message[]
}
/* 中断函数,供按钮调用 */
function abortFetch() {
if (controller.value) {
controller.value.abort()
controller.value = null
}
}
defineExpose({onSendParamToAI})
async function onSendParamToAI(user:string,arr:Array<{ uuids: string[]; params: { [key: string]: any } }>){
async function onSendParamToAI(arr:Array<{ uuids: string[]; params: { [key: string]: any } }>){
interact_msg.value=[]
for (let ele of arr){
interact_msg.value.unshift({ask:true,think:"", content:"AI正在分析。。。"})
for (let uid of ele.uuids){
await doRequest(user,uid,ele.params)
await doRequest(userid,uid,ele.params)
}
}
}
@ -63,21 +49,15 @@ async function onSendParamToAI(user:string,arr:Array<{ uuids: string[]; params:
async function doRequest(_user:string,uuid:string,param:any){
let mRespMsg=""
const params={
"onlineSearch":"否",
"useDataset":"否"
}
for (let item of checkedModel.value){
if(item==="onlineSearch") params.onlineSearch="是"
if(item==="useDataset") params.useDataset="是"
"checkType":"travel",
"checkInfo":JSON.stringify(param)
}
controller.value = new AbortController();
try{
const res= await doAiChat(`${baseURL}/aibot/assisted/${uuid}/chat`,{
const res= await doAiChat(`${baseURL}/aibot/assisted/${uuid}/workflow`,{
inputs: params,
query:JSON.stringify(param),
response_mode:"streaming",
conversation_id:"",//conversation.value,
user:_user,//base64
},controller.value.signal
)
@ -103,9 +83,9 @@ async function doRequest(_user:string,uuid:string,param:any){
if (line.startsWith('data: ')) {
const data = line.slice(6);
const json = JSON.parse(data);
if(json.event==="message"){
if(json.event==="text_chunk"){
//conversation.value=json.conversation_id
mRespMsg+=json.answer
mRespMsg+=json.data.text
}
}
}
@ -122,9 +102,15 @@ async function doRequest(_user:string,uuid:string,param:any){
interact_msg.value.unshift({ask:false,think:"",content:arr[0]})
}else{
//
let st = arr[1].trim().match(/({.*})/s)
if (st){
let res= JSON.parse(st[1])
interact_msg.value.unshift({ask:false,think:res.success,content:res.reason})
}else{
interact_msg.value.unshift({ask:false,think:arr[0],content:arr[1]})
}
}
}
function resetContext(){
interact_msg.value=[]
@ -142,7 +128,7 @@ function resetContext(){
<div class="reply_area" >
<template v-for="msg of interact_msg">
<div v-if="msg.ask" class="t_ask" >{{ msg.content }}</div>
<div v-else class="t_resp">
<div v-else class="t_resp" :class="{merr:msg.think==false}">
{{ msg.content }}
<!-- <VueMarkdown :markdown="msg.content"></VueMarkdown> -->
</div>
@ -170,8 +156,12 @@ function resetContext(){
}
.t_resp{
margin: 5px;
font-size:14px;
align-self: start;
color: black;
background-color: rgb(222, 243, 222);
}
.merr{
background-color: rgb(253 176 211);
}
</style>

34
src/components/DesignForm/public/form/form.vue

@ -160,7 +160,7 @@ const model = ref<any>({});
const getInitModel = () => {
if(props.formData.aiConfig?.length>0){
props.formData.aiConfig?.forEach(item=>{
currentAgent.value.push({name:"test",model:false,uuid:item.library,fields:item.title,trigger:item.trigger,params:{}})
currentAgent.value.push({name:"test",model:false,rowdex:0,uuid:item.library,fields:item.title,trigger:item.trigger,params:{},subparams:[]})
})
}
@ -495,33 +495,49 @@ watch(
//-----------------------AI setting--------------------------
//AIform
const currentAgent=ref<{model:boolean,name:string,uuid:string[],fields:string[],trigger:number,params:{[key: string]: any}}[]>([])
//params subparams ; rowdex:
const currentAgent=ref<{model:boolean,name:string,uuid:string[],rowdex:number,fields:string[],trigger:number,params:{[key: string]: any},subparams:{[key: string]: any}[]}[]>([])
const aiassistRef=ref()
//AI
provide(constAiEffect, ({ key, value, field}: any) => {
provide(constAiEffect, ({ key, value, field,rowdex}: any) => {
//ai_envents
const ai_events: Array<{ uuids: string[]; params: { [key: string]: any } }> = [];
currentAgent.value.forEach(ag=>{
if(ag.fields.includes(key)){ //trigger: 1: 2 3
if (rowdex!=null){//
ag.rowdex=rowdex //rowdex
if(rowdex>=ag.subparams.length){
ag.subparams.push({[field]:value})
}else{
ag.subparams[rowdex][field]=value
}
}else{ //, params
ag.params[field]=value; //keyfieldName
}
let mergedObj;
if(ag.subparams.length>0){
mergedObj = Object.assign({}, ag.params, ag.subparams[ag.rowdex]); //
}else{
mergedObj = ag.params
}
switch(ag.trigger){
case 2:
if(Object.keys(ag.params).length>=ag.fields.length/2){
ai_events.push({uuids:ag.uuid,params:ag.params})
if(Object.keys(mergedObj).length>=ag.fields.length/2){
ai_events.push({uuids:ag.uuid,params:mergedObj })
}
break;
case 3:
if(Object.keys(ag.params).length==ag.fields.length){
ai_events.push({uuids:ag.uuid,params:ag.params})
if(Object.keys(mergedObj).length==ag.fields.length){
ai_events.push({uuids:ag.uuid,params:mergedObj})
}
break;
default:
ai_events.push({uuids:ag.uuid,params:ag.params})
ai_events.push({uuids:ag.uuid,params:mergedObj})
}
}
})
if(ai_events.length>0){
aiassistRef.value.onSendParamToAI(props.formData.form.formName,ai_events)
aiassistRef.value.onSendParamToAI(ai_events)
}
})
//------------------------------------------------------------

44
src/components/DesignForm/public/form/formItem.vue

@ -127,10 +127,19 @@ const updateModel = (val: any) => {
//changeEventchangeEventfieldChange
const fieldChangeEnt = inject(constAiEffect, '') as any
function onValueChange(_type:string){
if(_type=="password") return;
if(["password","description"].includes(_type)) return;
fieldChangeEnt &&
fieldChangeEnt({key:props.data.name,value:props.modelValue, field:props.data.item.label})
fieldChangeEnt({key:props.data.name,value:value.value, field:props.data.item.label,rowdex:props.rowIndex})
}
//select
function onSekectValueChange(news:number){
if(props.data.options){
fieldChangeEnt &&
fieldChangeEnt({key:props.data.name,value:props.data.options[news-1].label, field:props.data.item.label,rowdex:props.rowIndex})
}
}
//--------------------------------------
const value = computed({
@ -1236,7 +1245,7 @@ const diGuiJilian = (val: any, options: any[]) => {
:placeholder="
data.control.placeholder
? data.control.placeholder
: '请输入>>>' + getLabel(data.item)
: '请输入' + getLabel(data.item)
"
>
<template #prepend v-if="config.prepend">
@ -1277,6 +1286,7 @@ const diGuiJilian = (val: any, options: any[]) => {
"
:style="getFormItemInputStyle(configStyle, 2)"
:input-style="getFormItemInputStyle(configStyle, 3)"
@change="onValueChange(data.type)"
v-if="['textarea', 'description'].includes(data.type)"
/>
<el-radio-group
@ -1284,6 +1294,7 @@ const diGuiJilian = (val: any, options: any[]) => {
:disabled="judgeIsDisabled(data.name)"
v-model="value"
v-if="data.type === 'radio'"
@change="onValueChange(data.type)"
:style="getFormItemInputStyle(configStyle, 4)"
>
<el-radio
@ -1299,6 +1310,7 @@ const diGuiJilian = (val: any, options: any[]) => {
:disabled="judgeIsDisabled(data.name)"
v-model="value"
v-if="data.type === 'checkbox'"
@change="onValueChange(data.type)"
:style="getFormItemInputStyle(configStyle, 4)"
>
<el-checkbox
@ -1317,6 +1329,7 @@ const diGuiJilian = (val: any, options: any[]) => {
:options="props.data.options"
:remote-method="getAxiosOptions"
:transformOption="transformOption"
@update:model-value="(news)=>onSekectValueChange(news)"
:placeholder="
data.control.placeholder
? data.control.placeholder
@ -1392,14 +1405,32 @@ const diGuiJilian = (val: any, options: any[]) => {
"
v-model="value"
/>
<component
v-if="
[
'rate',
'slider',
'switch',
'inputNumber',
].includes(data.type)
"
:is="currentComponent"
v-bind="control"
:disabled="judgeIsDisabled(data.name)"
:placeholder="
data.control.placeholder
? data.control.placeholder
: '请选择' + getLabel(data.item)
"
:data="data"
:type="type"
:rowIndex="rowIndex"
@change="onValueChange(data.type)"
v-model="value"
/>
<component
v-if="
[
'rate',
'slider',
'colorPicker',
'component',
'expand-user',
@ -1419,6 +1450,7 @@ const diGuiJilian = (val: any, options: any[]) => {
"
:data="data"
:type="type"
:rowIndex="rowIndex"
v-model="value"
/>
<component

Loading…
Cancel
Save