feat: 龙里小程序第一次上传
This commit is contained in:
commit
f23d598328
59 files changed
+11482
No files matched your search
@@ -0,0 +1,23 @@
|
||||
import request from "../base/request";
|
||||
|
||||
/**
|
||||
* 权益相关接口
|
||||
* 核心口径(v0.8/v0.11):权益不绑定具体商品、可多次使用;
|
||||
* 领取与使用只累加次数,不改变可用状态,无幂等约束。
|
||||
*/
|
||||
|
||||
/** 权益中心列表 */
|
||||
export const fetchBenefits = (params = {}) => request.get("/longli/benefit/list", params);
|
||||
|
||||
/** 我的权益列表 */
|
||||
export const fetchMyBenefits = (params = {}) => request.get("/longli/benefit/mine", params);
|
||||
|
||||
/** 领取权益 */
|
||||
export const claimBenefit = (id) => request.post("/longli/benefit/claim", { id });
|
||||
|
||||
/** 记录一次使用(只累加 use_count + last_used_at,不失效) */
|
||||
export const useBenefit = (id) => request.post("/longli/benefit/use", { id });
|
||||
|
||||
/** 商家关联的到店权益 */
|
||||
export const fetchRelatedBenefits = (entityId) =>
|
||||
request.get("/longli/benefit/related", { related_entity_id: entityId });
|
||||
@@ -0,0 +1,24 @@
|
||||
import request from "../base/request";
|
||||
|
||||
/**
|
||||
* 内容(板块 / 目录 / 条目 / 素材)接口
|
||||
* 字段口径见 需求说明 §2 / §5 / §6
|
||||
*/
|
||||
|
||||
/** 获取全部板块(4 个:票根经济 / 旅居服务 / 全域美食 / 龙里特产) */
|
||||
export const fetchSections = () => request.get("/longli/content/sections");
|
||||
|
||||
/** 获取板块详情(含分组与条目,已过滤 enabled=false 与空分组) */
|
||||
export const fetchSection = (sectionKey) => request.get("/longli/content/section", { key: sectionKey });
|
||||
|
||||
/** 获取条目详情 */
|
||||
export const fetchItem = (collection, id) => request.get("/longli/content/item", { collection, id });
|
||||
|
||||
/** 获取同类型推荐(排除自身) */
|
||||
export const fetchRelatedItems = (params) => request.get("/longli/content/related", params);
|
||||
|
||||
/** 首页精选推荐(一期为运营固定位,二期由后端下发) */
|
||||
export const fetchFeaturedItems = () => request.get("/longli/content/featured");
|
||||
|
||||
/** 素材(导览图等) */
|
||||
export const fetchAssets = (params = {}) => request.get("/longli/content/assets", params);
|
||||
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
* 登录 / 用户相关接口
|
||||
* ---------------------------------------------------------------------------
|
||||
* 与 YGChatCS src/request/api/LoginApi.js 保持一致(同一后端客户端 clientId = 2)。
|
||||
* 取 token 走 OAuth2 客户端凭据 Basic custom:custom,请求体是 form-urlencoded。
|
||||
*/
|
||||
import request from "../base/request";
|
||||
|
||||
/** 网关内置 OAuth2 客户端凭据(与 YGChatCS 相同,非用户凭据) */
|
||||
const BASIC_AUTH = "Basic Y3VzdG9tOmN1c3RvbQ==";
|
||||
|
||||
/**
|
||||
* code 换 token
|
||||
* @param {{ openIdCode: string[], grant_type: string, clientId: string, scope: string }} args
|
||||
*/
|
||||
export const oauthToken = (args) =>
|
||||
request.post("/auth/oauth2/token", args, {
|
||||
header: {
|
||||
Authorization: BASIC_AUTH,
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
},
|
||||
silent: true,
|
||||
});
|
||||
|
||||
/**
|
||||
* 绑定手机号
|
||||
* @param {{ wechatPhoneCode: string, clientId: string }} args
|
||||
*/
|
||||
export const bindUserPhone = (args) => request.post("/hotelBiz/user/bindUserPhone", args);
|
||||
|
||||
/** 检测当前登录用户是否已绑定手机号 → { data: boolean } */
|
||||
export const checkUserPhone = (config = {}) =>
|
||||
request.get("/hotelBiz/user/checkUserHasBindPhone", {}, config);
|
||||
|
||||
/** 获取当前登录用户的手机号(脱敏) */
|
||||
export const getLoginUserPhone = (args = {}, config = {}) =>
|
||||
request.get("/hotelBiz/user/getLoginUserPhone", args, config);
|
||||
|
||||
/** 服务协议原文 */
|
||||
export const getServiceAgreement = (args = {}) => request.get("/hotelBiz/mainScene/serviceAgreement", args);
|
||||
|
||||
/** 隐私政策原文 */
|
||||
export const getPrivacyAgreement = (args = {}) => request.get("/hotelBiz/mainScene/privacyPolicy", args);
|
||||
@@ -0,0 +1,78 @@
|
||||
/**
|
||||
* 服务地址解析(参照 YGChatCS request/base/config.js)
|
||||
* ---------------------------------------------------------------------------
|
||||
* 启动时用版本号去生产网关换当前环境的 httpUrl:
|
||||
* POST https://biz.nianxx.cn/hotelBiz/versionManager/getInfo { versionValue }
|
||||
* → { code: 0, data: { httpUrl, wssUrl } }
|
||||
* 换不到(版本未登记 / 网络异常)就退回内置测试网关,保证登录等真实接口仍可用。
|
||||
*/
|
||||
import {
|
||||
getEnvConfig,
|
||||
setBaseUrl,
|
||||
USE_MOCK_USER,
|
||||
FORCE_BASE_URL,
|
||||
BASE_URL_PRO,
|
||||
BASE_URL_DEV,
|
||||
SERVICE_URL_PATH,
|
||||
} from "@/config/env";
|
||||
import request from "./request";
|
||||
|
||||
/** 对外暴露的版本号,发版前与 env.js 的 VERSION 同步 */
|
||||
export const VERSION = getEnvConfig().version;
|
||||
|
||||
let envReady = false;
|
||||
let envPromise = null;
|
||||
|
||||
/** 是否已完成服务地址解析 */
|
||||
export const isEnvReady = () => envReady;
|
||||
|
||||
/**
|
||||
* 幂等确保服务地址已就绪:并发调用共用同一个请求。
|
||||
* 登录等真实接口在发请求前 await 它,避免拿不到 baseURL。
|
||||
*/
|
||||
export const ensureEnvReady = () => {
|
||||
if (envReady) return Promise.resolve(getEnvConfig().baseUrl);
|
||||
if (!envPromise) {
|
||||
envPromise = getEvnUrl().finally(() => {
|
||||
envPromise = null;
|
||||
});
|
||||
}
|
||||
return envPromise;
|
||||
};
|
||||
|
||||
const pickHttpUrl = (res) => {
|
||||
if (!res || res.code !== 0 || !res.data) return "";
|
||||
return res.data.httpUrl || res.data.baseUrl || "";
|
||||
};
|
||||
|
||||
export const getEvnUrl = async () => {
|
||||
const env = getEnvConfig();
|
||||
|
||||
// 手动钉死地址:跳过服务地址接口
|
||||
if (FORCE_BASE_URL) {
|
||||
setBaseUrl(FORCE_BASE_URL);
|
||||
envReady = true;
|
||||
return env.baseUrl;
|
||||
}
|
||||
|
||||
// 登录也走 mock 时不需要真实服务地址
|
||||
if (USE_MOCK_USER) {
|
||||
setBaseUrl(env.baseUrl || BASE_URL_DEV);
|
||||
envReady = true;
|
||||
return env.baseUrl;
|
||||
}
|
||||
|
||||
try {
|
||||
const res = await request.post(
|
||||
`${BASE_URL_PRO}${SERVICE_URL_PATH}`,
|
||||
{ versionValue: env.version },
|
||||
{ noToken: true, silent: true }
|
||||
);
|
||||
setBaseUrl(pickHttpUrl(res) || BASE_URL_DEV);
|
||||
} catch (e) {
|
||||
setBaseUrl(BASE_URL_DEV);
|
||||
}
|
||||
|
||||
envReady = true;
|
||||
return getEnvConfig().baseUrl;
|
||||
};
|
||||
@@ -0,0 +1,97 @@
|
||||
/**
|
||||
* 统一请求封装(参照 YGChatCS 的 request 层,按本项目裁剪)
|
||||
* - 自动拼 baseURL(http 开头则原样使用)
|
||||
* - 自动带 clientId(网关鉴权靠它,本项目 = "2")
|
||||
* - 自动带 Authorization: Bearer <token>;显式传 header.Authorization 时不覆盖(OAuth 取 token 用 Basic)
|
||||
* - 424 视为登录失效:清 token → 广播退出 → 跳登录页
|
||||
*/
|
||||
import { getEnvConfig } from "@/config/env";
|
||||
import { NOTICE_EVENT_LOGOUT } from "@/constant";
|
||||
import { clearLoginState, getAccessToken } from "@/constant/token";
|
||||
import { goLogin } from "@/utils/nav";
|
||||
|
||||
const defaultHeader = {
|
||||
"Content-Type": "application/json",
|
||||
};
|
||||
|
||||
/** 当前栈顶是否已是登录页(避免 424 时反复 stack 登录页) */
|
||||
const isOnLoginPage = () => {
|
||||
try {
|
||||
const pages = getCurrentPages();
|
||||
if (!pages || !pages.length) return false;
|
||||
return pages[pages.length - 1].route === "pages/login/index";
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
function request(url, args = {}, method = "POST", customConfig = {}) {
|
||||
const { noToken = false, silent = false, token: explicitToken, ...rest } = customConfig;
|
||||
const env = getEnvConfig();
|
||||
|
||||
let fullUrl = url;
|
||||
if (!/^http/.test(url)) {
|
||||
fullUrl = `${env.baseUrl}${url}`;
|
||||
}
|
||||
|
||||
const header = {
|
||||
...defaultHeader,
|
||||
clientId: env.clientId,
|
||||
...(rest.header || {}),
|
||||
};
|
||||
|
||||
if (noToken) {
|
||||
delete header.Authorization;
|
||||
} else if (!header.Authorization) {
|
||||
const token = explicitToken || getAccessToken();
|
||||
if (token) header.Authorization = `Bearer ${token}`;
|
||||
}
|
||||
|
||||
const config = {
|
||||
...rest,
|
||||
header,
|
||||
method,
|
||||
timeout: env.timeout,
|
||||
data: args,
|
||||
};
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
uni.request({
|
||||
url: fullUrl,
|
||||
...config,
|
||||
success: (res) => {
|
||||
const { statusCode = 0, data } = res;
|
||||
|
||||
if (statusCode === 424) {
|
||||
clearLoginState();
|
||||
uni.$emit(NOTICE_EVENT_LOGOUT);
|
||||
if (!isOnLoginPage()) setTimeout(() => goLogin(), 500);
|
||||
}
|
||||
|
||||
if (statusCode >= 200 && statusCode < 300) {
|
||||
resolve(data);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!silent) {
|
||||
const msg = (data && (data.message || data.msg)) || `请求失败(${statusCode})`;
|
||||
uni.showToast({ title: msg, icon: "none" });
|
||||
}
|
||||
reject(res);
|
||||
},
|
||||
fail: (err) => {
|
||||
if (!silent) {
|
||||
uni.showToast({ title: "网络异常,请稍后重试", icon: "none" });
|
||||
}
|
||||
reject(err);
|
||||
},
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
request.post = (url, args = {}, config = {}) => request(url, args, "POST", config);
|
||||
request.get = (url, args = {}, config = {}) => request(url, args, "GET", config);
|
||||
request.put = (url, args = {}, config = {}) => request(url, args, "PUT", config);
|
||||
request.del = (url, args = {}, config = {}) => request(url, args, "DELETE", config);
|
||||
|
||||
export default request;
|
||||
Reference in new issue
Block a user