diff --git a/Server/application/store/config/route.php b/Server/application/store/config/route.php
index c5fcfe0f..ae09c5df 100644
--- a/Server/application/store/config/route.php
+++ b/Server/application/store/config/route.php
@@ -35,9 +35,8 @@ Route::group('v1/store', function () {
// 数据统计相关路由
Route::group('statistics', function () {
Route::get('overview', 'app\store\controller\StatisticsController@getOverview'); // 获取数据概览
- Route::get('customer-analysis', 'app\store\controller\StatisticsController@getCustomerAnalysis'); // 获取客户分析数据
- Route::get('interaction-analysis', 'app\store\controller\StatisticsController@getInteractionAnalysis'); // 获取互动分析数据
- });
+ Route::get('comprehensive-analysis', 'app\store\controller\StatisticsController@getComprehensiveAnalysis'); // 获取综合分析数据
+ });
// 供应商相关路由
Route::group('vendor', function () {
diff --git a/Server/application/store/controller/StatisticsController.php b/Server/application/store/controller/StatisticsController.php
index 2096b2bc..17c9226c 100644
--- a/Server/application/store/controller/StatisticsController.php
+++ b/Server/application/store/controller/StatisticsController.php
@@ -4,6 +4,7 @@ namespace app\store\controller;
use app\store\model\WechatFriendModel;
use app\store\model\WechatMessageModel;
+use app\store\model\TrafficOrderModel;
use think\Db;
@@ -18,8 +19,8 @@ class StatisticsController extends BaseController
public function getOverview()
{
try {
- $companyId = $this->userInfo['companyId'];
- $userId = $this->userInfo['id'];
+ $companyId = $this->userInfo['companyId'];
+ $userId = $this->userInfo['id'];
// 构建查询条件
$deviceIds = Db::name('device_user')->where(['userId' => $userId, 'companyId' => $companyId])->order('id DESC')->column('deviceId');
@@ -34,7 +35,7 @@ class StatisticsController extends BaseController
->value('wechatId');
}
- $wechatAccountIds = Db::table('s2_wechat_account')->whereIn('wechatId',$ownerWechatIds)->column('id');
+ $wechatAccountIds = Db::table('s2_wechat_account')->whereIn('wechatId', $ownerWechatIds)->column('id');
// 获取时间范围
@@ -45,43 +46,57 @@ class StatisticsController extends BaseController
$lastEndTime = $timeRange['last_end_time'];
-
-
-
// 1. 总客户数
- $totalCustomers = WechatFriendModel::whereIn('ownerWechatId',$ownerWechatIds)
- ->where('isDeleted',0)
- ->count();
+ $totalCustomers = WechatFriendModel::whereIn('ownerWechatId', $ownerWechatIds)
+ ->where('isDeleted', 0)
+ ->whereTime('createTime', '>=', $startTime)
+ ->whereTime('createTime', '<', $endTime)
+ ->count();
// 上期总客户数
- $lastTotalCustomers = WechatFriendModel::whereIn('ownerWechatId',$ownerWechatIds)->count();
+ $lastTotalCustomers = WechatFriendModel::whereIn('ownerWechatId', $ownerWechatIds)
+ ->whereTime('createTime', '>=', $lastStartTime)
+ ->whereTime('createTime', '<', $lastEndTime)
+ ->count();
// 2. 新增客户数
- $newCustomers = WechatFriendModel::whereIn('ownerWechatId',$ownerWechatIds)
- ->whereTime('createTime', '>=', $startTime)
- ->whereTime('createTime', '<', $endTime)
- ->count();
+ $newCustomers = WechatFriendModel::whereIn('ownerWechatId', $ownerWechatIds)
+ ->whereTime('createTime', '>=', $startTime)
+ ->whereTime('createTime', '<', $endTime)
+ ->count();
// 上期新增客户数
- $lastNewCustomers = WechatFriendModel::whereIn('ownerWechatId',$ownerWechatIds)
- ->whereTime('createTime', '>=', $lastStartTime)
- ->whereTime('createTime', '<', $lastEndTime)
- ->count();
+ $lastNewCustomers = WechatFriendModel::whereIn('ownerWechatId', $ownerWechatIds)
+ ->whereTime('createTime', '>=', $lastStartTime)
+ ->whereTime('createTime', '<', $lastEndTime)
+ ->count();
//3. 互动次数
$interactionCount = WechatMessageModel::whereIn('wechatAccountId', $wechatAccountIds)
- ->where('createTime', '>=', $startTime)
- ->where('createTime', '<', $endTime)
- ->count();
+ ->where('createTime', '>=', $startTime)
+ ->where('createTime', '<', $endTime)
+ ->count();
// 上期互动次数
$lastInteractionCount = WechatMessageModel::whereIn('wechatAccountId', $wechatAccountIds)
- ->where('createTime', '>=', $lastStartTime)
- ->where('createTime', '<', $lastEndTime)
- ->count();
-
+ ->where('createTime', '>=', $lastStartTime)
+ ->where('createTime', '<', $lastEndTime)
+ ->count();
-
+ // 4. RFM 平均值计算(不查询上期数据)
+ $rfmStats = WechatFriendModel::whereIn('ownerWechatId', $ownerWechatIds)
+ ->where('isDeleted', 0)
+ ->field('AVG(`R`) as avgR, AVG(`F`) as avgF, AVG(`M`) as avgM')
+ ->find();
+
+ // 处理查询结果,如果字段为null则默认为0
+ $avgR = isset($rfmStats['avgR']) && $rfmStats['avgR'] !== null ? round((float)$rfmStats['avgR'], 2) : 0;
+ $avgF = isset($rfmStats['avgF']) && $rfmStats['avgF'] !== null ? round((float)$rfmStats['avgF'], 2) : 0;
+ $avgM = isset($rfmStats['avgM']) && $rfmStats['avgM'] !== null ? round((float)$rfmStats['avgM'], 2) : 0;
+
+ // 计算三者的平均值
+ $avgRFM = ($avgR + $avgF + $avgM) / 3;
+ $avgRFM = round($avgRFM, 2);
// 计算环比增长率
$customerGrowth = $this->calculateGrowth($totalCustomers, $lastTotalCustomers);
@@ -99,6 +114,16 @@ class StatisticsController extends BaseController
'interaction_count' => [
'value' => $interactionCount,
'growth' => $interactionGrowth
+ ],
+ 'conversion_rate' => [
+ 'value' => 10,
+ 'growth' => 15
+ ],
+ 'account_value' => [
+ 'avg_r' => $avgR,
+ 'avg_f' => $avgF,
+ 'avg_m' => $avgM,
+ 'avg_rfm' => $avgRFM
]
];
@@ -108,14 +133,15 @@ class StatisticsController extends BaseController
}
}
+
/**
- * 获取客户分析数据
+ * 获取综合分析数据
*/
- public function getCustomerAnalysis()
+ public function getComprehensiveAnalysis()
{
try {
- $companyId = $this->userInfo['companyId'];
- $userId = $this->userInfo['id'];
+ $companyId = $this->userInfo['companyId'];
+ $userId = $this->userInfo['id'];
// 构建查询条件
$deviceIds = Db::name('device_user')->where(['userId' => $userId, 'companyId' => $companyId])->order('id DESC')->column('deviceId');
@@ -129,58 +155,189 @@ class StatisticsController extends BaseController
->order('id DESC')
->value('wechatId');
}
+ $wechatAccountIds = Db::table('s2_wechat_account')->whereIn('wechatId', $ownerWechatIds)->column('id');
-
-
// 获取时间范围
$timeRange = $this->getTimeRange();
$startTime = $timeRange['start_time'];
$endTime = $timeRange['end_time'];
+ $lastStartTime = $timeRange['last_start_time'];
+ $lastEndTime = $timeRange['last_end_time'];
- // 1. 客户增长趋势数据
- $totalCustomers = WechatFriendModel::whereIn('ownerWechatId', $ownerWechatIds)
- ->where('isDeleted',0)
- ->whereTime('createTime', '<', $endTime)
+ // ========== 1. 客户平均转化金额 ==========
+ // 获取有订单的客户数(去重)
+ $convertedCustomers = TrafficOrderModel::whereIn('ownerWechatId', $ownerWechatIds)
+ ->where('createTime', '>=', $startTime)
+ ->where('createTime', '<', $endTime)
+ ->group('identifier')
+ ->column('identifier');
+ $convertedCustomerCount = count($convertedCustomers);
+
+ // 总销售额
+ $totalSales = TrafficOrderModel::whereIn('ownerWechatId', $ownerWechatIds)
+ ->where('createTime', '>=', $startTime)
+ ->where('createTime', '<', $endTime)
+ ->sum('actualPay');
+ $totalSales = $totalSales ?: 0;
+
+ // 客户平均转化金额
+ $avgConversionAmount = $convertedCustomerCount > 0 ? round($totalSales / $convertedCustomerCount, 2) : 0;
+
+ // ========== 2. 价值指标 ==========
+ // 销售总额(已计算)
+
+ // 平均订单金额(总订单数)
+ $totalOrderCount = TrafficOrderModel::whereIn('ownerWechatId', $ownerWechatIds)
+ ->where('createTime', '>=', $startTime)
+ ->where('createTime', '<', $endTime)
->count();
+ $avgOrderAmount = $totalOrderCount > 0 ? round($totalSales / $totalOrderCount, 2) : 0;
+
+ // 高价值客户(消费超过平均订单金额的客户)
+ // 先获取每个客户的消费总额
+ $customerTotalSpend = TrafficOrderModel::whereIn('ownerWechatId', $ownerWechatIds)
+ ->where('createTime', '>=', $startTime)
+ ->where('createTime', '<', $endTime)
+ ->field('identifier, SUM(actualPay) as totalSpend')
+ ->group('identifier')
+ ->select();
+
+ $highValueCustomerCount = 0;
+ $avgCustomerSpend = $convertedCustomerCount > 0 ? ($totalSales / $convertedCustomerCount) : 0;
+ foreach ($customerTotalSpend as $customer) {
+ if ($customer['totalSpend'] > $avgCustomerSpend) {
+ $highValueCustomerCount++;
+ }
+ }
+
+ // 高价值客户百分比
+ $totalCustomersForCalc = WechatFriendModel::whereIn('ownerWechatId', $ownerWechatIds)
+ ->where('isDeleted', 0)
+ ->count();
+ $highValueCustomerPercent = $totalCustomersForCalc > 0 ? round(($highValueCustomerCount / $totalCustomersForCalc) * 100, 1) : 0;
+ // ========== 3. 增长趋势 ==========
+ // 上期销售额
+ $lastTotalSales = TrafficOrderModel::whereIn('ownerWechatId', $ownerWechatIds)
+ ->where('createTime', '>=', $lastStartTime)
+ ->where('createTime', '<', $lastEndTime)
+ ->sum('actualPay');
+ $lastTotalSales = $lastTotalSales ?: 0;
+
+ // 周收益增长(金额差值)
+ $weeklyRevenueGrowth = round($totalSales - $lastTotalSales, 2);
+
+ // 新客转化(新客户中有订单的人数)
$newCustomers = WechatFriendModel::whereIn('ownerWechatId', $ownerWechatIds)
- ->where('isDeleted',0)
- ->whereTime('createTime', '>=', $startTime)
- ->whereTime('createTime', '<', $endTime)
+ ->where('createTime', '>=', $startTime)
+ ->where('createTime', '<', $endTime)
+ ->column('wechatId');
+
+ // 获取新客户中有订单的(identifier 对应 wechatId)
+ $newConvertedCustomers = 0;
+ if (!empty($newCustomers)) {
+ $newConvertedCustomers = TrafficOrderModel::whereIn('ownerWechatId', $ownerWechatIds)
+ ->where('createTime', '>=', $startTime)
+ ->where('createTime', '<', $endTime)
+ ->whereIn('identifier', $newCustomers)
+ ->group('identifier')
+ ->count();
+ }
+
+ // 活跃客户增长(有互动的客户)
+ $activeCustomers = WechatMessageModel::whereIn('wechatAccountId', $wechatAccountIds)
+ ->where('createTime', '>=', $startTime)
+ ->where('createTime', '<', $endTime)
+ ->group('wechatFriendId')
+ ->count();
+
+ $lastActiveCustomers = WechatMessageModel::whereIn('wechatAccountId', $wechatAccountIds)
+ ->where('createTime', '>=', $lastStartTime)
+ ->where('createTime', '<', $lastEndTime)
+ ->group('wechatFriendId')
+ ->count();
+
+ // 活跃客户增长(人数差值)
+ $activeCustomerGrowth = $activeCustomers - $lastActiveCustomers;
+
+ // ========== 4. 客户活跃度 ==========
+ // 按天统计每个客户的互动次数,然后分类
+ // 高频互动用户数(平均每天3次以上)
+ $days = max(1, ($endTime - $startTime) / 86400); // 计算天数
+ $highFrequencyThreshold = $days * 3; // 高频阈值
+
+ $highFrequencyUsers = WechatMessageModel::whereIn('wechatAccountId', $wechatAccountIds)
+ ->where('createTime', '>=', $startTime)
+ ->where('createTime', '<', $endTime)
+ ->field('wechatFriendId, COUNT(*) as count')
+ ->group('wechatFriendId')
+ ->having('count > ' . $highFrequencyThreshold)
->count();
- // 计算流失客户数
- $lostCustomers = WechatFriendModel::whereIn('ownerWechatId', $ownerWechatIds)
- ->where('isDeleted',1)
- ->where('createTime', '>', 0)
- ->whereTime('deleteTime', '>=', $startTime)
- ->whereTime('deleteTime', '<', $endTime)
+ // 中频互动用户数(平均每天1-3次)
+ $midFrequencyThreshold = $days * 1;
+ $midFrequencyUsers = WechatMessageModel::whereIn('wechatAccountId', $wechatAccountIds)
+ ->where('createTime', '>=', $startTime)
+ ->where('createTime', '<', $endTime)
+ ->field('wechatFriendId, COUNT(*) as count')
+ ->group('wechatFriendId')
+ ->having('count >= ' . $midFrequencyThreshold . ' AND count <= ' . $highFrequencyThreshold)
->count();
- // 2. 客户来源分布数据
- // 朋友推荐
- $friendRecommend = WechatFriendModel::whereIn('ownerWechatId', $ownerWechatIds)
- ->whereIn('addFrom', [17, 1000017])
+ // 低频互动用户数(少于平均每天1次)
+ $lowFrequencyUsers = WechatMessageModel::whereIn('wechatAccountId', $wechatAccountIds)
+ ->where('createTime', '>=', $startTime)
+ ->where('createTime', '<', $endTime)
+ ->field('wechatFriendId, COUNT(*) as count')
+ ->group('wechatFriendId')
+ ->having('count < ' . $midFrequencyThreshold)
->count();
- // 微信搜索
- $wechatSearch = WechatFriendModel::whereIn('ownerWechatId', $ownerWechatIds)
- ->whereIn('addFrom', [3, 15, 1000003, 1000015])
- ->count();
+ $frequency_analysis = [
+ ['name' => '高频', 'value' => $highFrequencyUsers],
+ ['name' => '中频', 'value' => $midFrequencyUsers],
+ ['name' => '低频', 'value' => $lowFrequencyUsers]
+ ];
- // 微信群
- $wechatGroup = WechatFriendModel::whereIn('ownerWechatId', $ownerWechatIds)
- ->whereIn('addFrom', [14, 1000014])
- ->count();
+ // ========== 5. 转化客户来源 ==========
+ // 只统计有订单的客户来源(identifier 对应 wechatId)
+ $convertedFriendIds = TrafficOrderModel::whereIn('ownerWechatId', $ownerWechatIds)
+ ->where('createTime', '>=', $startTime)
+ ->where('createTime', '<', $endTime)
+ ->group('identifier')
+ ->column('identifier');
+
+ $friendRecommend = 0;
+ $wechatSearch = 0;
+ $wechatGroup = 0;
+
+ if (!empty($convertedFriendIds)) {
+ // 朋友推荐(有订单的)
+ $friendRecommend = WechatFriendModel::whereIn('ownerWechatId', $ownerWechatIds)
+ ->whereIn('wechatId', $convertedFriendIds)
+ ->whereIn('addFrom', [17, 1000017])
+ ->count();
- // 其他渠道(总数减去已知渠道)
- $otherSource = $totalCustomers - $friendRecommend - $wechatSearch - $wechatGroup;
- $otherSource = max(0, $otherSource); // 确保不会出现负数
+ // 微信搜索(有订单的)
+ $wechatSearch = WechatFriendModel::whereIn('ownerWechatId', $ownerWechatIds)
+ ->whereIn('wechatId', $convertedFriendIds)
+ ->whereIn('addFrom', [3, 15, 1000003, 1000015])
+ ->count();
+
+ // 微信群(有订单的)
+ $wechatGroup = WechatFriendModel::whereIn('ownerWechatId', $ownerWechatIds)
+ ->whereIn('wechatId', $convertedFriendIds)
+ ->whereIn('addFrom', [14, 1000014])
+ ->count();
+ }
+
+ $totalConvertedCustomers = $convertedCustomerCount;
+ $otherSource = max(0, $totalConvertedCustomers - $friendRecommend - $wechatSearch - $wechatGroup);
// 计算百分比
- $calculatePercentage = function($value) use ($totalCustomers) {
- if ($totalCustomers <= 0) return 0;
- return round(($value / $totalCustomers) * 100, 2);
+ $calculatePercentage = function ($value) use ($totalConvertedCustomers) {
+ if ($totalConvertedCustomers <= 0) return 0;
+ return round(($value / $totalConvertedCustomers) * 100, 2);
};
$sourceDistribution = [
@@ -198,151 +355,24 @@ class StatisticsController extends BaseController
'name' => '微信群',
'value' => $calculatePercentage($wechatGroup) . '%',
'count' => $wechatGroup
- ],
- [
- 'name' => '其他渠道',
- 'value' => $calculatePercentage($otherSource) . '%',
- 'count' => $otherSource
]
];
- $data = [
- 'trend' => [
- 'total' => $totalCustomers,
- 'new' => $newCustomers,
- 'lost' => $lostCustomers
- ],
- 'source_distribution' => $sourceDistribution
- ];
-
- return successJson($data);
- } catch (\Exception $e) {
- return errorJson('获取客户分析数据失败:' . $e->getMessage());
- }
- }
-
- /**
- * 获取互动分析数据
- */
- public function getInteractionAnalysis()
- {
- try {
- $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'];
- $endTime = $timeRange['end_time'];
-
- // 不再需要转换为时间戳,因为getTimeRange已经转换
- // $startTimestamp = strtotime($startTime);
- // $endTimestamp = strtotime($endTime);
-
- // 1. 互动频率分析
- // 高频互动用户数(每天3次以上)
- $highFrequencyUsers = WechatMessageModel::whereIn('wechatAccountId' , $wechatAccountIds)
- ->where('createTime', '>=', $startTime)
- ->where('createTime', '<', $endTime)
- ->field('wechatFriendId, COUNT(*) as count')
- ->group('wechatFriendId')
- ->having('count > 3')
- ->count();
-
- // 中频互动用户数(每天1-3次)
- $midFrequencyUsers = WechatMessageModel::whereIn('wechatAccountId' , $wechatAccountIds)
- ->where('createTime', '>=', $startTime)
- ->where('createTime', '<', $endTime)
- ->field('wechatFriendId, COUNT(*) as count')
- ->group('wechatFriendId')
- ->having('count >= 1 AND count <= 3')
- ->count();
-
- // 低频互动用户数(仅有1次)
- $lowFrequencyUsers = WechatMessageModel::whereIn('wechatAccountId' , $wechatAccountIds)
- ->where('createTime', '>=', $startTime)
- ->where('createTime', '<', $endTime)
- ->field('wechatFriendId, COUNT(*) as count')
- ->group('wechatFriendId')
- ->having('count = 1')
- ->count();
-
- // 2. 互动内容分析
- // 文字消息数量
- $textMessages = WechatMessageModel::where([
- 'msgType' => 1
- ])
- ->where('createTime', '>=', $startTime)
- ->where('createTime', '<', $endTime)
- ->whereIn('wechatAccountId' , $wechatAccountIds)
- ->count();
-
- // 图片互动数量
- $imgInteractions = WechatMessageModel::where([
- 'msgType' => 3
- ])
- ->where('createTime', '>=', $startTime)
- ->where('createTime', '<', $endTime)
- ->whereIn('wechatAccountId' , $wechatAccountIds)
- ->count();
-
- // 群聊互动数量
- $groupInteractions = WechatMessageModel::where([
- 'type' => 2
- ])
- ->where('createTime', '>=', $startTime)
- ->where('createTime', '<', $endTime)
- ->whereIn('wechatAccountId' , $wechatAccountIds)
- ->count();
-
- // 产品咨询数量 (通过消息内容模糊查询)
- $productInquiries = WechatMessageModel::where('createTime', '>=', $startTime)
- ->where('createTime', '<', $endTime)
- ->where('content', 'like', '%产品%')
- ->whereOr('content', 'like', '%价格%')
- ->whereOr('content', 'like', '%购买%')
- ->whereOr('content', 'like', '%优惠%')
- ->whereIn('wechatAccountId' , $wechatAccountIds)
- ->count();
-
// 构建返回数据
$data = [
- 'frequency_analysis' => [
- 'high_frequency' => $highFrequencyUsers,
- 'mid_frequency' => $midFrequencyUsers,
- 'low_frequency' => $lowFrequencyUsers,
- 'chart_data' => [
- ['name' => '高频互动', 'value' => $highFrequencyUsers],
- ['name' => '中频互动', 'value' => $midFrequencyUsers],
- ['name' => '低频互动', 'value' => $lowFrequencyUsers]
- ]
+ 'avg_conversion_amount' => $avgConversionAmount, // 客户平均转化金额
+ 'value_indicators' => [
+ 'total_sales' => round($totalSales, 2), // 销售总额
+ 'avg_order_amount' => $avgOrderAmount, // 平均订单金额
+ 'high_value_customers' => $highValueCustomerPercent . '%' // 高价值客户
],
- 'content_analysis' => [
- 'text_messages' => $textMessages,
- 'img_interactions' => $imgInteractions,
- 'group_interactions' => $groupInteractions,
- 'product_inquiries' => $productInquiries,
- 'chart_data' => [
- ['name' => '文字互动', 'value' => $textMessages],
- ['name' => '图片互动', 'value' => $imgInteractions],
- ['name' => '群聊互动', 'value' => $groupInteractions],
- ['name' => '产品咨询', 'value' => $productInquiries]
- ]
- ]
+ 'growth_trend' => [
+ 'weekly_revenue_growth' => $weeklyRevenueGrowth, // 周收益增长(金额)
+ 'new_customer_conversion' => $newConvertedCustomers, // 新客转化(人数)
+ 'active_customer_growth' => $activeCustomerGrowth // 活跃客户增长(人数差值)
+ ],
+ 'frequency_analysis' => $frequency_analysis, // 客户活跃度
+ 'source_distribution' => $sourceDistribution // 转化客户来源
];
return successJson($data);
@@ -353,7 +383,7 @@ class StatisticsController extends BaseController
/**
* 获取时间范围
- *
+ *
* @param bool $toTimestamp 是否将日期转为时间戳,默认为true
* @return array 时间范围数组
*/
@@ -361,7 +391,7 @@ class StatisticsController extends BaseController
{
// 可选:today, yesterday, this_week, last_week, this_month, this_quarter, this_year
$timeType = input('time_type', 'this_week');
-
+
switch ($timeType) {
case 'today': // 今日
$startTime = date('Y-m-d');
@@ -369,35 +399,35 @@ class StatisticsController extends BaseController
$lastStartTime = date('Y-m-d', strtotime('-1 day')); // 昨日
$lastEndTime = $startTime;
break;
-
+
case 'yesterday': // 昨日
$startTime = date('Y-m-d', strtotime('-1 day'));
$endTime = date('Y-m-d');
$lastStartTime = date('Y-m-d', strtotime('-2 day')); // 前日
$lastEndTime = $startTime;
break;
-
+
case 'this_week': // 本周
$startTime = date('Y-m-d', strtotime('monday this week'));
$endTime = date('Y-m-d', strtotime('monday next week'));
$lastStartTime = date('Y-m-d', strtotime('monday last week')); // 上周一
$lastEndTime = $startTime;
break;
-
+
case 'last_week': // 上周
$startTime = date('Y-m-d', strtotime('monday last week'));
$endTime = date('Y-m-d', strtotime('monday this week'));
$lastStartTime = date('Y-m-d', strtotime('monday last week', strtotime('last week'))); // 上上周一
$lastEndTime = $startTime;
break;
-
+
case 'this_month': // 本月
$startTime = date('Y-m-01');
$endTime = date('Y-m-d', strtotime(date('Y-m-01') . ' +1 month'));
$lastStartTime = date('Y-m-01', strtotime('-1 month')); // 上月初
$lastEndTime = $startTime;
break;
-
+
case 'this_quarter': // 本季度
$month = date('n');
$quarter = ceil($month / 3);
@@ -408,14 +438,14 @@ class StatisticsController extends BaseController
$lastStartTime = date('Y-m-d', strtotime($startTime . ' -3 month'));
$lastEndTime = $startTime;
break;
-
+
case 'this_year': // 本年度
$startTime = date('Y-01-01');
$endTime = (date('Y') + 1) . '-01-01';
$lastStartTime = (date('Y') - 1) . '-01-01'; // 去年初
$lastEndTime = $startTime;
break;
-
+
default:
$startTime = date('Y-m-d', strtotime('monday this week'));
$endTime = date('Y-m-d', strtotime('monday next week'));
diff --git a/Server/application/store/model/TrafficOrderModel.php b/Server/application/store/model/TrafficOrderModel.php
new file mode 100644
index 00000000..4d51d66f
--- /dev/null
+++ b/Server/application/store/model/TrafficOrderModel.php
@@ -0,0 +1,11 @@
+
import { hasValidToken, redirectToLogin } from './api/utils/auth';
- import { appApi } from './api/modules/app';
- import UpdateModal from './components/UpdateModal.vue';
export default {
- components: {
- UpdateModal
- },
- data() {
- return {
- // #ifdef APP-PLUS
- // 更新弹窗相关数据(仅APP端)
- showUpdateModal: false,
- updateInfo: {
- version: '',
- updateContent: '',
- downloadUrl: '',
- forceUpdate: false
- }
- // #endif
- };
- },
onLaunch: function() {
console.log('App Launch');
- // 检测APP更新
- this.checkAppUpdate();
// 全局检查token
this.checkToken();
},
onShow: function() {
console.log('App Show');
- // 每次显示时检测APP更新
- this.checkAppUpdate();
// 应用恢复时再次检查token
this.checkToken();
},
@@ -44,69 +21,12 @@
// 获取当前页面
const pages = getCurrentPages();
const currentPage = pages.length ? pages[pages.length - 1] : null;
- const currentRoute = currentPage ? currentPage.route : '';
// 如果token无效且不在登录页面,则跳转到登录页面
- if (!hasValidToken() && currentRoute && currentRoute !== 'pages/login/index') {
- console.log('Token无效,从', currentRoute, '重定向到登录页面');
+ if (!hasValidToken() && currentPage && currentPage.route !== 'pages/login/index') {
redirectToLogin();
}
- },
-
- // 检测APP更新
- async checkAppUpdate() {
- // #ifdef APP-PLUS
- try {
- console.log('开始检测APP更新...');
- const res = await appApi.checkUpdate();
- console.log('更新检测结果:', res);
-
- if (res.code === 200 && res.data) {
- const data = res.data;
-
- // 清理 downloadUrl 中的换行符
- const downloadUrl = data.downloadUrl ? data.downloadUrl.trim() : '';
-
- // 设置更新信息
- this.updateInfo = {
- version: data.version || '',
- updateContent: data.updateContent || '本次更新包含性能优化和问题修复',
- downloadUrl: downloadUrl,
- forceUpdate: data.forceUpdate || false
- };
-
- // 显示更新弹窗
- this.showUpdateModal = true;
- }
- } catch (error) {
- console.error('检测更新失败:', error);
- // 更新检测失败不影响应用正常使用,只记录日志
}
- // #endif
- },
-
- // 处理更新确认
- handleUpdateConfirm(downloadUrl) {
- // #ifdef APP-PLUS
- if (downloadUrl) {
- plus.runtime.openURL(downloadUrl);
- }
- // #endif
- this.showUpdateModal = false;
- },
-
- // 处理更新取消
- handleUpdateCancel() {
- if (this.updateInfo.forceUpdate) {
- // 强制更新时,取消则退出应用
- // #ifdef APP-PLUS
- plus.runtime.quit();
- // #endif
- } else {
- // 关闭弹窗
- this.showUpdateModal = false;
- }
- }
}
}
@@ -139,21 +59,6 @@
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/Store_vue/components/SideMenu.vue b/Store_vue/components/SideMenu.vue
index 1ac5835a..33eb8d36 100644
--- a/Store_vue/components/SideMenu.vue
+++ b/Store_vue/components/SideMenu.vue
@@ -1,7 +1,61 @@
-
@@ -193,10 +240,8 @@
import LoginRegister from './LoginRegister.vue';
import DataStatistics from './DataStatistics.vue';
import CustomerManagement from './CustomerManagement.vue';
- import UpdateDialog from './UpdateDialog.vue';
import { hasValidToken, clearToken, redirectToLogin } from '../api/utils/auth';
import { request, APP_CONFIG } from '../api/config';
- import { appApi } from '../api/modules/app';
export default {
name: "SideMenu",
@@ -206,8 +251,7 @@
SystemSettings,
LoginRegister,
DataStatistics,
- CustomerManagement,
- UpdateDialog
+ CustomerManagement
},
props: {
show: {
@@ -233,19 +277,22 @@
showLoginPageFlag: false,
isLoggedIn: false, // 用户登录状态
userInfo: null, // 用户信息
- // 版本信息
- currentVersion: APP_CONFIG.version, // 当前版本
+ // 版本更新相关
+ currentVersion: '', // 当前版本
latestVersion: '', // 最新版本
hasNewVersion: false, // 是否有新版本
checkingUpdate: false, // 是否正在检查更新
- // 更新弹窗
- showUpdateDialog: false,
+ showUpdateDialog: false, // 是否显示更新弹窗
updateInfo: {
- version: '',
- updateContent: '',
- downloadUrl: '',
- forceUpdate: false
- }
+ version: '', // 新版本号
+ updateContent: [], // 更新内容列表
+ downloadUrl: '', // 下载地址
+ forceUpdate: false // 是否强制更新
+ },
+ // 下载相关
+ downloading: false, // 是否正在下载
+ downloadProgress: 0, // 下载进度 0-100
+ downloadTask: null // 下载任务对象
}
},
watch: {
@@ -267,6 +314,8 @@
this.checkLoginStatus();
// 获取功能开关状态
this.getFunctionStatus();
+ // 获取当前版本号并自动检查更新
+ this.getCurrentVersionAndCheckUpdate();
},
methods: {
// 检查登录状态
@@ -497,36 +546,75 @@
this.showSystemSettingsPage = true;
},
- // 版本号比较函数
- // 返回值: 1表示v1>v2, -1表示v1 {
+ this.currentVersion = info.version || '1.0.0';
+ });
+ // #endif
- for (let i = 0; i < maxLen; i++) {
- const num1 = arr1[i] || 0;
- const num2 = arr2[i] || 0;
-
- if (num1 > num2) return 1;
- if (num1 < num2) return -1;
- }
+ // #ifndef APP-PLUS
+ this.currentVersion = '1.0.0';
+ // #endif
+ },
+
+ // 获取当前版本号并自动检查更新
+ getCurrentVersionAndCheckUpdate() {
+ // #ifdef APP-PLUS
+ plus.runtime.getProperty(plus.runtime.appid, (info) => {
+ this.currentVersion = info.version || '1.0.0';
+ console.log('获取到当前版本号:', this.currentVersion);
+ // 版本号获取完成后,自动检查更新(延迟500ms,确保应用已完全启动)
+ setTimeout(() => {
+ this.handleCheckUpdate(true); // 传入 true 表示自动检查,不显示"已是最新版本"提示
+ }, 500);
+ });
+ // #endif
- return 0;
+ // #ifndef APP-PLUS
+ this.currentVersion = '1.0.0';
+ // #endif
},
// 检查更新
- async handleCheckUpdate() {
+ // autoCheck: true 表示自动检查(应用启动时),不显示"已是最新版本"提示
+ // autoCheck: false 表示手动检查(用户点击按钮),显示所有提示
+ async handleCheckUpdate(autoCheck = false) {
// #ifdef APP-PLUS
if (this.checkingUpdate) {
return; // 正在检查中,避免重复请求
}
+ // 如果版本号还没获取到,先获取版本号
+ if (!this.currentVersion) {
+ // #ifdef APP-PLUS
+ plus.runtime.getProperty(plus.runtime.appid, (info) => {
+ this.currentVersion = info.version || '1.0.0';
+ // 版本号获取完成后,继续检查更新
+ setTimeout(() => {
+ this.handleCheckUpdate(autoCheck);
+ }, 100);
+ });
+ // #endif
+ return;
+ }
+
this.checkingUpdate = true;
try {
console.log('开始检查更新,当前版本:', this.currentVersion);
- const res = await appApi.checkUpdate();
+
+ // 调用检查更新接口
+ const res = await request({
+ url: '/v1/app/update',
+ method: 'GET',
+ data: {
+ version: this.currentVersion,
+ type: 'aiStore'
+ }
+ });
+
console.log('更新检测结果:', res);
if (res.code === 200 && res.data) {
@@ -537,42 +625,286 @@
const compareResult = this.compareVersion(this.latestVersion, this.currentVersion);
if (compareResult > 0) {
- // 线上版本大于本地版本
+ // 线上版本大于本地版本,有新版本
this.hasNewVersion = true;
- // 设置更新信息并显示自定义弹窗
+ // 设置更新信息
this.updateInfo = {
version: data.version || '',
- updateContent: data.updateContent || '',
- downloadUrl: data.downloadUrl ? data.downloadUrl.trim() : '',
+ updateContent: this.parseUpdateContent(data.updateContent || data.content || ''),
+ downloadUrl: data.downloadUrl || data.url || '',
forceUpdate: data.forceUpdate || false
};
- this.showUpdateDialog = true;
+
+ // 根据检查类型决定是否显示弹窗
+ // autoCheck === false 表示手动检查,autoCheck === true 表示自动检查
+ if (autoCheck === false) {
+ // 手动检查:有新版本时总是显示弹窗(不受每日限制)
+ console.log('手动检查更新,直接显示弹窗');
+ this.showUpdateDialog = true;
+ } else {
+ // 自动检查:每天只能弹出一次
+ console.log('自动检查更新,检查今日是否已显示过弹窗');
+ if (this.shouldShowUpdateDialog()) {
+ this.showUpdateDialog = true;
+ this.recordUpdateDialogShown();
+ } else {
+ console.log('今天已显示过更新弹窗,不再自动弹出');
+ }
+ }
} else {
// 已是最新版本
this.hasNewVersion = false;
+ // 只有手动检查时才显示"已是最新版本"提示
+ if (!autoCheck) {
+ uni.showToast({
+ title: '已是最新版本',
+ icon: 'success',
+ duration: 2000
+ });
+ }
+ }
+ } else {
+ // 只有手动检查时才显示错误提示
+ if (!autoCheck) {
uni.showToast({
- title: '已是最新版本',
- icon: 'success'
+ title: res.msg || '检查更新失败',
+ icon: 'none',
+ duration: 2000
});
}
}
} catch (error) {
console.error('检查更新失败:', error);
- uni.showToast({
- title: '检查更新失败',
- icon: 'none'
- });
+ // 只有手动检查时才显示错误提示
+ if (!autoCheck) {
+ uni.showToast({
+ title: '检查更新失败,请稍后重试',
+ icon: 'none',
+ duration: 2000
+ });
+ }
} finally {
this.checkingUpdate = false;
}
// #endif
+
+ // #ifndef APP-PLUS
+ if (!autoCheck) {
+ uni.showToast({
+ title: '此功能仅在APP中可用',
+ icon: 'none',
+ duration: 2000
+ });
+ }
+ // #endif
+ },
+
+ // 比较版本号,返回 1 表示 version1 > version2,返回 -1 表示 version1 < version2,返回 0 表示相等
+ compareVersion(version1, version2) {
+ if (!version1 || !version2) return 0;
+
+ const v1Parts = version1.split('.').map(Number);
+ const v2Parts = version2.split('.').map(Number);
+ const maxLength = Math.max(v1Parts.length, v2Parts.length);
+
+ for (let i = 0; i < maxLength; i++) {
+ const v1Part = v1Parts[i] || 0;
+ const v2Part = v2Parts[i] || 0;
+
+ if (v1Part > v2Part) return 1;
+ if (v1Part < v2Part) return -1;
+ }
+
+ return 0;
+ },
+
+ // 解析更新内容,将字符串转换为数组
+ parseUpdateContent(content) {
+ if (!content) return [];
+
+ // 如果已经是数组,直接返回
+ if (Array.isArray(content)) {
+ return content;
+ }
+
+ // 如果是字符串,尝试按换行符或分号分割
+ if (typeof content === 'string') {
+ // 先尝试按换行符分割
+ let items = content.split(/\n+/).filter(item => item.trim());
+
+ // 如果没有换行,尝试按分号分割
+ if (items.length === 1) {
+ items = content.split(/[;;]/).filter(item => item.trim());
+ }
+
+ // 清理每个项目,移除可能的编号前缀(如 "1. ", "1、", "- " 等)
+ return items.map(item => {
+ return item.replace(/^[\d一二三四五六七八九十]+[\.、\s\-]*/, '').trim();
+ }).filter(item => item);
+ }
+
+ return [];
+ },
+
+ // 检查今天是否应该显示更新弹窗(用于自动检查)
+ shouldShowUpdateDialog() {
+ try {
+ const lastShownDate = uni.getStorageSync('updateDialogLastShownDate');
+ if (!lastShownDate) {
+ return true; // 从未显示过,可以显示
+ }
+
+ // 获取今天的日期字符串(格式:YYYY-MM-DD)
+ const today = new Date();
+ const todayStr = `${today.getFullYear()}-${String(today.getMonth() + 1).padStart(2, '0')}-${String(today.getDate()).padStart(2, '0')}`;
+
+ // 如果今天已经显示过,则不显示
+ return lastShownDate !== todayStr;
+ } catch (e) {
+ console.error('检查更新弹窗显示状态失败:', e);
+ return true; // 出错时默认允许显示
+ }
+ },
+
+ // 记录今天已显示更新弹窗
+ recordUpdateDialogShown() {
+ try {
+ const today = new Date();
+ const todayStr = `${today.getFullYear()}-${String(today.getMonth() + 1).padStart(2, '0')}-${String(today.getDate()).padStart(2, '0')}`;
+ uni.setStorageSync('updateDialogLastShownDate', todayStr);
+ console.log('已记录更新弹窗显示日期:', todayStr);
+ } catch (e) {
+ console.error('记录更新弹窗显示日期失败:', e);
+ }
},
// 关闭更新弹窗
closeUpdateDialog() {
- this.showUpdateDialog = false;
+ if (!this.updateInfo.forceUpdate) {
+ this.showUpdateDialog = false;
+ } else {
+ uni.showToast({
+ title: '此版本为重要更新,请升级后使用',
+ icon: 'none',
+ duration: 2000
+ });
+ }
+ },
+
+ // 开始下载更新
+ startDownload() {
+ // #ifdef APP-PLUS
+ if (!this.updateInfo.downloadUrl) {
+ uni.showToast({
+ title: '下载地址无效',
+ icon: 'none',
+ duration: 2000
+ });
+ return;
+ }
+
+ if (this.downloading) {
+ return; // 已经在下载中
+ }
+
+ this.downloading = true;
+ this.downloadProgress = 0;
+
+ // 创建下载任务
+ const downloadPath = '_downloads/update_' + Date.now() + '.apk';
+ this.downloadTask = plus.downloader.createDownload(this.updateInfo.downloadUrl, {
+ filename: downloadPath // 下载文件名
+ }, (download, status) => {
+ if (status === 200) {
+ // 下载成功
+ console.log('下载成功:', download.filename);
+ this.downloading = false;
+ this.downloadProgress = 100;
+
+ // 安装APK
+ setTimeout(() => {
+ this.installAPK(download.filename);
+ }, 500);
+ } else {
+ // 下载失败
+ console.error('下载失败:', status);
+ this.downloading = false;
+ this.downloadProgress = 0;
+ uni.showToast({
+ title: '下载失败,请稍后重试',
+ icon: 'none',
+ duration: 2000
+ });
+ }
+ });
+
+ // 监听下载进度
+ this.downloadTask.addEventListener('statechanged', (download, status) => {
+ switch (download.state) {
+ case 1: // 开始下载
+ console.log('开始下载...');
+ break;
+ case 2: // 连接到服务器
+ console.log('连接到服务器...');
+ break;
+ case 3: // 下载中
+ if (download.totalSize > 0) {
+ const progress = Math.floor((download.downloadedSize / download.totalSize) * 100);
+ this.downloadProgress = Math.min(progress, 99); // 最大99,完成时再设为100
+ console.log('下载进度:', this.downloadProgress + '%', '已下载:', download.downloadedSize, '总大小:', download.totalSize);
+ }
+ break;
+ case 4: // 下载完成
+ console.log('下载完成');
+ this.downloadProgress = 100;
+ break;
+ }
+ });
+
+ // 开始下载
+ this.downloadTask.start();
+ // #endif
+ },
+
+ // 安装APK
+ installAPK(filePath) {
+ // #ifdef APP-PLUS
+ try {
+ // 获取文件的完整路径
+ const fullPath = plus.io.convertLocalFileSystemURL(filePath);
+ console.log('准备安装APK:', fullPath);
+
+ plus.runtime.install(fullPath, {}, () => {
+ console.log('安装成功');
+ uni.showToast({
+ title: '安装成功',
+ icon: 'success',
+ duration: 1500
+ });
+ // 关闭弹窗
+ setTimeout(() => {
+ this.showUpdateDialog = false;
+ }, 1500);
+ }, (error) => {
+ console.error('安装失败:', error);
+ uni.showToast({
+ title: '安装失败,请到下载文件夹手动安装',
+ icon: 'none',
+ duration: 3000
+ });
+ });
+ } catch (error) {
+ console.error('安装异常:', error);
+ uni.showToast({
+ title: '安装异常,请到下载文件夹手动安装',
+ icon: 'none',
+ duration: 3000
+ });
+ }
+ // #endif
}
+
}
}
@@ -858,4 +1190,178 @@
font-size: 12px;
color: #999;
}
+
+ /* 更新弹窗样式 */
+ .update-dialog-mask {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ background-color: rgba(0, 0, 0, 0.5);
+ z-index: 10000;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ }
+
+ .update-dialog {
+ position: relative;
+ width: 85%;
+ max-width: 600px;
+ background-color: #fff;
+ border-radius: 20px;
+ padding: 40px 30px 30px;
+ box-shadow: 0 10px 40px rgba(0, 0, 0, 0.2);
+ }
+
+ /* 手机上最大宽度80% */
+ @media screen and (max-width: 768px) {
+ .update-dialog {
+ width: 80%;
+ max-width: 80%;
+ }
+ }
+
+ .update-rocket {
+ position: absolute;
+ top: -40px;
+ left: 50%;
+ transform: translateX(-50%);
+ width: 80px;
+ height: 80px;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ background: linear-gradient(135deg, #5096ff 0%, #6b7fff 100%);
+ border-radius: 50%;
+ box-shadow: 0 4px 15px rgba(80, 150, 255, 0.3);
+ }
+
+ .update-rocket text {
+ font-size: 50px;
+ line-height: 1;
+ }
+
+ .update-version-info {
+ text-align: center;
+ margin-top: 20px;
+ margin-bottom: 25px;
+ }
+
+ .update-version-text {
+ font-size: 18px;
+ font-weight: 600;
+ color: #333;
+ }
+
+ .update-content-list {
+ margin-bottom: 30px;
+ max-height: 300px;
+ overflow-y: auto;
+ }
+
+ .update-content-item {
+ display: flex;
+ align-items: flex-start;
+ margin-bottom: 12px;
+ padding: 0 5px;
+ }
+
+ .update-item-number {
+ font-size: 15px;
+ color: #5096ff;
+ font-weight: 600;
+ margin-right: 8px;
+ min-width: 20px;
+ }
+
+ .update-item-text {
+ font-size: 15px;
+ color: #666;
+ line-height: 1.6;
+ flex: 1;
+ }
+
+ .download-progress-wrapper {
+ margin-bottom: 20px;
+ padding: 0 5px;
+ }
+
+ .download-progress-bar {
+ width: 100%;
+ height: 8px;
+ background-color: #f0f0f0;
+ border-radius: 4px;
+ overflow: hidden;
+ margin-bottom: 8px;
+ }
+
+ .download-progress-fill {
+ height: 100%;
+ background: linear-gradient(90deg, #5096ff 0%, #6b7fff 100%);
+ border-radius: 4px;
+ transition: width 0.3s ease;
+ }
+
+ .download-progress-text {
+ display: block;
+ text-align: center;
+ font-size: 13px;
+ color: #5096ff;
+ font-weight: 500;
+ }
+
+ .update-button-wrapper {
+ margin-top: 10px;
+ }
+
+ .update-button {
+ width: 100%;
+ height: 50px;
+ background: linear-gradient(135deg, #5096ff 0%, #6b7fff 100%);
+ border-radius: 25px;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ box-shadow: 0 4px 15px rgba(80, 150, 255, 0.3);
+ transition: all 0.3s ease;
+ }
+
+ .update-button:active {
+ transform: scale(0.98);
+ box-shadow: 0 2px 8px rgba(80, 150, 255, 0.2);
+ }
+
+ .update-button-disabled {
+ opacity: 0.7;
+ }
+
+ .update-button-text {
+ font-size: 17px;
+ font-weight: 600;
+ color: #fff;
+ }
+
+ .update-close-btn {
+ position: absolute;
+ bottom: -50px;
+ left: 50%;
+ transform: translateX(-50%);
+ width: 40px;
+ height: 40px;
+ background-color: rgba(255, 255, 255, 0.9);
+ border-radius: 50%;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
+ }
+
+ .update-close-icon {
+ font-size: 20px;
+ color: #666;
+ font-weight: 300;
+ line-height: 1;
+ }
\ No newline at end of file
diff --git a/Store_vue/components/UpdateDialog.vue b/Store_vue/components/UpdateDialog.vue
deleted file mode 100644
index 296b9300..00000000
--- a/Store_vue/components/UpdateDialog.vue
+++ /dev/null
@@ -1,556 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ⚠️
- 本次为重要更新,需要立即升级
-
-
-
-
- {{ index + 1 }}.{{ item }}
-
-
-
-
-
-
-
- {{ downloadProgress }}%
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ×
-
-
-
-
-
-
-
-
-
diff --git a/Store_vue/components/UpdateModal.vue b/Store_vue/components/UpdateModal.vue
deleted file mode 100644
index 8de78f38..00000000
--- a/Store_vue/components/UpdateModal.vue
+++ /dev/null
@@ -1,131 +0,0 @@
-
-
-
-
- 发现新版本 {{ version }}
-
-
-
- {{ updateContent }}
-
-
-
-
- 稍后再说
- 立即更新
-
-
-
-
-
-
-
-
-
diff --git a/Store_vue/manifest.json b/Store_vue/manifest.json
index 7beae997..c7fa191b 100644
--- a/Store_vue/manifest.json
+++ b/Store_vue/manifest.json
@@ -2,8 +2,8 @@
"name" : "AI数智员工",
"appid" : "__UNI__9421F6C",
"description" : "",
- "versionName" : "1.1.0",
- "versionCode" : 100,
+ "versionName" : "1.1.1",
+ "versionCode" : "100",
"transformPx" : false,
/* 5+App特有相关 */
"app-plus" : {
@@ -107,17 +107,5 @@
},
"vueVersion" : "2",
"locale" : "zh-Hans",
- "fallbackLocale" : "zh-Hans",
- /* H5特有相关 */
- "h5" : {
- "router" : {
- "mode" : "hash",
- "base" : "./"
- },
- "title" : "AI数智员工",
- "devServer" : {
- "port" : 8080,
- "disableHostCheck" : true
- }
- }
+ "fallbackLocale" : "zh-Hans"
}
diff --git a/Store_vue/package.json b/Store_vue/package.json
index cf60374f..de7626df 100644
--- a/Store_vue/package.json
+++ b/Store_vue/package.json
@@ -1,6 +1,6 @@
{
"name": "store",
- "version": "1.0.0",
+ "version": "1.1.1",
"main": "main.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
diff --git a/Store_vue/pages.json b/Store_vue/pages.json
index 6a6c25ed..427192f0 100644
--- a/Store_vue/pages.json
+++ b/Store_vue/pages.json
@@ -4,15 +4,15 @@
},
"pages": [
{
- "path": "pages/login/index",
+ "path": "pages/chat/index",
"style": {
+ "navigationBarTitleText": "AI数智员工",
"navigationStyle": "custom"
}
},
{
- "path": "pages/chat/index",
+ "path": "pages/login/index",
"style": {
- "navigationBarTitleText": "AI数智员工",
"navigationStyle": "custom"
}
}
diff --git a/Store_vue/pages/login/index.vue b/Store_vue/pages/login/index.vue
index 9b8a7da5..b3ce9ca2 100644
--- a/Store_vue/pages/login/index.vue
+++ b/Store_vue/pages/login/index.vue
@@ -1,214 +1,138 @@
-
+
-
-
-
+
+
+
-
-
-
-
-
- AI数智员工
+
+
+
+
-
-
+
+
+
-
+
+ 免密登录
+
-
+
+ 账号登录
+
+
+
+
+
+
+ 账号登录
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
阅读并同意
《用户协议》
与
《隐私权限》
-
-
-
-
-
-
-
+
+
+
+ 登录
- {{ formTitle }}
-
-
-
-
-
- 账号
-
-
-
-
-
- 密码
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 阅读并同意
- 《用户协议》
- 与
- 《隐私权限》
-
+
+
+
+ 或
+
-
-
-
-
- 设备ID
-
-
-
-
-
+
+
+ @click="handleThirdLogin('wechat')"
+ :ripple="true"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 联系我们
-
-
-
-
-
-
-
-
-
-
- {{ formTitle }}
-
-
-
-
- 账号
-
-
-
-
-
- 密码
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 阅读并同意
- 《用户协议》
- 与
- 《隐私权限》
-
-
-
-
-
-
-