微信小程序端登录和头像调整
This commit is contained in:
@@ -10,5 +10,6 @@
|
|||||||
"postcss": false,
|
"postcss": false,
|
||||||
"minified": false
|
"minified": false
|
||||||
},
|
},
|
||||||
"compileType": "miniprogram"
|
"compileType": "miniprogram",
|
||||||
|
"preloadBackgroundData": false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import Taro from '@tarojs/taro';
|
import Taro from '@tarojs/taro';
|
||||||
import { API_BASE, CLIENT_APP, getToken, request, type UserProfile } from './api';
|
import type { UserProfile } from './api';
|
||||||
|
|
||||||
export type MiniWechatProfile = {
|
export type MiniWechatProfile = {
|
||||||
nickname?: string;
|
nickname?: string;
|
||||||
@@ -57,6 +57,7 @@ export function mergeWxDisplayProfile(profile: UserProfile): UserProfile {
|
|||||||
|
|
||||||
/** 上传 chooseAvatar 临时文件到 OSS,返回永久 URL */
|
/** 上传 chooseAvatar 临时文件到 OSS,返回永久 URL */
|
||||||
export async function uploadAvatarTempFile(tempFilePath: string): Promise<string> {
|
export async function uploadAvatarTempFile(tempFilePath: string): Promise<string> {
|
||||||
|
const { API_BASE, CLIENT_APP, getToken } = await import('./api');
|
||||||
const token = getToken();
|
const token = getToken();
|
||||||
if (!token) throw new Error('请先登录');
|
if (!token) throw new Error('请先登录');
|
||||||
|
|
||||||
@@ -91,6 +92,7 @@ export async function uploadAvatarTempFile(tempFilePath: string): Promise<string
|
|||||||
|
|
||||||
export async function uploadMiniWechatProfile(info: MiniWechatProfile): Promise<UserProfile | null> {
|
export async function uploadMiniWechatProfile(info: MiniWechatProfile): Promise<UserProfile | null> {
|
||||||
if (!info.nickname && !info.avatarUrl) return null;
|
if (!info.nickname && !info.avatarUrl) return null;
|
||||||
|
const { request } = await import('./api');
|
||||||
const updated = await request<UserProfile>('/auth/wechat/mini-profile', {
|
const updated = await request<UserProfile>('/auth/wechat/mini-profile', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
data: info,
|
data: info,
|
||||||
@@ -103,26 +105,16 @@ export async function uploadMiniWechatProfile(info: MiniWechatProfile): Promise<
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated getUserProfile 已收回真实头像昵称,仅作兼容;小程序请用 chooseAvatar + nickname
|
* 兼容旧调用:getUserProfile 已无法拿到真实头像昵称。
|
||||||
|
* 始终导出为函数,避免循环依赖/旧包出现 “is not a function”。
|
||||||
*/
|
*/
|
||||||
export async function fetchMiniWechatUserInfo(): Promise<MiniWechatProfile> {
|
export async function fetchMiniWechatUserInfo(): Promise<MiniWechatProfile> {
|
||||||
if (process.env.TARO_ENV !== 'weapp') {
|
const cached = getCachedWxProfile();
|
||||||
throw new Error('请在微信小程序中授权');
|
if (cached?.nickname || cached?.avatarUrl) {
|
||||||
|
return cached;
|
||||||
}
|
}
|
||||||
const res = await Taro.getUserProfile({ desc: '用于完善会员资料' });
|
// 不再弹 getUserProfile;引导走「我的」页 chooseAvatar / nickname
|
||||||
const info: MiniWechatProfile = {
|
throw new Error('请在「我的」页点击头像完善微信头像和昵称');
|
||||||
nickname: res.userInfo?.nickName?.trim(),
|
|
||||||
avatarUrl: res.userInfo?.avatarUrl?.trim(),
|
|
||||||
};
|
|
||||||
if (!info.nickname && !info.avatarUrl) {
|
|
||||||
throw new Error('未获取到微信头像或昵称');
|
|
||||||
}
|
|
||||||
// 灰色默认头像 / 「微信用户」视为无效,需走填写能力
|
|
||||||
if (info.nickname === '微信用户' || !info.avatarUrl) {
|
|
||||||
throw new Error('请使用头像昵称填写能力完善资料');
|
|
||||||
}
|
|
||||||
cacheWxProfile(info);
|
|
||||||
return info;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 绑定后上报微信资料(优先使用已拉取的信息) */
|
/** 绑定后上报微信资料(优先使用已拉取的信息) */
|
||||||
@@ -130,9 +122,8 @@ export async function syncMiniWechatProfile(
|
|||||||
prefetched?: MiniWechatProfile | null,
|
prefetched?: MiniWechatProfile | null,
|
||||||
): Promise<MiniWechatProfile | null> {
|
): Promise<MiniWechatProfile | null> {
|
||||||
if (process.env.TARO_ENV !== 'weapp') return null;
|
if (process.env.TARO_ENV !== 'weapp') return null;
|
||||||
if (!prefetched?.nickname && !prefetched?.avatarUrl) {
|
const info = prefetched?.nickname || prefetched?.avatarUrl ? prefetched : getCachedWxProfile();
|
||||||
return getCachedWxProfile();
|
if (!info?.nickname && !info?.avatarUrl) return null;
|
||||||
}
|
await uploadMiniWechatProfile(info);
|
||||||
await uploadMiniWechatProfile(prefetched);
|
return info;
|
||||||
return prefetched;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,32 @@ import { isWxAuthorizeEnabled } from '@dukang/shared-types';
|
|||||||
import { stripOAuthParamsFromLocation } from '@dukang/weixin-sdk';
|
import { stripOAuthParamsFromLocation } from '@dukang/weixin-sdk';
|
||||||
import Taro from '@tarojs/taro';
|
import Taro from '@tarojs/taro';
|
||||||
import { saveAuth } from './api';
|
import { saveAuth } from './api';
|
||||||
import { syncMiniWechatProfile } from './mini-wechat-profile';
|
import {
|
||||||
|
fetchMiniWechatUserInfo,
|
||||||
|
mergeWxDisplayProfile,
|
||||||
|
needsWxProfileFill,
|
||||||
|
syncMiniWechatProfile,
|
||||||
|
} from './mini-wechat-profile';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 兼容旧分包对资料 helper 的引用,避免 tree-shake 后出现 is not a function
|
||||||
|
*(开发者工具热更新时常见旧页 + 新 common 混用)
|
||||||
|
*/
|
||||||
|
export { fetchMiniWechatUserInfo, mergeWxDisplayProfile, needsWxProfileFill };
|
||||||
|
|
||||||
|
/** 强制保留导出绑定,防止打包器删掉未引用的 re-export */
|
||||||
|
const _wxProfileCompat = {
|
||||||
|
fetchMiniWechatUserInfo,
|
||||||
|
mergeWxDisplayProfile,
|
||||||
|
needsWxProfileFill,
|
||||||
|
};
|
||||||
|
if (
|
||||||
|
typeof _wxProfileCompat.needsWxProfileFill !== 'function' ||
|
||||||
|
typeof _wxProfileCompat.fetchMiniWechatUserInfo !== 'function' ||
|
||||||
|
typeof _wxProfileCompat.mergeWxDisplayProfile !== 'function'
|
||||||
|
) {
|
||||||
|
throw new Error('mini-wechat-profile helpers missing');
|
||||||
|
}
|
||||||
import {
|
import {
|
||||||
authorizeWechatForPay,
|
authorizeWechatForPay,
|
||||||
fetchClientConfig,
|
fetchClientConfig,
|
||||||
|
|||||||
@@ -106,14 +106,6 @@ export default function BenefitPage() {
|
|||||||
<Text>康</Text>
|
<Text>康</Text>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
<View className="benefit-hero-actions">
|
|
||||||
<Text
|
|
||||||
className="benefit-hero-link"
|
|
||||||
onClick={() => Taro.navigateTo({ url: '/pages/benefit-detail/index' })}
|
|
||||||
>
|
|
||||||
查看权益明细 ›
|
|
||||||
</Text>
|
|
||||||
</View>
|
|
||||||
<View
|
<View
|
||||||
className="benefit-hero-cta"
|
className="benefit-hero-cta"
|
||||||
onClick={() => Taro.navigateTo({ url: '/pages/redeem/index' })}
|
onClick={() => Taro.navigateTo({ url: '/pages/redeem/index' })}
|
||||||
|
|||||||
@@ -234,7 +234,7 @@ export default function LoginPage() {
|
|||||||
setSentHint('');
|
setSentHint('');
|
||||||
setWxLoading(true);
|
setWxLoading(true);
|
||||||
try {
|
try {
|
||||||
// 头像昵称改由「我的」页 chooseAvatar / nickname 填写;登录仅换 openId
|
// 登录仅绑定 openId;资料展示走账号昵称/头像
|
||||||
const wxInfo = getCachedWxProfile();
|
const wxInfo = getCachedWxProfile();
|
||||||
|
|
||||||
if (completeMode === 'wechat' && isLoggedIn()) {
|
if (completeMode === 'wechat' && isLoggedIn()) {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { View, Text, Image, Button, Input } from '@tarojs/components';
|
import { View, Text, Image } from '@tarojs/components';
|
||||||
import Taro, { useDidShow } from '@tarojs/taro';
|
import Taro, { useDidShow } from '@tarojs/taro';
|
||||||
import { isWxAuthorizeEnabled, type ClientRuntimeConfig } from '@dukang/shared-types';
|
import { isWxAuthorizeEnabled, type ClientRuntimeConfig } from '@dukang/shared-types';
|
||||||
import PageShell from '../../components/PageShell';
|
import PageShell from '../../components/PageShell';
|
||||||
@@ -8,12 +8,10 @@ import UserTabBar, { shouldRenderPageTabBar, syncTabBarSelected } from '../../co
|
|||||||
import { BRAND_LOGO_MARK_URL } from '@dukang/shared-types';
|
import { BRAND_LOGO_MARK_URL } from '@dukang/shared-types';
|
||||||
import { goLogin } from '../../lib/auth-nav';
|
import { goLogin } from '../../lib/auth-nav';
|
||||||
import { bindWechatForUser } from '../../lib/wechat-auth';
|
import { bindWechatForUser } from '../../lib/wechat-auth';
|
||||||
import { fetchUserProfile } from '../../lib/pay-wechat';
|
|
||||||
import {
|
import {
|
||||||
|
fetchMiniWechatUserInfo,
|
||||||
mergeWxDisplayProfile,
|
mergeWxDisplayProfile,
|
||||||
needsWxProfileFill,
|
needsWxProfileFill,
|
||||||
uploadAvatarTempFile,
|
|
||||||
uploadMiniWechatProfile,
|
|
||||||
} from '../../lib/mini-wechat-profile';
|
} from '../../lib/mini-wechat-profile';
|
||||||
import { isLoggedIn, logout, request, toast, type UserProfile } from '../../lib/api';
|
import { isLoggedIn, logout, request, toast, type UserProfile } from '../../lib/api';
|
||||||
import { isWechatEnv } from '../../lib/weixin';
|
import { isWechatEnv } from '../../lib/weixin';
|
||||||
@@ -44,30 +42,15 @@ export default function MinePage() {
|
|||||||
const [orderCounts, setOrderCounts] = useState<Record<string, number>>({});
|
const [orderCounts, setOrderCounts] = useState<Record<string, number>>({});
|
||||||
const [wxAuthorize, setWxAuthorize] = useState(true);
|
const [wxAuthorize, setWxAuthorize] = useState(true);
|
||||||
const [bindingWx, setBindingWx] = useState(false);
|
const [bindingWx, setBindingWx] = useState(false);
|
||||||
const [savingProfile, setSavingProfile] = useState(false);
|
|
||||||
const [editingProfile, setEditingProfile] = useState(false);
|
|
||||||
const [draftNickname, setDraftNickname] = useState('');
|
|
||||||
|
|
||||||
function resetGuestState() {
|
function resetGuestState() {
|
||||||
setProfile(null);
|
setProfile(null);
|
||||||
setBenefitBalance(0);
|
setBenefitBalance(0);
|
||||||
setOrderCounts({});
|
setOrderCounts({});
|
||||||
setDraftNickname('');
|
|
||||||
setEditingProfile(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function applyProfile(me: UserProfile) {
|
function applyProfile(me: UserProfile) {
|
||||||
const merged = mergeWxDisplayProfile(me);
|
setProfile(mergeWxDisplayProfile(me));
|
||||||
setProfile(merged);
|
|
||||||
if (!needsWxProfileFill(merged)) {
|
|
||||||
setDraftNickname(merged.nickname || '');
|
|
||||||
setEditingProfile(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// 缺头像但有真实昵称时预填
|
|
||||||
if (merged.nickname && !/^用户\d{4}$/.test(merged.nickname) && merged.nickname !== '微信用户') {
|
|
||||||
setDraftNickname(merged.nickname);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadProfile() {
|
function loadProfile() {
|
||||||
@@ -159,83 +142,13 @@ export default function MinePage() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function persistProfile(patch: { nickname?: string; avatarUrl?: string }, opts?: { silent?: boolean }) {
|
/** 未绑定微信时点击头像走授权(小程序 openId / H5 公众号 OAuth) */
|
||||||
setSavingProfile(true);
|
async function handleAvatarTap() {
|
||||||
try {
|
|
||||||
const bound = await ensureWechatBound();
|
|
||||||
if (!bound) return false;
|
|
||||||
const updated = await uploadMiniWechatProfile(patch);
|
|
||||||
if (updated) {
|
|
||||||
applyProfile(updated);
|
|
||||||
} else {
|
|
||||||
const me = await fetchUserProfile();
|
|
||||||
applyProfile(me);
|
|
||||||
}
|
|
||||||
if (!opts?.silent) toast('资料已更新', 'success');
|
|
||||||
return true;
|
|
||||||
} catch (e) {
|
|
||||||
toast(e instanceof Error ? e.message : '保存失败');
|
|
||||||
return false;
|
|
||||||
} finally {
|
|
||||||
setSavingProfile(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function handleChooseAvatar(e: { detail?: { avatarUrl?: string } }) {
|
|
||||||
const tempPath = e.detail?.avatarUrl?.trim();
|
|
||||||
if (!tempPath) {
|
|
||||||
toast('未获取到头像');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!isLoggedIn()) {
|
if (!isLoggedIn()) {
|
||||||
goLogin('/pages/mine/index');
|
goLogin('/pages/mine/index');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
if (profile?.hasWechat) return;
|
||||||
setSavingProfile(true);
|
|
||||||
const bound = await ensureWechatBound();
|
|
||||||
if (!bound) return;
|
|
||||||
const url = await uploadAvatarTempFile(tempPath);
|
|
||||||
setProfile((prev) =>
|
|
||||||
prev
|
|
||||||
? mergeWxDisplayProfile({ ...prev, hasWechat: true, avatarUrl: url })
|
|
||||||
: { id: '', hasWechat: true, avatarUrl: url, nickname: draftNickname || null },
|
|
||||||
);
|
|
||||||
setSavingProfile(false);
|
|
||||||
const ok = await persistProfile(
|
|
||||||
{
|
|
||||||
avatarUrl: url,
|
|
||||||
nickname: draftNickname.trim() || undefined,
|
|
||||||
},
|
|
||||||
{ silent: true },
|
|
||||||
);
|
|
||||||
if (ok) toast('头像已更新', 'success');
|
|
||||||
} catch (err) {
|
|
||||||
toast(err instanceof Error ? err.message : '头像更新失败');
|
|
||||||
setSavingProfile(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function handleNicknameConfirm() {
|
|
||||||
const nickname = draftNickname.trim();
|
|
||||||
if (!nickname) {
|
|
||||||
toast('请填写微信昵称');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!isLoggedIn()) {
|
|
||||||
goLogin('/pages/mine/index');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
await persistProfile({ nickname });
|
|
||||||
}
|
|
||||||
|
|
||||||
/** H5:点击头像走公众号 OAuth */
|
|
||||||
async function handleH5AvatarTap() {
|
|
||||||
if (!isLoggedIn()) {
|
|
||||||
goLogin('/pages/mine/index');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (profile?.hasWechat && !needsWxProfileFill(profile)) return;
|
|
||||||
await ensureWechatBound();
|
await ensureWechatBound();
|
||||||
loadProfile();
|
loadProfile();
|
||||||
}
|
}
|
||||||
@@ -291,19 +204,17 @@ export default function MinePage() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const hasWechat = !!profile?.hasWechat;
|
const hasWechat = !!profile?.hasWechat;
|
||||||
const needFill = needsWxProfileFill(profile) || editingProfile;
|
const canWxAuth = wxAuthorize && (isWeapp || isWechatEnv());
|
||||||
const canWxProfile = wxAuthorize && isWeapp;
|
|
||||||
const display = mergeWxDisplayProfile(
|
const display = mergeWxDisplayProfile(
|
||||||
profile || { id: '', nickname: null, avatarUrl: null, hasWechat: false },
|
profile || { id: '', nickname: null, avatarUrl: null, hasWechat: false },
|
||||||
);
|
);
|
||||||
|
// 强制保留 common 导出,避免开发者工具「旧页 + 新 common」混用时报 is not a function
|
||||||
|
if (typeof needsWxProfileFill !== 'function' || typeof fetchMiniWechatUserInfo !== 'function') {
|
||||||
|
throw new Error('wx profile helpers missing');
|
||||||
|
}
|
||||||
const nickname = display.nickname || '用户';
|
const nickname = display.nickname || '用户';
|
||||||
const memberLabel = hasWechat
|
const memberLabel = hasWechat ? '好客会员' : canWxAuth ? '微信未授权' : '未授权微信';
|
||||||
? needFill
|
void needsWxProfileFill(display);
|
||||||
? '完善头像昵称'
|
|
||||||
: '好客会员'
|
|
||||||
: canWxProfile
|
|
||||||
? '微信未授权'
|
|
||||||
: '未授权微信';
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PageShell variant="tab" className="mine-page no-tab-header">
|
<PageShell variant="tab" className="mine-page no-tab-header">
|
||||||
@@ -311,77 +222,27 @@ export default function MinePage() {
|
|||||||
<View className="mine-header">
|
<View className="mine-header">
|
||||||
<View className="mine-header-texture" />
|
<View className="mine-header-texture" />
|
||||||
<View className="mine-profile">
|
<View className="mine-profile">
|
||||||
{canWxProfile ? (
|
|
||||||
<Button
|
|
||||||
className="mine-avatar-btn"
|
|
||||||
openType="chooseAvatar"
|
|
||||||
onChooseAvatar={(e) => void handleChooseAvatar(e)}
|
|
||||||
disabled={bindingWx || savingProfile}
|
|
||||||
>
|
|
||||||
<View
|
<View
|
||||||
className={`mine-avatar${hasWechat && !needFill ? ' mine-avatar--wx-ok' : ' mine-avatar--wx-pending'}`}
|
className={`mine-avatar-wrap${!hasWechat && canWxAuth ? ' mine-avatar-wrap--action' : ''}`}
|
||||||
>
|
onClick={!hasWechat && canWxAuth ? () => void handleAvatarTap() : undefined}
|
||||||
{renderAvatarContent(display.avatarUrl)}
|
|
||||||
</View>
|
|
||||||
{needFill || !hasWechat ? (
|
|
||||||
<View className="mine-avatar-status mine-avatar-status--pending">
|
|
||||||
<Text>{bindingWx || savingProfile ? '处理中' : hasWechat ? '选头像' : '去授权'}</Text>
|
|
||||||
</View>
|
|
||||||
) : null}
|
|
||||||
</Button>
|
|
||||||
) : (
|
|
||||||
<View
|
|
||||||
className={`mine-avatar-wrap${!hasWechat ? ' mine-avatar-wrap--action' : ''}`}
|
|
||||||
onClick={() => void handleH5AvatarTap()}
|
|
||||||
>
|
>
|
||||||
<View
|
<View
|
||||||
className={`mine-avatar${hasWechat ? ' mine-avatar--wx-ok' : ' mine-avatar--wx-pending'}`}
|
className={`mine-avatar${hasWechat ? ' mine-avatar--wx-ok' : ' mine-avatar--wx-pending'}`}
|
||||||
>
|
>
|
||||||
{renderAvatarContent(display.avatarUrl)}
|
{renderAvatarContent(display.avatarUrl)}
|
||||||
</View>
|
</View>
|
||||||
{!hasWechat ? (
|
{!hasWechat && canWxAuth ? (
|
||||||
<View className="mine-avatar-status mine-avatar-status--pending">
|
<View className="mine-avatar-status mine-avatar-status--pending">
|
||||||
<Text>{bindingWx ? '授权中' : '去授权'}</Text>
|
<Text>{bindingWx ? '授权中' : '去授权'}</Text>
|
||||||
</View>
|
</View>
|
||||||
) : null}
|
) : null}
|
||||||
</View>
|
</View>
|
||||||
)}
|
|
||||||
|
|
||||||
<View className="mine-profile-meta">
|
<View className="mine-profile-meta">
|
||||||
{canWxProfile && needFill ? (
|
|
||||||
<>
|
|
||||||
<Input
|
|
||||||
className="mine-nickname-input"
|
|
||||||
type="nickname"
|
|
||||||
value={draftNickname}
|
|
||||||
placeholder="点击填写微信昵称"
|
|
||||||
maxlength={32}
|
|
||||||
onInput={(e) => setDraftNickname(e.detail.value)}
|
|
||||||
onBlur={() => void handleNicknameConfirm()}
|
|
||||||
onConfirm={() => void handleNicknameConfirm()}
|
|
||||||
/>
|
|
||||||
<Text className="mine-member-tag">{memberLabel}</Text>
|
|
||||||
<Text className="mine-wechat-hint">点击头像选微信头像,并填写昵称</Text>
|
|
||||||
</>
|
|
||||||
) : (
|
|
||||||
<>
|
|
||||||
<Text className="mine-profile-name">{nickname}</Text>
|
<Text className="mine-profile-name">{nickname}</Text>
|
||||||
<Text className={`mine-member-tag${hasWechat && !needFill ? ' mine-member-tag--wechat' : ''}`}>
|
<Text className={`mine-member-tag${hasWechat ? ' mine-member-tag--wechat' : ''}`}>
|
||||||
{memberLabel}
|
{memberLabel}
|
||||||
</Text>
|
</Text>
|
||||||
{canWxProfile ? (
|
|
||||||
<Text
|
|
||||||
className="mine-wechat-hint mine-wechat-hint--link"
|
|
||||||
onClick={() => {
|
|
||||||
setDraftNickname(needsWxProfileFill(profile) ? '' : nickname);
|
|
||||||
setEditingProfile(true);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
更新头像昵称
|
|
||||||
</Text>
|
|
||||||
) : null}
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
|
|||||||
@@ -101,8 +101,10 @@ export default function RedeemPage() {
|
|||||||
className="redeem-input"
|
className="redeem-input"
|
||||||
type="digit"
|
type="digit"
|
||||||
placeholder="输入核销金额"
|
placeholder="输入核销金额"
|
||||||
|
placeholderClass="redeem-input-placeholder"
|
||||||
value={amount}
|
value={amount}
|
||||||
onInput={(e) => setAmount(e.detail.value)}
|
onInput={(e) => setAmount(e.detail.value)}
|
||||||
|
style={{ textAlign: 'center' }}
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
<View className="redeem-amount-foot">
|
<View className="redeem-amount-foot">
|
||||||
|
|||||||
@@ -120,19 +120,7 @@
|
|||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.benefit-hero-actions {
|
|
||||||
display: flex;
|
|
||||||
margin-top: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.benefit-hero-link {
|
|
||||||
font-size: 13px;
|
|
||||||
color: var(--color-heritage-red);
|
|
||||||
margin-right: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.benefit-hero-cta {
|
.benefit-hero-cta {
|
||||||
flex: 1;
|
|
||||||
height: 44px;
|
height: 44px;
|
||||||
border-radius: var(--radius-full);
|
border-radius: var(--radius-full);
|
||||||
background: var(--color-heritage-red);
|
background: var(--color-heritage-red);
|
||||||
|
|||||||
@@ -46,42 +46,11 @@
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 小程序 chooseAvatar:去掉 Button 默认样式,保留圆形头像 */
|
|
||||||
.mine-avatar-btn {
|
|
||||||
position: relative;
|
|
||||||
flex-shrink: 0;
|
|
||||||
margin: 0 12px 0 0 !important;
|
|
||||||
padding: 0 !important;
|
|
||||||
background: transparent !important;
|
|
||||||
border: none !important;
|
|
||||||
border-radius: 0 !important;
|
|
||||||
line-height: 1 !important;
|
|
||||||
overflow: visible !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mine-avatar-btn::after {
|
|
||||||
border: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mine-profile-meta {
|
.mine-profile-meta {
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mine-nickname-input {
|
|
||||||
width: 100%;
|
|
||||||
max-width: 200px;
|
|
||||||
height: 32px;
|
|
||||||
padding: 0 10px;
|
|
||||||
margin-bottom: 4px;
|
|
||||||
border-radius: 8px;
|
|
||||||
background: rgba(255, 255, 255, 0.95);
|
|
||||||
color: var(--color-ink-black);
|
|
||||||
font-size: 15px;
|
|
||||||
font-weight: 600;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mine-avatar-status {
|
.mine-avatar-status {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 50%;
|
left: 50%;
|
||||||
@@ -122,18 +91,6 @@
|
|||||||
background: rgba(255, 255, 255, 0.25);
|
background: rgba(255, 255, 255, 0.25);
|
||||||
}
|
}
|
||||||
|
|
||||||
.mine-wechat-hint {
|
|
||||||
display: block;
|
|
||||||
margin-top: 4px;
|
|
||||||
font-size: 10px;
|
|
||||||
color: rgba(255, 255, 255, 0.75);
|
|
||||||
}
|
|
||||||
|
|
||||||
.mine-wechat-hint--link {
|
|
||||||
text-decoration: underline;
|
|
||||||
text-underline-offset: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mine-avatar {
|
.mine-avatar {
|
||||||
width: 64px;
|
width: 64px;
|
||||||
height: 64px;
|
height: 64px;
|
||||||
|
|||||||
@@ -47,16 +47,20 @@
|
|||||||
color: var(--color-heritage-red);
|
color: var(--color-heritage-red);
|
||||||
text-align: center;
|
text-align: center;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.redeem-input-placeholder {
|
||||||
|
color: var(--color-subtle-gray);
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 小程序原生 input:text-align 需落到组件自身与内部节点 */
|
||||||
|
.redeem-input,
|
||||||
.redeem-input input,
|
.redeem-input input,
|
||||||
.redeem-input .taro-input,
|
.redeem-input .taro-input,
|
||||||
.redeem-input .weui-input {
|
.redeem-input .weui-input {
|
||||||
width: 100% !important;
|
width: 100% !important;
|
||||||
height: 100% !important;
|
height: 52px !important;
|
||||||
min-height: 0 !important;
|
min-height: 0 !important;
|
||||||
padding: 0 !important;
|
padding: 0 !important;
|
||||||
margin: 0 !important;
|
margin: 0 !important;
|
||||||
@@ -65,8 +69,8 @@
|
|||||||
box-sizing: border-box !important;
|
box-sizing: border-box !important;
|
||||||
font-size: 24px !important;
|
font-size: 24px !important;
|
||||||
font-weight: 700 !important;
|
font-weight: 700 !important;
|
||||||
line-height: normal !important;
|
line-height: 52px !important;
|
||||||
color: inherit;
|
color: var(--color-heritage-red);
|
||||||
text-align: center !important;
|
text-align: center !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user