fix: 修复登录失败被当成功、列表假分页与首页裁切等隐患

1. 登录/验证码改判业务码 data.code(外层 errcode 恒为0),失败不再写入 phone 造成假登录态,并透出后端真实原因;倒计时改为发送成功后才启动;token 按 accessToken 兜底读取,不再写入 undefined

2. 权益包三 Tab 由 pageSize=1000 的假分页改为真实分页 + 页面级触底加载,各 Tab 独立游标与请求序号,合并去重兜底;中奖名单页码改为按期维护,修复切期后重复追加

3. 首页去掉整页 overflow:hidden,小屏不再裁切活动指南卡片;接口表去重并清理 7 个废弃端点;基址/客服电话集中到 common/config.js;删除权益详情不可达的假成功分支
This commit is contained in:
jacobxu666
2026-09-14 23:38:13 +08:00
parent 4e72e81d47
commit 745f4bf5f1
8 changed files with 279 additions and 255 deletions
+12
View File
@@ -0,0 +1,12 @@
// xuchao: 全站集中配置项 —— 后端基址/客服电话等只在这里维护一处
const config = {
// 后端 API 基址。当前指向 UAT 测试环境(见 AGENTS.md 部署信息),切生产改这一行即可
baseUrl: 'https://dscp-uat.hn12301.net',
// 对外统一客服电话,与《用户协议》《隐私协议》公示号码保持一致
servicePhone: '0731-88912301',
// xuchao: open-api/pingXiang/login 强制校验固定 password 字段(后端为 H5 开的旁路),
// 前端去掉即登录失败,故集中存放并在此说明;待后端改造 H5 免密登录后删除。
loginFixedPassword: '1232321'
}
export default config
+55 -69
View File
@@ -1,87 +1,73 @@
// 如果没有通过拦截器配置域名的话,可以在这里写上完整的URL(加上域名部分)
let LoginUrl = 'open-api/pingXiang/login';
let SendVerifyCodeUrl = 'open-api/pingXiang/sendLoginVerifyCode';
let VenueListUrl = 'mp-api/hhrs/venue/list';
let VenueDetailUrl = 'mp-api/hhrs/venue/detail';
let MerchantListUrl = 'mp-api/hhrs/merchant/list';
let MerchantDetailUrl = 'mp-api/hhrs/merchant/detail';
let RightsInfoUrl = 'mp-api/hhrs/rights/info';
let RightsDetailUrl = 'mp-api/hhrsRights/detail';
let RightsAuthUrl = 'mp-api/hhrs/rights/auth';
let EligibilityUrl = 'mp-api/hhrsRights/eligibility';
let RightsBookUrl = 'mp-api/hhrs/rights/book';
let InitFaceVerifyUrl = 'open-api/aliyun/face/initFaceVerify';
let DescribeFaceVerifyUrl = 'open-api/aliyun/face/describeFaceVerify';
let RightsListUrl = 'mp-api/hhrsRights/list';
let AppointmentListUrl = 'mp-api/hhrsRights/appointment/list';
let CheckListUrl = 'mp-api/hhrsRights/check/list';
let StoreListUrl = 'mp-api/hhrsStore/list';
let StoreDetailUrl = 'mp-api/hhrsStore/detail';
let WinnerDatesUrl = 'mp-api/hhrsWinner/dates';
let WinnerListUrl = 'mp-api/hhrsWinner/list';
let AppointUrl = 'zhy-api/cardBag/appoint';
let TokenDecodeUrl = 'open-api/hhService/tokenDecode';
// xuchao: 怀化人社 H5 接口清单,与 docs/hhrs-api-doc.md 一一对应
// 基址由 common/http.interceptor.js 统一注入(common/config.js.baseUrl)
// 登录 / 云闪付入口
const LoginUrl = 'open-api/pingXiang/login'
const SendVerifyCodeUrl = 'open-api/pingXiang/sendLoginVerifyCode'
const TokenDecodeUrl = 'open-api/hhService/tokenDecode'
// 门店(文旅场馆 typeId=1 / 商户折扣 typeId=2)
const StoreListUrl = 'mp-api/hhrsStore/list'
const StoreDetailUrl = 'mp-api/hhrsStore/detail'
// 权益包
const RightsListUrl = 'mp-api/hhrsRights/list'
const RightsDetailUrl = 'mp-api/hhrsRights/detail'
const EligibilityUrl = 'mp-api/hhrsRights/eligibility'
const AppointmentListUrl = 'mp-api/hhrsRights/appointment/list'
const CheckListUrl = 'mp-api/hhrsRights/check/list'
// 实名人脸认证(阿里云)
const InitFaceVerifyUrl = 'open-api/aliyun/face/initFaceVerify'
const DescribeFaceVerifyUrl = 'open-api/aliyun/face/describeFaceVerify'
// 中奖公示
const WinnerDatesUrl = 'mp-api/hhrsWinner/dates'
const WinnerListUrl = 'mp-api/hhrsWinner/list'
// 预约下单(智慧游卡包)
const AppointUrl = 'zhy-api/cardBag/appoint'
// 此处第二个参数vm,就是我们在页面使用的this
const install = (Vue, vm) => {
let checkerLogin = (params = {}) => vm.$u.post(LoginUrl, params);
let sendLoginVerifyCode = (params = {}) => vm.$u.post(SendVerifyCodeUrl, params);
// 登录与凭证
const checkerLogin = (params = {}) => vm.$u.post(LoginUrl, params)
const sendLoginVerifyCode = (params = {}) => vm.$u.post(SendVerifyCodeUrl, params)
// xuchao: 云闪付入口 token 解码
let tokenDecode = (params = {}) => vm.$u.post(TokenDecodeUrl, params);
const tokenDecode = (params = {}) => vm.$u.post(TokenDecodeUrl, params)
// 文旅场馆
let getVenueList = (params = {}) => vm.$u.get(VenueListUrl, params);
let getVenueDetail = (params = {}) => vm.$u.post(VenueDetailUrl, params);
// 商户折扣
let getMerchantList = (params = {}) => vm.$u.get(MerchantListUrl, params);
let getMerchantDetail = (params = {}) => vm.$u.post(MerchantDetailUrl, params);
// 中奖名单
let getWinnerDates = (params = {}) => vm.$u.get(WinnerDatesUrl, params);
let getWinnerList = (params = {}) => vm.$u.post(WinnerListUrl, params);
let doAppoint = (params = {}) => vm.$u.post(AppointUrl, params);
// 门店列表/详情
const getStoreList = (params = {}) => vm.$u.post(StoreListUrl, params)
const getStoreDetail = (params = {}) => vm.$u.post(StoreDetailUrl, params)
// 权益包
let getRightsInfo = (params = {}) => vm.$u.get(RightsInfoUrl, params);
let getRightsDetail = (params = {}) => vm.$u.post(RightsDetailUrl, params);
let doRightsAuth = (params = {}) => vm.$u.post(RightsAuthUrl, params);
let doRightsBook = (params = {}) => vm.$u.post(RightsBookUrl, params);
let getEligibility = (params = {}) => vm.$u.post(EligibilityUrl, params);
let initFaceVerify = (params = {}) => vm.$u.post(InitFaceVerifyUrl, params);
let describeFaceVerify = (params = {}) => vm.$u.post(DescribeFaceVerifyUrl, params);
let getRightsList = (params = {}) => vm.$u.post(RightsListUrl, params);
let getAppointmentList = (params = {}) => vm.$u.post(AppointmentListUrl, params);
let getCheckList = (params = {}) => vm.$u.post(CheckListUrl, params);
let getStoreList = (params = {}) => vm.$u.post(StoreListUrl, params);
let getStoreDetail = (params = {}) => vm.$u.post(StoreDetailUrl, params);
const getRightsList = (params = {}) => vm.$u.post(RightsListUrl, params)
const getRightsDetail = (params = {}) => vm.$u.post(RightsDetailUrl, params)
// xuchao: 注意 identityNo 会触发后端“被动认证”回写,仅在认证流程中传
const getEligibility = (params = {}) => vm.$u.post(EligibilityUrl, params)
const getAppointmentList = (params = {}) => vm.$u.post(AppointmentListUrl, params)
const getCheckList = (params = {}) => vm.$u.post(CheckListUrl, params)
const doAppoint = (params = {}) => vm.$u.post(AppointUrl, params)
// 人脸核身
const initFaceVerify = (params = {}) => vm.$u.post(InitFaceVerifyUrl, params)
const describeFaceVerify = (params = {}) => vm.$u.post(DescribeFaceVerifyUrl, params)
// 中奖名单
const getWinnerDates = (params = {}) => vm.$u.get(WinnerDatesUrl, params)
const getWinnerList = (params = {}) => vm.$u.post(WinnerListUrl, params)
vm.$u.api = {
checkerLogin,
sendLoginVerifyCode,
tokenDecode,
getVenueList,
getVenueDetail,
getMerchantList,
getMerchantDetail,
getWinnerList,
getRightsInfo,
getRightsDetail,
doRightsAuth,
doRightsBook,
getEligibility,
initFaceVerify,
describeFaceVerify,
getRightsList,
getAppointmentList,
getCheckList,
getStoreList,
getStoreDetail,
getWinnerDates,
getWinnerList,
getRightsList,
getRightsDetail,
getEligibility,
getAppointmentList,
getCheckList,
doAppoint,
};
initFaceVerify,
describeFaceVerify,
getWinnerDates,
getWinnerList
}
}
export default {
+15 -5
View File
@@ -1,8 +1,11 @@
import config from '@/common/config.js'
// 这里的vm,就是我们在vue文件里面的this,所以我们能在这里获取vuex的变量,比如存放在里面的token
// 同时,我们也可以在此使用getApp().globalData,如果你把token放在getApp().globalData的话,也是可以使用的
const install = (Vue, vm) => {
Vue.prototype.$u.http.setConfig({
baseUrl: 'https://dscp-uat.hn12301.net',
// xuchao: 基址统一取 common/config.js,避免多处硬编码
baseUrl: config.baseUrl,
// loadingText: '努力加载中~',
// loadingTime: 18800,
// 如果将此值设置为true,拦截回调中将会返回服务端返回的所有数据response,而不是response.data
@@ -41,10 +44,17 @@ const install = (Vue, vm) => {
// 如果把originalData设置为了true,这里return回什么,this.$u.post的then回调中就会得到什么
return res;
}else if(res.errcode==-99){
uni.navigateTo({
url:'/pages/index/login'
})
}else if(res.errcode==-99 || res.errcode==30002){
// xuchao: 未登录/会话失效(-99 自定义、30002 框架 SESSION_AUTH_FAIL)—— 已在登录页则不再入栈
const stack = getCurrentPages() || []
const top = stack.length ? stack[stack.length - 1].route : ''
if (top !== 'pages/index/login') {
uni.navigateTo({
url:'/pages/index/login'
})
}
// xuchao: 必须把 res 交回调用方,否则页面 .then(res => res.errcode) 会因 undefined 抛错
return res
}else {
// uni.showToast({