咨询助理功能开发
This commit is contained in:
parent
715b8abc5b
commit
ea9535be7b
30
pages.json
30
pages.json
@ -136,8 +136,8 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"root": "pages/rate",
|
"root": "pages/rate",
|
||||||
"name": "rate",
|
"name": "rate",
|
||||||
"pages": [
|
"pages": [
|
||||||
{
|
{
|
||||||
@ -154,10 +154,28 @@
|
|||||||
"disableScroll": true
|
"disableScroll": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"root": "pages/archive",
|
"root": "pages/ai-consult",
|
||||||
|
"name": "ai-consult",
|
||||||
|
"pages": [
|
||||||
|
{
|
||||||
|
"path": "list",
|
||||||
|
"style": { "navigationBarTitleText": "AI咨询记录", "disableScroll": true }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "chat",
|
||||||
|
"style": { "navigationBarTitleText": "AI咨询助理", "disableScroll": true }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "entry",
|
||||||
|
"style": { "navigationBarTitleText": "AI咨询助理", "disableScroll": true }
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"root": "pages/archive",
|
||||||
"name": "archive",
|
"name": "archive",
|
||||||
"pages": [
|
"pages": [
|
||||||
{
|
{
|
||||||
|
|||||||
158
pages/ai-consult/chat.vue
Normal file
158
pages/ai-consult/chat.vue
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
<template>
|
||||||
|
<view class="chat-page">
|
||||||
|
<scroll-view scroll-y class="chat-content" :scroll-into-view="bottomId">
|
||||||
|
<view class="message-list">
|
||||||
|
<view v-for="(item, index) in messages" :key="item._id" :id="`message-${item._id}`" class="message-item" :class="`message-${item.sender}`">
|
||||||
|
<view v-if="shouldShowTime(item, index)" class="time-divider">{{ formatMessageTime(item.createTime) }}</view>
|
||||||
|
<view v-if="item.sender === 'system'" class="system-message" :class="{ warn: item.messageType === 'sensitive_notice' }">{{ displayContent(item) }}</view>
|
||||||
|
<evaluation-card v-if="item.messageType === 'consult_ended' && (item.rateId || session?.rateId)" class="rate-card" :extension="{ rateId: item.rateId || session.rateId }" :doctor-info="rateAssistantInfo" />
|
||||||
|
<view v-else class="message-content">
|
||||||
|
<view v-if="item.sender === 'assistant'" class="avatar assistant-avatar">AI</view>
|
||||||
|
<view class="message-bubble-container">
|
||||||
|
<view v-if="item.sender === 'assistant'" class="username-label">{{ session?.assistantName || 'AI咨询助理' }}</view>
|
||||||
|
<view class="message-bubble" :class="{ pending: item._sendStatus === 'pending' }">
|
||||||
|
<text class="message-text">{{ displayContent(item) }}</text>
|
||||||
|
</view>
|
||||||
|
<text v-if="item._sendStatus === 'failed'" class="send-status">发送失败,请重试</text>
|
||||||
|
</view>
|
||||||
|
<view v-if="item.sender === 'patient'" class="avatar patient-avatar">我</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view v-if="waitingAi" class="message-item message-assistant">
|
||||||
|
<view class="message-content"><view class="avatar assistant-avatar">AI</view><view class="message-bubble-container"><view class="username-label">{{ session?.assistantName || 'AI咨询助理' }}</view><view class="message-bubble thinking"><view class="thinking-dot"></view><view class="thinking-dot"></view><view class="thinking-dot"></view></view></view></view>
|
||||||
|
</view>
|
||||||
|
<view id="bottom" />
|
||||||
|
</view>
|
||||||
|
</scroll-view>
|
||||||
|
<view v-if="active" class="input-section">
|
||||||
|
<textarea v-model="content" class="text-input" maxlength="1000" auto-height confirm-type="send" :show-confirm-bar="false" :disabled="sending" placeholder="请输入消息" @confirm="send" />
|
||||||
|
<button class="send-btn" :loading="sending" :disabled="!content.trim() || sending" @click="send">发送</button>
|
||||||
|
</view>
|
||||||
|
<view v-else class="ended">本次AI咨询已结束</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, nextTick, computed } from 'vue';
|
||||||
|
import { onLoad, onShow } from '@dcloudio/uni-app';
|
||||||
|
import api from '@/utils/api';
|
||||||
|
import useAccountStore from '@/store/account';
|
||||||
|
import { storeToRefs } from 'pinia';
|
||||||
|
import EvaluationCard from '@/pages/message/components/special-message/evaluation.vue';
|
||||||
|
|
||||||
|
const { openid } = storeToRefs(useAccountStore());
|
||||||
|
const corpId = ref('');
|
||||||
|
const sessionId = ref('');
|
||||||
|
const session = ref(null);
|
||||||
|
const messages = ref([]);
|
||||||
|
const content = ref('');
|
||||||
|
const sending = ref(false);
|
||||||
|
const waitingAi = ref(false);
|
||||||
|
const bottomId = ref('');
|
||||||
|
const active = ref(false);
|
||||||
|
const rateAssistantInfo = computed(() => ({ name: session.value?.assistantName || 'AI咨询助理', title: 'AI咨询助理', department: session.value?.teamName || '', avatar: '' }));
|
||||||
|
|
||||||
|
function displayContent(item) {
|
||||||
|
const value = item?.content || '';
|
||||||
|
if (item?.sender !== 'assistant' || typeof value !== 'string') return value;
|
||||||
|
const contents = [];
|
||||||
|
const matcher = /"streamContent"\s*:\s*"((?:\\.|[^"\\])*)"/g;
|
||||||
|
let match;
|
||||||
|
while ((match = matcher.exec(value))) {
|
||||||
|
try {
|
||||||
|
const text = JSON.parse(`"${match[1]}"`);
|
||||||
|
if (text) contents.push(text);
|
||||||
|
} catch (error) {
|
||||||
|
// 兼容历史会话中无法解析的单段协议消息。
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return contents.join('') || value;
|
||||||
|
}
|
||||||
|
function formatMessageTime(value) {
|
||||||
|
const date = new Date(Number(value));
|
||||||
|
if (Number.isNaN(date.getTime())) return '';
|
||||||
|
return `${String(date.getHours()).padStart(2, '0')}:${String(date.getMinutes()).padStart(2, '0')}`;
|
||||||
|
}
|
||||||
|
function shouldShowTime(item, index) {
|
||||||
|
if (index === 0) return Boolean(item?.createTime);
|
||||||
|
return Number(item?.createTime) - Number(messages.value[index - 1]?.createTime) > 5 * 60 * 1000;
|
||||||
|
}
|
||||||
|
async function scrollToBottom() {
|
||||||
|
bottomId.value = '';
|
||||||
|
await nextTick();
|
||||||
|
bottomId.value = 'bottom';
|
||||||
|
}
|
||||||
|
async function detail() {
|
||||||
|
const res = await api('getAiConsultSessionDetail', { corpId: corpId.value, sessionId: sessionId.value, miniAppId: openid.value || uni.getStorageSync('openid') }, false);
|
||||||
|
if (!res?.success) return uni.showToast({ title: res?.message || '加载失败', icon: 'none' });
|
||||||
|
session.value = res.data.session;
|
||||||
|
messages.value = res.data.messages || [];
|
||||||
|
active.value = session.value.status === 'active';
|
||||||
|
uni.setNavigationBarTitle({ title: session.value.assistantName || 'AI咨询助理' });
|
||||||
|
await scrollToBottom();
|
||||||
|
}
|
||||||
|
async function send() {
|
||||||
|
if (!active.value || sending.value || !content.value.trim()) return;
|
||||||
|
const value = content.value.trim();
|
||||||
|
const localMessage = { _id: `local-${Date.now()}`, sender: 'patient', content: value, messageType: 'text', createTime: Date.now(), _sendStatus: 'pending' };
|
||||||
|
messages.value.push(localMessage);
|
||||||
|
content.value = '';
|
||||||
|
sending.value = true;
|
||||||
|
waitingAi.value = true;
|
||||||
|
await scrollToBottom();
|
||||||
|
try {
|
||||||
|
const res = await api('sendAiConsultMessage', { corpId: corpId.value, sessionId: sessionId.value, customerId: session.value.customerId, miniAppId: openid.value || uni.getStorageSync('openid'), content: value }, false);
|
||||||
|
if (!res?.success) {
|
||||||
|
localMessage._sendStatus = 'failed';
|
||||||
|
uni.showToast({ title: res?.message || '发送失败', icon: 'none' });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
await detail();
|
||||||
|
} catch (error) {
|
||||||
|
localMessage._sendStatus = 'failed';
|
||||||
|
uni.showToast({ title: '发送失败,请重试', icon: 'none' });
|
||||||
|
} finally {
|
||||||
|
sending.value = false;
|
||||||
|
waitingAi.value = false;
|
||||||
|
await scrollToBottom();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onLoad(opts => { corpId.value = opts.corpId; sessionId.value = opts.sessionId; detail(); });
|
||||||
|
onShow(detail);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.chat-page { height: 100vh; display: flex; flex-direction: column; background: #f5f7fb; overflow: hidden; }
|
||||||
|
.chat-content { flex: 1; height: 0; box-sizing: border-box; }
|
||||||
|
.message-list { padding: 28rpx 24rpx 40rpx; }
|
||||||
|
.message-item { margin-bottom: 28rpx; }
|
||||||
|
.message-content { display: flex; align-items: flex-start; gap: 16rpx; }
|
||||||
|
.message-patient .message-content { justify-content: flex-end; }
|
||||||
|
.avatar { width: 72rpx; height: 72rpx; flex: 0 0 72rpx; display: flex; align-items: center; justify-content: center; border-radius: 50%; font-size: 24rpx; font-weight: 600; }
|
||||||
|
.assistant-avatar { color: #fff; background: linear-gradient(135deg, #4d93ff, #0877f1); }
|
||||||
|
.patient-avatar { color: #0877f1; background: #e2efff; }
|
||||||
|
.message-bubble-container { max-width: 74%; min-width: 0; }
|
||||||
|
.message-patient .message-bubble-container { display: flex; flex-direction: column; align-items: flex-end; }
|
||||||
|
.username-label { margin: 2rpx 0 10rpx; color: #8a919f; font-size: 24rpx; line-height: 32rpx; }
|
||||||
|
.message-bubble { padding: 18rpx 22rpx; border-radius: 8rpx 22rpx 22rpx; background: #fff; box-shadow: 0 4rpx 14rpx rgba(17, 48, 89, .06); }
|
||||||
|
.message-patient .message-bubble { color: #fff; border-radius: 22rpx 8rpx 22rpx 22rpx; background: #0877f1; box-shadow: 0 4rpx 14rpx rgba(8, 119, 241, .18); }
|
||||||
|
.message-bubble.pending { opacity: .72; }
|
||||||
|
.message-text { color: inherit; font-size: 30rpx; line-height: 46rpx; white-space: pre-wrap; word-break: break-word; }
|
||||||
|
.time-divider { margin: 2rpx 0 22rpx; color: #a0a6b0; text-align: center; font-size: 23rpx; }
|
||||||
|
.system-message { display: inline-block; margin: 0 auto; padding: 10rpx 20rpx; color: #79808c; background: #e9ecf1; border-radius: 22rpx; font-size: 24rpx; line-height: 36rpx; }
|
||||||
|
.message-system { text-align: center; }
|
||||||
|
.system-message.warn { color: #d84256; background: #fff0f1; }
|
||||||
|
.send-status { margin-top: 8rpx; color: #e34d59; font-size: 23rpx; }
|
||||||
|
.thinking { display: flex; align-items: center; gap: 8rpx; min-width: 84rpx; padding: 26rpx 28rpx; }
|
||||||
|
.thinking-dot { width: 10rpx; height: 10rpx; border-radius: 50%; background: #7f8998; animation: thinking 1.2s infinite ease-in-out; }
|
||||||
|
.thinking-dot:nth-child(2) { animation-delay: .16s; }
|
||||||
|
.thinking-dot:nth-child(3) { animation-delay: .32s; }
|
||||||
|
@keyframes thinking { 0%, 60%, 100% { opacity: .35; transform: translateY(0); } 30% { opacity: 1; transform: translateY(-7rpx); } }
|
||||||
|
.input-section { display: flex; align-items: flex-end; gap: 16rpx; padding: 16rpx 24rpx calc(16rpx + env(safe-area-inset-bottom)); background: #fff; border-top: 1rpx solid #edf0f4; }
|
||||||
|
.text-input { flex: 1; max-height: 180rpx; padding: 16rpx 20rpx; box-sizing: border-box; color: #283242; background: #f3f5f8; border-radius: 12rpx; font-size: 29rpx; line-height: 40rpx; }
|
||||||
|
.send-btn { flex: 0 0 auto; height: 72rpx; margin: 0; padding: 0 26rpx; color: #fff; background: #0877f1; border-radius: 12rpx; font-size: 27rpx; line-height: 72rpx; }
|
||||||
|
.send-btn[disabled] { color: #fff; background: #a9cfff; }
|
||||||
|
.rate-card { display: block; margin: 20rpx 0 0; }
|
||||||
|
.ended { padding: 30rpx; color: #7d8590; text-align: center; background: #fff; font-size: 27rpx; }
|
||||||
|
</style>
|
||||||
12
pages/ai-consult/entry.vue
Normal file
12
pages/ai-consult/entry.vue
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<template><view class="page"><template v-if="customers.length"><view class="title">请选择本次咨询档案</view><view v-for="item in customers" :key="item._id" class="customer" @click="open(item)"><view>{{item.name || '未命名'}}</view><view class="sub">{{ item.age ? item.age + '岁' : '' }}</view></view></template><view v-else-if="loaded" class="empty">正在进入AI咨询...</view></view></template>
|
||||||
|
<script setup>
|
||||||
|
import { ref } from 'vue';
|
||||||
|
import { onLoad } from '@dcloudio/uni-app';
|
||||||
|
import api from '@/utils/api';
|
||||||
|
import useAccountStore from '@/store/account';
|
||||||
|
import { storeToRefs } from 'pinia';
|
||||||
|
const { openid } = storeToRefs(useAccountStore()); const corpId=ref(''),teamId=ref(''),assistantId=ref(''),qrid=ref(''),customers=ref([]),loaded=ref(false);
|
||||||
|
async function load(){const miniAppId=openid.value||uni.getStorageSync('openid');const res=await api('getMiniAppCustomers',{corpId:corpId.value,miniAppId},false);customers.value=res?.success?(res.data||[]):[];loaded.value=true;if(!customers.value.length)await open();}
|
||||||
|
async function open(customer){const res=await api('openAiConsultSession',{corpId:corpId.value,teamId:teamId.value,assistantId:assistantId.value,qrid:qrid.value,customerId:customer?._id||'',miniAppId:openid.value||uni.getStorageSync('openid')});if(!res?.success)return uni.showToast({title:res?.message||'创建失败',icon:'none'});uni.redirectTo({url:`/pages/ai-consult/chat?corpId=${corpId.value}&sessionId=${res.data.session._id}`});}
|
||||||
|
onLoad(opts=>{corpId.value=opts.corpId||'';teamId.value=opts.teamId||'';assistantId.value=opts.assistantId||'';qrid.value=opts.qrid||'';load();});
|
||||||
|
</script><style scoped>.page{min-height:100vh;background:#f7f8fa;padding:28rpx}.title{font-size:34rpx;font-weight:600;margin-bottom:20rpx}.customer{background:#fff;border-radius:16rpx;padding:24rpx;margin-bottom:18rpx;font-size:30rpx}.sub,.empty{font-size:25rpx;color:#888;margin-top:8rpx}.empty{text-align:center;padding-top:100rpx}</style>
|
||||||
40
pages/ai-consult/list.vue
Normal file
40
pages/ai-consult/list.vue
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
<template>
|
||||||
|
<full-page @reachBottom="loadMore">
|
||||||
|
<template #header>
|
||||||
|
<scroll-view scroll-x class="tabs" :show-scrollbar="false">
|
||||||
|
<view v-for="item in customers" :key="item.value" class="tab" :class="{ active: customerId === item.value }" @click="selectCustomer(item.value)">{{ item.name }}</view>
|
||||||
|
</scroll-view>
|
||||||
|
</template>
|
||||||
|
<view class="page">
|
||||||
|
<empty-data v-if="!loading && list.length === 0" text="暂无AI咨询记录" />
|
||||||
|
<view v-for="item in list" :key="item._id" class="card" @click="openChat(item)">
|
||||||
|
<view class="title"><text>{{ item.assistantName }}</text><text class="status" :class="item.status">{{ statusText(item) }}</text></view>
|
||||||
|
<view class="line">团队:{{ item.teamName || item.teamId || '-' }}</view>
|
||||||
|
<view class="line">档案:{{ item.customerName || '-' }}</view>
|
||||||
|
<view class="line">最近互动:{{ format(item.lastActiveTime) }}</view>
|
||||||
|
<view v-if="item.sensitiveHit" class="warn">已触发敏感词</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</full-page>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import { ref, onMounted } from 'vue';
|
||||||
|
import { onLoad } from '@dcloudio/uni-app';
|
||||||
|
import api from '@/utils/api';
|
||||||
|
import useAccountStore from '@/store/account';
|
||||||
|
import { storeToRefs } from 'pinia';
|
||||||
|
import FullPage from '@/components/full-page.vue';
|
||||||
|
import EmptyData from '@/components/empty-data.vue';
|
||||||
|
const { openid } = storeToRefs(useAccountStore());
|
||||||
|
const corpId = ref(''); const customerId = ref(''); const customers = ref([{ name: '全部档案', value: '' }]);
|
||||||
|
const list = ref([]); const page = ref(1); const pages = ref(0); const loading = ref(false);
|
||||||
|
const format = value => value ? new Date(value).toLocaleString('zh-CN', { hour12: false }) : '-';
|
||||||
|
const statusText = item => item.status === 'active' ? '咨询中' : item.endReason === 'sensitive_word' ? '敏感词结束' : '已结束';
|
||||||
|
async function loadCustomers() { const res = await api('getMiniAppCustomers', { corpId: corpId.value, miniAppId: openid.value || uni.getStorageSync('openid') }, false); if (res?.success) customers.value = [customers.value[0], ...(res.data || []).map(item => ({ name: item.name || '未命名', value: item._id }))]; }
|
||||||
|
async function load(reset = false) { if (loading.value) return; if (reset) { page.value = 1; list.value = []; } loading.value = true; const res = await api('getAiConsultSessions', { corpId: corpId.value, customerId: customerId.value, miniAppId: openid.value || uni.getStorageSync('openid'), page: page.value, pageSize: 20 }, false); if (res?.success) { list.value = page.value === 1 ? res.list : [...list.value, ...res.list]; pages.value = res.pages || 0; } loading.value = false; }
|
||||||
|
function selectCustomer(value) { if (customerId.value === value) return; customerId.value = value; load(true); }
|
||||||
|
function loadMore() { if (!loading.value && page.value < pages.value) { page.value += 1; load(); } }
|
||||||
|
function openChat(item) { uni.navigateTo({ url: `/pages/ai-consult/chat?corpId=${item.corpId}&sessionId=${item._id}` }); }
|
||||||
|
onLoad(async opts => { corpId.value = opts.corpId || ''; await loadCustomers(); await load(true); });
|
||||||
|
</script>
|
||||||
|
<style scoped>.page{min-height:100vh;background:#f7f8fa;padding:24rpx}.tabs{white-space:nowrap;background:#fff;padding:18rpx 20rpx}.tab{display:inline-block;padding:10rpx 22rpx;margin-right:16rpx;border-radius:28rpx;color:#666;background:#f5f5f5}.tab.active{color:#0877f1;background:#e8f3ff}.card{background:#fff;border-radius:16rpx;padding:24rpx;margin-bottom:20rpx}.title{display:flex;justify-content:space-between;font-size:32rpx;font-weight:600;margin-bottom:16rpx}.status{font-size:24rpx;color:#ff8a00}.status.active{color:#18a058}.line{font-size:26rpx;color:#777;line-height:44rpx}.warn{font-size:24rpx;color:#e34d59;margin-top:8rpx}</style>
|
||||||
@ -49,6 +49,7 @@ const props = defineProps({
|
|||||||
const { account } = storeToRefs(useAccount());
|
const { account } = storeToRefs(useAccount());
|
||||||
const consultantPopup = ref(null);
|
const consultantPopup = ref(null);
|
||||||
const badgeMap = ref({});
|
const badgeMap = ref({});
|
||||||
|
const aiConsultEnabled = ref(false);
|
||||||
let loading = false;
|
let loading = false;
|
||||||
|
|
||||||
const consultItems = ref([
|
const consultItems = ref([
|
||||||
@ -80,6 +81,12 @@ const consultItems = ref([
|
|||||||
path: "/pages/rate/rate-list",
|
path: "/pages/rate/rate-list",
|
||||||
badge: 'rate'
|
badge: 'rate'
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: "aiConsultRecord",
|
||||||
|
label: "AI咨询记录",
|
||||||
|
icon: "/static/home/chat-consult.png",
|
||||||
|
path: "/pages/ai-consult/list",
|
||||||
|
},
|
||||||
]);
|
]);
|
||||||
const hideMenus = computed(() => {
|
const hideMenus = computed(() => {
|
||||||
const result = {};
|
const result = {};
|
||||||
@ -87,6 +94,7 @@ const hideMenus = computed(() => {
|
|||||||
if (!(props.team && props.team.createSource === 'yzs')) {
|
if (!(props.team && props.team.createSource === 'yzs')) {
|
||||||
result.chat = true;
|
result.chat = true;
|
||||||
}
|
}
|
||||||
|
if (!aiConsultEnabled.value) result.aiConsultRecord = true;
|
||||||
return result;
|
return result;
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -191,8 +199,15 @@ async function getBadgeCount() {
|
|||||||
loading = false;
|
loading = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function loadAiConsultPermission() {
|
||||||
|
if (!props.corpId) return;
|
||||||
|
const res = await api('getAiConsultPermission', { corpId: props.corpId }, false);
|
||||||
|
aiConsultEnabled.value = Boolean(res?.success && res?.data?.enabled);
|
||||||
|
}
|
||||||
|
|
||||||
watch(() => [props.customers, props.teamId, props.corpId], n => {
|
watch(() => [props.customers, props.teamId, props.corpId], n => {
|
||||||
getBadgeCount()
|
getBadgeCount()
|
||||||
|
loadAiConsultPermission()
|
||||||
}, { immediate: true })
|
}, { immediate: true })
|
||||||
|
|
||||||
defineExpose({
|
defineExpose({
|
||||||
@ -216,23 +231,26 @@ defineExpose({
|
|||||||
}
|
}
|
||||||
|
|
||||||
.consult-grid {
|
.consult-grid {
|
||||||
height: 208rpx;
|
min-height: 208rpx;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
border-radius: 16rpx;
|
border-radius: 16rpx;
|
||||||
padding: 24rpx 30rpx;
|
padding: 26rpx 22rpx;
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(4, 1fr);
|
grid-template-columns: repeat(4, 1fr);
|
||||||
align-items: center;
|
grid-auto-rows: 120rpx;
|
||||||
gap: 32rpx;
|
align-items: start;
|
||||||
|
column-gap: 0;
|
||||||
|
row-gap: 24rpx;
|
||||||
box-shadow: 0 8rpx 10rpx 0 rgba(60, 169, 145, 0.06);
|
box-shadow: 0 8rpx 10rpx 0 rgba(60, 169, 145, 0.06);
|
||||||
}
|
}
|
||||||
|
|
||||||
.consult-item {
|
.consult-item {
|
||||||
|
min-width: 0;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 12rpx;
|
gap: 10rpx;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -242,7 +260,7 @@ defineExpose({
|
|||||||
|
|
||||||
.item-icon {
|
.item-icon {
|
||||||
width: 80rpx;
|
width: 80rpx;
|
||||||
height: 80;
|
height: 80rpx;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
@ -270,9 +288,12 @@ defineExpose({
|
|||||||
}
|
}
|
||||||
|
|
||||||
.item-label {
|
.item-label {
|
||||||
font-size: 30rpx;
|
max-width: 100%;
|
||||||
color: #666d76;
|
color: #596273;
|
||||||
|
font-size: 26rpx;
|
||||||
|
line-height: 36rpx;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -20,6 +20,13 @@ const urlsConfig = {
|
|||||||
recordBusinessCardBehavior: 'recordBusinessCardBehavior',
|
recordBusinessCardBehavior: 'recordBusinessCardBehavior',
|
||||||
getJoinedTeams: 'getJoinedTeams',
|
getJoinedTeams: 'getJoinedTeams',
|
||||||
getCorpBusinessCardStatus: 'getCorpBusinessCardStatus',
|
getCorpBusinessCardStatus: 'getCorpBusinessCardStatus',
|
||||||
|
getAiConsultPermission: 'getAiConsultPermission',
|
||||||
|
getAiConsultAssistants: 'getAiConsultAssistants',
|
||||||
|
getAiConsultSessions: 'getAiConsultSessions',
|
||||||
|
getAiConsultSessionDetail: 'getAiConsultSessionDetail',
|
||||||
|
openAiConsultSession: 'openAiConsultSession',
|
||||||
|
sendAiConsultMessage: 'sendAiConsultMessage',
|
||||||
|
closeAiConsultSession: 'closeAiConsultSession',
|
||||||
},
|
},
|
||||||
|
|
||||||
knowledgeBase: {
|
knowledgeBase: {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user