2026-01-28 13:38:05 +08:00
|
|
|
<template>
|
|
|
|
|
<view class="consult-container">
|
|
|
|
|
<view class="consult-title">咨询互动</view>
|
|
|
|
|
|
|
|
|
|
<view class="consult-grid">
|
2026-02-06 17:20:12 +08:00
|
|
|
<view class="consult-item" v-for="item in consultItems" :key="item.id" @click="handleItemClick(item)">
|
2026-03-04 10:49:25 +08:00
|
|
|
<view class="relative item-icon">
|
2026-02-03 10:45:54 +08:00
|
|
|
<image :src="item.icon" class="icon-img" mode="aspectFill" />
|
2026-03-04 10:49:25 +08:00
|
|
|
<view v-if="badgeMap[item.badge]" class="item-dot"></view>
|
2026-01-28 13:38:05 +08:00
|
|
|
</view>
|
|
|
|
|
<view class="item-label">{{ item.label }}</view>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
<!-- 选择咨询人弹窗 -->
|
2026-02-06 17:20:12 +08:00
|
|
|
<select-consultant-popup ref="consultantPopup" :customers="customers" :corpId="corpId" :teamId="teamId"
|
|
|
|
|
@confirm="handleConsultantConfirm" @addNew="handleAddNewArchive" />
|
2026-01-28 13:38:05 +08:00
|
|
|
</view>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script setup>
|
2026-03-04 10:49:25 +08:00
|
|
|
import { ref, watch } from "vue";
|
2026-01-28 13:38:05 +08:00
|
|
|
import { storeToRefs } from "pinia";
|
|
|
|
|
import useAccount from "@/store/account";
|
|
|
|
|
import api from "@/utils/api";
|
|
|
|
|
import { toast } from "@/utils/widget";
|
|
|
|
|
import SelectConsultantPopup from "./select-consultant-popup.vue";
|
|
|
|
|
|
|
|
|
|
const props = defineProps({
|
|
|
|
|
corpId: {
|
|
|
|
|
type: String,
|
|
|
|
|
default: "",
|
|
|
|
|
},
|
2026-02-06 17:20:12 +08:00
|
|
|
team: {
|
|
|
|
|
type: Object,
|
|
|
|
|
default: () => ({})
|
|
|
|
|
},
|
2026-01-28 13:38:05 +08:00
|
|
|
teamId: {
|
|
|
|
|
type: String,
|
|
|
|
|
default: "",
|
|
|
|
|
},
|
|
|
|
|
customers: {
|
|
|
|
|
type: Array,
|
|
|
|
|
default: () => [],
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const { account } = storeToRefs(useAccount());
|
|
|
|
|
const consultantPopup = ref(null);
|
2026-03-04 10:49:25 +08:00
|
|
|
const badgeMap = ref({});
|
|
|
|
|
let loading = false;
|
2026-01-28 13:38:05 +08:00
|
|
|
|
|
|
|
|
const consultItems = ref([
|
|
|
|
|
{
|
|
|
|
|
id: "chat",
|
|
|
|
|
label: "聊天咨询",
|
2026-02-03 15:42:32 +08:00
|
|
|
icon: "/static/home/chat-consult.png",
|
2026-01-28 13:38:05 +08:00
|
|
|
needSelectConsultant: true,
|
2026-03-04 10:49:25 +08:00
|
|
|
badge: 'chat'
|
2026-01-28 13:38:05 +08:00
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
id: "education",
|
|
|
|
|
label: "我的宣教",
|
2026-02-03 15:42:32 +08:00
|
|
|
icon: "/static/home/my-education.png",
|
2026-01-28 13:38:05 +08:00
|
|
|
path: "/pages/article/article-list",
|
2026-03-04 10:49:25 +08:00
|
|
|
badge: 'article'
|
2026-01-28 13:38:05 +08:00
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
id: "survey",
|
|
|
|
|
label: "我的问卷",
|
2026-02-03 15:42:32 +08:00
|
|
|
icon: "/static/home/my-questionnaire.png",
|
2026-01-30 15:16:07 +08:00
|
|
|
path: "/pages/survey/survey-list",
|
2026-03-04 10:49:25 +08:00
|
|
|
badge: 'survey'
|
2026-01-28 13:38:05 +08:00
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
id: "rating",
|
|
|
|
|
label: "服务评价",
|
2026-02-03 15:42:32 +08:00
|
|
|
icon: "/static/home/service-rating.png",
|
2026-02-28 15:08:23 +08:00
|
|
|
path: "/pages/rate/rate-list",
|
2026-03-04 10:49:25 +08:00
|
|
|
badge: 'rate'
|
2026-01-28 13:38:05 +08:00
|
|
|
},
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
function handleItemClick(item) {
|
|
|
|
|
// 聊天咨询需要选择咨询人
|
|
|
|
|
if (item.needSelectConsultant) {
|
2026-02-06 17:20:12 +08:00
|
|
|
if (!props.team || !props.team.creator) {
|
|
|
|
|
return toast('该团队暂未开放咨询服务')
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-28 13:38:05 +08:00
|
|
|
if (!props.customers || props.customers.length === 0) {
|
|
|
|
|
toast("请先添加档案");
|
|
|
|
|
// 跳转到档案管理页面
|
|
|
|
|
uni.navigateTo({
|
|
|
|
|
url: `/pages/archive/archive-manage?corpId=${props.corpId}&teamId=${props.teamId}`,
|
|
|
|
|
});
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 打开选择咨询人弹窗
|
|
|
|
|
consultantPopup.value?.open();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 其他功能直接跳转
|
|
|
|
|
if (!item.path) {
|
|
|
|
|
toast("功能开发中");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uni.navigateTo({
|
2026-02-09 17:31:16 +08:00
|
|
|
url: `${item.path}?teamId=${props.teamId}&corpId=${props.corpId}`,
|
2026-01-28 13:38:05 +08:00
|
|
|
fail: () => {
|
|
|
|
|
toast("页面跳转失败");
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 确认选择咨询人
|
|
|
|
|
async function handleConsultantConfirm(customer) {
|
2026-02-08 10:41:41 +08:00
|
|
|
const teamIds = customer && Array.isArray(customer.teamId) ? customer.teamId : [];
|
|
|
|
|
if (!teamIds.includes(props.teamId)) {
|
|
|
|
|
const res = await api("authCustomerToTeam", {
|
|
|
|
|
corpId: props.team.corpId,
|
|
|
|
|
teamId: props.team.teamId,
|
|
|
|
|
id: customer._id,
|
|
|
|
|
});
|
|
|
|
|
if (res && res.success) {
|
|
|
|
|
uni.$emit("reloadTeamCustomers");
|
|
|
|
|
} else {
|
|
|
|
|
toast(res?.message || "授权团队失败");
|
|
|
|
|
}
|
|
|
|
|
}
|
2026-01-28 13:38:05 +08:00
|
|
|
// 调用创建咨询群组接口
|
|
|
|
|
uni.showLoading({ title: "创建咨询中..." });
|
|
|
|
|
try {
|
|
|
|
|
const res = await api("createConsultGroup", {
|
|
|
|
|
teamId: props.teamId,
|
|
|
|
|
corpId: props.corpId,
|
2026-02-06 17:20:12 +08:00
|
|
|
customerId: customer._id,
|
2026-01-28 13:38:05 +08:00
|
|
|
customerImUserId: account.value.openid,
|
|
|
|
|
});
|
|
|
|
|
uni.hideLoading();
|
|
|
|
|
if (res && res.success) {
|
|
|
|
|
const { groupId, isExisting } = res.data;
|
|
|
|
|
// 跳转到聊天页面
|
|
|
|
|
uni.navigateTo({
|
|
|
|
|
url: `/pages/message/index?conversationID=GROUP${groupId}&groupID=${groupId}`,
|
|
|
|
|
});
|
|
|
|
|
} else {
|
|
|
|
|
toast(res?.message || "创建咨询失败");
|
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
uni.hideLoading();
|
|
|
|
|
console.error("创建咨询群组失败:", error);
|
|
|
|
|
toast("创建咨询失败");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 新建档案
|
|
|
|
|
function handleAddNewArchive() {
|
|
|
|
|
uni.navigateTo({
|
|
|
|
|
url: `/pages/archive/edit-archive?corpId=${props.corpId}&teamId=${props.teamId}`,
|
|
|
|
|
});
|
|
|
|
|
}
|
2026-03-04 10:49:25 +08:00
|
|
|
|
|
|
|
|
async function getBadgeCount() {
|
|
|
|
|
if (loading) return;
|
|
|
|
|
loading = true;
|
|
|
|
|
const customerIds = props.customers.map((item) => item._id);
|
|
|
|
|
if (customerIds.length === 0) {
|
|
|
|
|
badgeMap.value = {};
|
|
|
|
|
loading = false
|
|
|
|
|
return
|
|
|
|
|
}
|
2026-03-05 15:03:07 +08:00
|
|
|
const res = await api('getMiniAppHomeStats', { corpId: props.corpId, teamId: props.teamId, customerIds }, false)
|
2026-03-04 10:49:25 +08:00
|
|
|
const data = res?.data || {};
|
|
|
|
|
const article = typeof data.article === 'number' ? data.article : 0;
|
|
|
|
|
const survey = typeof data.survey === 'number' ? data.survey : 0;
|
|
|
|
|
const rate = typeof data.rate === 'number' ? data.rate : 0;
|
|
|
|
|
badgeMap.value = { article, survey, rate };
|
|
|
|
|
loading = false;
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-04 17:19:52 +08:00
|
|
|
watch(() => [props.customers, props.teamId, props.corpId], n => {
|
2026-03-04 10:49:25 +08:00
|
|
|
getBadgeCount()
|
|
|
|
|
}, { immediate: true })
|
|
|
|
|
|
|
|
|
|
defineExpose({
|
|
|
|
|
getBadgeCount,
|
|
|
|
|
})
|
2026-01-28 13:38:05 +08:00
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
|
|
.consult-container {
|
2026-02-03 09:59:49 +08:00
|
|
|
margin: 0 30rpx;
|
|
|
|
|
margin-top: 24rpx;
|
2026-01-28 13:38:05 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.consult-title {
|
2026-02-03 15:42:32 +08:00
|
|
|
color: #000000;
|
2026-02-03 09:59:49 +08:00
|
|
|
font-size: 36rpx;
|
2026-02-03 15:42:32 +08:00
|
|
|
font-style: normal;
|
2026-01-28 13:38:05 +08:00
|
|
|
font-weight: 600;
|
2026-02-03 15:42:32 +08:00
|
|
|
line-height: normal;
|
2026-02-03 09:59:49 +08:00
|
|
|
margin-bottom: 24rpx;
|
2026-01-28 13:38:05 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.consult-grid {
|
2026-02-03 15:42:32 +08:00
|
|
|
height: 208rpx;
|
|
|
|
|
box-sizing: border-box;
|
2026-02-03 09:59:49 +08:00
|
|
|
background: #fff;
|
2026-02-03 15:42:32 +08:00
|
|
|
border-radius: 16rpx;
|
2026-02-03 10:45:54 +08:00
|
|
|
padding: 24rpx 30rpx;
|
2026-01-28 13:38:05 +08:00
|
|
|
display: grid;
|
|
|
|
|
grid-template-columns: repeat(4, 1fr);
|
2026-02-03 15:42:32 +08:00
|
|
|
align-items: center;
|
2026-02-03 09:59:49 +08:00
|
|
|
gap: 32rpx;
|
2026-02-03 15:42:32 +08:00
|
|
|
box-shadow: 0 8rpx 10rpx 0 rgba(60, 169, 145, 0.06);
|
2026-01-28 13:38:05 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.consult-item {
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
align-items: center;
|
2026-02-03 10:45:54 +08:00
|
|
|
gap: 12rpx;
|
2026-01-28 13:38:05 +08:00
|
|
|
cursor: pointer;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.item-icon {
|
2026-02-03 15:42:32 +08:00
|
|
|
width: 80rpx;
|
|
|
|
|
height: 80;
|
2026-01-28 13:38:05 +08:00
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
justify-content: center;
|
|
|
|
|
transition: transform 0.2s;
|
2026-02-03 10:45:54 +08:00
|
|
|
overflow: hidden;
|
2026-01-28 13:38:05 +08:00
|
|
|
}
|
|
|
|
|
|
2026-03-04 10:49:25 +08:00
|
|
|
.item-dot {
|
|
|
|
|
position: absolute;
|
|
|
|
|
right: 0;
|
|
|
|
|
top: 0;
|
|
|
|
|
width: 20rpx;
|
|
|
|
|
height: 20rpx;
|
|
|
|
|
background: red;
|
|
|
|
|
border-radius: 50%;
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-28 13:38:05 +08:00
|
|
|
.consult-item:active .item-icon {
|
|
|
|
|
transform: scale(0.95);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.icon-img {
|
2026-02-03 15:42:32 +08:00
|
|
|
width: 80rpx;
|
|
|
|
|
height: 80rpx;
|
2026-01-28 13:38:05 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.item-label {
|
2026-02-03 15:42:32 +08:00
|
|
|
font-size: 28rpx;
|
|
|
|
|
color: #666d76;
|
2026-01-28 13:38:05 +08:00
|
|
|
text-align: center;
|
2026-02-03 15:42:32 +08:00
|
|
|
font-weight: 400;
|
2026-01-28 13:38:05 +08:00
|
|
|
}
|
|
|
|
|
</style>
|