diff --git a/src/apis.js b/src/apis.js
index 7e8f0ed..3ae9fc2 100644
--- a/src/apis.js
+++ b/src/apis.js
@@ -752,3 +752,14 @@ export const getNearbyStoresAPI = ({
pageSize,
});
};
+
+// 分页获取指定门店的公开金币规则。
+export const getStoreGoldRuleListAPI = ({storeId, page = 1, pageSize = 20} = {}) => {
+ return request(
+ "GET",
+ `/gin/api/v1/super-admin/gold-rule/store/${storeId}/list`,
+ {page, page_size: pageSize},
+ API_ROOT_URL,
+ [0, 200]
+ );
+};
diff --git a/src/pages/coin/components/CoinEmptyState.vue b/src/pages/coin/components/CoinEmptyState.vue
index 005f2ed..6f8b5b9 100644
--- a/src/pages/coin/components/CoinEmptyState.vue
+++ b/src/pages/coin/components/CoinEmptyState.vue
@@ -9,7 +9,10 @@ defineProps({
-
+
{{ text }}
diff --git a/src/pages/coin/components/LocationPermissionState.vue b/src/pages/coin/components/LocationPermissionState.vue
index 66faf2e..ccf8c9a 100644
--- a/src/pages/coin/components/LocationPermissionState.vue
+++ b/src/pages/coin/components/LocationPermissionState.vue
@@ -4,7 +4,10 @@ const emit = defineEmits(["authorize"]);
-
+
授权获取你的定位,以便推荐附近门店。
diff --git a/src/pages/coin/components/OfflineExchangeNotice.vue b/src/pages/coin/components/OfflineExchangeNotice.vue
index 44b760f..63f7383 100644
--- a/src/pages/coin/components/OfflineExchangeNotice.vue
+++ b/src/pages/coin/components/OfflineExchangeNotice.vue
@@ -9,7 +9,10 @@ defineProps({
-
+
暂不支持线上兑换,请前往线下门店进行兑换。
diff --git a/src/pages/coin/components/ProductHeroSwiper.vue b/src/pages/coin/components/ProductHeroSwiper.vue
index 160d30c..73a56ba 100644
--- a/src/pages/coin/components/ProductHeroSwiper.vue
+++ b/src/pages/coin/components/ProductHeroSwiper.vue
@@ -1,7 +1,8 @@
-
+
{{ store.name }}
diff --git a/src/pages/coin/data.js b/src/pages/coin/data.js
index b13d24e..24f7efc 100644
--- a/src/pages/coin/data.js
+++ b/src/pages/coin/data.js
@@ -2,29 +2,21 @@ export const quickMenus = [
{
key: "rules",
label: "金币规则",
- icon: "/static/coin/icon-rules.png",
+ icon: "https://static.shelingxingqiu.com/shootmini/static/coin/icon-rules.png",
},
{
key: "earningRecords",
label: "获取明细",
- icon: "/static/coin/icon-earning-records.png",
+ icon: "https://static.shelingxingqiu.com/shootmini/static/coin/icon-earning-records.png",
},
{
key: "exchangeRecords",
label: "兑换记录",
- icon: "/static/coin/icon-exchange-records.png",
+ icon: "https://static.shelingxingqiu.com/shootmini/static/coin/icon-exchange-records.png",
},
{
key: "nearbyStores",
label: "附近门店",
- icon: "/static/coin/icon-nearby-store.png",
+ icon: "https://static.shelingxingqiu.com/shootmini/static/coin/icon-nearby-store.png",
},
];
-
-export const coinRules = [
- "金币获取规则:登录个人账号后,使用射灵智能弓体验个人训练、好友约战、排位赛三种模式,每射出一箭并判为有效,即可根据该箭的实际环数,获得等额金币。如:用户在个人训练中,射出一箭并获得9环,即获得9金币。",
- "累计金币:累计金币为用户历史获得的所有金币,不会过期、不受兑换影响。",
- "可兑换金币:可兑换金币为用户可用于兑换奖品的金币,用户使用金币兑换相应礼品后,将扣除相应金币。同时,可兑换金币有1年有效期,自金币获得之日起开始计算。",
- "射灵星球官方可能会不定期举办各类活动,有机会额外获得更多机会,具体以实际公告为准。",
- "金币以每个门店/俱乐部为单位独立计算与兑换核销,暂不支持跨门店、跨俱乐部计算,具体以各门店实际公告为准。",
-];
diff --git a/src/pages/coin/earning-records.vue b/src/pages/coin/earning-records.vue
index 57efd2e..f5aa518 100644
--- a/src/pages/coin/earning-records.vue
+++ b/src/pages/coin/earning-records.vue
@@ -8,6 +8,7 @@ import CoinEmptyState from "./components/CoinEmptyState.vue";
import { getGoldLogAPI } from "@/apis";
const PAGE_SIZE = 20;
+const storeId = ref("");
const earningRecords = ref([]);
const page = ref(0);
const total = ref(0);
@@ -61,6 +62,7 @@ const loadRecords = async ({ reset = false } = {}) => {
page: nextPage,
pageSize: PAGE_SIZE,
type: 1,
+ storeId: storeId.value,
});
const list = Array.isArray(result?.list) ? result.list : [];
const mappedList = list.map(formatRecord);
@@ -80,7 +82,18 @@ const loadRecords = async ({ reset = false } = {}) => {
}
};
-onLoad(() => loadRecords({ reset: true }));
+onLoad((options = {}) => {
+ const currentStoreId = String(options.storeId || "");
+ if (!/^\d+$/.test(currentStoreId) || Number(currentStoreId) <= 0) {
+ uni.redirectTo({
+ url: "/pages/coin/nearby-stores",
+ });
+ return;
+ }
+
+ storeId.value = currentStoreId;
+ loadRecords({ reset: true });
+});
diff --git a/src/pages/coin/exchange-records.vue b/src/pages/coin/exchange-records.vue
index 30242aa..f661d9b 100644
--- a/src/pages/coin/exchange-records.vue
+++ b/src/pages/coin/exchange-records.vue
@@ -8,6 +8,7 @@ import CoinEmptyState from "./components/CoinEmptyState.vue";
import { getGoldLogAPI } from "@/apis";
const PAGE_SIZE = 20;
+const storeId = ref("");
const exchangeRecords = ref([]);
const page = ref(0);
const total = ref(0);
@@ -61,6 +62,7 @@ const loadRecords = async ({ reset = false } = {}) => {
page: nextPage,
pageSize: PAGE_SIZE,
type: 2,
+ storeId: storeId.value,
});
const list = Array.isArray(result?.list) ? result.list : [];
const mappedList = list.map(formatRecord);
@@ -80,7 +82,18 @@ const loadRecords = async ({ reset = false } = {}) => {
}
};
-onLoad(() => loadRecords({ reset: true }));
+onLoad((options = {}) => {
+ const currentStoreId = String(options.storeId || "");
+ if (!/^\d+$/.test(currentStoreId) || Number(currentStoreId) <= 0) {
+ uni.redirectTo({
+ url: "/pages/coin/nearby-stores",
+ });
+ return;
+ }
+
+ storeId.value = currentStoreId;
+ loadRecords({ reset: true });
+});
diff --git a/src/pages/coin/index.vue b/src/pages/coin/index.vue
index 5319b00..8f1e46e 100644
--- a/src/pages/coin/index.vue
+++ b/src/pages/coin/index.vue
@@ -15,6 +15,8 @@ const coinSummary = ref({
cumulative: 0,
available: 0,
});
+const selectedStoreId = ref("");
+const selectedStoreName = ref("");
const rewardProducts = ref([]);
const productPage = ref(0);
const productTotal = ref(0);
@@ -23,7 +25,7 @@ const productNoMore = ref(false);
const loadCoinSummary = async () => {
try {
- const result = await getMyGoldAPI();
+ const result = await getMyGoldAPI(selectedStoreId.value);
coinSummary.value = {
cumulative: Number(result?.totalGold) || 0,
available: Number(result?.usableGold) || 0,
@@ -86,10 +88,37 @@ const menuRoutes = {
rules: "/pages/coin/rules",
earningRecords: "/pages/coin/earning-records",
exchangeRecords: "/pages/coin/exchange-records",
- nearbyStores: "/pages/coin/nearby-stores",
+};
+
+const buildStorePageUrl = (path, extraQuery = "") => {
+ const query = [
+ `storeId=${encodeURIComponent(selectedStoreId.value)}`,
+ `storeName=${encodeURIComponent(selectedStoreName.value)}`,
+ extraQuery,
+ ]
+ .filter(Boolean)
+ .join("&");
+ return `${path}?${query}`;
+};
+
+const decodeRouteText = (value = "") => {
+ const text = String(value);
+ try {
+ return decodeURIComponent(text.replace(/\+/g, " "));
+ } catch (error) {
+ console.error("门店名称解码失败", error);
+ return text;
+ }
};
const onMenuSelect = (menu) => {
+ if (menu.key === "nearbyStores") {
+ uni.redirectTo({
+ url: "/pages/coin/nearby-stores",
+ });
+ return;
+ }
+
const url = menuRoutes[menu.key];
if (!url) {
uni.showToast({
@@ -98,16 +127,31 @@ const onMenuSelect = (menu) => {
});
return;
}
- uni.navigateTo({ url });
+ uni.navigateTo({
+ url: buildStorePageUrl(url),
+ });
};
const toProductDetail = (product) => {
uni.navigateTo({
- url: `/pages/coin/product-detail?id=${product.id}`,
+ url: buildStorePageUrl(
+ "/pages/coin/product-detail",
+ `id=${encodeURIComponent(product.id)}`
+ ),
});
};
-onLoad(() => {
+onLoad((options = {}) => {
+ const storeId = String(options.storeId || "");
+ if (!/^\d+$/.test(storeId) || Number(storeId) <= 0) {
+ uni.redirectTo({
+ url: "/pages/coin/nearby-stores",
+ });
+ return;
+ }
+
+ selectedStoreId.value = storeId;
+ selectedStoreName.value = decodeRouteText(options.storeName);
loadCoinSummary();
loadProducts({ reset: true });
});
@@ -116,7 +160,7 @@ onLoad(() => {
-
+
{
});
};
+// 选择门店后替换当前页面,返回时直接回到进入金币模块前的页面。
+const selectStore = (store) => {
+ const storeId = String(store?.id || "");
+ if (!/^\d+$/.test(storeId) || Number(storeId) <= 0) {
+ uni.showToast({
+ title: "门店信息无效",
+ icon: "none",
+ });
+ return;
+ }
+
+ const storeName = encodeURIComponent(store?.name || "");
+ uni.redirectTo({
+ url: `/pages/coin/index?storeId=${encodeURIComponent(storeId)}&storeName=${storeName}`,
+ });
+};
+
onLoad(locateAndLoadStores);
@@ -114,7 +132,12 @@ onLoad(locateAndLoadStores);
@authorize="authorizeLocation"
/>
-
+
附近暂无门店~
diff --git a/src/pages/coin/rules.vue b/src/pages/coin/rules.vue
index b8987ef..c8a6abe 100644
--- a/src/pages/coin/rules.vue
+++ b/src/pages/coin/rules.vue
@@ -1,21 +1,104 @@
-
+
-
- {{ index + 1 }}、{{ rule }}
+
+
+
+
+
+
+
+ 加载中...
@@ -35,4 +118,16 @@ import { coinRules } from "./data";
line-height: 52rpx;
text-align: justify;
}
+
+.rules-page__content {
+ display: block;
+}
+
+.rules-page__status {
+ padding: 12rpx 0 20rpx;
+ color: rgba(255, 255, 255, 0.6);
+ font-size: 24rpx;
+ line-height: 34rpx;
+ text-align: center;
+}
diff --git a/src/pages/user.vue b/src/pages/user.vue
index a0fa130..dd37b4c 100644
--- a/src/pages/user.vue
+++ b/src/pages/user.vue
@@ -26,7 +26,7 @@ const toFristTryPage = async () => {
};
const toCoinPage = () => {
uni.navigateTo({
- url: "/pages/coin/index",
+ url: "/pages/coin/nearby-stores",
});
};
const toBeVipPage = () => {