微信小程序登录页面调整
This commit is contained in:
@@ -21,6 +21,27 @@ pnpm --filter @dukang/mini-user dev:weapp
|
||||
| **编译注入** | `config/index.ts` → `defineConstants.TARO_APP_API_ORIGIN` | 默认 `https://dkapi.runxian.top`;可用环境变量 `VITE_API_TARGET` 覆盖 |
|
||||
| **运行时拼装** | `src/lib/api.ts` → `resolveApiBase()` | `{origin}/api/v1` |
|
||||
|
||||
### 微信登录 `invalid code`
|
||||
|
||||
`wx.login` 的 code 只能由**与小程序 appid 匹配**的后端 `jscode2session` 兑换。
|
||||
|
||||
| 项 | 当前值 |
|
||||
|----|--------|
|
||||
| 小程序 appid | `project.config.json` → `wxda31c8e8e85051e7` |
|
||||
| 后端须配置 | `WX_MINI_APP_ID` / `WX_MINI_APP_SECRET`(与上表一致) |
|
||||
|
||||
**本地联调(不接真实微信)**:API 指到本机且开启 Mock:
|
||||
|
||||
```bash
|
||||
# 终端 1
|
||||
pnpm dev:api # server/.env 保持 MOCK_WECHAT=true
|
||||
|
||||
# 终端 2
|
||||
$env:VITE_API_TARGET="http://localhost:3000"; pnpm dev:mini-user:weapp
|
||||
```
|
||||
|
||||
**连远程 API**:在 `dkapi.runxian.top` 所在服务器配置 `WX_MINI_APP_ID=wxda31c8e8e85051e7` 及对应 AppSecret,并部署含 `code2Session` 小程序凭证逻辑的后端。
|
||||
|
||||
## 页面结构(18 页)
|
||||
|
||||
**Tab**:首页 / 门店 / 好客权益 / 我的
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
import { View, Text } from '@tarojs/components';
|
||||
|
||||
type WechatLoginButtonProps = {
|
||||
loading?: boolean;
|
||||
disabled?: boolean;
|
||||
onClick: () => void;
|
||||
};
|
||||
|
||||
function WechatIcon() {
|
||||
return (
|
||||
<View className="wechat-login-icon" aria-hidden>
|
||||
<View className="wechat-login-icon__big" />
|
||||
<View className="wechat-login-icon__small" />
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
/** 微信授权一键登录按钮(对齐 h5-user login-wechat-btn) */
|
||||
export default function WechatLoginButton({
|
||||
loading = false,
|
||||
disabled = false,
|
||||
onClick,
|
||||
}: WechatLoginButtonProps) {
|
||||
const inactive = loading || disabled;
|
||||
|
||||
return (
|
||||
<View
|
||||
className={`login-wechat-btn${inactive ? ' login-wechat-btn--disabled' : ''}`}
|
||||
onClick={inactive ? undefined : onClick}
|
||||
>
|
||||
<WechatIcon />
|
||||
<Text className="login-wechat-btn__text">
|
||||
{loading ? '授权中...' : '微信一键授权'}
|
||||
</Text>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
type WechatLoginResult,
|
||||
} from '@dukang/shared-types';
|
||||
import PageShell from '../../components/PageShell';
|
||||
import WechatLoginButton from '../../components/WechatLoginButton';
|
||||
import { finishLoginNavigate } from '../../lib/auth-nav';
|
||||
import { request, saveAuth, toast, type SessionPayload } from '../../lib/api';
|
||||
import { loginWithWechat } from '../../lib/wechat-auth';
|
||||
@@ -154,7 +155,11 @@ export default function LoginPage() {
|
||||
const result = await loginWithWechat();
|
||||
handleWechatLoginResult(result);
|
||||
} catch (e) {
|
||||
setMsg(e instanceof Error ? e.message : '微信登录失败');
|
||||
const raw = e instanceof Error ? e.message : '微信登录失败';
|
||||
const hint = /invalid code/i.test(raw)
|
||||
? '微信 code 无效:请确认后端 WX_MINI_APP_ID 与小程序 appid 一致,或本地联调使用 MOCK_WECHAT'
|
||||
: raw;
|
||||
setMsg(hint);
|
||||
} finally {
|
||||
setWxLoading(false);
|
||||
}
|
||||
@@ -162,6 +167,8 @@ export default function LoginPage() {
|
||||
|
||||
const displayMsg = msg || sentHint;
|
||||
const codeDisabled = cooldown > 0 || sending;
|
||||
const showWechatLogin =
|
||||
!bindMode && (process.env.TARO_ENV === 'weapp' || wxAuthorize);
|
||||
|
||||
return (
|
||||
<PageShell variant="plain" className="login-page">
|
||||
@@ -233,22 +240,17 @@ export default function LoginPage() {
|
||||
</Button>
|
||||
</View>
|
||||
|
||||
{!bindMode && wxAuthorize ? (
|
||||
{showWechatLogin ? (
|
||||
<>
|
||||
<View className="login-divider">
|
||||
<View className="login-divider-line" />
|
||||
<Text className="login-divider-text">或者</Text>
|
||||
<View className="login-divider-line" />
|
||||
</View>
|
||||
<Button
|
||||
className="login-wechat-btn"
|
||||
<WechatLoginButton
|
||||
loading={wxLoading}
|
||||
disabled={wxLoading}
|
||||
onClick={() => void wechatLogin()}
|
||||
>
|
||||
<Text className="login-wechat-icon">微</Text>
|
||||
<Text>微信一键授权</Text>
|
||||
</Button>
|
||||
/>
|
||||
</>
|
||||
) : null}
|
||||
</View>
|
||||
|
||||
@@ -221,20 +221,52 @@
|
||||
font-weight: 600;
|
||||
line-height: 1;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
box-shadow: 0 8px 24px rgba(166, 29, 36, 0.1);
|
||||
}
|
||||
|
||||
.login-wechat-btn::after {
|
||||
border: none;
|
||||
.login-wechat-btn:active {
|
||||
transform: scale(0.98);
|
||||
}
|
||||
|
||||
.login-wechat-btn[disabled] {
|
||||
.login-wechat-btn--disabled {
|
||||
opacity: 0.7;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.login-wechat-icon {
|
||||
font-size: 22px;
|
||||
line-height: 1;
|
||||
.login-wechat-btn__text {
|
||||
color: #fff;
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
line-height: 26px;
|
||||
}
|
||||
|
||||
.wechat-login-icon {
|
||||
position: relative;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.wechat-login-icon__big,
|
||||
.wechat-login-icon__small {
|
||||
position: absolute;
|
||||
border-radius: 50%;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.wechat-login-icon__big {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
left: 0;
|
||||
top: 5px;
|
||||
}
|
||||
|
||||
.wechat-login-icon__small {
|
||||
width: 11px;
|
||||
height: 11px;
|
||||
right: 0;
|
||||
bottom: 3px;
|
||||
}
|
||||
|
||||
.login-footer {
|
||||
|
||||
Reference in New Issue
Block a user