From e91dbf71844d0d0de3460848923c341dbf84f3c9 Mon Sep 17 00:00:00 2001 From: ylj20011123 Date: Fri, 6 Feb 2026 16:51:47 +0800 Subject: [PATCH] update --- pages/index/index.vue | 412 +++++++++++++++++++++++++++++++----------- 1 file changed, 307 insertions(+), 105 deletions(-) diff --git a/pages/index/index.vue b/pages/index/index.vue index a3a3670..d11b07d 100644 --- a/pages/index/index.vue +++ b/pages/index/index.vue @@ -152,7 +152,7 @@ -
+
@@ -3623,14 +3623,14 @@ }} 已完成/{{ plan.revenueType === "yi" ? "亿元" : "万元" - }} + }} {{ plan.BudgetYear_Amount ? plan.BudgetYear_Amount : "-" }} 计划/{{ plan.budgetType === "yi" ? "亿元" : "万元" - }} + }} {{ @@ -3918,7 +3918,29 @@ - + + + + + +
+ 数智助手 + 您的春运动态播报专家。为您实时呈现全省及区域经营动态、车流预警与数据分析。 + + 知道了 + 看一下 + +
+
+
@@ -4262,6 +4284,14 @@ export default { realBoxPageX: 0, // 注释说明弹出框的x位置 realBoxPageY: 0, // 注释说明弹出框的y位置 showAi: false,// 判断用户是否有数智助手的权限 + guideInfo: { + visible: false, + top: 0, + left: 0, + width: 0, + height: 0 + }, + isScrollLock: false, // 是否锁定页面滚动 }; }, watch: { @@ -4321,6 +4351,7 @@ export default { ] === 1 ) { this.showAi = true; + // 移除这里的触发,统合到 getData 结束后触发 } if (!this.isReturn) { @@ -4340,9 +4371,7 @@ export default { } uni.setStorageSync("festival", this.isShowFestival); - this.getData(this.option); - this.handleNoticeMonth(); - this.handleNoticeYear(); + await this.getData(this.option); } } }, @@ -4546,6 +4575,7 @@ export default { ] === 1 ) { this.showAi = true; + // 移除这里的触发,统合到 getData 结束后触发 } @@ -4553,7 +4583,7 @@ export default { this.option = option; // 获取数据的方法 if (this.user.Membership_Id) { - this.getData(option); + await this.getData(option); } // 判断缓存中是否有位置信息 没有的话 向用户请求 拿到用户当前位置 // 拿到当前位置之后去请求离当前位置最近的服务区 作为第一次进入小程序自动选中的服务区 @@ -4579,9 +4609,7 @@ export default { //拿到最近服务区的数据 this.nearestService(); } - //问号显示的内容 月份的数据请求 和 年份的数据请求 - this.handleNoticeMonth(); - this.handleNoticeYear(); + // 移除这里的冗余重复调用,已统合进 getData // 如果十秒之后 isSuccess 没有变成true 说明接口有慢的或者报错了 才出现提示 setTimeout(() => { @@ -4609,9 +4637,9 @@ export default { onUnload() { this.$util.addUserBehavior(); }, - onPullDownRefresh: function () { + onPullDownRefresh: async function () { if (!this.isReturn) { - this.getData(this.option); + await this.getData(this.option); this.currentMoney = 0; if (new Date().getTime() < new Date("2024-05-03 00:00:00").getTime()) { this.showAdvertisement = true; @@ -4621,6 +4649,9 @@ export default { } uni.stopPullDownRefresh(); }, + onPageScroll(e) { + // 移除之前的错误锁定逻辑,不再强制重置 scrollTop + }, methods: { numeral, ...mapActions(["memberLogin", "getLoginCode"]), @@ -4902,7 +4933,10 @@ export default { }, goToRobot() { this.$util.toNextRoute("navigateTo", `/pages/robot/index`); - // this.$util.toNextRoute("navigateTo", `/pages/testPage/index`); + }, + handleGoToRobot() { + this.handleCloseGuide(); + this.goToRobot(); }, goToBillLading() { this.$util.toNextRoute("navigateTo", `/pages/billOfLading/index`); @@ -4993,9 +5027,11 @@ export default { "CommercialApi/Analysis/GetANALYSISINSList", req ); - this.monthNoticeText = data.Result_Data.List[0] - ? data.Result_Data.List[0].ANALYSIS_CONTENT - : ""; + if (data && data.Result_Data && data.Result_Data.List) { + this.monthNoticeText = data.Result_Data.List[0] + ? data.Result_Data.List[0].ANALYSIS_CONTENT + : ""; + } }, async handleNoticeYear() { let date = new Date(this.lastDay); @@ -5018,8 +5054,10 @@ export default { "CommercialApi/Analysis/GetANALYSISINSList", reqYear ); - if (totalData.Result_Data.List[0]) { - this.yearNoticeText = totalData.Result_Data.List[0].ANALYSIS_CONTENT; + if (totalData && totalData.Result_Data && totalData.Result_Data.List) { + this.yearNoticeText = totalData.Result_Data.List[0] + ? totalData.Result_Data.List[0].ANALYSIS_CONTENT + : ""; } }, async nearestService() { @@ -5135,13 +5173,17 @@ export default { } }, // option是请求的参数 type是否是切换时间 - getData(option, type) { + async getData(option, type) { //老代码 if (this.user.Membership_Id) { uni.showLoading({ title: "正在加载...", }); } + + this.isSuccess = false; + const promises = []; + //判断是否从推送进来 if (option.ProvinceCode) { // 从推送进入 @@ -5152,69 +5194,47 @@ export default { this.lastDay = this.$util.cutDate(option.time, "YYYY-MM-DD"); //修改时间选择器里面的时间 this.single = timestampToTimeMonth(new Date(this.lastDay).getTime()); - // //显示当前选择的时间是星期几 - // const date = new Date(this.lastDay) - // this.thisDay = getThisDay(date.getDay()) } // 老项目的请求数据的那部分 this.initData(); - //根据新页面请求数据的方法 - this.initYesterdayData(type, "first"); - //车流分析 - // this.getCarInfo() - //月度计划、年度计划 - // this.monthYearPlan() - // 预警信息 有值会显示车流预警 - this.handleGetWarningList(); - // 获取月度考核数据 - // this.handleGetExamine() - // 获取巡检数据 - // this.handleGetDailyPatrol() - // 获取全省平均车流量 - this.handleGetAllCarTraffic(); - // 国庆数据 - // this.handleGetNationalData() - // 实时营收 - this.handleRealRevenue(); + + promises.push(this.initYesterdayData(type, "first")); + promises.push(this.handleGetWarningList()); + promises.push(this.handleGetAllCarTraffic()); + promises.push(this.handleRealRevenue()); + promises.push(this.getDetail(this.theRequest)); + // 增加公告加载进同步队列 + promises.push(this.handleNoticeMonth()); + promises.push(this.handleNoticeYear()); } else if (this.user.Membership_Id) { - // 默认 - // 不是从推送进来 走正常的请求方法 - // if (!this.PushAuthority){return} - // if (this.PushAuthority.length > 0) { - // 定义initData中的入参 this.theRequest = this.defaultMsg() || {}; this.theRequest.time = this.lastDay; this.theRequest.month = this.$util.cutDate(this.lastDay, "YYYYMM"); - // 请求数据的方法 initData是老项目中的接口,形参true传入 可以让两个没用到的接口不调用 this.initData(); - // 请求用的到的 昨日的数据 - this.initYesterdayData(type, "first"); - //车流分析 - // this.getCarInfo() - //月度计划、年度计划 - // this.monthYearPlan() - // 是否显示预警信息 - this.handleGetWarningList(); - // 获取月度考核数据 - // this.handleGetExamine() - // 获取巡检数据 - // this.handleGetDailyPatrol() - // 获取全省平均车流量 - this.handleGetAllCarTraffic(); - // 国庆数据 - // this.handleGetNationalData() - // 实时营收 - this.handleRealRevenue(); + + promises.push(this.initYesterdayData(type, "first")); + promises.push(this.handleGetWarningList()); + promises.push(this.handleGetAllCarTraffic()); + promises.push(this.handleRealRevenue()); + promises.push(this.getDetail(this.theRequest)); + // 增加公告加载进同步队列 + promises.push(this.handleNoticeMonth()); + promises.push(this.handleNoticeYear()); + } + + // 等待所有核心数据加载完成 + try { + await Promise.all(promises); + } catch (err) { + console.error('部分数据加载失败', err); } // 老代码 不知道干啥用的 this.nowTab = this.theRequest.ProvinceCode == 340000 ? 1 : 2; - if (this.theRequest.GroupType == 1010) { - this.getDetail(this.theRequest); - } + // 若省份为甘肃,则加载甘肃单品排行 if (this.theRequest.ProvinceCode == 620000) { - this.getRankContent(); + await this.getRankContent(); } }, // 实时营收 @@ -5223,10 +5243,9 @@ export default { pushProvinceCode: this.useInfo.userData ? this.useInfo.userData.ProvinceCode : "340000", StatisticsDate: this.nowDay, }; - request + return request .$webGet("CommercialApi/Revenue/GetCurRevenue", req) .then((res) => { - // this.currentMoney = this.$util.fmoney(res.Result_Data.CurRevenueAmount,2) this.currentMoney = res.Result_Data.CurRevenueAmount.toFixed(2); }); }, @@ -5260,7 +5279,7 @@ export default { ShowCount: 20, }; - request + return request .$webGet("CommercialApi/BigData/GetBayonetWarning", req) .then((res) => { if (res.Result_Data.List && res.Result_Data.List.length > 0) { @@ -5314,7 +5333,7 @@ export default { } console.log('fjdjafjsa', req); - request.$webGet('CommercialApi/BigData/GetHolidayBayonetWarning', req).then((res) => { + return request.$webGet('CommercialApi/BigData/GetHolidayBayonetWarning', req).then((res) => { const list = res.Result_Data.List || []; if (list.length > 0) { this.special = true; @@ -5415,10 +5434,67 @@ export default { } }, // 改变时间触发的方法 ,改变页面的内容数据 - onRefresh(type) { + initAiGuide() { + if (!this.showAi || this.guideInfo.visible || uni.getStorageSync('has_ai_guide_shown_v1')) return; + if (!this.isSuccess) return; + + console.log('触发数智助手引导定位...'); + + const query = uni.createSelectorQuery().in(this); + query.select('.szzs').boundingClientRect(); + query.selectViewport().scrollOffset(); + + query.exec(res => { + const element = res[0]; + const viewport = res[1]; + + if (element && element.top > 0) { + const absoluteTop = element.top + viewport.scrollTop; + console.log('布局定位点高度:', absoluteTop); + + uni.pageScrollTo({ + scrollTop: absoluteTop - 250, + duration: 500, + success: () => { + setTimeout(() => { + this.calculateSzzsPosition(); + }, 600); + } + }); + } else { + // 容错:如果没找到元素,可能是刚赋值还没渲染,微等后再试一次 + setTimeout(() => { + if (this.isSuccess) this.initAiGuide(); + }, 300); + } + }); + }, + // 计算数智助手按钮的位置并锁定页面 + calculateSzzsPosition() { + const query = uni.createSelectorQuery().in(this); + query.select('.szzs').boundingClientRect(rect => { + if (rect) { + console.log('滚动后获取坐标:', rect); + this.guideInfo.top = rect.top; + this.guideInfo.left = rect.left; + this.guideInfo.width = rect.width; + this.guideInfo.height = rect.height; + + this.isScrollLock = true; // 锁定滚动 + this.guideInfo.visible = true; // 显示遮罩 + } + }).exec(); + }, + // 关闭引导并恢复滚动 + handleCloseGuide() { + this.guideInfo.visible = false; + this.isScrollLock = false; + uni.setStorageSync('has_ai_guide_shown_v1', true); + }, + async onRefresh(type) { // 有权限就让他刷新 不没权限的时候下拉刷新不会调用 if (!this.isReturn) { - this.getData(this.option, type); + await this.getData(this.option, type); } }, getUnUpLoadList() { @@ -5781,7 +5857,7 @@ export default { uni.showLoading({ title: "正在加载...", }); - request + return request .$webGet("CommercialApi/Revenue/GetSummaryRevenueMonth", req) .then((lastData) => { flag3 = true; @@ -5985,32 +6061,6 @@ export default { this.todayAmount(); } }); - - // const lastData = await request.$webGet('CommercialApi/Revenue/GetSummaryRevenue',allPriceData) - // flag3 = true - // let result = lastData.Result_Data - // // 接口返回的数据中有三个数组的结构 排除掉不是数组的几项 对数组进行操作 - // for(let key in result){ - // if (key!=='RevenuePushModel' && key!=='GrowthRate' && key!=='MonthRevenueAmount' && key!=='YearRevenueAmount'){ - // let all = 0 - // // 先算出全部的总额数量 用来计算百分比 - // result[key].forEach(item=>{ - // all += Number(item.value) - // }) - // // 把百分比计算出来加到每一项中 - // result[key].map(item=>{ - // item.percentage = ((Number(item.value)/all)*100).toFixed(2) - // }) - // // 格式化掉处理的数据 - // result[key].forEach(item=>{ - // item.value = _this.$util.fmoney(item.value) - // }) - // } - // } - // this.monthAmountAdd = this.$util.fmoney(result.MonthRevenueAmount) - // this.yearAmountAdd = result.YearRevenueAmount?this.$util.fmoney(result.YearRevenueAmount):'-' - // this.modelProgress = result.BusinessTypeList - // 只有当前面的接口通了 才能一起处理数据的方法 }, //获取全省平均车流量 handleGetAllCarTraffic() { @@ -6031,7 +6081,7 @@ export default { Province_Code: this.useInfo.userData ? this.useInfo.userData.ProvinceCode : "340000", Statistics_Date: time, }; - request + return request .$webGet("CommercialApi/Revenue/GetProvinceAvgBayonetAnalysis", req) .then((res) => { res.Result_Data.List.forEach((item) => { @@ -6180,7 +6230,7 @@ export default { // title: `数据看板仅支持查看${endMonth}.${endDay+1}之前的数据,更多数据请登陆商业综合平台查看`, // // title: `数据看板仅支持查看${startMonth}.${startDay}-${endMonth}.${endDay}的数据,更多数据请登陆商业综合平台查看`, // icon:'none', - // showCancel: fainitYesterdayDatalse, + // showCancel: false, // duration:3000 // }); } @@ -6252,10 +6302,50 @@ export default { this.stopSwiper = false; _this.$forceUpdate(); + + // 在数据渲染完毕后的关键节点,触发新功能提示 + this.$nextTick(() => { + this.initAiGuide(); + }); + }, + getListDetail(data) { + let arr = [] + let keyJson = { + SHOWMORE_SIGN: { + 1: '【长款】', + 2: '【异常长款】' + }, // 长款 + SHOWLESS_SIGN: { + 1: '【短款】', + 2: '【异常短款】' + }, // 短款 + SHOWABNORMAL_SIGN: { + 1: '【异常校验】' + }, // 异常日结 + SHOWSCAN_SIGN: { + 1: '【扫】' + }, // 扫码上传 + SHOWSSUPPLY_SIGN: { + 1: '【补】' + }, // 账期补录 + SHOWCHECK_SIGN: { + 1: '【稽核检查】' + }, // 稽核检查 + INTERFACE_SIGN: { + 1: '【接口传输】' + }, // 接口传输 + } + var keyCode = ['SHOWABNORMAL_SIGN', 'SHOWCHECK_SIGN', 'SHOWMORE_SIGN', 'SHOWLESS_SIGN', 'SHOWSCAN_SIGN', + 'SHOWSSUPPLY_SIGN', 'INTERFACE_SIGN' + ] + keyCode.map(n => { + if (keyJson[n][data[n]]) arr.push(keyJson[n][data[n]]) + }) + return arr }, getDetail(obj) { let _this = this; - this.$request + return this.$request .$webGet("CommercialApi/Revenue/GetServerpartEndAccountList", { Serverpart_ID: obj.ServerpartIds, pushProvinceCode: obj.ProvinceCode, @@ -11065,4 +11155,116 @@ $iphoneHeight: env(safe-area-inset-bottom); } } } + +/* 数智助手新功能引导样式 */ +.guide-mask { + position: fixed; + top: 0; + left: 0; + width: 100vw; + height: 100vh; + z-index: 99999; + background-color: transparent; +} + +.guide-highlight { + position: absolute; + border-radius: 12rpx; + box-shadow: 0 0 0 2000px rgba(0, 0, 0, 0.7); + transition: all 0.3s; + pointer-events: none; +} + +.guide-highlight::after { + content: ''; + position: absolute; + top: -4px; + left: -4px; + right: -4px; + bottom: -4px; + border: 2px solid #1677FE; + border-radius: 16rpx; + animation: guide-pulse 1.5s infinite; +} + +@keyframes guide-pulse { + 0% { + opacity: 1; + transform: scale(1); + } + + 100% { + opacity: 0; + transform: scale(1.1); + } +} + +.guide-bubble { + position: absolute; + transform: translateX(-50%); + width: 500rpx; + z-index: 10001; + pointer-events: auto; +} + +.guide-bubble-content { + background: rgba(30, 30, 30, 0.9); + backdrop-filter: blur(10px); + padding: 30rpx; + border-radius: 20rpx; + color: #fff; + position: relative; +} + +.guide-bubble-content::before { + content: ''; + position: absolute; + bottom: 100%; + left: 50%; + transform: translateX(-50%); + border: 15rpx solid transparent; + border-bottom-color: rgba(30, 30, 30, 0.9); +} + +.guide-title { + display: block; + font-size: 32rpx; + font-weight: bold; + color: #1677FE; + margin-bottom: 15rpx; +} + +.guide-desc { + display: block; + font-size: 26rpx; + line-height: 1.5; + margin-bottom: 30rpx; + color: #e0e0e0; +} + +.guide-btn-group { + display: flex; + justify-content: space-between; + gap: 20rpx; +} + +.guide-btn { + flex: 1; + text-align: center; + padding: 15rpx 0; + border-radius: 40rpx; + font-size: 26rpx; + font-weight: 500; + transition: all 0.2s; +} + +.guide-btn.outline { + border: 1px solid #1677FE; + color: #1677FE; +} + +.guide-btn.primary { + background: #1677FE; + color: #ffffff; +}