2122 lines
84 KiB
JavaScript
2122 lines
84 KiB
JavaScript
"use strict";
|
||
const common_vendor = require("../../common/vendor.js");
|
||
const pages_furniture_customer_utils_dataInit = require("./utils/dataInit.js");
|
||
const common_config = require("../../common/config.js");
|
||
const CustomerList = () => "./components/CustomerList.js";
|
||
const ServiceList = () => "./components/ServiceList.js";
|
||
const CustomerProfileModal = () => "./components/CustomerProfileModal.js";
|
||
const ConversationSummaryFurniture = () => "./components/ConversationSummaryFurniture.js";
|
||
const _sfc_main = {
|
||
components: {
|
||
CustomerList,
|
||
ServiceList,
|
||
CustomerProfileModal,
|
||
ConversationSummaryFurniture
|
||
},
|
||
data() {
|
||
const systemInfo = common_vendor.index.getSystemInfoSync();
|
||
const statusBarHeight = systemInfo.statusBarHeight || 20;
|
||
const navbarHeight = 44;
|
||
const statusBarHeightRpx = statusBarHeight * 2;
|
||
const navbarHeightRpx = navbarHeight * 2;
|
||
const totalNavbarHeight = statusBarHeightRpx + navbarHeightRpx;
|
||
return {
|
||
navbarTop: totalNavbarHeight + "rpx",
|
||
// tab栏距离顶部的距离
|
||
contentTop: totalNavbarHeight + 72 + "rpx",
|
||
// 内容区域距离顶部的距离(tab栏高度72rpx)
|
||
activeTab: "customer",
|
||
activeDetailTab: "summary",
|
||
isPlaying: false,
|
||
currentServiceDetail: {
|
||
title: "",
|
||
date: "",
|
||
duration: "",
|
||
description: "",
|
||
customerName: ""
|
||
},
|
||
currentCustomerProfile: {
|
||
name: "",
|
||
intent: "",
|
||
serviceCount: 0,
|
||
lastService: "",
|
||
phone: "",
|
||
serviceStaff: "",
|
||
wechatStatus: "",
|
||
address: "",
|
||
source: "",
|
||
followStage: "",
|
||
systemTags: [],
|
||
customTags: [],
|
||
intentDescription: ""
|
||
},
|
||
summaryList: [],
|
||
furnitureAnalysisList: [],
|
||
// 家具意向分析数据
|
||
productCategoryList: [],
|
||
// 产品类别列表
|
||
activeProductCategory: "",
|
||
// 当前选中的产品类别
|
||
productRequirementMap: {},
|
||
// 产品需求映射 {categoryKey: {rows: [...]}}
|
||
summarySentence: "",
|
||
// 一句话总结
|
||
dealKeyPoints: "",
|
||
// 成交关键点
|
||
performanceData: {
|
||
totalScore: 81,
|
||
categories: []
|
||
},
|
||
serviceList: [],
|
||
serviceListTotal: 0,
|
||
serviceListPage: {
|
||
current: 1,
|
||
size: 10
|
||
},
|
||
todoList: [],
|
||
// 待办事项列表
|
||
todoListPage: {
|
||
current: 1,
|
||
size: 10
|
||
},
|
||
todoListTotal: 0,
|
||
// 待办事项总数
|
||
activeTodoMenuIndex: null,
|
||
// 当前打开的下拉菜单索引
|
||
todoMenuStyle: {},
|
||
// 下拉菜单样式(用于fixed定位)
|
||
currentTodoItem: null,
|
||
// 当前操作的待办事项
|
||
chapterSummaryList: [],
|
||
// 章节概要列表,包含summary1, summary2, summary3
|
||
audioSegmentsList: [],
|
||
// 录音分段列表
|
||
audioSegmentsLoading: false,
|
||
// 录音分段加载状态
|
||
playingAudioId: null,
|
||
// 当前正在播放的录音ID
|
||
innerAudioContext: null,
|
||
// 音频播放器实例
|
||
currentAudioUrl: null,
|
||
// 当前音频URL(用于清理Blob URL)
|
||
showTextModal: false,
|
||
// 是否显示文本内容弹框
|
||
currentRecordingText: "",
|
||
// 当前显示的录音文本内容
|
||
transcribingIds: []
|
||
// 正在转文本的录音ID列表
|
||
};
|
||
},
|
||
computed: {
|
||
// 当前选中的产品需求
|
||
currentProductRequirement() {
|
||
if (!this.activeProductCategory)
|
||
return null;
|
||
return this.productRequirementMap[this.activeProductCategory] || null;
|
||
},
|
||
// 计算导航栏和内容区域的位置(使用计算属性确保响应式)
|
||
computedNavbarTop() {
|
||
const systemInfo = common_vendor.index.getSystemInfoSync();
|
||
const statusBarHeight = systemInfo.statusBarHeight || 20;
|
||
const navbarHeight = 44;
|
||
const statusBarHeightRpx = statusBarHeight * 2;
|
||
const navbarHeightRpx = navbarHeight * 2;
|
||
const totalNavbarHeight = statusBarHeightRpx + navbarHeightRpx;
|
||
return totalNavbarHeight + "rpx";
|
||
},
|
||
computedContentTop() {
|
||
const systemInfo = common_vendor.index.getSystemInfoSync();
|
||
const statusBarHeight = systemInfo.statusBarHeight || 20;
|
||
const navbarHeight = 44;
|
||
const statusBarHeightRpx = statusBarHeight * 2;
|
||
const navbarHeightRpx = navbarHeight * 2;
|
||
const totalNavbarHeight = statusBarHeightRpx + navbarHeightRpx;
|
||
return totalNavbarHeight + 72 + "rpx";
|
||
}
|
||
},
|
||
onLoad() {
|
||
common_vendor.index.__f__("log", "at pages/furniture_customer/furniture_customer.vue:521", "[FurnitureCustomer][onLoad] 页面加载");
|
||
this.updateNavbarPosition();
|
||
if (this.activeTab === "service") {
|
||
this.loadServiceList();
|
||
}
|
||
},
|
||
onShow() {
|
||
common_vendor.index.__f__("log", "at pages/furniture_customer/furniture_customer.vue:530", "[FurnitureCustomer][onShow] 页面显示");
|
||
this.$nextTick(() => {
|
||
this.updateNavbarPosition();
|
||
setTimeout(() => {
|
||
this.updateNavbarPosition();
|
||
common_vendor.index.__f__("log", "at pages/furniture_customer/furniture_customer.vue:538", "[FurnitureCustomer][onShow] 延迟更新后的位置:", {
|
||
navbarTop: this.navbarTop,
|
||
contentTop: this.contentTop
|
||
});
|
||
}, 50);
|
||
});
|
||
},
|
||
onReady() {
|
||
common_vendor.index.__f__("log", "at pages/furniture_customer/furniture_customer.vue:547", "[FurnitureCustomer][onReady] 页面渲染完成");
|
||
common_vendor.index.__f__("log", "at pages/furniture_customer/furniture_customer.vue:548", "[FurnitureCustomer][onReady] activeTab:", this.activeTab);
|
||
common_vendor.index.__f__("log", "at pages/furniture_customer/furniture_customer.vue:549", "[FurnitureCustomer][onReady] navbarTop:", this.navbarTop);
|
||
common_vendor.index.__f__("log", "at pages/furniture_customer/furniture_customer.vue:550", "[FurnitureCustomer][onReady] contentTop:", this.contentTop);
|
||
this.updateNavbarPosition();
|
||
this.initUrlHidingAfterPageLoad();
|
||
const systemInfo = common_vendor.index.getSystemInfoSync();
|
||
common_vendor.index.__f__("log", "at pages/furniture_customer/furniture_customer.vue:559", "[FurnitureCustomer][onReady] 系统信息:", {
|
||
statusBarHeight: systemInfo.statusBarHeight,
|
||
windowHeight: systemInfo.windowHeight,
|
||
screenHeight: systemInfo.screenHeight
|
||
});
|
||
setTimeout(() => {
|
||
const query = common_vendor.index.createSelectorQuery().in(this);
|
||
query.select(".tabs").boundingClientRect((data) => {
|
||
common_vendor.index.__f__("log", "at pages/furniture_customer/furniture_customer.vue:570", "[FurnitureCustomer][onReady] tab栏元素信息:", data);
|
||
if (!data) {
|
||
common_vendor.index.__f__("error", "at pages/furniture_customer/furniture_customer.vue:572", "[FurnitureCustomer][onReady] tab栏元素未找到!");
|
||
} else {
|
||
common_vendor.index.__f__("log", "at pages/furniture_customer/furniture_customer.vue:574", "[FurnitureCustomer][onReady] tab栏位置:", {
|
||
top: data.top,
|
||
left: data.left,
|
||
width: data.width,
|
||
height: data.height,
|
||
expectedTop: this.navbarTop,
|
||
isVisible: data.width > 0 && data.height > 0,
|
||
isOnScreen: data.top >= 0 && data.top < systemInfo.windowHeight
|
||
});
|
||
if (data.width === 0 || data.height === 0 || data.top < 0) {
|
||
common_vendor.index.__f__("warn", "at pages/furniture_customer/furniture_customer.vue:586", "[FurnitureCustomer][onReady] tab栏不可见,强制更新位置");
|
||
this.updateNavbarPosition();
|
||
this.$forceUpdate();
|
||
}
|
||
}
|
||
}).exec();
|
||
}, 100);
|
||
},
|
||
onUnload() {
|
||
if (this.innerAudioContext) {
|
||
try {
|
||
this.innerAudioContext.stop();
|
||
this.innerAudioContext.destroy();
|
||
} catch (e) {
|
||
common_vendor.index.__f__("error", "at pages/furniture_customer/furniture_customer.vue:602", "销毁音频播放器失败:", e);
|
||
}
|
||
this.innerAudioContext = null;
|
||
}
|
||
this.currentAudioUrl = null;
|
||
this.playingAudioId = null;
|
||
},
|
||
methods: {
|
||
// 计算并更新导航栏和内容区域的位置
|
||
updateNavbarPosition() {
|
||
common_vendor.index.__f__("log", "at pages/furniture_customer/furniture_customer.vue:622", "[FurnitureCustomer][updateNavbarPosition] 开始更新导航栏位置");
|
||
const systemInfo = common_vendor.index.getSystemInfoSync();
|
||
const statusBarHeight = systemInfo.statusBarHeight || 20;
|
||
const navbarHeight = 44;
|
||
const statusBarHeightRpx = statusBarHeight * 2;
|
||
const navbarHeightRpx = navbarHeight * 2;
|
||
const totalNavbarHeight = statusBarHeightRpx + navbarHeightRpx;
|
||
const navbarTop = totalNavbarHeight + "rpx";
|
||
const contentTop = totalNavbarHeight + 72 + "rpx";
|
||
common_vendor.index.__f__("log", "at pages/furniture_customer/furniture_customer.vue:634", "[FurnitureCustomer][updateNavbarPosition] 更新导航栏位置:", {
|
||
statusBarHeight,
|
||
navbarHeight,
|
||
totalNavbarHeight,
|
||
navbarTop,
|
||
contentTop,
|
||
currentNavbarTop: this.navbarTop,
|
||
currentContentTop: this.contentTop
|
||
});
|
||
this.$set(this, "navbarTop", navbarTop);
|
||
this.$set(this, "contentTop", contentTop);
|
||
this.$forceUpdate();
|
||
},
|
||
goBack() {
|
||
const pages = getCurrentPages();
|
||
if (pages.length <= 1) {
|
||
common_vendor.index.__f__("log", "at pages/furniture_customer/furniture_customer.vue:659", "[FurnitureCustomer][goBack] 当前是第一个页面,无法返回");
|
||
return;
|
||
}
|
||
common_vendor.index.navigateBack({
|
||
fail: (err) => {
|
||
common_vendor.index.__f__("error", "at pages/furniture_customer/furniture_customer.vue:664", "[FurnitureCustomer][goBack] 返回失败:", err);
|
||
}
|
||
});
|
||
},
|
||
switchTab(tab) {
|
||
this.activeTab = tab;
|
||
if (tab === "service" && this.serviceList.length === 0) {
|
||
this.loadServiceList();
|
||
}
|
||
},
|
||
// 刷新服务记录列表
|
||
refreshServiceList(filterParams = {}) {
|
||
this.serviceListPage.current = 1;
|
||
this.loadServiceList(filterParams);
|
||
},
|
||
// 服务记录列表到底部加载更多
|
||
onServiceListReachBottom() {
|
||
if (this.serviceList.length >= this.serviceListTotal) {
|
||
return;
|
||
}
|
||
this.serviceListPage.current += 1;
|
||
this.loadServiceList();
|
||
},
|
||
async viewDetail(item) {
|
||
this.currentServiceDetail = { ...item };
|
||
this.todoList = [];
|
||
this.todoListTotal = 0;
|
||
this.chapterSummaryList = [];
|
||
if (this.activeDetailTab === "todo") {
|
||
this.loadTodoList();
|
||
}
|
||
if (this.activeDetailTab === "chapter") {
|
||
this.loadChapterSummary();
|
||
}
|
||
if (this.activeDetailTab === "performance") {
|
||
this.loadPerformanceData();
|
||
}
|
||
this.$refs.serviceDetailPopup.open();
|
||
},
|
||
// 处理菜单操作
|
||
async handleMenuAction({ action, item }) {
|
||
common_vendor.index.__f__("log", "at pages/furniture_customer/furniture_customer.vue:719", "父组件收到菜单操作:", action, item);
|
||
switch (action) {
|
||
case "view":
|
||
this.viewDetail(item);
|
||
break;
|
||
case "analysis":
|
||
break;
|
||
case "audio":
|
||
await this.loadAudioSegments(item);
|
||
break;
|
||
case "delete":
|
||
await this.deleteServiceRecord(item);
|
||
break;
|
||
default:
|
||
common_vendor.index.__f__("warn", "at pages/furniture_customer/furniture_customer.vue:737", "未知的菜单操作:", action);
|
||
}
|
||
},
|
||
// 处理列表项更新
|
||
handleUpdateItem({ recordId, data }) {
|
||
const index = this.serviceList.findIndex(
|
||
(serviceItem) => {
|
||
var _a;
|
||
return (serviceItem.id || ((_a = serviceItem.rawData) == null ? void 0 : _a.id)) === recordId;
|
||
}
|
||
);
|
||
if (index !== -1) {
|
||
this.$set(this.serviceList, index, data);
|
||
}
|
||
},
|
||
// 删除服务记录
|
||
async deleteServiceRecord(item) {
|
||
var _a, _b;
|
||
common_vendor.index.__f__("log", "at pages/furniture_customer/furniture_customer.vue:752", "删除服务记录,item:", item);
|
||
const res = await new Promise((resolve) => {
|
||
common_vendor.index.showModal({
|
||
title: "确认删除",
|
||
content: "确定要删除这条服务记录吗?删除后无法恢复。",
|
||
confirmText: "删除",
|
||
confirmColor: "#FF3B30",
|
||
cancelText: "取消",
|
||
success: (result) => {
|
||
resolve(result.confirm);
|
||
},
|
||
fail: () => {
|
||
resolve(false);
|
||
}
|
||
});
|
||
});
|
||
if (!res) {
|
||
return;
|
||
}
|
||
try {
|
||
const recordId = item.id || ((_a = item.rawData) == null ? void 0 : _a.id);
|
||
if (!recordId) {
|
||
common_vendor.index.showToast({
|
||
title: "无法获取记录ID",
|
||
icon: "none"
|
||
});
|
||
return;
|
||
}
|
||
const url = common_config.getApiUrl(`/api/audioManagement/delete/${recordId}`);
|
||
let tenantId = "";
|
||
let token = "";
|
||
try {
|
||
tenantId = common_vendor.index.getStorageSync("backend-tenant-id") || "";
|
||
token = common_vendor.index.getStorageSync("backend-token") || "";
|
||
} catch (e) {
|
||
common_vendor.index.__f__("error", "at pages/furniture_customer/furniture_customer.vue:795", "获取认证信息失败:", e);
|
||
}
|
||
const headers = {
|
||
"Content-Type": "application/json"
|
||
};
|
||
if (token) {
|
||
headers["Authorization"] = `Bearer ${token}`;
|
||
}
|
||
if (tenantId) {
|
||
headers["X-Tenant-Id"] = tenantId;
|
||
}
|
||
const deleteRes = await common_vendor.index.request({
|
||
url,
|
||
method: "DELETE",
|
||
header: headers,
|
||
timeout: 1e4
|
||
});
|
||
if (deleteRes.statusCode === 200 && deleteRes.data && deleteRes.data.success) {
|
||
common_vendor.index.showToast({
|
||
title: "删除成功",
|
||
icon: "success"
|
||
});
|
||
this.serviceListPage.current = 1;
|
||
this.serviceList = [];
|
||
await this.loadServiceList();
|
||
} else {
|
||
common_vendor.index.showToast({
|
||
title: ((_b = deleteRes.data) == null ? void 0 : _b.message) || "删除失败",
|
||
icon: "none"
|
||
});
|
||
}
|
||
} catch (error) {
|
||
common_vendor.index.__f__("error", "at pages/furniture_customer/furniture_customer.vue:832", "删除服务记录失败:", error);
|
||
common_vendor.index.showToast({
|
||
title: `删除失败: ${error.errMsg || error.message || "未知错误"}`,
|
||
icon: "none"
|
||
});
|
||
}
|
||
},
|
||
// 加载录音分段列表
|
||
async loadAudioSegments(item) {
|
||
var _a, _b;
|
||
try {
|
||
const parentId = ((_a = item.rawData) == null ? void 0 : _a.id) || item.id;
|
||
if (!parentId) {
|
||
common_vendor.index.showToast({
|
||
title: "无法获取录音ID",
|
||
icon: "none"
|
||
});
|
||
return;
|
||
}
|
||
this.audioSegmentsLoading = true;
|
||
this.audioSegmentsList = [];
|
||
common_vendor.index.showLoading({
|
||
title: "加载中..."
|
||
});
|
||
const url = `${common_config.getApiUrl("/api/audioManagementSegments/listByParentId")}?parentId=${parentId}`;
|
||
let tenantId = "";
|
||
let token = "";
|
||
try {
|
||
tenantId = common_vendor.index.getStorageSync("backend-tenant-id") || "";
|
||
token = common_vendor.index.getStorageSync("backend-token") || "";
|
||
} catch (e) {
|
||
common_vendor.index.__f__("error", "at pages/furniture_customer/furniture_customer.vue:869", "获取认证信息失败:", e);
|
||
}
|
||
const headers = {
|
||
"Content-Type": "application/json"
|
||
};
|
||
if (token) {
|
||
headers["Authorization"] = `Bearer ${token}`;
|
||
}
|
||
if (tenantId) {
|
||
headers["X-Tenant-Id"] = tenantId;
|
||
}
|
||
const res = await common_vendor.index.request({
|
||
url,
|
||
method: "GET",
|
||
header: headers,
|
||
timeout: 1e4
|
||
});
|
||
common_vendor.index.hideLoading();
|
||
if (res.statusCode === 200 && res.data && res.data.success) {
|
||
const segments = res.data.data || [];
|
||
common_vendor.index.__f__("log", "at pages/furniture_customer/furniture_customer.vue:894", "录音分段列表:", segments);
|
||
this.audioSegmentsList = segments;
|
||
this.audioSegmentsLoading = false;
|
||
this.$refs.audioListPopup.open();
|
||
} else {
|
||
common_vendor.index.showToast({
|
||
title: ((_b = res.data) == null ? void 0 : _b.message) || "获取录音分段失败",
|
||
icon: "none"
|
||
});
|
||
}
|
||
} catch (error) {
|
||
common_vendor.index.hideLoading();
|
||
this.audioSegmentsLoading = false;
|
||
common_vendor.index.__f__("error", "at pages/furniture_customer/furniture_customer.vue:911", "获取录音分段列表失败:", error);
|
||
common_vendor.index.showToast({
|
||
title: `获取录音分段失败: ${error.errMsg || error.message || "未知错误"}`,
|
||
icon: "none"
|
||
});
|
||
}
|
||
},
|
||
// 关闭录音列表弹窗
|
||
closeAudioList() {
|
||
if (this.playingAudioId) {
|
||
this.stopAudioPlay({ id: this.playingAudioId });
|
||
}
|
||
this.$refs.audioListPopup.close();
|
||
},
|
||
// 切换录音播放/暂停
|
||
async toggleAudioPlay(item, index) {
|
||
try {
|
||
const audioId = item.id || item.segmentId;
|
||
if (!audioId) {
|
||
common_vendor.index.__f__("warn", "at pages/furniture_customer/furniture_customer.vue:932", "录音项缺少ID:", item);
|
||
common_vendor.index.showToast({
|
||
title: "无法获取录音ID",
|
||
icon: "none"
|
||
});
|
||
return;
|
||
}
|
||
if (this.playingAudioId === audioId) {
|
||
await this.stopAudioPlay(item);
|
||
} else {
|
||
if (this.playingAudioId) {
|
||
await this.stopAudioPlay({ id: this.playingAudioId });
|
||
}
|
||
this.currentRecordingText = item.recordingText || "";
|
||
this.showTextModal = true;
|
||
this.$refs.textModalPopup.open();
|
||
await this.startAudioPlay(item);
|
||
}
|
||
} catch (error) {
|
||
common_vendor.index.__f__("error", "at pages/furniture_customer/furniture_customer.vue:958", "切换播放状态失败:", error);
|
||
common_vendor.index.showToast({
|
||
title: "操作失败",
|
||
icon: "none"
|
||
});
|
||
}
|
||
},
|
||
// 关闭文本内容弹框
|
||
closeTextModal() {
|
||
this.showTextModal = false;
|
||
this.currentRecordingText = "";
|
||
this.$refs.textModalPopup.close();
|
||
},
|
||
// 文本弹框状态变化
|
||
onTextModalChange(e) {
|
||
if (!e.show) {
|
||
this.showTextModal = false;
|
||
this.currentRecordingText = "";
|
||
}
|
||
},
|
||
// 开始播放录音
|
||
async startAudioPlay(item) {
|
||
try {
|
||
const audioId = item.id || item.segmentId;
|
||
if (!audioId) {
|
||
common_vendor.index.__f__("warn", "at pages/furniture_customer/furniture_customer.vue:985", "录音项缺少ID:", item);
|
||
common_vendor.index.showToast({
|
||
title: "无法获取录音ID",
|
||
icon: "none"
|
||
});
|
||
return;
|
||
}
|
||
if (this.innerAudioContext) {
|
||
this.innerAudioContext.stop();
|
||
this.innerAudioContext.destroy();
|
||
this.innerAudioContext = null;
|
||
}
|
||
common_vendor.index.showLoading({
|
||
title: "加载中..."
|
||
});
|
||
let tenantId = "";
|
||
let token = "";
|
||
try {
|
||
tenantId = common_vendor.index.getStorageSync("backend-tenant-id") || "";
|
||
token = common_vendor.index.getStorageSync("backend-token") || "";
|
||
} catch (e) {
|
||
common_vendor.index.__f__("error", "at pages/furniture_customer/furniture_customer.vue:1011", "获取认证信息失败:", e);
|
||
}
|
||
const url = common_config.getApiUrl(`/api/audioManagementSegments/playSegmentById/${audioId}`);
|
||
common_vendor.index.__f__("log", "at pages/furniture_customer/furniture_customer.vue:1020", "请求音频URL:", url);
|
||
common_vendor.index.__f__("log", "at pages/furniture_customer/furniture_customer.vue:1021", "音频ID:", audioId);
|
||
const headers = {
|
||
"Content-Type": "application/json"
|
||
};
|
||
if (token) {
|
||
headers["Authorization"] = `Bearer ${token}`;
|
||
}
|
||
if (tenantId) {
|
||
headers["X-Tenant-Id"] = tenantId;
|
||
}
|
||
common_vendor.index.__f__("log", "at pages/furniture_customer/furniture_customer.vue:1034", "请求头:", headers);
|
||
const res = await common_vendor.index.request({
|
||
url,
|
||
method: "POST",
|
||
header: headers,
|
||
responseType: "arraybuffer",
|
||
// 接收二进制数据
|
||
timeout: 3e4
|
||
// 音频文件可能较大,增加超时时间
|
||
});
|
||
common_vendor.index.__f__("log", "at pages/furniture_customer/furniture_customer.vue:1046", "响应状态码:", res.statusCode);
|
||
common_vendor.index.__f__("log", "at pages/furniture_customer/furniture_customer.vue:1047", "响应头:", res.header);
|
||
if (res.statusCode !== 200) {
|
||
common_vendor.index.__f__("error", "at pages/furniture_customer/furniture_customer.vue:1050", "请求失败,状态码:", res.statusCode);
|
||
common_vendor.index.__f__("error", "at pages/furniture_customer/furniture_customer.vue:1051", "响应数据:", res.data);
|
||
if (res.statusCode === 404) {
|
||
throw new Error(`接口路径不存在(404),请检查后端接口路径是否正确。当前URL: ${url}`);
|
||
}
|
||
throw new Error(`请求失败,状态码: ${res.statusCode}`);
|
||
}
|
||
let audioType = "audio/mpeg";
|
||
if (res.header && res.header["Content-Type"]) {
|
||
audioType = res.header["Content-Type"];
|
||
} else if (res.header && res.header["content-type"]) {
|
||
audioType = res.header["content-type"];
|
||
}
|
||
const base64 = common_vendor.index.arrayBufferToBase64(res.data);
|
||
const audioUrl = `data:${audioType};base64,${base64}`;
|
||
this.currentAudioUrl = audioUrl;
|
||
const innerAudioContext = common_vendor.index.createInnerAudioContext();
|
||
innerAudioContext.src = audioUrl;
|
||
innerAudioContext.onPlay(() => {
|
||
common_vendor.index.__f__("log", "at pages/furniture_customer/furniture_customer.vue:1090", "开始播放音频");
|
||
common_vendor.index.hideLoading();
|
||
this.playingAudioId = audioId;
|
||
common_vendor.index.showToast({
|
||
title: "开始播放",
|
||
icon: "success",
|
||
duration: 1e3
|
||
});
|
||
});
|
||
innerAudioContext.onError((error) => {
|
||
common_vendor.index.__f__("error", "at pages/furniture_customer/furniture_customer.vue:1102", "音频播放错误:", error);
|
||
common_vendor.index.hideLoading();
|
||
this.playingAudioId = null;
|
||
innerAudioContext.destroy();
|
||
this.innerAudioContext = null;
|
||
this.currentAudioUrl = null;
|
||
common_vendor.index.showToast({
|
||
title: "播放失败,请检查网络或音频文件",
|
||
icon: "none",
|
||
duration: 2e3
|
||
});
|
||
});
|
||
innerAudioContext.onEnded(() => {
|
||
common_vendor.index.__f__("log", "at pages/furniture_customer/furniture_customer.vue:1123", "音频播放结束");
|
||
this.playingAudioId = null;
|
||
innerAudioContext.destroy();
|
||
this.innerAudioContext = null;
|
||
this.currentAudioUrl = null;
|
||
});
|
||
innerAudioContext.onPause(() => {
|
||
common_vendor.index.__f__("log", "at pages/furniture_customer/furniture_customer.vue:1138", "音频播放暂停");
|
||
this.playingAudioId = null;
|
||
});
|
||
this.innerAudioContext = innerAudioContext;
|
||
innerAudioContext.play();
|
||
} catch (error) {
|
||
common_vendor.index.hideLoading();
|
||
common_vendor.index.__f__("error", "at pages/furniture_customer/furniture_customer.vue:1150", "播放录音失败:", error);
|
||
if (this.innerAudioContext) {
|
||
this.innerAudioContext.destroy();
|
||
this.innerAudioContext = null;
|
||
}
|
||
this.playingAudioId = null;
|
||
common_vendor.index.showToast({
|
||
title: `播放失败: ${error.errMsg || error.message || "未知错误"}`,
|
||
icon: "none",
|
||
duration: 2e3
|
||
});
|
||
}
|
||
},
|
||
// 停止播放录音
|
||
async stopAudioPlay(item) {
|
||
try {
|
||
if (this.innerAudioContext) {
|
||
this.innerAudioContext.stop();
|
||
this.innerAudioContext.destroy();
|
||
this.innerAudioContext = null;
|
||
}
|
||
this.playingAudioId = null;
|
||
common_vendor.index.showToast({
|
||
title: "已停止",
|
||
icon: "success",
|
||
duration: 1e3
|
||
});
|
||
} catch (error) {
|
||
if (this.innerAudioContext) {
|
||
try {
|
||
this.innerAudioContext.stop();
|
||
this.innerAudioContext.destroy();
|
||
} catch (e) {
|
||
common_vendor.index.__f__("error", "at pages/furniture_customer/furniture_customer.vue:1188", "销毁音频播放器失败:", e);
|
||
}
|
||
this.innerAudioContext = null;
|
||
}
|
||
this.playingAudioId = null;
|
||
common_vendor.index.__f__("error", "at pages/furniture_customer/furniture_customer.vue:1193", "停止播放失败:", error);
|
||
common_vendor.index.showToast({
|
||
title: "已停止",
|
||
icon: "success",
|
||
duration: 1e3
|
||
});
|
||
}
|
||
},
|
||
// 转文本
|
||
async transcribeAudio(item, index) {
|
||
var _a;
|
||
try {
|
||
const audioId = item.id || item.segmentId;
|
||
if (!audioId) {
|
||
common_vendor.index.showToast({
|
||
title: "无法获取录音ID",
|
||
icon: "none"
|
||
});
|
||
return;
|
||
}
|
||
if (this.transcribingIds.includes(audioId)) {
|
||
return;
|
||
}
|
||
this.transcribingIds.push(audioId);
|
||
const url = common_config.getApiUrl(`/api/audioManagementSegments/transcribe/${audioId}`);
|
||
let tenantId = "";
|
||
let token = "";
|
||
try {
|
||
tenantId = common_vendor.index.getStorageSync("backend-tenant-id") || "";
|
||
token = common_vendor.index.getStorageSync("backend-token") || "";
|
||
} catch (e) {
|
||
common_vendor.index.__f__("error", "at pages/furniture_customer/furniture_customer.vue:1232", "获取认证信息失败:", e);
|
||
}
|
||
const headers = {
|
||
"Content-Type": "application/json"
|
||
};
|
||
if (token) {
|
||
headers["Authorization"] = `Bearer ${token}`;
|
||
}
|
||
if (tenantId) {
|
||
headers["X-Tenant-Id"] = tenantId;
|
||
}
|
||
const res = await common_vendor.index.request({
|
||
url,
|
||
method: "POST",
|
||
header: headers,
|
||
timeout: 3e4
|
||
// 转文本可能需要较长时间
|
||
});
|
||
const idIndex = this.transcribingIds.indexOf(audioId);
|
||
if (idIndex > -1) {
|
||
this.transcribingIds.splice(idIndex, 1);
|
||
}
|
||
if (res.statusCode === 200 && res.data && res.data.success) {
|
||
common_vendor.index.showToast({
|
||
title: res.data.message || "转文本请求已提交",
|
||
icon: "success",
|
||
duration: 2e3
|
||
});
|
||
if (res.data.data) {
|
||
this.$set(this.audioSegmentsList, index, {
|
||
...item,
|
||
...res.data.data
|
||
});
|
||
} else {
|
||
}
|
||
} else {
|
||
common_vendor.index.showToast({
|
||
title: ((_a = res.data) == null ? void 0 : _a.message) || "转文本请求失败",
|
||
icon: "none",
|
||
duration: 2e3
|
||
});
|
||
}
|
||
} catch (error) {
|
||
const audioId = item.id || item.segmentId;
|
||
const idIndex = this.transcribingIds.indexOf(audioId);
|
||
if (idIndex > -1) {
|
||
this.transcribingIds.splice(idIndex, 1);
|
||
}
|
||
common_vendor.index.__f__("error", "at pages/furniture_customer/furniture_customer.vue:1293", "转文本失败:", error);
|
||
common_vendor.index.showToast({
|
||
title: `转文本失败: ${error.errMsg || error.message || "未知错误"}`,
|
||
icon: "none",
|
||
duration: 2e3
|
||
});
|
||
}
|
||
},
|
||
// 格式化时长(秒转换为时分秒)
|
||
formatDuration(seconds) {
|
||
if (!seconds)
|
||
return "00:00:00";
|
||
const hours = Math.floor(seconds / 3600);
|
||
const minutes = Math.floor(seconds % 3600 / 60);
|
||
const secs = seconds % 60;
|
||
return `${String(hours).padStart(2, "0")}:${String(minutes).padStart(2, "0")}:${String(secs).padStart(2, "0")}`;
|
||
},
|
||
// 格式化日期时间
|
||
formatDateTime(dateTime) {
|
||
if (!dateTime)
|
||
return "";
|
||
const date = new Date(dateTime);
|
||
const year = date.getFullYear();
|
||
const month = String(date.getMonth() + 1).padStart(2, "0");
|
||
const day = String(date.getDate()).padStart(2, "0");
|
||
const hours = String(date.getHours()).padStart(2, "0");
|
||
const minutes = String(date.getMinutes()).padStart(2, "0");
|
||
const seconds = String(date.getSeconds()).padStart(2, "0");
|
||
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
|
||
},
|
||
// 格式化录音文件名:只显示第一个中划线之后和最后一个中划线之前的内容
|
||
formatAudioFileName(fileName) {
|
||
if (!fileName)
|
||
return "未命名录音";
|
||
const firstDashIndex = fileName.indexOf("-");
|
||
if (firstDashIndex === -1) {
|
||
return fileName;
|
||
}
|
||
const lastDashIndex = fileName.lastIndexOf("-");
|
||
if (firstDashIndex === lastDashIndex) {
|
||
return fileName.substring(firstDashIndex + 1);
|
||
}
|
||
return fileName.substring(firstDashIndex + 1, lastDashIndex);
|
||
},
|
||
// 截断文本,只显示指定长度
|
||
truncateText(text, maxLength) {
|
||
if (!text)
|
||
return "";
|
||
if (text.length <= maxLength)
|
||
return text;
|
||
return text.substring(0, maxLength) + "...";
|
||
},
|
||
closeDetail() {
|
||
this.$refs.serviceDetailPopup.close();
|
||
},
|
||
shareDetail() {
|
||
common_vendor.index.showToast({
|
||
title: "分享功能",
|
||
icon: "none"
|
||
});
|
||
},
|
||
togglePlay() {
|
||
this.isPlaying = !this.isPlaying;
|
||
},
|
||
switchDetailTab(tab) {
|
||
this.activeDetailTab = tab;
|
||
if (tab === "todo") {
|
||
this.loadTodoList();
|
||
}
|
||
if (tab === "chapter") {
|
||
this.loadChapterSummary();
|
||
}
|
||
if (tab === "performance") {
|
||
this.loadPerformanceData();
|
||
}
|
||
},
|
||
getDetailTabName(tab) {
|
||
const names = {
|
||
"todo": "智能待办",
|
||
"chapter": "章节概要",
|
||
"performance": "服务表现"
|
||
};
|
||
return names[tab] || "";
|
||
},
|
||
initSummaryList(item) {
|
||
this.summaryList = pages_furniture_customer_utils_dataInit.initSummaryList(item);
|
||
this.performanceData = pages_furniture_customer_utils_dataInit.initPerformanceData();
|
||
},
|
||
// 加载家具意向分析数据
|
||
async loadFurnitureAnalysis(item) {
|
||
var _a, _b;
|
||
try {
|
||
const parentId = ((_a = item.rawData) == null ? void 0 : _a.id) || item.id;
|
||
if (!parentId) {
|
||
common_vendor.index.__f__("warn", "at pages/furniture_customer/furniture_customer.vue:1391", "无法获取parentId");
|
||
this.furnitureAnalysisList = [];
|
||
return;
|
||
}
|
||
const url = `${common_config.getApiUrl("/api/audioTextAnalysisFurniture/byParentId")}?parentId=${parentId}`;
|
||
const res = await common_vendor.index.request({
|
||
url,
|
||
method: "GET",
|
||
timeout: 1e4
|
||
});
|
||
if (res.statusCode === 200 && res.data && res.data.success) {
|
||
this.furnitureAnalysisList = res.data.data || [];
|
||
if (this.furnitureAnalysisList.length > 0) {
|
||
this.updateSummaryWithFurnitureData();
|
||
}
|
||
} else {
|
||
common_vendor.index.__f__("warn", "at pages/furniture_customer/furniture_customer.vue:1412", "获取家具意向分析失败:", ((_b = res.data) == null ? void 0 : _b.message) || "未知错误");
|
||
this.furnitureAnalysisList = [];
|
||
}
|
||
} catch (error) {
|
||
common_vendor.index.__f__("error", "at pages/furniture_customer/furniture_customer.vue:1416", "获取家具意向分析失败:", error);
|
||
this.furnitureAnalysisList = [];
|
||
}
|
||
},
|
||
// 用家具意向分析数据更新会话总结
|
||
updateSummaryWithFurnitureData() {
|
||
if (this.furnitureAnalysisList.length === 0)
|
||
return;
|
||
const firstItem = this.furnitureAnalysisList[0];
|
||
const summaryItems = [];
|
||
if (firstItem.customerType) {
|
||
summaryItems.push({
|
||
label: "客户类型",
|
||
value: firstItem.customerType,
|
||
rawData: firstItem
|
||
});
|
||
}
|
||
if (firstItem.familyStructure) {
|
||
summaryItems.push({
|
||
label: "家庭结构",
|
||
value: firstItem.familyStructure,
|
||
rawData: firstItem
|
||
});
|
||
}
|
||
if (firstItem.summarySentence) {
|
||
this.summarySentence = firstItem.summarySentence;
|
||
}
|
||
if (firstItem.dealKeyPoints) {
|
||
this.dealKeyPoints = firstItem.dealKeyPoints;
|
||
} else if (firstItem.summarySentence) {
|
||
const keyWords = [];
|
||
const summary = firstItem.summarySentence;
|
||
if (summary.includes("优惠") || summary.includes("活动")) {
|
||
keyWords.push("活动优惠");
|
||
}
|
||
if (summary.includes("搭配")) {
|
||
keyWords.push("整套搭配");
|
||
}
|
||
if (summary.includes("环保")) {
|
||
keyWords.push("环保");
|
||
}
|
||
if (summary.includes("安全")) {
|
||
keyWords.push("安全");
|
||
}
|
||
if (summary.includes("交付") || summary.includes("周期")) {
|
||
keyWords.push("快速交付");
|
||
}
|
||
if (summary.includes("退换") || summary.includes("服务")) {
|
||
keyWords.push("无忧退换服务");
|
||
}
|
||
if (keyWords.length > 0) {
|
||
this.dealKeyPoints = keyWords.join(",");
|
||
}
|
||
}
|
||
if (summaryItems.length > 0) {
|
||
this.summaryList = summaryItems;
|
||
}
|
||
this.buildProductRequirementList(firstItem);
|
||
},
|
||
// 构建产品需求清单(固定显示所有产品类别)
|
||
buildProductRequirementList(data) {
|
||
const categories = [
|
||
{ key: "sofa", name: "沙发", field: "sofa" },
|
||
{ key: "bed", name: "床", field: "bedAndMattress" },
|
||
{ key: "mattress", name: "床垫", field: "bedAndMattress" },
|
||
{ key: "dining_table", name: "餐桌椅", field: "diningTable" },
|
||
{ key: "tea_table", name: "茶几", field: "teaTable" },
|
||
{ key: "tv_cabinet", name: "电视柜", field: "tvCabinet" },
|
||
{ key: "study_desk", name: "学习桌", field: "studyDesk" },
|
||
{ key: "cabinet", name: "橱柜", field: "cabinet" },
|
||
{ key: "wine_cabinet", name: "酒柜", field: "wineCabinet" },
|
||
{ key: "master_bedroom_cabinet", name: "主卧衣柜", field: "masterBedroomCabinet" },
|
||
{ key: "secondary_bedroom_cabinet", name: "次卧衣柜", field: "secondaryBedroomCabinet" },
|
||
{ key: "shoe_cabinet", name: "鞋柜", field: "shoeCabinet" },
|
||
{ key: "custom", name: "定制家居", field: null }
|
||
];
|
||
const requirementMap = {};
|
||
const categoryList = [];
|
||
categories.forEach((category) => {
|
||
let hasData = false;
|
||
let productData = null;
|
||
if (category.key === "bed" || category.key === "mattress") {
|
||
const fieldValue = data.bedAndMattress || data.bed_and_mattress || "";
|
||
if (fieldValue && fieldValue.trim()) {
|
||
hasData = true;
|
||
productData = this.parseProductJson(fieldValue);
|
||
}
|
||
} else if (category.key === "custom") {
|
||
hasData = false;
|
||
} else {
|
||
const fieldValue = data[category.field] || data[this.toSnakeCase(category.field)] || "";
|
||
if (fieldValue && fieldValue.trim()) {
|
||
hasData = true;
|
||
productData = this.parseProductJson(fieldValue);
|
||
}
|
||
}
|
||
if (hasData) {
|
||
categoryList.push({ key: category.key, name: category.name });
|
||
const rows = this.buildProductDimensionRows(productData, data, category.key);
|
||
requirementMap[category.key] = { rows };
|
||
}
|
||
});
|
||
this.productRequirementMap = requirementMap;
|
||
this.productCategoryList = categoryList;
|
||
if (categoryList.length > 0) {
|
||
this.activeProductCategory = categoryList[0].key;
|
||
}
|
||
},
|
||
// 解析产品JSON字符串
|
||
parseProductJson(jsonString) {
|
||
if (!jsonString || typeof jsonString !== "string") {
|
||
return null;
|
||
}
|
||
try {
|
||
const parsed = JSON.parse(jsonString);
|
||
return parsed;
|
||
} catch (error) {
|
||
common_vendor.index.__f__("warn", "at pages/furniture_customer/furniture_customer.vue:1565", "解析产品JSON失败:", error, jsonString);
|
||
return null;
|
||
}
|
||
},
|
||
// 驼峰转蛇形命名
|
||
toSnakeCase(str) {
|
||
if (!str)
|
||
return "";
|
||
return str.replace(/([A-Z])/g, "_$1").toLowerCase().replace(/^_/, "");
|
||
},
|
||
// 切换产品类别
|
||
switchProductCategory(categoryKey) {
|
||
this.activeProductCategory = categoryKey;
|
||
},
|
||
// 获取产品类别名称
|
||
getProductCategoryName(categoryKey) {
|
||
const category = this.productCategoryList.find((item) => item.key === categoryKey);
|
||
return category ? category.name : "";
|
||
},
|
||
// 获取所有产品类别名称(用于意向产品清单显示)
|
||
getProductCategoryNames() {
|
||
return this.productCategoryList.map((item) => item.name).join(",");
|
||
},
|
||
parseProductAttributes(productKey, requirementText, data) {
|
||
const attributes = {};
|
||
const text = (requirementText || "").trim();
|
||
if (!text)
|
||
return attributes;
|
||
const matchFirst = (pattern) => {
|
||
const result = text.match(pattern);
|
||
return result ? result[0] : "";
|
||
};
|
||
switch (productKey) {
|
||
case "sofa":
|
||
attributes.type = matchFirst(/(L型|L形|一字型|U型|U形|带贵妃榻|贵妃榻|三人位|四人位|转角|组合)/);
|
||
attributes.material = matchFirst(/(真皮|科技布|布艺|布|皮质|皮革|实木|板式|棉麻|绒布)/);
|
||
attributes.size = matchFirst(/(\d+\.?\d*)\s*(米|m|平米|平方米)/);
|
||
attributes.color = matchFirst(/(米白|白色|灰色|黑色|棕色|蓝色|绿色|暖色调|冷色调|灰白色系)/);
|
||
attributes.style = matchFirst(/(现代简约|简约现代|现代|北欧|中式|美式|欧式|工业风|原木风|简约|极简)/);
|
||
if (text.includes("储物") || text.includes("收纳"))
|
||
attributes.feature = "储物";
|
||
if (text.includes("好打理"))
|
||
attributes.remark = "要求好打理";
|
||
break;
|
||
case "bed":
|
||
attributes.size = matchFirst(/(\d+\.?\d*)\s*(米|m)/);
|
||
attributes.material = matchFirst(/(实木|板式|软包|皮质|布艺)/);
|
||
attributes.style = data.decorationStyle || "";
|
||
if (text.includes("主卧"))
|
||
attributes.remark = "主卧";
|
||
break;
|
||
case "mattress":
|
||
attributes.size = matchFirst(/(\d+\.?\d*)\s*(米|m)/);
|
||
attributes.material = matchFirst(/(弹簧|记忆棉|乳胶|椰棕|海绵)/);
|
||
if (text.includes("分区支撑"))
|
||
attributes.softness = "分区支撑(兼顾软硬需求)";
|
||
else if (text.includes("偏软") || text.includes("软"))
|
||
attributes.softness = "偏软";
|
||
else if (text.includes("偏硬") || text.includes("硬"))
|
||
attributes.softness = "偏硬";
|
||
break;
|
||
case "dining_table":
|
||
if (text.includes("伸缩"))
|
||
attributes.type = "可伸缩";
|
||
const rangeMatch = text.match(/(\d+\.?\d*)\s*[-~到]\s*(\d+\.?\d*)\s*米/);
|
||
if (rangeMatch)
|
||
attributes.size = `${rangeMatch[1]}-${rangeMatch[2]}米`;
|
||
else
|
||
attributes.size = matchFirst(/(\d+\.?\d*)\s*米/);
|
||
attributes.chairCount = matchFirst(/(\d+)\s*把/);
|
||
if (text.includes("舒适"))
|
||
attributes.feature = "舒适型";
|
||
attributes.style = data.decorationStyle || "";
|
||
break;
|
||
case "tea_table":
|
||
if (text.includes("抽屉"))
|
||
attributes.type = "带抽屉";
|
||
if (text.includes("储物") || text.includes("收纳"))
|
||
attributes.feature = "储物";
|
||
attributes.style = data.decorationStyle || "";
|
||
break;
|
||
case "tv_cabinet":
|
||
if (text.includes("组合"))
|
||
attributes.type = "组合式";
|
||
if (text.includes("储物"))
|
||
attributes.feature = "储物";
|
||
attributes.style = data.decorationStyle || "";
|
||
break;
|
||
case "study_desk":
|
||
if (text.includes("可调节") || text.includes("调节高度"))
|
||
attributes.type = "可调节高度";
|
||
if (text.includes("成长"))
|
||
attributes.feature = "适应孩子成长";
|
||
break;
|
||
case "wine_cabinet":
|
||
if (text.includes("恒温"))
|
||
attributes.feature = "恒温";
|
||
const capacity = text.match(/(\d+)[-~到](\d+)\s*瓶|(\d+)\s*瓶/);
|
||
if (capacity) {
|
||
if (capacity[1] && capacity[2])
|
||
attributes.capacity = `${capacity[1]}-${capacity[2]}瓶`;
|
||
else if (capacity[3])
|
||
attributes.capacity = `${capacity[3]}瓶`;
|
||
}
|
||
break;
|
||
case "master_bedroom_cabinet":
|
||
case "secondary_bedroom_cabinet":
|
||
if (text.includes("定制") || text.includes("整墙"))
|
||
attributes.type = text.includes("整墙") ? "整墙定制" : "定制";
|
||
attributes.size = matchFirst(/(\d+\.?\d*)\s*(米|m)/);
|
||
if (text.includes("衣帽间"))
|
||
attributes.feature = "带衣帽间";
|
||
if (text.includes("主卧"))
|
||
attributes.remark = "主卧";
|
||
if (text.includes("次卧"))
|
||
attributes.remark = "次卧";
|
||
break;
|
||
case "shoe_cabinet":
|
||
if (text.includes("窄款") || text.includes("高型"))
|
||
attributes.type = "窄款高型";
|
||
attributes.size = matchFirst(/(\d+\.?\d*)\s*(米|m)/);
|
||
if (text.includes("带座") || text.includes("可坐"))
|
||
attributes.feature = "带座功能";
|
||
if (text.includes("收纳空间"))
|
||
attributes.remark = "大容量收纳";
|
||
break;
|
||
default:
|
||
attributes.description = text;
|
||
break;
|
||
}
|
||
if (!attributes.style && data && data.decorationStyle)
|
||
attributes.style = data.decorationStyle;
|
||
if (!attributes.color && data && data.decorationStyle) {
|
||
const color = data.decorationStyle.match(/(米白|白色|灰色|黑色|棕色|蓝色|暖色调|冷色调|灰白色系|原木色)/);
|
||
if (color)
|
||
attributes.color = color[0];
|
||
}
|
||
if (!attributes.description && text)
|
||
attributes.description = text;
|
||
return attributes;
|
||
},
|
||
buildProductDimensionRows(productData = null, data = {}, categoryKey = "") {
|
||
const dimensionLabels = [
|
||
{ key: "styleColor", label: "偏好风格与颜色", field: "preferenceStyleAndColor" },
|
||
{ key: "material", label: "材质偏好", field: "materialPreference" },
|
||
{ key: "focus", label: "客户重点关注", field: "customerFocusAreas" },
|
||
{ key: "price", label: "价格敏感度", field: "priceSensitivity" },
|
||
{ key: "campaign", label: "活动参与度", field: "activityParticipation" },
|
||
{ key: "ordered", label: "客户疑虑点", field: "customerConcerns" },
|
||
{ key: "service", label: "交付服务", field: "deliveryService" },
|
||
{ key: "competitor", label: "竞品反馈", field: "competitorFeedback" },
|
||
{ key: "delivery", label: "交付周期", field: "deliveryCycle" },
|
||
{ key: "appearance", label: "产品颜值", field: "productAppearance" }
|
||
];
|
||
const isParsedJson = productData && typeof productData === "object" && !Array.isArray(productData) && productData !== null && ("preferenceStyleAndColor" in productData || "materialPreference" in productData || "customerConcerns" in productData);
|
||
const getValue = (field) => {
|
||
if (isParsedJson) {
|
||
const value = productData[field];
|
||
if (value === null || value === void 0 || value === "") {
|
||
return "暂无信息";
|
||
}
|
||
if (typeof value === "string") {
|
||
const trimmed = value.trim();
|
||
return trimmed || "暂无信息";
|
||
}
|
||
return String(value) || "暂无信息";
|
||
} else {
|
||
const attributes = productData || {};
|
||
switch (field) {
|
||
case "preferenceStyleAndColor":
|
||
const parts = [];
|
||
if (attributes.style)
|
||
parts.push(attributes.style);
|
||
if (attributes.color)
|
||
parts.push(attributes.color);
|
||
if (parts.length === 0 && data.decorationStyle)
|
||
parts.push(data.decorationStyle);
|
||
return parts.join(" / ") || "暂无信息";
|
||
case "materialPreference":
|
||
return attributes.material || "暂无信息";
|
||
case "customerFocusAreas":
|
||
return attributes.feature || attributes.remark || "暂无信息";
|
||
case "priceSensitivity":
|
||
return data.priceSensitivity || "暂无信息";
|
||
case "activityParticipation":
|
||
return data.campaignPreference || data.activityParticipation || "暂无信息";
|
||
case "customerConcerns":
|
||
return attributes.description || "暂无信息";
|
||
case "deliveryService":
|
||
return data.serviceExpectation || "暂无信息";
|
||
case "competitorFeedback":
|
||
return data.competitorFeedback || "暂无信息";
|
||
case "deliveryCycle":
|
||
return data.deliveryCycle || "暂无信息";
|
||
case "productAppearance":
|
||
return data.appearancePreference || attributes.style || "暂无信息";
|
||
default:
|
||
return "暂无信息";
|
||
}
|
||
}
|
||
};
|
||
return dimensionLabels.map((item) => ({
|
||
label: item.label,
|
||
content: getValue(item.field) || "暂无信息"
|
||
}));
|
||
},
|
||
toggleCategory(index) {
|
||
this.performanceData.categories[index].expanded = !this.performanceData.categories[index].expanded;
|
||
},
|
||
toggleItem(categoryIndex, itemIndex) {
|
||
common_vendor.index.__f__("log", "at pages/furniture_customer/furniture_customer.vue:1762", "查看子项详情", categoryIndex, itemIndex);
|
||
},
|
||
viewSummaryDetail(item) {
|
||
common_vendor.index.__f__("log", "at pages/furniture_customer/furniture_customer.vue:1766", "查看总结详情", item);
|
||
},
|
||
viewCustomer() {
|
||
this.closeDetail();
|
||
this.switchTab("customer");
|
||
},
|
||
viewCustomerDetail(item) {
|
||
this.currentCustomerProfile = pages_furniture_customer_utils_dataInit.initCustomerProfile(item);
|
||
this.$refs.customerProfileModal.open();
|
||
},
|
||
// 加载待办事项列表
|
||
async loadTodoList(params = {}) {
|
||
var _a, _b, _c;
|
||
try {
|
||
const parentId = ((_a = this.currentServiceDetail.rawData) == null ? void 0 : _a.id) || this.currentServiceDetail.id;
|
||
if (!parentId) {
|
||
common_vendor.index.__f__("warn", "at pages/furniture_customer/furniture_customer.vue:1784", "无法获取parentId,无法加载待办事项");
|
||
this.todoList = [];
|
||
this.todoListTotal = 0;
|
||
return;
|
||
}
|
||
const queryParams = {
|
||
current: this.todoListPage.current,
|
||
size: this.todoListPage.size,
|
||
parentId
|
||
};
|
||
if (params.status) {
|
||
queryParams.status = params.status;
|
||
}
|
||
if (params.todoTitle) {
|
||
queryParams.todoTitle = params.todoTitle;
|
||
}
|
||
if (params.ownerName) {
|
||
queryParams.ownerName = params.ownerName;
|
||
}
|
||
if (params.ownerPhone) {
|
||
queryParams.ownerPhone = params.ownerPhone;
|
||
}
|
||
if (params.createStartTime) {
|
||
queryParams.createStartTime = params.createStartTime;
|
||
}
|
||
if (params.createEndTime) {
|
||
queryParams.createEndTime = params.createEndTime;
|
||
}
|
||
if (params.updateStartTime) {
|
||
queryParams.updateStartTime = params.updateStartTime;
|
||
}
|
||
if (params.updateEndTime) {
|
||
queryParams.updateEndTime = params.updateEndTime;
|
||
}
|
||
const queryString = Object.keys(queryParams).filter((key) => queryParams[key] !== null && queryParams[key] !== void 0 && queryParams[key] !== "").map((key) => `${key}=${encodeURIComponent(queryParams[key])}`).join("&");
|
||
const baseUrl = common_config.getApiUrl("/api/todoItem/list");
|
||
const url = queryString ? `${baseUrl}?${queryString}` : baseUrl;
|
||
const res = await common_vendor.index.request({
|
||
url,
|
||
method: "GET",
|
||
timeout: 1e4
|
||
});
|
||
if (res.statusCode === 200 && res.data && res.data.success) {
|
||
this.todoList = res.data.data || [];
|
||
this.todoListTotal = res.data.total || 0;
|
||
} else {
|
||
common_vendor.index.__f__("warn", "at pages/furniture_customer/furniture_customer.vue:1842", "获取待办事项失败:", ((_b = res.data) == null ? void 0 : _b.message) || "未知错误");
|
||
this.todoList = [];
|
||
this.todoListTotal = 0;
|
||
common_vendor.index.showToast({
|
||
title: ((_c = res.data) == null ? void 0 : _c.message) || "获取待办事项失败",
|
||
icon: "none"
|
||
});
|
||
}
|
||
} catch (error) {
|
||
common_vendor.index.__f__("error", "at pages/furniture_customer/furniture_customer.vue:1851", "获取待办事项失败:", error);
|
||
this.todoList = [];
|
||
this.todoListTotal = 0;
|
||
common_vendor.index.showToast({
|
||
title: `获取待办事项失败: ${error.errMsg || error.message || "未知错误"}`,
|
||
icon: "none",
|
||
duration: 3e3
|
||
});
|
||
}
|
||
},
|
||
// 获取待办事项状态样式类
|
||
getTodoStatusClass(status) {
|
||
if (!status)
|
||
return "status-pending";
|
||
if (status.includes("完成") || status === "已完成") {
|
||
return "status-completed";
|
||
}
|
||
if (status.includes("进行") || status === "进行中") {
|
||
return "status-processing";
|
||
}
|
||
if (status.includes("待") || status === "待处理") {
|
||
return "status-pending";
|
||
}
|
||
return "status-pending";
|
||
},
|
||
// 获取待办事项状态文本样式类
|
||
getTodoStatusTextClass(status) {
|
||
if (!status)
|
||
return "status-text-pending";
|
||
if (status.includes("完成") || status === "已完成") {
|
||
return "status-text-completed";
|
||
}
|
||
if (status.includes("进行") || status === "进行中") {
|
||
return "status-text-processing";
|
||
}
|
||
if (status.includes("待") || status === "待处理") {
|
||
return "status-text-pending";
|
||
}
|
||
return "status-text-pending";
|
||
},
|
||
// 格式化日期时间
|
||
formatDateTime(dateTimeStr) {
|
||
if (!dateTimeStr)
|
||
return "";
|
||
try {
|
||
const date = new Date(dateTimeStr);
|
||
const year = date.getFullYear();
|
||
const month = String(date.getMonth() + 1).padStart(2, "0");
|
||
const day = String(date.getDate()).padStart(2, "0");
|
||
const hours = String(date.getHours()).padStart(2, "0");
|
||
const minutes = String(date.getMinutes()).padStart(2, "0");
|
||
return `${year}-${month}-${day} ${hours}:${minutes}`;
|
||
} catch (error) {
|
||
common_vendor.index.__f__("warn", "at pages/furniture_customer/furniture_customer.vue:1901", "格式化日期时间失败:", error);
|
||
return dateTimeStr;
|
||
}
|
||
},
|
||
// 判断待办事项是否为待处理状态
|
||
isTodoPending(status) {
|
||
if (!status)
|
||
return true;
|
||
return status.includes("待") || status === "待处理" || status === "待处理";
|
||
},
|
||
// 切换待办事项下拉菜单
|
||
toggleTodoMenu(index, event) {
|
||
if (this.activeTodoMenuIndex === index) {
|
||
this.activeTodoMenuIndex = null;
|
||
this.currentTodoItem = null;
|
||
this.todoMenuStyle = {};
|
||
} else {
|
||
this.activeTodoMenuIndex = index;
|
||
this.currentTodoItem = this.todoList[index];
|
||
this.$nextTick(() => {
|
||
const query = common_vendor.index.createSelectorQuery().in(this);
|
||
query.select(`#todo-status-${index}`).boundingClientRect((rect) => {
|
||
if (rect) {
|
||
common_vendor.index.getSystemInfo({
|
||
success: (res) => {
|
||
const rpxToPx = res.windowWidth / 750;
|
||
const menuWidth = 200 * rpxToPx;
|
||
const right = res.windowWidth - rect.right;
|
||
const top = rect.bottom + 4;
|
||
this.todoMenuStyle = {
|
||
right: `${right}px`,
|
||
top: `${top}px`,
|
||
width: `${menuWidth}px`
|
||
};
|
||
}
|
||
});
|
||
}
|
||
}).exec();
|
||
});
|
||
}
|
||
},
|
||
// 关闭待办事项下拉菜单
|
||
closeTodoMenu() {
|
||
this.activeTodoMenuIndex = null;
|
||
this.currentTodoItem = null;
|
||
this.todoMenuStyle = {};
|
||
},
|
||
// 处理完成待办事项
|
||
async handleTodoComplete(item, index) {
|
||
var _a;
|
||
this.closeTodoMenu();
|
||
const todoId = item.id;
|
||
if (!todoId) {
|
||
common_vendor.index.showToast({
|
||
title: "待办事项ID不存在",
|
||
icon: "none"
|
||
});
|
||
return;
|
||
}
|
||
try {
|
||
const url = common_config.getApiUrl("/api/todoItem/updateTodoStatus");
|
||
const res = await common_vendor.index.request({
|
||
url,
|
||
method: "POST",
|
||
data: {
|
||
id: todoId
|
||
},
|
||
timeout: 1e4,
|
||
header: {
|
||
"Content-Type": "application/json"
|
||
}
|
||
});
|
||
if (res.statusCode === 200 && res.data && res.data.success) {
|
||
common_vendor.index.showToast({
|
||
title: "处理完成",
|
||
icon: "success"
|
||
});
|
||
await this.loadTodoList();
|
||
} else {
|
||
common_vendor.index.showToast({
|
||
title: ((_a = res.data) == null ? void 0 : _a.message) || "处理失败",
|
||
icon: "none"
|
||
});
|
||
}
|
||
} catch (error) {
|
||
common_vendor.index.__f__("error", "at pages/furniture_customer/furniture_customer.vue:1996", "处理待办事项失败:", error);
|
||
common_vendor.index.showToast({
|
||
title: `处理失败: ${error.errMsg || error.message || "未知错误"}`,
|
||
icon: "none",
|
||
duration: 3e3
|
||
});
|
||
}
|
||
},
|
||
// 延期处理待办事项
|
||
async handleTodoDelay(item, index) {
|
||
var _a;
|
||
this.closeTodoMenu();
|
||
const todoId = item.id;
|
||
if (!todoId) {
|
||
common_vendor.index.showToast({
|
||
title: "待办事项ID不存在",
|
||
icon: "none"
|
||
});
|
||
return;
|
||
}
|
||
try {
|
||
const url = common_config.getApiUrl("/api/todoItem/delayProcessTodo");
|
||
const res = await common_vendor.index.request({
|
||
url,
|
||
method: "POST",
|
||
data: {
|
||
id: todoId
|
||
},
|
||
timeout: 1e4,
|
||
header: {
|
||
"Content-Type": "application/json"
|
||
}
|
||
});
|
||
if (res.statusCode === 200 && res.data && res.data.success) {
|
||
common_vendor.index.showToast({
|
||
title: "已延期3天",
|
||
icon: "success"
|
||
});
|
||
await this.loadTodoList();
|
||
} else {
|
||
common_vendor.index.showToast({
|
||
title: ((_a = res.data) == null ? void 0 : _a.message) || "延期失败",
|
||
icon: "none"
|
||
});
|
||
}
|
||
} catch (error) {
|
||
common_vendor.index.__f__("error", "at pages/furniture_customer/furniture_customer.vue:2047", "延期待办事项失败:", error);
|
||
common_vendor.index.showToast({
|
||
title: `延期失败: ${error.errMsg || error.message || "未知错误"}`,
|
||
icon: "none",
|
||
duration: 3e3
|
||
});
|
||
}
|
||
},
|
||
onCustomerProfileClose() {
|
||
},
|
||
// 加载章节概要数据
|
||
async loadChapterSummary() {
|
||
var _a, _b;
|
||
try {
|
||
const parentId = ((_a = this.currentServiceDetail.rawData) == null ? void 0 : _a.id) || this.currentServiceDetail.id;
|
||
if (!parentId) {
|
||
common_vendor.index.__f__("warn", "at pages/furniture_customer/furniture_customer.vue:2064", "无法获取parentId,无法加载章节概要");
|
||
this.chapterSummaryList = [];
|
||
return;
|
||
}
|
||
const url = `${common_config.getApiUrl("/api/audioTextAnalysisFurniture/byParentId")}?parentId=${parentId}`;
|
||
const res = await common_vendor.index.request({
|
||
url,
|
||
method: "GET",
|
||
timeout: 1e4
|
||
});
|
||
if (res.statusCode === 200 && res.data && res.data.success) {
|
||
const data = res.data.data || [];
|
||
const summaryList = [];
|
||
const item = Array.isArray(data) && data.length > 0 ? data[0] : data;
|
||
if (item) {
|
||
if (item.summary1) {
|
||
try {
|
||
const summary1Data = typeof item.summary1 === "string" ? JSON.parse(item.summary1) : item.summary1;
|
||
if (summary1Data && (summary1Data.customerConcerns || summary1Data.answer)) {
|
||
summaryList.push({
|
||
title: "章节1",
|
||
customerConcerns: summary1Data.customerConcerns || "",
|
||
answer: summary1Data.answer || ""
|
||
});
|
||
}
|
||
} catch (error) {
|
||
common_vendor.index.__f__("warn", "at pages/furniture_customer/furniture_customer.vue:2101", "解析summary1失败:", error);
|
||
}
|
||
}
|
||
if (item.summary2) {
|
||
try {
|
||
const summary2Data = typeof item.summary2 === "string" ? JSON.parse(item.summary2) : item.summary2;
|
||
if (summary2Data && (summary2Data.customerConcerns || summary2Data.answer)) {
|
||
summaryList.push({
|
||
title: "章节2",
|
||
customerConcerns: summary2Data.customerConcerns || "",
|
||
answer: summary2Data.answer || ""
|
||
});
|
||
}
|
||
} catch (error) {
|
||
common_vendor.index.__f__("warn", "at pages/furniture_customer/furniture_customer.vue:2119", "解析summary2失败:", error);
|
||
}
|
||
}
|
||
if (item.summary3) {
|
||
try {
|
||
const summary3Data = typeof item.summary3 === "string" ? JSON.parse(item.summary3) : item.summary3;
|
||
if (summary3Data && (summary3Data.customerConcerns || summary3Data.answer)) {
|
||
summaryList.push({
|
||
title: "章节3",
|
||
customerConcerns: summary3Data.customerConcerns || "",
|
||
answer: summary3Data.answer || ""
|
||
});
|
||
}
|
||
} catch (error) {
|
||
common_vendor.index.__f__("warn", "at pages/furniture_customer/furniture_customer.vue:2137", "解析summary3失败:", error);
|
||
}
|
||
}
|
||
}
|
||
this.chapterSummaryList = summaryList;
|
||
} else {
|
||
common_vendor.index.__f__("warn", "at pages/furniture_customer/furniture_customer.vue:2144", "获取章节概要失败:", ((_b = res.data) == null ? void 0 : _b.message) || "未知错误");
|
||
this.chapterSummaryList = [];
|
||
}
|
||
} catch (error) {
|
||
common_vendor.index.__f__("error", "at pages/furniture_customer/furniture_customer.vue:2148", "获取章节概要失败:", error);
|
||
this.chapterSummaryList = [];
|
||
}
|
||
},
|
||
// 加载服务表现数据
|
||
async loadPerformanceData() {
|
||
var _a, _b;
|
||
try {
|
||
const parentId = ((_a = this.currentServiceDetail.rawData) == null ? void 0 : _a.id) || this.currentServiceDetail.id;
|
||
if (!parentId) {
|
||
common_vendor.index.__f__("warn", "at pages/furniture_customer/furniture_customer.vue:2158", "无法获取parentId,无法加载服务表现数据");
|
||
this.performanceData = pages_furniture_customer_utils_dataInit.initPerformanceData();
|
||
return;
|
||
}
|
||
const url = `${common_config.getApiUrl("/api/audioTextAnalysisSop/listByParentId")}?parentId=${parentId}`;
|
||
const res = await common_vendor.index.request({
|
||
url,
|
||
method: "GET",
|
||
timeout: 1e4
|
||
});
|
||
if (res.statusCode === 200 && res.data && res.data.success) {
|
||
const data = res.data.data;
|
||
const sopData = Array.isArray(data) && data.length > 0 ? data[0] : data;
|
||
if (sopData) {
|
||
this.performanceData = this.convertSopDataToPerformanceData(sopData);
|
||
} else {
|
||
common_vendor.index.__f__("warn", "at pages/furniture_customer/furniture_customer.vue:2181", "服务表现数据为空");
|
||
this.performanceData = pages_furniture_customer_utils_dataInit.initPerformanceData();
|
||
}
|
||
} else {
|
||
common_vendor.index.__f__("warn", "at pages/furniture_customer/furniture_customer.vue:2186", "获取服务表现数据失败:", ((_b = res.data) == null ? void 0 : _b.message) || "未知错误");
|
||
this.performanceData = pages_furniture_customer_utils_dataInit.initPerformanceData();
|
||
}
|
||
} catch (error) {
|
||
common_vendor.index.__f__("error", "at pages/furniture_customer/furniture_customer.vue:2191", "获取服务表现数据失败:", error);
|
||
this.performanceData = pages_furniture_customer_utils_dataInit.initPerformanceData();
|
||
}
|
||
},
|
||
// 将后端SOP数据转换为前端performanceData格式
|
||
convertSopDataToPerformanceData(sopData) {
|
||
const isCompleted = (score) => score !== null && score !== void 0 && score >= 60;
|
||
const allScores = [
|
||
sopData.greetingIceBreaking,
|
||
sopData.brandIntroduction,
|
||
sopData.goldenThreeQuestions,
|
||
sopData.needsGuidance,
|
||
sopData.serviceProgression,
|
||
sopData.reassuranceHandbook,
|
||
sopData.threeLevelPricing,
|
||
sopData.objectionHandling,
|
||
sopData.activityImplantation,
|
||
sopData.closingCooperation,
|
||
sopData.proactiveWechatAdd,
|
||
sopData.politeFarewell
|
||
].filter((score) => score !== null && score !== void 0);
|
||
let totalScore = sopData.comprehensiveScore || sopData.comprehensive_score;
|
||
if (totalScore === null || totalScore === void 0) {
|
||
if (allScores.length > 0) {
|
||
const sum = allScores.reduce((acc, score) => acc + score, 0);
|
||
totalScore = Math.round(sum / allScores.length);
|
||
} else {
|
||
totalScore = 0;
|
||
}
|
||
}
|
||
const categories = [
|
||
{
|
||
name: "迎宾探寻",
|
||
completed: isCompleted(sopData.greetingIceBreaking) || isCompleted(sopData.brandIntroduction),
|
||
expanded: true,
|
||
showBanner: false,
|
||
showAudio: false,
|
||
items: [
|
||
{
|
||
name: "破冰",
|
||
completed: isCompleted(sopData.greetingIceBreaking),
|
||
points: sopData.greetingIceBreaking || 0
|
||
},
|
||
{
|
||
name: "品牌介绍",
|
||
completed: isCompleted(sopData.brandIntroduction),
|
||
points: sopData.brandIntroduction || 0
|
||
}
|
||
]
|
||
},
|
||
{
|
||
name: "展厅体验",
|
||
completed: isCompleted(sopData.goldenThreeQuestions) || isCompleted(sopData.needsGuidance),
|
||
expanded: true,
|
||
showBanner: false,
|
||
showAudio: false,
|
||
items: [
|
||
{
|
||
name: "黄金三问",
|
||
completed: isCompleted(sopData.goldenThreeQuestions),
|
||
points: sopData.goldenThreeQuestions || 0
|
||
},
|
||
{
|
||
name: "需求引导",
|
||
completed: isCompleted(sopData.needsGuidance),
|
||
points: sopData.needsGuidance || 0
|
||
}
|
||
]
|
||
},
|
||
{
|
||
name: "落座规划",
|
||
completed: isCompleted(sopData.serviceProgression) || isCompleted(sopData.reassuranceHandbook),
|
||
expanded: true,
|
||
showBanner: false,
|
||
showAudio: false,
|
||
items: [
|
||
{
|
||
name: "服务递进",
|
||
completed: isCompleted(sopData.serviceProgression),
|
||
points: sopData.serviceProgression || 0
|
||
},
|
||
{
|
||
name: "SGS放心手册",
|
||
completed: isCompleted(sopData.reassuranceHandbook),
|
||
points: sopData.reassuranceHandbook || 0
|
||
}
|
||
]
|
||
},
|
||
{
|
||
name: "方案报价",
|
||
completed: isCompleted(sopData.threeLevelPricing),
|
||
expanded: true,
|
||
showBanner: false,
|
||
showAudio: false,
|
||
items: [
|
||
{
|
||
name: "三级报价",
|
||
completed: isCompleted(sopData.threeLevelPricing),
|
||
points: sopData.threeLevelPricing || 0
|
||
}
|
||
]
|
||
},
|
||
{
|
||
name: "促单成交",
|
||
completed: isCompleted(sopData.objectionHandling),
|
||
expanded: true,
|
||
showBanner: false,
|
||
showAudio: false,
|
||
items: [
|
||
{
|
||
name: "解答异议",
|
||
completed: isCompleted(sopData.objectionHandling),
|
||
points: sopData.objectionHandling || 0
|
||
}
|
||
]
|
||
},
|
||
{
|
||
name: "送客跟进",
|
||
completed: isCompleted(sopData.activityImplantation) || isCompleted(sopData.closingCooperation) || isCompleted(sopData.proactiveWechatAdd) || isCompleted(sopData.politeFarewell),
|
||
expanded: true,
|
||
showBanner: false,
|
||
showAudio: false,
|
||
items: [
|
||
{
|
||
name: "活动植入",
|
||
completed: isCompleted(sopData.activityImplantation),
|
||
points: sopData.activityImplantation || 0
|
||
},
|
||
{
|
||
name: "压单配合",
|
||
completed: isCompleted(sopData.closingCooperation),
|
||
points: sopData.closingCooperation || 0
|
||
},
|
||
{
|
||
name: "主动添加微信",
|
||
completed: isCompleted(sopData.proactiveWechatAdd),
|
||
points: sopData.proactiveWechatAdd || 0
|
||
},
|
||
{
|
||
name: "邀约量尺时间",
|
||
completed: false,
|
||
points: 0
|
||
},
|
||
{
|
||
name: "礼貌道别",
|
||
completed: isCompleted(sopData.politeFarewell),
|
||
points: sopData.politeFarewell || 0
|
||
}
|
||
]
|
||
}
|
||
];
|
||
return {
|
||
totalScore,
|
||
categories
|
||
};
|
||
},
|
||
// 加载服务记录列表
|
||
async loadServiceList(params = {}) {
|
||
var _a, _b;
|
||
try {
|
||
const queryParams = {
|
||
current: this.serviceListPage.current,
|
||
size: this.serviceListPage.size,
|
||
serviceStatus: "服务结束"
|
||
// 默认搜索条件:服务结束
|
||
};
|
||
const trimmedSalesName = (_a = params.salesName) == null ? void 0 : _a.trim();
|
||
const trimmedCustomerName = (_b = params.customerName) == null ? void 0 : _b.trim();
|
||
if (trimmedSalesName) {
|
||
queryParams.salesName = trimmedSalesName;
|
||
}
|
||
if (trimmedCustomerName) {
|
||
queryParams.customerName = trimmedCustomerName;
|
||
}
|
||
const queryString = Object.keys(queryParams).filter((key) => queryParams[key] !== null && queryParams[key] !== void 0 && queryParams[key] !== "").map((key) => `${encodeURIComponent(key)}=${encodeURIComponent(queryParams[key])}`).join("&");
|
||
common_vendor.index.__f__("log", "at pages/furniture_customer/furniture_customer.vue:2387", "服务记录查询参数:", JSON.stringify(queryParams));
|
||
common_vendor.index.__f__("log", "at pages/furniture_customer/furniture_customer.vue:2388", "查询字符串:", queryString);
|
||
const baseUrl = common_config.getApiUrl("/api/audioManagement/list");
|
||
const url = queryString ? `${baseUrl}?${queryString}` : baseUrl;
|
||
let tenantId = "";
|
||
let token = "";
|
||
try {
|
||
tenantId = common_vendor.index.getStorageSync("backend-tenant-id") || "";
|
||
token = common_vendor.index.getStorageSync("backend-token") || "";
|
||
} catch (e) {
|
||
common_vendor.index.__f__("error", "at pages/furniture_customer/furniture_customer.vue:2401", "获取认证信息失败:", e);
|
||
}
|
||
const headers = {
|
||
"Content-Type": "application/json"
|
||
};
|
||
if (token) {
|
||
headers["Authorization"] = `Bearer ${token}`;
|
||
}
|
||
if (tenantId) {
|
||
headers["X-Tenant-Id"] = tenantId;
|
||
}
|
||
const res = await common_vendor.index.request({
|
||
url,
|
||
method: "POST",
|
||
data: {},
|
||
// POST 请求体为空,参数都在 URL 查询字符串中
|
||
header: headers,
|
||
timeout: 1e4
|
||
});
|
||
if (res.statusCode === 200 && res.data && res.data.success) {
|
||
const mappedList = res.data.data.map((item) => {
|
||
let formattedTime = "";
|
||
if (item.createTime) {
|
||
const date = new Date(item.createTime);
|
||
const year = date.getFullYear();
|
||
const month = String(date.getMonth() + 1).padStart(2, "0");
|
||
const day = String(date.getDate()).padStart(2, "0");
|
||
const hours = String(date.getHours()).padStart(2, "0");
|
||
const minutes = String(date.getMinutes()).padStart(2, "0");
|
||
const seconds = String(date.getSeconds()).padStart(2, "0");
|
||
formattedTime = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
|
||
}
|
||
return {
|
||
id: item.id,
|
||
title: `${item.salesName || ""}的服务记录`,
|
||
date: formattedTime ? `时间:${formattedTime}` : "",
|
||
description: item.summary || "",
|
||
customerName: item.customerName || "",
|
||
recordingName: item.recordingName || "",
|
||
// 记录名称
|
||
// 保留原始数据,用于详情页
|
||
rawData: item
|
||
};
|
||
});
|
||
if (this.serviceListPage.current === 1) {
|
||
this.serviceList = mappedList;
|
||
} else {
|
||
this.serviceList = this.serviceList.concat(mappedList);
|
||
}
|
||
this.serviceListTotal = res.data.total || 0;
|
||
} else {
|
||
common_vendor.index.showToast({
|
||
title: res.data.message || "获取服务记录失败",
|
||
icon: "none"
|
||
});
|
||
}
|
||
} catch (error) {
|
||
common_vendor.index.__f__("error", "at pages/furniture_customer/furniture_customer.vue:2464", "获取服务记录失败:", error);
|
||
common_vendor.index.showToast({
|
||
title: `获取服务记录失败: ${error.errMsg || error.message || "未知错误"}`,
|
||
icon: "none",
|
||
duration: 3e3
|
||
});
|
||
}
|
||
},
|
||
// 页面加载后的URL隐藏初始化:只在用户导航时执行
|
||
initUrlHidingAfterPageLoad() {
|
||
},
|
||
// 设置tab导航时的URL隐藏
|
||
setupTabNavigationHiding() {
|
||
},
|
||
// 设置浏览器导航时的URL隐藏
|
||
setupBrowserNavigationHiding() {
|
||
},
|
||
// 为当前页面尝试URL隐藏
|
||
attemptUrlHidingForCurrentPage() {
|
||
}
|
||
}
|
||
};
|
||
if (!Array) {
|
||
const _easycom_uni_nav_bar2 = common_vendor.resolveComponent("uni-nav-bar");
|
||
const _component_ServiceList = common_vendor.resolveComponent("ServiceList");
|
||
const _component_CustomerList = common_vendor.resolveComponent("CustomerList");
|
||
const _component_CustomerProfileModal = common_vendor.resolveComponent("CustomerProfileModal");
|
||
const _easycom_uni_icons2 = common_vendor.resolveComponent("uni-icons");
|
||
const _easycom_uni_popup2 = common_vendor.resolveComponent("uni-popup");
|
||
const _component_ConversationSummaryFurniture = common_vendor.resolveComponent("ConversationSummaryFurniture");
|
||
(_easycom_uni_nav_bar2 + _component_ServiceList + _component_CustomerList + _component_CustomerProfileModal + _easycom_uni_icons2 + _easycom_uni_popup2 + _component_ConversationSummaryFurniture)();
|
||
}
|
||
const _easycom_uni_nav_bar = () => "../../uni_modules/uni-nav-bar/components/uni-nav-bar/uni-nav-bar.js";
|
||
const _easycom_uni_icons = () => "../../uni_modules/uni-icons/components/uni-icons/uni-icons.js";
|
||
const _easycom_uni_popup = () => "../../uni_modules/uni-popup/components/uni-popup/uni-popup.js";
|
||
if (!Math) {
|
||
(_easycom_uni_nav_bar + _easycom_uni_icons + _easycom_uni_popup)();
|
||
}
|
||
function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
|
||
var _a;
|
||
return common_vendor.e({
|
||
a: common_vendor.o($options.goBack),
|
||
b: common_vendor.p({
|
||
fixed: true,
|
||
statusBar: true,
|
||
title: "AI销冠系统",
|
||
leftIcon: "left",
|
||
color: "#333",
|
||
backgroundColor: "#FFFFFF"
|
||
}),
|
||
c: $data.activeTab === "service" ? 1 : "",
|
||
d: common_vendor.o(($event) => $options.switchTab("service")),
|
||
e: $data.activeTab === "customer" ? 1 : "",
|
||
f: common_vendor.o(($event) => $options.switchTab("customer")),
|
||
g: $options.computedNavbarTop || $data.navbarTop,
|
||
h: $data.activeTab === "service"
|
||
}, $data.activeTab === "service" ? {
|
||
i: $options.computedContentTop || $data.contentTop,
|
||
j: common_vendor.o($options.viewDetail),
|
||
k: common_vendor.o($options.refreshServiceList),
|
||
l: common_vendor.o($options.onServiceListReachBottom),
|
||
m: common_vendor.o($options.handleMenuAction),
|
||
n: common_vendor.o($options.handleUpdateItem),
|
||
o: common_vendor.p({
|
||
list: $data.serviceList,
|
||
total: $data.serviceListTotal
|
||
})
|
||
} : {}, {
|
||
p: $data.activeTab === "customer"
|
||
}, $data.activeTab === "customer" ? {
|
||
q: $options.computedContentTop || $data.contentTop,
|
||
r: common_vendor.o($options.viewCustomerDetail)
|
||
} : {}, {
|
||
s: common_vendor.sr("customerProfileModal", "08b6e2e0-3"),
|
||
t: common_vendor.o($options.onCustomerProfileClose),
|
||
v: common_vendor.p({
|
||
profile: $data.currentCustomerProfile
|
||
}),
|
||
w: common_vendor.p({
|
||
type: "close",
|
||
size: "24",
|
||
color: "#333"
|
||
}),
|
||
x: common_vendor.o((...args) => $options.closeAudioList && $options.closeAudioList(...args)),
|
||
y: common_vendor.t($data.audioSegmentsList.length),
|
||
z: common_vendor.f($data.audioSegmentsList, (item, index, i0) => {
|
||
return common_vendor.e({
|
||
a: common_vendor.t($data.playingAudioId === (item.id || item.segmentId) ? "暂停" : "播放"),
|
||
b: common_vendor.n($data.playingAudioId === (item.id || item.segmentId) ? "audio-play-text--playing" : ""),
|
||
c: common_vendor.o(($event) => $options.toggleAudioPlay(item, index), index),
|
||
d: common_vendor.t($options.formatAudioFileName(item.audioFileOriginalName)),
|
||
e: item.recordingText
|
||
}, item.recordingText ? {
|
||
f: common_vendor.t($options.truncateText(item.recordingText, 30))
|
||
} : common_vendor.e({
|
||
g: !$data.transcribingIds.includes(item.id || item.segmentId)
|
||
}, !$data.transcribingIds.includes(item.id || item.segmentId) ? {} : {}, {
|
||
h: $data.transcribingIds.includes(item.id || item.segmentId) ? 1 : "",
|
||
i: common_vendor.o(($event) => $options.transcribeAudio(item, index), index)
|
||
}), {
|
||
j: item.endTime
|
||
}, item.endTime ? {
|
||
k: common_vendor.t($options.formatDateTime(item.endTime))
|
||
} : {}, {
|
||
l: item.duration
|
||
}, item.duration ? {
|
||
m: common_vendor.t($options.formatDuration(item.duration))
|
||
} : {}, {
|
||
n: item.deviceNo
|
||
}, item.deviceNo ? {
|
||
o: common_vendor.t(item.deviceNo)
|
||
} : {}, {
|
||
p: index
|
||
});
|
||
}),
|
||
A: !$data.audioSegmentsLoading && $data.audioSegmentsList.length === 0
|
||
}, !$data.audioSegmentsLoading && $data.audioSegmentsList.length === 0 ? {} : {}, {
|
||
B: common_vendor.sr("audioListPopup", "08b6e2e0-4"),
|
||
C: common_vendor.p({
|
||
type: "bottom",
|
||
["mask-click"]: false
|
||
}),
|
||
D: common_vendor.p({
|
||
type: "close",
|
||
size: "24",
|
||
color: "#333"
|
||
}),
|
||
E: common_vendor.o((...args) => $options.closeTextModal && $options.closeTextModal(...args)),
|
||
F: common_vendor.t($data.currentRecordingText || "暂无录音文本"),
|
||
G: common_vendor.sr("textModalPopup", "08b6e2e0-6"),
|
||
H: common_vendor.o($options.onTextModalChange),
|
||
I: common_vendor.p({
|
||
type: "center",
|
||
["mask-click"]: true
|
||
}),
|
||
J: common_vendor.p({
|
||
type: "close",
|
||
size: "24",
|
||
color: "#333"
|
||
}),
|
||
K: common_vendor.o((...args) => $options.closeDetail && $options.closeDetail(...args)),
|
||
L: common_vendor.t($data.currentServiceDetail.title),
|
||
M: common_vendor.p({
|
||
type: "forward",
|
||
size: "20",
|
||
color: "#333"
|
||
}),
|
||
N: common_vendor.o((...args) => $options.shareDetail && $options.shareDetail(...args)),
|
||
O: common_vendor.t($data.currentServiceDetail.date),
|
||
P: common_vendor.p({
|
||
type: "loop",
|
||
size: "18",
|
||
color: "#007AFF"
|
||
}),
|
||
Q: common_vendor.p({
|
||
type: $data.isPlaying ? "pause-filled" : "play-filled",
|
||
size: "24",
|
||
color: "#007AFF"
|
||
}),
|
||
R: common_vendor.o((...args) => $options.togglePlay && $options.togglePlay(...args)),
|
||
S: $data.activeDetailTab === "summary" ? 1 : "",
|
||
T: common_vendor.o(($event) => $options.switchDetailTab("summary")),
|
||
U: $data.activeDetailTab === "todo" ? 1 : "",
|
||
V: common_vendor.o(($event) => $options.switchDetailTab("todo")),
|
||
W: $data.activeDetailTab === "chapter" ? 1 : "",
|
||
X: common_vendor.o(($event) => $options.switchDetailTab("chapter")),
|
||
Y: $data.activeDetailTab === "performance" ? 1 : "",
|
||
Z: common_vendor.o(($event) => $options.switchDetailTab("performance")),
|
||
aa: $data.activeDetailTab === "summary"
|
||
}, $data.activeDetailTab === "summary" ? {
|
||
ab: `summary-${$data.currentServiceDetail.id || ((_a = $data.currentServiceDetail.rawData) == null ? void 0 : _a.id) || Date.now()}`,
|
||
ac: common_vendor.p({
|
||
serviceItem: $data.currentServiceDetail
|
||
})
|
||
} : {}, {
|
||
ad: $data.activeDetailTab === "performance"
|
||
}, $data.activeDetailTab === "performance" ? {
|
||
ae: common_vendor.t($data.performanceData.totalScore),
|
||
af: common_vendor.f($data.performanceData.categories, (category, categoryIndex, i0) => {
|
||
return common_vendor.e({
|
||
a: common_vendor.n(category.completed ? "bullet-blue" : "bullet-gray"),
|
||
b: common_vendor.t(category.name),
|
||
c: "08b6e2e0-14-" + i0 + ",08b6e2e0-8",
|
||
d: common_vendor.p({
|
||
type: category.expanded ? "up" : "down",
|
||
size: "16",
|
||
color: "#999"
|
||
}),
|
||
e: common_vendor.o(($event) => $options.toggleCategory(categoryIndex), categoryIndex),
|
||
f: category.expanded
|
||
}, category.expanded ? common_vendor.e({
|
||
g: category.showBanner
|
||
}, category.showBanner ? {
|
||
h: "08b6e2e0-15-" + i0 + ",08b6e2e0-8",
|
||
i: common_vendor.p({
|
||
type: "loop",
|
||
size: "18",
|
||
color: "#007AFF"
|
||
})
|
||
} : {}, {
|
||
j: category.showAudio
|
||
}, category.showAudio ? {
|
||
k: "08b6e2e0-16-" + i0 + ",08b6e2e0-8",
|
||
l: common_vendor.p({
|
||
type: $data.isPlaying ? "pause-filled" : "play-filled",
|
||
size: "24",
|
||
color: "#007AFF"
|
||
}),
|
||
m: common_vendor.o((...args) => $options.togglePlay && $options.togglePlay(...args), categoryIndex)
|
||
} : {}, {
|
||
n: common_vendor.f(category.items, (item, itemIndex, i1) => {
|
||
return common_vendor.e({
|
||
a: common_vendor.t(item.name),
|
||
b: !item.completed
|
||
}, !item.completed ? {
|
||
c: common_vendor.t(item.completed ? "已完成" : "未提及"),
|
||
d: common_vendor.n(item.completed ? "status-completed" : "status-missing")
|
||
} : {}, {
|
||
e: common_vendor.t(item.points),
|
||
f: "08b6e2e0-17-" + i0 + "-" + i1 + ",08b6e2e0-8",
|
||
g: common_vendor.o(($event) => $options.toggleItem(categoryIndex, itemIndex), itemIndex),
|
||
h: itemIndex,
|
||
i: item.completed ? 1 : ""
|
||
});
|
||
}),
|
||
o: common_vendor.p({
|
||
type: "down",
|
||
size: "16",
|
||
color: "#999"
|
||
})
|
||
}) : {}, {
|
||
p: categoryIndex
|
||
});
|
||
})
|
||
} : {}, {
|
||
ag: $data.activeDetailTab === "todo"
|
||
}, $data.activeDetailTab === "todo" ? common_vendor.e({
|
||
ah: $data.todoList.length > 0
|
||
}, $data.todoList.length > 0 ? {
|
||
ai: common_vendor.f($data.todoList, (item, index, i0) => {
|
||
return common_vendor.e({
|
||
a: common_vendor.n($options.getTodoStatusClass(item.status)),
|
||
b: common_vendor.t(item.todoTitle || item.title || "待办事项"),
|
||
c: $options.isTodoPending(item.status)
|
||
}, $options.isTodoPending(item.status) ? {
|
||
d: common_vendor.t(item.status || "待处理"),
|
||
e: "08b6e2e0-18-" + i0 + ",08b6e2e0-8",
|
||
f: common_vendor.p({
|
||
type: "down",
|
||
size: "14",
|
||
color: "#FF9800"
|
||
}),
|
||
g: common_vendor.n($options.getTodoStatusTextClass(item.status)),
|
||
h: "todo-status-" + index,
|
||
i: common_vendor.o(($event) => $options.toggleTodoMenu(index, $event), index)
|
||
} : {
|
||
j: common_vendor.t(item.status || "待处理"),
|
||
k: common_vendor.n($options.getTodoStatusTextClass(item.status))
|
||
}, {
|
||
l: item.todoContent || item.content || item.description
|
||
}, item.todoContent || item.content || item.description ? {
|
||
m: common_vendor.t(item.todoContent || item.content || item.description)
|
||
} : {}, {
|
||
n: item.ownerName
|
||
}, item.ownerName ? {
|
||
o: common_vendor.t(item.ownerName)
|
||
} : {}, {
|
||
p: item.ownerPhone
|
||
}, item.ownerPhone ? {
|
||
q: common_vendor.t(item.ownerPhone)
|
||
} : {}, {
|
||
r: item.PendingDate || item.pendingDate
|
||
}, item.PendingDate || item.pendingDate ? {
|
||
s: common_vendor.t($options.formatDateTime(item.PendingDate || item.pendingDate))
|
||
} : {}, {
|
||
t: index,
|
||
v: item.status && (item.status.includes("完成") || item.status === "已完成") ? 1 : "",
|
||
w: $options.isTodoPending(item.status) ? 1 : ""
|
||
});
|
||
})
|
||
} : {}) : {}, {
|
||
aj: $data.activeTodoMenuIndex !== null
|
||
}, $data.activeTodoMenuIndex !== null ? {
|
||
ak: common_vendor.o((...args) => $options.closeTodoMenu && $options.closeTodoMenu(...args))
|
||
} : {}, {
|
||
al: $data.activeTodoMenuIndex !== null
|
||
}, $data.activeTodoMenuIndex !== null ? {
|
||
am: common_vendor.o(($event) => $options.handleTodoComplete($data.currentTodoItem, $data.activeTodoMenuIndex)),
|
||
an: common_vendor.o(($event) => $options.handleTodoDelay($data.currentTodoItem, $data.activeTodoMenuIndex)),
|
||
ao: common_vendor.s($data.todoMenuStyle),
|
||
ap: common_vendor.o(() => {
|
||
})
|
||
} : {}, {
|
||
aq: $data.activeDetailTab === "chapter"
|
||
}, $data.activeDetailTab === "chapter" ? common_vendor.e({
|
||
ar: $data.chapterSummaryList.length > 0
|
||
}, $data.chapterSummaryList.length > 0 ? {
|
||
as: common_vendor.f($data.chapterSummaryList, (item, index, i0) => {
|
||
return common_vendor.e({
|
||
a: common_vendor.t(item.title || `章节${index + 1}`),
|
||
b: item.customerConcerns
|
||
}, item.customerConcerns ? {
|
||
c: common_vendor.t(item.customerConcerns)
|
||
} : {}, {
|
||
d: item.answer
|
||
}, item.answer ? {
|
||
e: common_vendor.t(item.answer)
|
||
} : {}, {
|
||
f: index
|
||
});
|
||
})
|
||
} : {}) : {}, {
|
||
at: $data.activeDetailTab !== "summary" && $data.activeDetailTab !== "performance" && $data.activeDetailTab !== "todo" && $data.activeDetailTab !== "chapter"
|
||
}, $data.activeDetailTab !== "summary" && $data.activeDetailTab !== "performance" && $data.activeDetailTab !== "todo" && $data.activeDetailTab !== "chapter" ? {
|
||
av: common_vendor.t($options.getDetailTabName($data.activeDetailTab))
|
||
} : {}, {
|
||
aw: common_vendor.p({
|
||
type: "person",
|
||
size: "20",
|
||
color: "#666"
|
||
}),
|
||
ax: common_vendor.t($data.currentServiceDetail.customerName),
|
||
ay: common_vendor.p({
|
||
type: "right",
|
||
size: "16",
|
||
color: "#999"
|
||
}),
|
||
az: common_vendor.o((...args) => $options.viewCustomer && $options.viewCustomer(...args)),
|
||
aA: common_vendor.sr("serviceDetailPopup", "08b6e2e0-8"),
|
||
aB: common_vendor.p({
|
||
type: "bottom",
|
||
["mask-click"]: false
|
||
})
|
||
});
|
||
}
|
||
const MiniProgramPage = /* @__PURE__ */ common_vendor._export_sfc(_sfc_main, [["render", _sfc_render]]);
|
||
wx.createPage(MiniProgramPage);
|
||
//# sourceMappingURL=../../../.sourcemap/mp-weixin/pages/furniture_customer/furniture_customer.js.map
|