接待客户统计页面的改造
This commit is contained in:
492
unpackage/dist/dev/mp-weixin/pages-subpackage/ai_features/customer_count/customer_count.js
vendored
Normal file
492
unpackage/dist/dev/mp-weixin/pages-subpackage/ai_features/customer_count/customer_count.js
vendored
Normal file
@@ -0,0 +1,492 @@
|
||||
"use strict";
|
||||
const common_vendor = require("../../../common/vendor.js");
|
||||
const common_request = require("../../../common/request.js");
|
||||
const common_config = require("../../../common/config.js");
|
||||
function getSystemInfo() {
|
||||
if (typeof common_vendor.wx$1 !== "undefined" && common_vendor.wx$1.getWindowInfo) {
|
||||
try {
|
||||
const windowInfo = common_vendor.wx$1.getWindowInfo();
|
||||
return {
|
||||
statusBarHeight: windowInfo.statusBarHeight || 20,
|
||||
windowWidth: windowInfo.windowWidth,
|
||||
windowHeight: windowInfo.windowHeight
|
||||
};
|
||||
} catch (e) {
|
||||
common_vendor.index.__f__("warn", "at pages-subpackage/ai_features/customer_count/customer_count.vue:102", "[CustomerCount] Failed to use wx.getWindowInfo, fallback to getSystemInfoSync:", e);
|
||||
}
|
||||
}
|
||||
try {
|
||||
const systemInfo = common_vendor.index.getSystemInfoSync();
|
||||
return {
|
||||
statusBarHeight: systemInfo.statusBarHeight || 20,
|
||||
windowWidth: systemInfo.windowWidth,
|
||||
windowHeight: systemInfo.windowHeight
|
||||
};
|
||||
} catch (e) {
|
||||
common_vendor.index.__f__("error", "at pages-subpackage/ai_features/customer_count/customer_count.vue:116", "[CustomerCount] Failed to get system info:", e);
|
||||
return {
|
||||
statusBarHeight: 20,
|
||||
windowWidth: 375,
|
||||
windowHeight: 667
|
||||
};
|
||||
}
|
||||
}
|
||||
const _sfc_main = {
|
||||
data() {
|
||||
const systemInfo = getSystemInfo();
|
||||
const statusBarHeight = systemInfo.statusBarHeight;
|
||||
const navbarHeight = 44;
|
||||
const statusBarHeightRpx = statusBarHeight * 2;
|
||||
const navbarHeightRpx = navbarHeight * 2;
|
||||
const totalNavbarHeight = statusBarHeightRpx + navbarHeightRpx;
|
||||
return {
|
||||
statusBarHeight,
|
||||
// 状态栏高度(px)
|
||||
contentTop: totalNavbarHeight + "rpx",
|
||||
// 内容区域距离顶部的距离
|
||||
contentBottom: "0rpx",
|
||||
// 内容区域距离底部的距离(默认值,会在 onReady 中更新)
|
||||
timeRangeOptions: ["1个月", "3个月", "6个月"],
|
||||
timeRangeIndex: 0,
|
||||
// 默认选择1个月
|
||||
showTimeRangeDropdown: false,
|
||||
// 控制下拉菜单显示
|
||||
totalCustomers: "0",
|
||||
todayCustomers: "0",
|
||||
dataList: [],
|
||||
loading: false,
|
||||
chartWidth: 0,
|
||||
chartHeight: 300,
|
||||
chartData: []
|
||||
};
|
||||
},
|
||||
onLoad() {
|
||||
this.loadData();
|
||||
this.initChartSize();
|
||||
},
|
||||
onReady() {
|
||||
this.$nextTick(() => {
|
||||
const query = common_vendor.index.createSelectorQuery().in(this);
|
||||
query.select(".nav-bar").boundingClientRect((data) => {
|
||||
if (data && data.height) {
|
||||
const actualHeight = data.height;
|
||||
const actualHeightRpx = actualHeight * 2;
|
||||
const statusBarHeightRpx = this.statusBarHeight * 2;
|
||||
const totalHeight = statusBarHeightRpx + actualHeightRpx;
|
||||
const adjustedHeight = Math.max(totalHeight - 4, 0);
|
||||
this.$set(this, "contentTop", adjustedHeight + "rpx");
|
||||
common_vendor.index.__f__("log", "at pages-subpackage/ai_features/customer_count/customer_count.vue:174", "[CustomerCount] 使用实际导航栏高度:", actualHeight, "px =", actualHeightRpx, "rpx, 总高度:", totalHeight, "rpx, 调整后:", adjustedHeight, "rpx");
|
||||
} else {
|
||||
const systemInfo = getSystemInfo();
|
||||
const statusBarHeight = systemInfo.statusBarHeight;
|
||||
const navbarHeight = 44;
|
||||
const statusBarHeightRpx = statusBarHeight * 2;
|
||||
const navbarHeightRpx = navbarHeight * 2;
|
||||
const totalNavbarHeight = statusBarHeightRpx + navbarHeightRpx;
|
||||
const adjustedHeight = Math.max(totalNavbarHeight - 4, 0);
|
||||
this.$set(this, "contentTop", adjustedHeight + "rpx");
|
||||
}
|
||||
}).exec();
|
||||
const queryTabbar = common_vendor.index.createSelectorQuery().in(this);
|
||||
queryTabbar.select(".tabbar").boundingClientRect((tabbarData) => {
|
||||
if (tabbarData && tabbarData.height) {
|
||||
const tabbarHeight = tabbarData.height;
|
||||
const tabbarHeightRpx = tabbarHeight * 2;
|
||||
const adjustedBottom = Math.max(tabbarHeightRpx - 4, 0);
|
||||
this.$set(this, "contentBottom", adjustedBottom + "rpx");
|
||||
common_vendor.index.__f__("log", "at pages-subpackage/ai_features/customer_count/customer_count.vue:198", "[CustomerCount] 使用实际tabbar高度:", tabbarHeight, "px =", tabbarHeightRpx, "rpx, 调整后:", adjustedBottom, "rpx");
|
||||
} else {
|
||||
this.$set(this, "contentBottom", "0rpx");
|
||||
}
|
||||
}).exec();
|
||||
setTimeout(() => {
|
||||
const query2 = common_vendor.index.createSelectorQuery().in(this);
|
||||
query2.select(".nav-bar").boundingClientRect((data) => {
|
||||
if (data && data.height) {
|
||||
const actualHeight = data.height;
|
||||
const actualHeightRpx = actualHeight * 2;
|
||||
const statusBarHeightRpx = this.statusBarHeight * 2;
|
||||
const totalHeight = statusBarHeightRpx + actualHeightRpx;
|
||||
const adjustedHeight = Math.max(totalHeight - 4, 0);
|
||||
this.$set(this, "contentTop", adjustedHeight + "rpx");
|
||||
common_vendor.index.__f__("log", "at pages-subpackage/ai_features/customer_count/customer_count.vue:217", "[CustomerCount] 延迟更新导航栏高度:", actualHeight, "px =", actualHeightRpx, "rpx, 总高度:", totalHeight, "rpx, 调整后:", adjustedHeight, "rpx");
|
||||
}
|
||||
}).exec();
|
||||
const queryTabbar2 = common_vendor.index.createSelectorQuery().in(this);
|
||||
queryTabbar2.select(".tabbar").boundingClientRect((tabbarData) => {
|
||||
if (tabbarData && tabbarData.height) {
|
||||
const tabbarHeight = tabbarData.height;
|
||||
const tabbarHeightRpx = tabbarHeight * 2;
|
||||
const adjustedBottom = Math.max(tabbarHeightRpx - 4, 0);
|
||||
this.$set(this, "contentBottom", adjustedBottom + "rpx");
|
||||
common_vendor.index.__f__("log", "at pages-subpackage/ai_features/customer_count/customer_count.vue:229", "[CustomerCount] 延迟更新tabbar高度:", tabbarHeight, "px =", tabbarHeightRpx, "rpx, 调整后:", adjustedBottom, "rpx");
|
||||
}
|
||||
}).exec();
|
||||
}, 200);
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
goBack() {
|
||||
common_vendor.index.navigateBack();
|
||||
},
|
||||
toggleTimeRangeDropdown() {
|
||||
this.showTimeRangeDropdown = !this.showTimeRangeDropdown;
|
||||
},
|
||||
closeTimeRangeDropdown() {
|
||||
this.showTimeRangeDropdown = false;
|
||||
},
|
||||
selectTimeRange(index) {
|
||||
this.timeRangeIndex = index;
|
||||
this.showTimeRangeDropdown = false;
|
||||
this.loadData();
|
||||
},
|
||||
onRefresh() {
|
||||
this.loadData();
|
||||
},
|
||||
/**
|
||||
* 获取当前登录用户信息
|
||||
*/
|
||||
getCurrentUserInfo() {
|
||||
try {
|
||||
const loginResponse = common_vendor.index.getStorageSync("backend-login-response") || {};
|
||||
return {
|
||||
salesId: loginResponse.userId ? String(loginResponse.userId) : null,
|
||||
salesPhone: loginResponse.phone || null
|
||||
};
|
||||
} catch (e) {
|
||||
common_vendor.index.__f__("error", "at pages-subpackage/ai_features/customer_count/customer_count.vue:266", "获取用户信息失败:", e);
|
||||
return { salesId: null, salesPhone: null };
|
||||
}
|
||||
},
|
||||
/**
|
||||
* 格式化客户数
|
||||
*/
|
||||
formatCustomerCount(count) {
|
||||
if (!count || count === 0)
|
||||
return "0";
|
||||
return String(count);
|
||||
},
|
||||
/**
|
||||
* 格式化日期
|
||||
*/
|
||||
formatDate(dateStr) {
|
||||
if (!dateStr)
|
||||
return "";
|
||||
try {
|
||||
const date = new Date(dateStr);
|
||||
const year = date.getFullYear();
|
||||
const month = String(date.getMonth() + 1).padStart(2, "0");
|
||||
const day = String(date.getDate()).padStart(2, "0");
|
||||
return `${year}-${month}-${day}`;
|
||||
} catch (e) {
|
||||
return dateStr;
|
||||
}
|
||||
},
|
||||
/**
|
||||
* 加载统计数据
|
||||
*/
|
||||
async loadData() {
|
||||
if (this.loading) {
|
||||
return;
|
||||
}
|
||||
this.loading = true;
|
||||
try {
|
||||
const userInfo = this.getCurrentUserInfo();
|
||||
const { salesId, salesPhone } = userInfo;
|
||||
if (!salesId && !salesPhone) {
|
||||
common_vendor.index.showToast({
|
||||
title: "无法获取用户信息",
|
||||
icon: "none",
|
||||
duration: 2e3
|
||||
});
|
||||
this.loading = false;
|
||||
return;
|
||||
}
|
||||
const dateRangeType = this.timeRangeIndex + 1;
|
||||
const queryParams = {
|
||||
dateRangeType
|
||||
};
|
||||
if (salesId) {
|
||||
queryParams.salesId = salesId;
|
||||
}
|
||||
if (salesPhone) {
|
||||
queryParams.salesPhone = salesPhone;
|
||||
}
|
||||
const queryString = Object.keys(queryParams).filter((key) => queryParams[key] !== null && queryParams[key] !== void 0 && queryParams[key] !== "").map((key) => `${encodeURIComponent(key)}=${encodeURIComponent(queryParams[key])}`).join("&");
|
||||
const baseUrl = common_config.getApiUrl("/api/customer-statistics/sales");
|
||||
const url = queryString ? `${baseUrl}?${queryString}` : baseUrl;
|
||||
common_vendor.index.__f__("log", "at pages-subpackage/ai_features/customer_count/customer_count.vue:347", "[CustomerCount] 请求参数:", queryParams);
|
||||
common_vendor.index.__f__("log", "at pages-subpackage/ai_features/customer_count/customer_count.vue:348", "[CustomerCount] 请求URL:", url);
|
||||
common_vendor.index.showLoading({
|
||||
title: "加载中...",
|
||||
mask: true
|
||||
});
|
||||
const res = await common_request.post(url, {});
|
||||
common_vendor.index.hideLoading();
|
||||
if (res.statusCode === 200 && res.data) {
|
||||
const result = res.data;
|
||||
const isSuccess = result.success === true || result.code === 0 || result.code === 200;
|
||||
if (!isSuccess) {
|
||||
const errorMsg = result.msg || result.message || "查询失败";
|
||||
common_vendor.index.showToast({
|
||||
title: errorMsg,
|
||||
icon: "none",
|
||||
duration: 2e3
|
||||
});
|
||||
this.loading = false;
|
||||
return;
|
||||
}
|
||||
const statisticsList = result.data || [];
|
||||
common_vendor.index.__f__("log", "at pages-subpackage/ai_features/customer_count/customer_count.vue:383", "[CustomerCount] 返回数据:", statisticsList);
|
||||
common_vendor.index.__f__("log", "at pages-subpackage/ai_features/customer_count/customer_count.vue:384", "[CustomerCount] 返回结果:", result);
|
||||
this.processStatisticsData(statisticsList);
|
||||
common_vendor.index.showToast({
|
||||
title: "刷新成功",
|
||||
icon: "success",
|
||||
duration: 1500
|
||||
});
|
||||
} else {
|
||||
throw new Error("请求失败,状态码: " + res.statusCode);
|
||||
}
|
||||
} catch (error) {
|
||||
common_vendor.index.hideLoading();
|
||||
common_vendor.index.__f__("error", "at pages-subpackage/ai_features/customer_count/customer_count.vue:402", "[CustomerCount] 加载数据失败:", error);
|
||||
common_vendor.index.showToast({
|
||||
title: error.message || "加载失败,请重试",
|
||||
icon: "none",
|
||||
duration: 2e3
|
||||
});
|
||||
} finally {
|
||||
this.loading = false;
|
||||
}
|
||||
},
|
||||
/**
|
||||
* 处理统计数据
|
||||
*/
|
||||
processStatisticsData(statisticsList) {
|
||||
if (!statisticsList || statisticsList.length === 0) {
|
||||
this.totalCustomers = "0";
|
||||
this.todayCustomers = "0";
|
||||
this.dataList = [];
|
||||
return;
|
||||
}
|
||||
const firstItem = statisticsList[0];
|
||||
const totalCustomerCount = firstItem.salesTotalCustomerCount || firstItem.salesCustomerCount || 0;
|
||||
const today = /* @__PURE__ */ new Date();
|
||||
const todayStr = this.formatDate(today.toISOString());
|
||||
const todayItem = statisticsList.find((item) => {
|
||||
const itemDate = this.formatDate(item.statisticsDate);
|
||||
return itemDate === todayStr;
|
||||
});
|
||||
const todayCustomerCount = todayItem ? todayItem.salesCustomerCount || 0 : 0;
|
||||
const formattedList = statisticsList.map((item) => {
|
||||
const customerCount = item.salesCustomerCount || 0;
|
||||
const date = this.formatDate(item.statisticsDate);
|
||||
let description = "";
|
||||
if (item.dealershipName) {
|
||||
description = `${item.dealershipName}`;
|
||||
} else if (item.salesName) {
|
||||
description = `${item.salesName}的接待`;
|
||||
} else {
|
||||
description = "客户接待统计";
|
||||
}
|
||||
return {
|
||||
date,
|
||||
description,
|
||||
count: `${this.formatCustomerCount(customerCount)} 人`,
|
||||
// 保存原始数据,方便后续使用
|
||||
rawData: item
|
||||
};
|
||||
});
|
||||
formattedList.sort((a, b) => {
|
||||
if (a.date > b.date)
|
||||
return -1;
|
||||
if (a.date < b.date)
|
||||
return 1;
|
||||
return 0;
|
||||
});
|
||||
this.totalCustomers = this.formatCustomerCount(totalCustomerCount);
|
||||
this.todayCustomers = this.formatCustomerCount(todayCustomerCount);
|
||||
this.dataList = formattedList;
|
||||
common_vendor.index.__f__("log", "at pages-subpackage/ai_features/customer_count/customer_count.vue:477", "[CustomerCount] 数据处理完成:", {
|
||||
totalCustomers: this.totalCustomers,
|
||||
todayCustomers: this.todayCustomers,
|
||||
dataListCount: this.dataList.length,
|
||||
statisticsListLength: statisticsList.length
|
||||
});
|
||||
this.prepareChartData(statisticsList);
|
||||
},
|
||||
/**
|
||||
* 初始化图表尺寸
|
||||
*/
|
||||
initChartSize() {
|
||||
const systemInfo = common_vendor.index.getSystemInfoSync();
|
||||
const screenWidth = systemInfo.windowWidth || 375;
|
||||
this.chartWidth = screenWidth - 60;
|
||||
},
|
||||
/**
|
||||
* 准备图表数据
|
||||
*/
|
||||
prepareChartData(statisticsList) {
|
||||
if (!statisticsList || statisticsList.length === 0) {
|
||||
this.chartData = [];
|
||||
return;
|
||||
}
|
||||
const sortedList = [...statisticsList].sort((a, b) => {
|
||||
const dateA = new Date(a.statisticsDate);
|
||||
const dateB = new Date(b.statisticsDate);
|
||||
return dateA - dateB;
|
||||
});
|
||||
this.chartData = sortedList.map((item) => ({
|
||||
date: item.statisticsDate,
|
||||
count: item.salesCustomerCount || 0
|
||||
}));
|
||||
this.$nextTick(() => {
|
||||
setTimeout(() => {
|
||||
this.drawChart();
|
||||
}, 100);
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 绘制趋势图
|
||||
*/
|
||||
drawChart() {
|
||||
if (!this.chartData || this.chartData.length === 0) {
|
||||
return;
|
||||
}
|
||||
const ctx = common_vendor.index.createCanvasContext("trendChart", this);
|
||||
const width = this.chartWidth;
|
||||
const height = this.chartHeight;
|
||||
const padding = {
|
||||
top: 40,
|
||||
right: 20,
|
||||
bottom: 50,
|
||||
left: 50
|
||||
};
|
||||
const chartWidth = width - padding.left - padding.right;
|
||||
const chartHeight = height - padding.top - padding.bottom;
|
||||
ctx.clearRect(0, 0, width, height);
|
||||
const counts = this.chartData.map((item) => item.count);
|
||||
const maxCount = Math.max(...counts, 1);
|
||||
Math.min(...counts, 0);
|
||||
const yMax = Math.ceil(maxCount / 10) * 10;
|
||||
const yStep = yMax / 5;
|
||||
ctx.setFillStyle("#666666");
|
||||
ctx.setFontSize(10);
|
||||
for (let i = 0; i <= 5; i++) {
|
||||
const y = padding.top + chartHeight - chartHeight / 5 * i;
|
||||
const value = Math.round(yStep * i);
|
||||
ctx.fillText(value.toString(), 5, y + 4);
|
||||
ctx.setStrokeStyle("#e0e0e0");
|
||||
ctx.setLineWidth(1);
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(padding.left, y);
|
||||
ctx.lineTo(padding.left + chartWidth, y);
|
||||
ctx.stroke();
|
||||
}
|
||||
const dataCount = this.chartData.length;
|
||||
const xStep = chartWidth / Math.max(dataCount - 1, 1);
|
||||
this.chartData.forEach((item, index) => {
|
||||
const x = padding.left + xStep * index;
|
||||
const date = new Date(item.date);
|
||||
const month = date.getMonth() + 1;
|
||||
const day = date.getDate();
|
||||
const label = `${month}/${day}`;
|
||||
ctx.setFillStyle("#666666");
|
||||
ctx.setFontSize(10);
|
||||
ctx.fillText(label, x - 15, height - padding.bottom + 20);
|
||||
});
|
||||
ctx.setStrokeStyle("#007aff");
|
||||
ctx.setLineWidth(2);
|
||||
ctx.beginPath();
|
||||
this.chartData.forEach((item, index) => {
|
||||
const x = padding.left + xStep * index;
|
||||
const y = padding.top + chartHeight - item.count / yMax * chartHeight;
|
||||
if (index === 0) {
|
||||
ctx.moveTo(x, y);
|
||||
} else {
|
||||
ctx.lineTo(x, y);
|
||||
}
|
||||
});
|
||||
ctx.stroke();
|
||||
ctx.setFillStyle("#007aff");
|
||||
this.chartData.forEach((item, index) => {
|
||||
const x = padding.left + xStep * index;
|
||||
const y = padding.top + chartHeight - item.count / yMax * chartHeight;
|
||||
ctx.beginPath();
|
||||
ctx.arc(x, y, 4, 0, 2 * Math.PI);
|
||||
ctx.fill();
|
||||
});
|
||||
ctx.setStrokeStyle("#333333");
|
||||
ctx.setLineWidth(1);
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(padding.left, padding.top);
|
||||
ctx.lineTo(padding.left, padding.top + chartHeight);
|
||||
ctx.stroke();
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(padding.left, padding.top + chartHeight);
|
||||
ctx.lineTo(padding.left + chartWidth, padding.top + chartHeight);
|
||||
ctx.stroke();
|
||||
ctx.draw();
|
||||
}
|
||||
}
|
||||
};
|
||||
if (!Array) {
|
||||
const _easycom_uni_icons2 = common_vendor.resolveComponent("uni-icons");
|
||||
_easycom_uni_icons2();
|
||||
}
|
||||
const _easycom_uni_icons = () => "../../../uni_modules/uni-icons/components/uni-icons/uni-icons.js";
|
||||
if (!Math) {
|
||||
_easycom_uni_icons();
|
||||
}
|
||||
function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
|
||||
return common_vendor.e({
|
||||
a: common_vendor.o((...args) => $options.goBack && $options.goBack(...args)),
|
||||
b: $data.statusBarHeight + "px",
|
||||
c: common_vendor.t($data.timeRangeOptions[$data.timeRangeIndex]),
|
||||
d: common_vendor.p({
|
||||
type: $data.showTimeRangeDropdown ? "top" : "bottom",
|
||||
size: "14",
|
||||
color: "#999"
|
||||
}),
|
||||
e: $data.showTimeRangeDropdown
|
||||
}, $data.showTimeRangeDropdown ? {
|
||||
f: common_vendor.f($data.timeRangeOptions, (option, index, i0) => {
|
||||
return {
|
||||
a: common_vendor.t(option),
|
||||
b: index,
|
||||
c: $data.timeRangeIndex === index ? 1 : "",
|
||||
d: common_vendor.o(($event) => $options.selectTimeRange(index), index)
|
||||
};
|
||||
})
|
||||
} : {}, {
|
||||
g: common_vendor.o((...args) => $options.toggleTimeRangeDropdown && $options.toggleTimeRangeDropdown(...args)),
|
||||
h: common_vendor.p({
|
||||
type: "refresh",
|
||||
size: "18",
|
||||
color: "#2A68FF"
|
||||
}),
|
||||
i: common_vendor.o((...args) => $options.onRefresh && $options.onRefresh(...args)),
|
||||
j: $data.showTimeRangeDropdown
|
||||
}, $data.showTimeRangeDropdown ? {
|
||||
k: common_vendor.o((...args) => $options.closeTimeRangeDropdown && $options.closeTimeRangeDropdown(...args))
|
||||
} : {}, {
|
||||
l: common_vendor.t($data.totalCustomers),
|
||||
m: common_vendor.t($data.todayCustomers),
|
||||
n: $data.chartWidth + "px",
|
||||
o: $data.chartHeight + "px",
|
||||
p: common_vendor.f($data.dataList, (item, index, i0) => {
|
||||
return {
|
||||
a: common_vendor.t(item.date),
|
||||
b: common_vendor.t(item.description),
|
||||
c: common_vendor.t(item.count),
|
||||
d: index
|
||||
};
|
||||
}),
|
||||
q: $data.contentTop,
|
||||
r: $data.contentBottom
|
||||
});
|
||||
}
|
||||
const MiniProgramPage = /* @__PURE__ */ common_vendor._export_sfc(_sfc_main, [["render", _sfc_render], ["__scopeId", "data-v-e0c5faaf"]]);
|
||||
wx.createPage(MiniProgramPage);
|
||||
//# sourceMappingURL=../../../../.sourcemap/mp-weixin/pages-subpackage/ai_features/customer_count/customer_count.js.map
|
||||
6
unpackage/dist/dev/mp-weixin/pages-subpackage/ai_features/customer_count/customer_count.json
vendored
Normal file
6
unpackage/dist/dev/mp-weixin/pages-subpackage/ai_features/customer_count/customer_count.json
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"navigationStyle": "custom",
|
||||
"usingComponents": {
|
||||
"uni-icons": "../../../uni_modules/uni-icons/components/uni-icons/uni-icons"
|
||||
}
|
||||
}
|
||||
1
unpackage/dist/dev/mp-weixin/pages-subpackage/ai_features/customer_count/customer_count.wxml
vendored
Normal file
1
unpackage/dist/dev/mp-weixin/pages-subpackage/ai_features/customer_count/customer_count.wxml
vendored
Normal file
@@ -0,0 +1 @@
|
||||
<view class="feature-page data-v-e0c5faaf"><view class="page-header data-v-e0c5faaf" style="{{'padding-top:' + b}}"><view class="nav-bar data-v-e0c5faaf"><view class="nav-left data-v-e0c5faaf" bindtap="{{a}}"><text class="back-icon data-v-e0c5faaf">←</text></view><text class="nav-title data-v-e0c5faaf">接待客户数统计</text></view></view><scroll-view class="content-scroll data-v-e0c5faaf" scroll-y="true" style="{{'top:' + q + ';' + ('bottom:' + r)}}"><view class="search-toolbar data-v-e0c5faaf"><view class="toolbar-picker-wrapper data-v-e0c5faaf" bindtap="{{g}}"><view class="toolbar-picker-view data-v-e0c5faaf"><text class="toolbar-picker-text data-v-e0c5faaf">{{c}}</text><uni-icons wx:if="{{d}}" class="data-v-e0c5faaf" u-i="e0c5faaf-0" bind:__l="__l" u-p="{{d}}"></uni-icons></view><view wx:if="{{e}}" class="time-range-dropdown data-v-e0c5faaf"><view wx:for="{{f}}" wx:for-item="option" wx:key="b" class="{{['dropdown-item', 'data-v-e0c5faaf', option.c && 'dropdown-item-active']}}" catchtap="{{option.d}}"><text class="data-v-e0c5faaf">{{option.a}}</text></view></view></view><view class="toolbar-actions data-v-e0c5faaf"><view class="toolbar-btn toolbar-btn--refresh data-v-e0c5faaf" bindtap="{{i}}"><uni-icons wx:if="{{h}}" class="data-v-e0c5faaf" u-i="e0c5faaf-1" bind:__l="__l" u-p="{{h}}"></uni-icons><text class="data-v-e0c5faaf">刷新</text></view></view></view><view wx:if="{{j}}" class="dropdown-mask data-v-e0c5faaf" bindtap="{{k}}"></view><view class="stats-card data-v-e0c5faaf"><view class="stat-item data-v-e0c5faaf"><text class="stat-value data-v-e0c5faaf">{{l}}</text><text class="stat-label data-v-e0c5faaf">累计接待客户</text></view><view class="stat-item data-v-e0c5faaf"><text class="stat-value data-v-e0c5faaf">{{m}}</text><text class="stat-label data-v-e0c5faaf">今日接待客户</text></view></view><view class="chart-section data-v-e0c5faaf"><text class="section-title data-v-e0c5faaf">客户数趋势图</text><view class="chart-container data-v-e0c5faaf"><canvas canvas-id="trendChart" id="trendChart" class="chart-canvas data-v-e0c5faaf" style="{{'width:' + n + ';' + ('height:' + o)}}"></canvas></view></view><view class="data-list data-v-e0c5faaf"><text class="section-title data-v-e0c5faaf">详细数据</text><view wx:for="{{p}}" wx:for-item="item" wx:key="d" class="list-item data-v-e0c5faaf"><view class="item-left data-v-e0c5faaf"><text class="item-date data-v-e0c5faaf">{{item.a}}</text><text class="item-desc data-v-e0c5faaf">{{item.b}}</text></view><view class="item-right data-v-e0c5faaf"><text class="item-count data-v-e0c5faaf">{{item.c}}</text></view></view></view></scroll-view></view>
|
||||
234
unpackage/dist/dev/mp-weixin/pages-subpackage/ai_features/customer_count/customer_count.wxss
vendored
Normal file
234
unpackage/dist/dev/mp-weixin/pages-subpackage/ai_features/customer_count/customer_count.wxss
vendored
Normal file
@@ -0,0 +1,234 @@
|
||||
|
||||
.feature-page.data-v-e0c5faaf {
|
||||
min-height: 100vh;
|
||||
background: #f8f9fa;
|
||||
}
|
||||
.page-header.data-v-e0c5faaf {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 999;
|
||||
background: #ffffff;
|
||||
border-bottom: 1rpx solid #e9ecef;
|
||||
}
|
||||
.nav-bar.data-v-e0c5faaf {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 88rpx;
|
||||
padding: 0 30rpx;
|
||||
}
|
||||
.nav-left.data-v-e0c5faaf {
|
||||
width: 60rpx;
|
||||
height: 60rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-right: 20rpx;
|
||||
}
|
||||
.back-icon.data-v-e0c5faaf {
|
||||
font-size: 36rpx;
|
||||
color: #333333;
|
||||
}
|
||||
.nav-title.data-v-e0c5faaf {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
color: #333333;
|
||||
}
|
||||
.content-scroll.data-v-e0c5faaf {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0; /* 先从顶部开始,通过内联样式动态设置 */
|
||||
bottom: 0; /* 先从底部开始,通过内联样式动态设置 */
|
||||
/* top和bottom值通过内联样式动态设置,覆盖上面的默认值 */
|
||||
padding: 0 !important;
|
||||
margin: 0 !important;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.search-toolbar.data-v-e0c5faaf {
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
align-items: center;
|
||||
gap: 8rpx;
|
||||
padding: 12rpx 30rpx;
|
||||
margin: 20rpx 30rpx;
|
||||
background-color: #F8F8FA;
|
||||
border-radius: 8rpx;
|
||||
border: 1rpx solid #EFEFF2;
|
||||
}
|
||||
.toolbar-picker-wrapper.data-v-e0c5faaf {
|
||||
position: relative;
|
||||
flex: 1;
|
||||
min-width: 120rpx;
|
||||
max-width: 200rpx;
|
||||
flex-shrink: 1;
|
||||
z-index: 100;
|
||||
}
|
||||
.toolbar-picker-view.data-v-e0c5faaf {
|
||||
height: 56rpx;
|
||||
line-height: 56rpx;
|
||||
background-color: #F5F6FA;
|
||||
border-radius: 8rpx;
|
||||
padding: 0 12rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.toolbar-picker-text.data-v-e0c5faaf {
|
||||
font-size: 24rpx;
|
||||
color: #333;
|
||||
flex: 1;
|
||||
}
|
||||
.time-range-dropdown.data-v-e0c5faaf {
|
||||
position: absolute;
|
||||
top: calc(100% + 8rpx);
|
||||
left: 0;
|
||||
right: 0;
|
||||
background-color: #FFFFFF;
|
||||
border-radius: 8rpx;
|
||||
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.12);
|
||||
z-index: 101;
|
||||
overflow: hidden;
|
||||
border: 1rpx solid #EFEFF2;
|
||||
}
|
||||
.dropdown-item.data-v-e0c5faaf {
|
||||
padding: 20rpx 24rpx;
|
||||
border-bottom: 1rpx solid #F3F4F6;
|
||||
transition: background-color 0.2s ease;
|
||||
}
|
||||
.dropdown-item.data-v-e0c5faaf:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
.dropdown-item.data-v-e0c5faaf:active {
|
||||
background-color: #F9FAFB;
|
||||
}
|
||||
.dropdown-item text.data-v-e0c5faaf {
|
||||
font-size: 24rpx;
|
||||
color: #333;
|
||||
}
|
||||
.dropdown-item-active.data-v-e0c5faaf {
|
||||
background-color: #F0F7FF;
|
||||
}
|
||||
.dropdown-item-active text.data-v-e0c5faaf {
|
||||
color: #2A68FF;
|
||||
font-weight: 500;
|
||||
}
|
||||
.dropdown-mask.data-v-e0c5faaf {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: transparent;
|
||||
z-index: 99;
|
||||
}
|
||||
.toolbar-actions.data-v-e0c5faaf {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-left: auto;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.toolbar-btn.data-v-e0c5faaf {
|
||||
padding: 0 12rpx;
|
||||
height: 56rpx;
|
||||
min-width: 56rpx;
|
||||
color: #2A68FF;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 4rpx;
|
||||
font-size: 24rpx;
|
||||
font-weight: 400;
|
||||
}
|
||||
.toolbar-btn text.data-v-e0c5faaf {
|
||||
color: #2A68FF;
|
||||
}
|
||||
.stats-card.data-v-e0c5faaf {
|
||||
display: flex;
|
||||
margin: 20rpx 30rpx;
|
||||
background: #ffffff;
|
||||
border-radius: 16rpx;
|
||||
padding: 40rpx 30rpx;
|
||||
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
.stat-item.data-v-e0c5faaf {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
}
|
||||
.stat-item.data-v-e0c5faaf:not(:last-child) {
|
||||
border-right: 1rpx solid #e9ecef;
|
||||
}
|
||||
.stat-value.data-v-e0c5faaf {
|
||||
display: block;
|
||||
font-size: 48rpx;
|
||||
font-weight: bold;
|
||||
color: #007aff;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
.stat-label.data-v-e0c5faaf {
|
||||
display: block;
|
||||
font-size: 24rpx;
|
||||
color: #666666;
|
||||
}
|
||||
.chart-section.data-v-e0c5faaf, .data-list.data-v-e0c5faaf {
|
||||
margin: 20rpx 30rpx;
|
||||
background: #ffffff;
|
||||
border-radius: 16rpx;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
.section-title.data-v-e0c5faaf {
|
||||
display: block;
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
color: #333333;
|
||||
padding: 30rpx;
|
||||
border-bottom: 1rpx solid #e9ecef;
|
||||
}
|
||||
.chart-container.data-v-e0c5faaf {
|
||||
padding: 30rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
.chart-canvas.data-v-e0c5faaf {
|
||||
display: block;
|
||||
}
|
||||
.list-item.data-v-e0c5faaf {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 30rpx;
|
||||
border-bottom: 1rpx solid #f0f0f0;
|
||||
}
|
||||
.list-item.data-v-e0c5faaf:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
.item-left.data-v-e0c5faaf {
|
||||
flex: 1;
|
||||
}
|
||||
.item-date.data-v-e0c5faaf {
|
||||
display: block;
|
||||
font-size: 28rpx;
|
||||
font-weight: bold;
|
||||
color: #333333;
|
||||
margin-bottom: 8rpx;
|
||||
}
|
||||
.item-desc.data-v-e0c5faaf {
|
||||
display: block;
|
||||
font-size: 24rpx;
|
||||
color: #666666;
|
||||
}
|
||||
.item-right.data-v-e0c5faaf {
|
||||
text-align: right;
|
||||
}
|
||||
.item-count.data-v-e0c5faaf {
|
||||
display: block;
|
||||
font-size: 28rpx;
|
||||
font-weight: bold;
|
||||
color: #007aff;
|
||||
}
|
||||
Reference in New Issue
Block a user