From 343c142d876f6f04a77f401d2e0750a5cc3ef12b Mon Sep 17 00:00:00 2001 From: wong <106998207@qq.com> Date: Sat, 30 Aug 2025 17:14:57 +0800 Subject: [PATCH] =?UTF-8?q?=E9=97=A8=E5=BA=97=E7=AB=AF=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../store/controller/CustomerController.php | 38 ++++--- .../store/controller/StatisticsController.php | 100 ++++++++++++------ Store_vue/App.vue | 36 ++++++- Store_vue/api/config/index.js | 4 +- Store_vue/components/CustomerManagement.vue | 2 +- Store_vue/components/DataStatistics.vue | 2 +- Store_vue/components/LoginRegister.vue | 2 +- Store_vue/components/PackageDetail.vue | 2 +- Store_vue/components/SideMenu.vue | 9 +- Store_vue/components/SupplyChainPurchase.vue | 2 +- Store_vue/components/SupplyItemDetail.vue | 2 +- Store_vue/components/SystemSettings.vue | 2 +- Store_vue/components/TrafficPurchase.vue | 2 +- Store_vue/pages/chat/index.vue | 2 +- Store_vue/pages/login/index.vue | 18 ++-- 15 files changed, 147 insertions(+), 76 deletions(-) diff --git a/Server/application/store/controller/CustomerController.php b/Server/application/store/controller/CustomerController.php index 9bec2a68..e61e62e7 100644 --- a/Server/application/store/controller/CustomerController.php +++ b/Server/application/store/controller/CustomerController.php @@ -27,24 +27,33 @@ class CustomerController extends Api $pageSize = isset($params['pageSize']) ? intval($params['pageSize']) : 10; $userInfo = request()->userInfo; - + $where = []; // 必要的查询条件 $userId = $userInfo['id']; $companyId = $userInfo['companyId']; - + if (empty($userId) || empty($companyId)) { return errorJson('缺少必要参数'); } // 构建查询条件 - $where = [ - 'du.userId' => $userId, - 'du.companyId' => $companyId - ]; - + $deviceIds = Db::name('device_user')->where(['userId' => $userId, 'companyId' => $companyId])->order('id DESC')->column('deviceId'); + if (empty($deviceIds)) { + return errorJson('设备不存在'); + } + $wechatIds = []; + foreach ($deviceIds as $deviceId) { + $wechatIds[] = Db::name('device_wechat_login') + ->where(['deviceId' => $deviceId]) + ->order('id DESC') + ->value('wechatId'); + } + + + // 搜索条件 if (!empty($params['keyword'])) { - $where['wf.alias|wf.nickname|wf.wechatId'] = ['like', '%' . $params['keyword'] . '%']; + $where['alias|nickname|wechatId'] = ['like', '%' . $params['keyword'] . '%']; } // if (!empty($params['email'])) { // $where['wa.bindEmail'] = ['like', '%' . $params['email'] . '%']; @@ -54,14 +63,10 @@ class CustomerController extends Api // } // 构建查询 - $query = Db::name('device_user') - ->alias('du') - ->join(['s2_device' => 'd'], 'd.id = du.deviceId','left') - ->join(['s2_wechat_account' => 'wa'], 'wa.imei = d.imei','left') - ->join(['s2_wechat_friend' => 'wf'], 'wf.ownerWechatId = wa.wechatId','left') + $query = Db::table('s2_wechat_friend') ->where($where) - ->field('d.id as deviceId,d.imei,wf.*') - ->group('wf.wechatId'); // 防止重复数据 + ->whereIn('ownerWechatId',$wechatIds) + ->group('wechatId'); // 防止重复数据 // 克隆查询对象,用于计算总数 $countQuery = clone $query; @@ -69,10 +74,9 @@ class CustomerController extends Api // 获取分页数据 $list = $query->page($page, $pageSize) - ->order('wa.id DESC') + ->order('id DESC') ->select(); - // 格式化数据 foreach ($list as &$item) { diff --git a/Server/application/store/controller/StatisticsController.php b/Server/application/store/controller/StatisticsController.php index 56ac7c2a..11cda5fb 100644 --- a/Server/application/store/controller/StatisticsController.php +++ b/Server/application/store/controller/StatisticsController.php @@ -4,7 +4,8 @@ namespace app\store\controller; use app\store\model\WechatFriendModel; use app\store\model\WechatMessageModel; -use think\facade\Db; +use think\Db; + /** * 数据统计控制器 @@ -18,8 +19,23 @@ class StatisticsController extends BaseController { try { $companyId = $this->userInfo['companyId']; - $wechatAccountId = $this->device['wechatAccountId']; - $ownerWechatId = $this->device['wechatId']; + $userId = $this->userInfo['id']; + + // 构建查询条件 + $deviceIds = Db::name('device_user')->where(['userId' => $userId, 'companyId' => $companyId])->order('id DESC')->column('deviceId'); + if (empty($deviceIds)) { + return errorJson('设备不存在'); + } + $ownerWechatIds = []; + foreach ($deviceIds as $deviceId) { + $ownerWechatIds[] = Db::name('device_wechat_login') + ->where(['deviceId' => $deviceId]) + ->order('id DESC') + ->value('wechatId'); + } + + $wechatAccountIds = Db::table('s2_wechat_account')->whereIn('wechatId',$ownerWechatIds)->column('id'); + // 获取时间范围 $timeRange = $this->getTimeRange(); @@ -33,37 +49,37 @@ class StatisticsController extends BaseController // 1. 总客户数 - $totalCustomers = WechatFriendModel::where(['ownerWechatId'=> $ownerWechatId]) + $totalCustomers = WechatFriendModel::whereIn('ownerWechatId',$ownerWechatIds) ->whereTime('createTime', '>=', $startTime) ->whereTime('createTime', '<', $endTime) ->count(); // 上期总客户数 - $lastTotalCustomers = WechatFriendModel::where(['ownerWechatId'=> $ownerWechatId]) + $lastTotalCustomers = WechatFriendModel::whereIn('ownerWechatId',$ownerWechatIds) ->whereTime('createTime', '>=', $lastStartTime) ->whereTime('createTime', '<', $lastEndTime) ->count(); // 2. 新增客户数 - $newCustomers = WechatFriendModel::where(['ownerWechatId'=> $ownerWechatId]) + $newCustomers = WechatFriendModel::whereIn('ownerWechatId',$ownerWechatIds) ->whereTime('createTime', '>=', $startTime) ->whereTime('createTime', '<', $endTime) ->count(); // 上期新增客户数 - $lastNewCustomers = WechatFriendModel::where(['ownerWechatId'=> $ownerWechatId]) + $lastNewCustomers = WechatFriendModel::whereIn('ownerWechatId',$ownerWechatIds) ->whereTime('createTime', '>=', $lastStartTime) ->whereTime('createTime', '<', $lastEndTime) ->count(); //3. 互动次数 - $interactionCount = WechatMessageModel::where(['wechatAccountId'=> $wechatAccountId]) + $interactionCount = WechatMessageModel::whereIn('wechatAccountId', $wechatAccountIds) ->where('createTime', '>=', $startTime) ->where('createTime', '<', $endTime) ->count(); // 上期互动次数 - $lastInteractionCount = WechatMessageModel::where(['wechatAccountId'=> $wechatAccountId]) + $lastInteractionCount = WechatMessageModel::whereIn('wechatAccountId', $wechatAccountIds) ->where('createTime', '>=', $lastStartTime) ->where('createTime', '<', $lastEndTime) ->count(); @@ -103,10 +119,20 @@ class StatisticsController extends BaseController { try { $companyId = $this->userInfo['companyId']; - $wechatAccountId = $this->device['wechatAccountId']; - $ownerWechatId = $this->device['wechatId']; - + $userId = $this->userInfo['id']; + // 构建查询条件 + $deviceIds = Db::name('device_user')->where(['userId' => $userId, 'companyId' => $companyId])->order('id DESC')->column('deviceId'); + if (empty($deviceIds)) { + return errorJson('设备不存在'); + } + $ownerWechatIds = []; + foreach ($deviceIds as $deviceId) { + $ownerWechatIds[] = Db::name('device_wechat_login') + ->where(['deviceId' => $deviceId]) + ->order('id DESC') + ->value('wechatId'); + } @@ -116,35 +142,35 @@ class StatisticsController extends BaseController $endTime = $timeRange['end_time']; // 1. 客户增长趋势数据 - $totalCustomers = WechatFriendModel::where(['ownerWechatId'=> $ownerWechatId]) + $totalCustomers = WechatFriendModel::whereIn('ownerWechatId', $ownerWechatIds) ->whereTime('createTime', '<', $endTime) ->count(); - $newCustomers = WechatFriendModel::where(['ownerWechatId'=> $ownerWechatId]) + $newCustomers = WechatFriendModel::whereIn('ownerWechatId', $ownerWechatIds) ->whereTime('createTime', '>=', $startTime) ->whereTime('createTime', '<', $endTime) ->count(); // 计算流失客户数(假设超过30天未互动的客户为流失客户) $thirtyDaysAgo = strtotime('-30 days'); - $lostCustomers = WechatFriendModel::where(['ownerWechatId'=> $ownerWechatId]) + $lostCustomers = WechatFriendModel::whereIn('ownerWechatId', $ownerWechatIds) ->where('createTime', '>', 0) ->where('deleteTime', '<', $thirtyDaysAgo) ->count(); // 2. 客户来源分布数据 // 朋友推荐 - $friendRecommend = WechatFriendModel::where(['ownerWechatId'=> $ownerWechatId]) + $friendRecommend = WechatFriendModel::whereIn('ownerWechatId', $ownerWechatIds) // ->whereIn('addFrom', [17, 1000017]) ->count(); // 微信搜索 - $wechatSearch = WechatFriendModel::where(['ownerWechatId'=> $ownerWechatId]) + $wechatSearch = WechatFriendModel::whereIn('ownerWechatId', $ownerWechatIds) // ->whereIn('addFrom', [3, 15, 1000003, 1000015]) ->count(); // 微信群 - $wechatGroup = WechatFriendModel::where(['ownerWechatId'=> $ownerWechatId]) + $wechatGroup = WechatFriendModel::whereIn('ownerWechatId', $ownerWechatIds) // ->whereIn('addFrom', [14, 1000014]) ->count(); @@ -202,9 +228,23 @@ class StatisticsController extends BaseController public function getInteractionAnalysis() { try { - $companyId = $this->userInfo['companyId']; - $wechatAccountId = $this->device['wechatAccountId']; - + $companyId = $this->userInfo['companyId']; + $userId = $this->userInfo['id']; + + // 构建查询条件 + $deviceIds = Db::name('device_user')->where(['userId' => $userId, 'companyId' => $companyId])->order('id DESC')->column('deviceId'); + if (empty($deviceIds)) { + return errorJson('设备不存在'); + } + $ownerWechatIds = []; + foreach ($deviceIds as $deviceId) { + $ownerWechatIds[] = Db::name('device_wechat_login') + ->where(['deviceId' => $deviceId]) + ->order('id DESC') + ->value('wechatId'); + } + $wechatAccountIds = Db::table('s2_wechat_account')->whereIn('wechatId',$ownerWechatIds)->column('id'); + // 获取时间范围 $timeRange = $this->getTimeRange(); $startTime = $timeRange['start_time']; @@ -216,7 +256,7 @@ class StatisticsController extends BaseController // 1. 互动频率分析 // 高频互动用户数(每天3次以上) - $highFrequencyUsers = WechatMessageModel::where(['wechatAccountId' => $wechatAccountId]) + $highFrequencyUsers = WechatMessageModel::whereIn('wechatAccountId' , $wechatAccountIds) ->where('createTime', '>=', $startTime) ->where('createTime', '<', $endTime) ->field('wechatFriendId, COUNT(*) as count') @@ -225,7 +265,7 @@ class StatisticsController extends BaseController ->count(); // 中频互动用户数(每天1-3次) - $midFrequencyUsers = WechatMessageModel::where(['wechatAccountId' => $wechatAccountId]) + $midFrequencyUsers = WechatMessageModel::whereIn('wechatAccountId' , $wechatAccountIds) ->where('createTime', '>=', $startTime) ->where('createTime', '<', $endTime) ->field('wechatFriendId, COUNT(*) as count') @@ -234,7 +274,7 @@ class StatisticsController extends BaseController ->count(); // 低频互动用户数(仅有1次) - $lowFrequencyUsers = WechatMessageModel::where(['wechatAccountId' => $wechatAccountId]) + $lowFrequencyUsers = WechatMessageModel::whereIn('wechatAccountId' , $wechatAccountIds) ->where('createTime', '>=', $startTime) ->where('createTime', '<', $endTime) ->field('wechatFriendId, COUNT(*) as count') @@ -245,41 +285,39 @@ class StatisticsController extends BaseController // 2. 互动内容分析 // 文字消息数量 $textMessages = WechatMessageModel::where([ - 'wechatAccountId' => $wechatAccountId, 'msgType' => 1 ]) ->where('createTime', '>=', $startTime) ->where('createTime', '<', $endTime) + ->whereIn('wechatAccountId' , $wechatAccountIds) ->count(); // 图片互动数量 $imgInteractions = WechatMessageModel::where([ - 'wechatAccountId' => $wechatAccountId, 'msgType' => 3 ]) ->where('createTime', '>=', $startTime) ->where('createTime', '<', $endTime) + ->whereIn('wechatAccountId' , $wechatAccountIds) ->count(); // 群聊互动数量 $groupInteractions = WechatMessageModel::where([ - 'wechatAccountId' => $wechatAccountId, 'type' => 2 ]) ->where('createTime', '>=', $startTime) ->where('createTime', '<', $endTime) + ->whereIn('wechatAccountId' , $wechatAccountIds) ->count(); // 产品咨询数量 (通过消息内容模糊查询) - $productInquiries = WechatMessageModel::where([ - 'wechatAccountId' => $wechatAccountId - ]) - ->where('createTime', '>=', $startTime) + $productInquiries = WechatMessageModel::where('createTime', '>=', $startTime) ->where('createTime', '<', $endTime) ->where('content', 'like', '%产品%') ->whereOr('content', 'like', '%价格%') ->whereOr('content', 'like', '%购买%') ->whereOr('content', 'like', '%优惠%') + ->whereIn('wechatAccountId' , $wechatAccountIds) ->count(); // 构建返回数据 diff --git a/Store_vue/App.vue b/Store_vue/App.vue index a75c505b..b97e7bc2 100644 --- a/Store_vue/App.vue +++ b/Store_vue/App.vue @@ -29,6 +29,34 @@ } } } + + export function getSafeAreaHeight() { + // 1. 优先使用 CSS 环境变量 + if (CSS.supports("padding-top", "env(safe-area-inset-top)")) { + const safeAreaTop = getComputedStyle( + document.documentElement, + ).getPropertyValue("env(safe-area-inset-top)"); + const height = parseInt(safeAreaTop) || 0; + if (height > 0) return height; + } + + // 2. 设备检测 + const isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent); + const isAndroid = /Android/.test(navigator.userAgent); + const isAppMode = getSetting("isAppMode"); + if (isIOS && isAppMode) { + // iOS 设备 + const isIPhoneX = window.screen.height >= 812; + return isIPhoneX ? 44 : 20; + } else if (isAndroid) { + // Android 设备 + return 24; + } + + // 3. 默认值 + return 0; + } +