48 lines
4.6 KiB
Vue
Raw Normal View History

2026-08-07 09:35:21 +08:00
<template>
<full-page @reachBottom="loadMore">
<template #header>
<scroll-view scroll-x class="tabs" :show-scrollbar="false">
2026-08-11 09:21:20 +08:00
<view v-for="item in sources" :key="item.value" class="tab" :class="{ active: source === item.value }" @click="selectSource(item.value)">{{ item.name }}</view>
</scroll-view>
<scroll-view scroll-x class="tabs customer-tabs" :show-scrollbar="false">
2026-08-07 09:35:21 +08:00
<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">
2026-08-11 09:21:20 +08:00
<empty-data v-if="!loading && list.length === 0" text="暂无咨询记录" />
<view v-for="item in list" :key="`${item.source}-${item.id}`" class="card" @click="openChat(item)">
2026-08-24 14:00:38 +08:00
<view class="title"><text>{{ removeAiLabel(item.assistantName, '咨询助理') }}</text><text class="status" :class="item.status">{{ item.statusLabel }}</text></view>
<view class="line"><text class="source" :class="item.source">{{ removeAiLabel(item.sourceLabel, '咨询') }}</text></view>
2026-08-07 09:35:21 +08:00
<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';
2026-08-24 14:00:38 +08:00
import { removeAiLabel } from '@/utils/ai-consult-display';
2026-08-07 09:35:21 +08:00
const { openid } = storeToRefs(useAccountStore());
2026-08-11 09:21:20 +08:00
const corpId = ref(''); const customerId = ref(''); const source = ref('');
2026-08-24 14:00:38 +08:00
const sources = [{ name: '全部咨询', value: '' }, { name: '咨询', value: 'ai' }, { name: 'IM咨询', value: 'im' }];
2026-08-11 09:21:20 +08:00
const customers = ref([{ name: '全部档案', value: '' }]);
2026-08-07 09:35:21 +08:00
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 }) : '-';
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 }))]; }
2026-08-11 09:21:20 +08:00
async function load(reset = false) { if (loading.value) return; if (reset) { page.value = 1; list.value = []; } loading.value = true; const res = await api('getUnifiedConsultSessions', { corpId: corpId.value, customerId: customerId.value, miniAppId: openid.value || uni.getStorageSync('openid'), source: source.value, 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; }
2026-08-07 09:35:21 +08:00
function selectCustomer(value) { if (customerId.value === value) return; customerId.value = value; load(true); }
2026-08-11 09:21:20 +08:00
function selectSource(value) { if (source.value === value) return; source.value = value; load(true); }
2026-08-07 09:35:21 +08:00
function loadMore() { if (!loading.value && page.value < pages.value) { page.value += 1; load(); } }
2026-08-11 09:21:20 +08:00
function openChat(item) { const url = item.source === 'im' ? `/pages/message/index?conversationID=GROUP${item.groupId}&groupID=${item.groupId}` : `/pages/ai-consult/chat?corpId=${item.corpId}&sessionId=${item.id}`; uni.navigateTo({ url }); }
2026-08-07 09:35:21 +08:00
onLoad(async opts => { corpId.value = opts.corpId || ''; await loadCustomers(); await load(true); });
</script>
2026-08-11 09:21:20 +08:00
<style scoped>.page{min-height:100vh;background:#f7f8fa;padding:24rpx}.tabs{white-space:nowrap;background:#fff;padding:18rpx 20rpx}.customer-tabs{border-top:1rpx solid #f2f3f5;padding-top:12rpx}.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,.status.processing{color:#18a058}.line{font-size:26rpx;color:#777;line-height:44rpx}.source{font-size:22rpx;border-radius:6rpx;padding:2rpx 10rpx;color:#0877f1;background:#e8f3ff}.source.im{color:#7c55d1;background:#f1ebff}.warn{font-size:24rpx;color:#e34d59;margin-top:8rpx}</style>