feat: 分销码
All checks were successful
构建并部署前端到生产环境 / build-and-deploy (push) Successful in 1m6s

This commit is contained in:
luo
2026-10-08 12:26:39 +08:00
parent 2b4fd6fff8
commit b2ed8b5df4
5 changed files with 57 additions and 2 deletions

View File

@@ -0,0 +1,15 @@
# Change: Encode agent registration URL in distribution QR code
## Why
The current distribution QR code encodes only the raw distribution code, so scanning it does not open agent registration with the code prefilled. Scanners should open the registration route with the current shop's distribution code in its query string.
## What Changes
- Change the locally generated QR content to an absolute URL composed from `VITE_API_BASE_URL`, `/agent-registration`, and the URL-encoded `distribution_code` query parameter.
- Keep the existing agent-only access checks, shop lookup, and local QR rendering behavior.
## Impact
- Affected specs: `agent-distribution-code`
- Affected code: `src/pages/agent-system/distribution-code/index.vue`

View File

@@ -0,0 +1,23 @@
## MODIFIED Requirements
### Requirement: Agent users can view their shop distribution code
The authenticated home page SHALL show a "View my distribution code" shortcut immediately after withdrawal management only when the current user's `user_type` is `3`. The shortcut SHALL use `src/static/icons/分销码.png`. Opening it SHALL use the current user's `shop_id` to retrieve that shop's `distribution_code` from `/api/admin/shops/{shop_id}` and display a QR code encoding the absolute registration URL formed from `VITE_API_BASE_URL`, `/agent-registration`, and the URL-encoded `distribution_code` query parameter. The code SHALL be generated locally and SHALL NOT be sent to a third-party QR service.
#### Scenario: Agent sees and opens the shortcut
- **GIVEN** `/api/auth/me` returns a user with `user_type` `3` and a valid `shop_id`
- **WHEN** the home page displays its quick actions
- **THEN** "View my distribution code" appears immediately after withdrawal management with the supplied distribution-code icon
- **AND** opening it displays a QR code whose decoded value is `${VITE_API_BASE_URL}/agent-registration?distribution_code=${encodeURIComponent(distribution_code)}`
#### Scenario: Non-agent does not see the shortcut
- **GIVEN** `/api/auth/me` returns a user whose `user_type` is not `3`
- **WHEN** the home page displays its quick actions
- **THEN** the distribution-code shortcut is not shown
- **AND** direct navigation to the distribution-code page does not reveal a code
#### Scenario: Shop or distribution code is unavailable
- **GIVEN** an agent opens the distribution-code page
- **WHEN** the current account has no `shop_id`, the shop request fails, or the shop has no `distribution_code`
- **THEN** no QR code is rendered
- **AND** the page explains that the distribution code is currently unavailable

View File

@@ -0,0 +1,10 @@
## 1. Proposal Review
- [x] 1.1 Review and approve this proposal before implementation
## 2. Implementation
- [x] 2.1 Build the registration URL from the configured API base URL and URL-encoded distribution code
- [x] 2.2 Generate the QR code from the registration URL while preserving existing access and error handling
## 3. Verification
- [x] 3.1 Verify URL composition, including trailing slash handling and query encoding
- [x] 3.2 Run target-page ESLint, H5 build, and project type-check; record existing unrelated type-check errors

View File

@@ -30,7 +30,7 @@
/>
</view>
<text class="mt-4 text-13px text-[#7a8590]">
扫描二维码获取分销信息
扫描二维码进入代理注册
</text>
</view>
</view>
@@ -51,6 +51,11 @@ const loading = ref(true);
const distributionCode = ref('');
const errorMessage = ref('');
function getRegistrationUrl(code: string) {
const apiBaseUrl = import.meta.env.VITE_API_BASE_URL.replace(/\/+$/, '');
return `${apiBaseUrl}/agent-registration?distribution_code=${encodeURIComponent(code)}`;
}
function drawQrCode(value: string) {
const qrCode = qrcodeGenerator(0, 'M');
qrCode.addData(value);
@@ -106,7 +111,7 @@ async function loadDistributionCode() {
distributionCode.value = code;
await nextTick();
drawQrCode(code);
drawQrCode(getRegistrationUrl(code));
}
catch (error) {
console.error('加载分销码失败:', error);

View File

@@ -11,6 +11,8 @@ declare module 'vue' {
AgentFundSummaryCard: typeof import('./../src/components/AgentFundSummaryCard.vue')['default']
AgreePrivacy: typeof import('./../src/components/agree-privacy/index.vue')['default']
LangSelect: typeof import('./../src/components/lang-select/index.vue')['default']
RouterLink: typeof import('vue-router')['RouterLink']
RouterView: typeof import('vue-router')['RouterView']
ShopCascadePicker: typeof import('./../src/components/ShopCascadePicker.vue')['default']
SimplePicker: typeof import('./../src/components/SimplePicker.vue')['default']
Skeleton: typeof import('./../src/components/Skeleton.vue')['default']