ykt-team-wxapp/pages/home/consult.vue

266 lines
6.1 KiB
Vue
Raw Normal View History

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)">
<view class="relative item-icon">
2026-02-03 10:45:54 +08:00
<image :src="item.icon" class="icon-img" mode="aspectFill" />
<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>
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);
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,
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",
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",
path: "/pages/survey/survey-list",
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",
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}`,
});
}
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)
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 => {
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
}
.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>