From f0d8f6bac4b720e7635284cea115b4cb17b83fcf Mon Sep 17 00:00:00 2001
From: liu <2302563948@qq.com>
Date: Fri, 21 Aug 2026 11:01:37 +0800
Subject: [PATCH] =?UTF-8?q?=E8=B4=A6=E6=88=B7=E5=AF=86=E7=A0=81=E7=99=BB?=
=?UTF-8?q?=E5=BD=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/app.config.ts | 2 +-
src/pages/change-password/index.config.ts | 3 +
src/pages/change-password/index.less | 48 +++++
src/pages/change-password/index.tsx | 111 +++++++++++
src/pages/login/index.less | 55 ++++--
src/pages/login/index.tsx | 104 +++++-----
src/pages/profile/index.tsx | 43 ++---
src/pages/register/index.config.ts | 4 -
src/pages/register/index.less | 196 -------------------
src/pages/register/index.tsx | 222 ----------------------
src/services/auth.ts | 51 ++---
src/stores/auth/useAuthStore.ts | 27 +--
src/types/user.ts | 61 ++----
13 files changed, 328 insertions(+), 599 deletions(-)
create mode 100644 src/pages/change-password/index.config.ts
create mode 100644 src/pages/change-password/index.less
create mode 100644 src/pages/change-password/index.tsx
delete mode 100644 src/pages/register/index.config.ts
delete mode 100644 src/pages/register/index.less
delete mode 100644 src/pages/register/index.tsx
diff --git a/src/app.config.ts b/src/app.config.ts
index 10b4f41..422e995 100644
--- a/src/app.config.ts
+++ b/src/app.config.ts
@@ -14,7 +14,7 @@ export default defineAppConfig({
'pages/payment-detail/index',
'pages/settings/index',
'pages/login/index',
- 'pages/register/index',
+ 'pages/change-password/index',
'pages/store-info/index',
],
window: {
diff --git a/src/pages/change-password/index.config.ts b/src/pages/change-password/index.config.ts
new file mode 100644
index 0000000..96fdbcc
--- /dev/null
+++ b/src/pages/change-password/index.config.ts
@@ -0,0 +1,3 @@
+export default definePageConfig({
+ navigationBarTitleText: '修改密码',
+})
diff --git a/src/pages/change-password/index.less b/src/pages/change-password/index.less
new file mode 100644
index 0000000..15d24d2
--- /dev/null
+++ b/src/pages/change-password/index.less
@@ -0,0 +1,48 @@
+.change-password-page {
+ min-height: 100vh;
+ background: #f7f8fa;
+ padding: 20rpx 24rpx 60rpx;
+ box-sizing: border-box;
+
+ // ===== 表单区块 =====
+ .pwd-section {
+ background: #fff;
+ border-radius: 20rpx;
+ padding: 8rpx 28rpx;
+ margin-bottom: 20rpx;
+ }
+
+ // ===== 表单行 =====
+ .pwd-field {
+ display: flex;
+ align-items: center;
+ padding: 28rpx 0;
+ border-bottom: 1rpx solid #f2f3f5;
+
+ &:last-child {
+ border-bottom: none;
+ }
+
+ &__label {
+ width: 160rpx;
+ flex-shrink: 0;
+ font-size: 28rpx;
+ color: #323233;
+ }
+
+ &__input {
+ flex: 1;
+ font-size: 28rpx;
+ color: #323233;
+ }
+
+ &__placeholder {
+ color: #c8c9cc;
+ }
+ }
+
+ // ===== 提交按钮 =====
+ .pwd-submit {
+ margin-top: 40rpx;
+ }
+}
diff --git a/src/pages/change-password/index.tsx b/src/pages/change-password/index.tsx
new file mode 100644
index 0000000..92cbdfc
--- /dev/null
+++ b/src/pages/change-password/index.tsx
@@ -0,0 +1,111 @@
+import { useCallback, useState } from 'react'
+import Taro from '@tarojs/taro'
+import { View, Text, Input } from '@tarojs/components'
+import { Button } from '@antmjs/vantui'
+import { changePasswordApi } from '@/services/auth'
+import './index.less'
+
+/** 新密码长度限制(与后端一致:6~20 位) */
+const LIMITS = {
+ passwordMin: 6,
+ passwordMax: 20,
+} as const
+
+/**
+ * 修改密码页
+ * 修改成功后现有 token 仍然有效,无需重新登录
+ */
+export default function ChangePasswordPage() {
+ /** 原密码 */
+ const [oldPassword, setOldPassword] = useState('')
+ /** 新密码 */
+ const [newPassword, setNewPassword] = useState('')
+ /** 确认新密码 */
+ const [rePassword, setRePassword] = useState('')
+ const [saving, setSaving] = useState(false)
+
+ /** 提交:PUT /mini/auth/password */
+ const handleSubmit = useCallback(async () => {
+ if (saving) return
+ if (!oldPassword) {
+ Taro.showToast({ title: '请输入原密码', icon: 'none' })
+ return
+ }
+ if (newPassword.length < LIMITS.passwordMin) {
+ Taro.showToast({ title: `新密码至少 ${LIMITS.passwordMin} 位`, icon: 'none' })
+ return
+ }
+ if (newPassword !== rePassword) {
+ Taro.showToast({ title: '两次输入的密码不一致', icon: 'none' })
+ return
+ }
+ setSaving(true)
+ try {
+ await changePasswordApi({ oldPassword, newPassword, rePassword })
+ Taro.showToast({ title: '密码修改成功', icon: 'success' })
+ setTimeout(() => Taro.navigateBack(), 800)
+ } catch {
+ // 错误提示已由 request 层 toast(原密码不正确等)
+ } finally {
+ setSaving(false)
+ }
+ }, [saving, oldPassword, newPassword, rePassword])
+
+ return (
+
+ {/* ========== 密码表单 ========== */}
+
+
+ 原密码
+ setOldPassword(e.detail.value)}
+ />
+
+
+ 新密码
+ setNewPassword(e.detail.value)}
+ />
+
+
+ 确认新密码
+ setRePassword(e.detail.value)}
+ onConfirm={handleSubmit}
+ />
+
+
+
+ {/* ========== 提交 ========== */}
+
+
+ )
+}
diff --git a/src/pages/login/index.less b/src/pages/login/index.less
index 50befb1..b64fb01 100644
--- a/src/pages/login/index.less
+++ b/src/pages/login/index.less
@@ -100,17 +100,44 @@
}
}
-/* ========== 功能介绍 ========== */
-.login-features {
- margin-bottom: 80px;
+/* ========== 登录表单 ========== */
+.login-form {
+ width: 100%;
+ background: #f7f8fa;
+ border-radius: 24px;
+ padding: 0 32px;
+ margin-bottom: 60px;
+}
- .feature-text {
- font-size: 26px;
- color: #c8c9cc;
- letter-spacing: 2px;
+.form-item {
+ display: flex;
+ align-items: center;
+ height: 112px;
+ border-bottom: 1px solid #ebedf0;
+
+ &:last-child {
+ border-bottom: none;
}
}
+.form-label {
+ width: 120px;
+ font-size: 30px;
+ color: #323233;
+ flex-shrink: 0;
+}
+
+.form-input {
+ flex: 1;
+ height: 100%;
+ font-size: 30px;
+ color: #323233;
+}
+
+.form-input-placeholder {
+ color: #c8c9cc;
+}
+
/* ========== 登录操作区 ========== */
.login-actions {
width: 100%;
@@ -144,23 +171,17 @@
opacity: 0.75;
}
-/* ========== 去注册入口 ========== */
-.login-switch {
+/* ========== 客服提示 ========== */
+.login-tip {
display: flex;
align-items: center;
justify-content: center;
margin-top: 32px;
- .switch-text {
- font-size: 28px;
+ .tip-text {
+ font-size: 26px;
color: #969799;
}
-
- .switch-link {
- font-size: 28px;
- color: #ee0a24;
- margin-left: 8px;
- }
}
/* ========== 协议文字 ========== */
diff --git a/src/pages/login/index.tsx b/src/pages/login/index.tsx
index 617b3e8..d2c5256 100644
--- a/src/pages/login/index.tsx
+++ b/src/pages/login/index.tsx
@@ -1,18 +1,24 @@
-import { useCallback, useEffect, useState } from 'react'
+import { useCallback, useState } from 'react'
import Taro from '@tarojs/taro'
-import { View, Text, Button } from '@tarojs/components'
+import { View, Text, Button, Input } from '@tarojs/components'
import CustomNavBar from '@/components/NavBar'
import useAuthStore from '@/stores/auth/useAuthStore'
import './index.less'
+/** 登录账号长度限制(与后端一致:4~20 位) */
+const USERNAME_MAX = 20
+/** 密码长度限制 */
+const PASSWORD_MAX = 20
+
export default function LoginPage() {
const login = useAuthStore(s => s.login)
- const isLoggedIn = useAuthStore(s => !!s.token && !!s.user)
+ /** 登录账号(商家后台分配) */
+ const [username, setUsername] = useState('')
+ /** 登录密码 */
+ const [password, setPassword] = useState('')
const [submitting, setSubmitting] = useState(false)
- const isWeb = Taro.getEnv() === Taro.ENV_TYPE.WEB
-
/** 返回上一页(无页面栈时回首页) */
const goBack = useCallback(() => {
const pages = Taro.getCurrentPages()
@@ -23,50 +29,29 @@ export default function LoginPage() {
}
}, [])
- /** 前往注册页 */
- const goRegister = useCallback(() => {
- Taro.navigateTo({ url: '/pages/register/index' })
- }, [])
-
- /** 已登录 → 自动返回 */
- useEffect(() => {
- if (isLoggedIn) goBack()
- }, [isLoggedIn, goBack])
-
- /** 微信一键登录(wx.login code 换 openid,仅已注册用户可登录) */
+ /** 账号密码登录:POST /mini/auth/login */
const handleLogin = useCallback(async () => {
if (submitting) return
- // H5 环境无法获取微信登录凭证
- if (isWeb) {
- Taro.showToast({ title: '请在微信小程序中使用微信登录', icon: 'none' })
+ const account = username.trim()
+ if (!account) {
+ Taro.showToast({ title: '请输入登录账号', icon: 'none' })
+ return
+ }
+ if (!password) {
+ Taro.showToast({ title: '请输入登录密码', icon: 'none' })
return
}
setSubmitting(true)
try {
- const res = await Taro.login()
- if (!res.code) {
- Taro.showToast({ title: '获取登录凭证失败', icon: 'none' })
- return
- }
- await login({ code: res.code })
- // 登录成功后由 effect 自动返回
- } catch (e: any) {
- // 未注册用户:引导前往注册页(其余错误已由 request 层提示)
- if (typeof e?.msg === 'string' && e.msg.includes('用户不存在')) {
- Taro.showModal({
- title: '未注册',
- content: '该微信账号尚未注册,需授权手机号并填写门店编码完成注册',
- confirmText: '去注册',
- cancelText: '取消',
- success: res => {
- if (res.confirm) goRegister()
- },
- })
- }
+ await login({ username: account, password })
+ Taro.showToast({ title: '登录成功', icon: 'success' })
+ goBack()
+ } catch {
+ // 错误提示已由 request 层 toast(账号或密码错误 / 账号已停用等)
} finally {
setSubmitting(false)
}
- }, [login, submitting, isWeb, goRegister])
+ }, [login, submitting, username, password, goBack])
/** 查看用户协议 */
const handleShowAgreement = useCallback(() => {
@@ -94,9 +79,34 @@ export default function LoginPage() {
门店订货 · 对账结算 · 一站式采购
- {/* 功能介绍 */}
-
- 在线订货 · 价格透明 · 周期对账
+ {/* 登录表单 */}
+
+
+ 账号
+ setUsername(e.detail.value)}
+ />
+
+
+ 密码
+ setPassword(e.detail.value)}
+ onConfirm={handleLogin}
+ />
+
{/* 登录操作 */}
@@ -107,13 +117,11 @@ export default function LoginPage() {
loading={submitting}
disabled={submitting}
>
- {submitting ? '登录中...' : '微信一键登录'}
+ {submitting ? '登录中...' : '登 录'}
- {/* 未注册用户入口 */}
-
- 还没有账号?
- 立即注册
+
+ 账号密码由商家分配,如需帮助请联系客服
diff --git a/src/pages/profile/index.tsx b/src/pages/profile/index.tsx
index 945d28c..eefe04d 100644
--- a/src/pages/profile/index.tsx
+++ b/src/pages/profile/index.tsx
@@ -8,7 +8,6 @@ import { getBillListApi } from '@/services/bill'
import type { BillSummary } from '@/services/bill'
import { ORDER_NAV_ITEMS } from '@/types/order'
import { resolveAvatarUrl } from '@/utils/format'
-import type { UserType } from '@/types/user'
import './index.less'
/** 菜单项(订单/账单入口已由上方专区承载,后续单独页面开发时在此追加) */
@@ -38,9 +37,9 @@ export default function ProfilePage() {
const loggedIn = !!token && !!user
- /** 功能菜单(门店账号追加「门店信息」「支付记录」入口) */
+ /** 功能菜单(登录门店可用:门店信息 / 支付记录 / 修改密码) */
const menuItems = useMemo(() => {
- if (!user?.store) return MENU_ITEMS
+ if (!loggedIn) return MENU_ITEMS
return [
{
key: 'store-info',
@@ -54,9 +53,15 @@ export default function ProfilePage() {
icon: 'balance-o',
onClick: () => Taro.navigateTo({ url: '/pages/payment-records/index' }),
},
+ {
+ key: 'change-password',
+ label: '修改密码',
+ icon: 'lock',
+ onClick: () => Taro.navigateTo({ url: '/pages/change-password/index' }),
+ },
...MENU_ITEMS,
]
- }, [user?.store])
+ }, [loggedIn])
useDidShow(() => {
if (!loggedIn) return
@@ -70,13 +75,6 @@ export default function ProfilePage() {
.catch(() => {})
})
- /** 身份标签 */
- const getTypeLabel = useCallback((type: UserType): string => {
- if (type === 1) return '门店'
- if (type === 2) return '供应商'
- return '待绑定'
- }, [])
-
/** 订单总汇 → 订单列表页(按状态) */
const handleOrderNav = useCallback((status?: number) => {
Taro.navigateTo({ url: `/pages/order-list/index?status=${status ?? 'all'}` })
@@ -130,29 +128,18 @@ export default function ProfilePage() {
/>
) : (
- {user?.nickname?.[0] || '用'}
+ {user?.name?.[0] || '店'}
)}
- {user?.nickname}
- {user?.phone || '未绑定手机号'}
+ {user?.name}
+ {user?.phone || '未设置联系电话'}
- {user?.type === 0 && (
- 绑定手机号
- )}
- {user?.store ? (
- <>
- 门店 · {user.store.name}
- {user.store.level && (
- {user.store.level.name}
- )}
- >
- ) : user?.supplier ? (
- 供应商 · {user.supplier.name}
- ) : (
- {getTypeLabel(user?.type ?? 0)},联系客服或绑定手机号
+ 门店编码 · {user?.code}
+ {user?.level && (
+ {user.level.name}
)}
>
diff --git a/src/pages/register/index.config.ts b/src/pages/register/index.config.ts
deleted file mode 100644
index 0a728e8..0000000
--- a/src/pages/register/index.config.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-export default definePageConfig({
- navigationStyle: 'custom',
- navigationBarTitleText: '注册',
-})
diff --git a/src/pages/register/index.less b/src/pages/register/index.less
deleted file mode 100644
index 2058bbc..0000000
--- a/src/pages/register/index.less
+++ /dev/null
@@ -1,196 +0,0 @@
-/* ========================================
- 注册页面
- ======================================== */
-
-.register-page {
- min-height: 100vh;
- background: #fff;
-}
-
-/* ========== 内容区域 ========== */
-.register-content {
- display: flex;
- flex-direction: column;
- align-items: center;
- padding: 80px 60px 0;
-}
-
-/* ========== 品牌区域 ========== */
-.register-brand {
- display: flex;
- flex-direction: column;
- align-items: center;
- margin-bottom: 60px;
-
- .logo-wrapper {
- width: 160px;
- height: 160px;
- border-radius: 50%;
- background: linear-gradient(160deg, #ee0a24 0%, #ff4d4f 100%);
- display: flex;
- align-items: center;
- justify-content: center;
- margin-bottom: 24px;
- box-shadow: 0 8px 32px rgba(238, 10, 36, 0.3);
- }
-
- .logo-text {
- font-size: 80px;
- color: #fff;
- font-weight: 700;
- }
-
- .app-name {
- font-size: 44px;
- font-weight: 600;
- color: #323233;
- margin-bottom: 12px;
- }
-
- .app-slogan {
- font-size: 28px;
- color: #969799;
- }
-}
-
-/* ========== 注册表单 ========== */
-.register-form {
- width: 100%;
- background: #f7f8fa;
- border-radius: 24px;
- padding: 0 32px;
- margin-bottom: 80px;
-}
-
-.form-item {
- display: flex;
- align-items: center;
- height: 112px;
- border-bottom: 1px solid #ebedf0;
-
- &:last-child {
- border-bottom: none;
- }
-}
-
-.form-label {
- width: 160px;
- font-size: 30px;
- color: #323233;
- flex-shrink: 0;
-}
-
-.form-input {
- flex: 1;
- height: 100%;
- font-size: 30px;
- color: #323233;
-}
-
-.form-input-placeholder {
- color: #c8c9cc;
-}
-
-/* 手机号已授权状态 */
-.form-phone-ok {
- flex: 1;
- display: flex;
- align-items: center;
-
- .form-phone-ok__text {
- font-size: 30px;
- color: #07c160;
- }
-}
-
-/* 手机号授权按钮(微信原生 Button 需重置样式) */
-.phone-auth-btn {
- flex: 1;
- height: 64px;
- line-height: 64px;
- background: #fff0f0;
- color: #ee0a24;
- font-size: 28px;
- font-weight: 500;
- border: none;
- border-radius: 32px;
- text-align: center;
- padding: 0 32px;
-
- /* 重置微信 Button 默认样式 */
- &::after {
- border: none;
- }
-}
-
-/* ========== 注册操作区 ========== */
-.register-actions {
- width: 100%;
- display: flex;
- flex-direction: column;
- align-items: center;
-}
-
-.register-btn {
- width: 100%;
- height: 96px;
- line-height: 96px;
- background: linear-gradient(160deg, #ee0a24 0%, #ff4d4f 100%);
- color: #fff;
- font-size: 34px;
- font-weight: 500;
- border: none;
- border-radius: 48px;
- text-align: center;
- padding: 0;
- box-shadow: 0 6px 24px rgba(238, 10, 36, 0.35);
- transition: opacity 0.2s;
-
- /* 重置微信 Button 默认样式 */
- &::after {
- border: none;
- }
-}
-
-.register-btn--loading {
- opacity: 0.75;
-}
-
-/* ========== 去登录入口 ========== */
-.register-switch {
- display: flex;
- align-items: center;
- justify-content: center;
- margin-top: 32px;
-
- .switch-text {
- font-size: 28px;
- color: #969799;
- }
-
- .switch-link {
- font-size: 28px;
- color: #ee0a24;
- margin-left: 8px;
- }
-}
-
-/* ========== 协议文字 ========== */
-.register-agreement {
- display: flex;
- align-items: center;
- justify-content: center;
- flex-wrap: wrap;
- margin-top: 32px;
- line-height: 1.6;
-
- .agree-text {
- font-size: 24px;
- color: #c8c9cc;
- }
-
- .agree-link {
- font-size: 24px;
- color: #ee0a24;
- }
-}
diff --git a/src/pages/register/index.tsx b/src/pages/register/index.tsx
deleted file mode 100644
index 08d4b79..0000000
--- a/src/pages/register/index.tsx
+++ /dev/null
@@ -1,222 +0,0 @@
-import { useCallback, useEffect, useState } from 'react'
-import Taro from '@tarojs/taro'
-import { View, Text, Button, Input } from '@tarojs/components'
-import CustomNavBar from '@/components/NavBar'
-import useAuthStore from '@/stores/auth/useAuthStore'
-import './index.less'
-
-export default function RegisterPage() {
- const register = useAuthStore(s => s.register)
- const isLoggedIn = useAuthStore(s => !!s.token && !!s.user)
-
- /** 门店编码(后台门店管理维护) */
- const [storeCode, setStoreCode] = useState('')
- /** 微信手机号授权得到的 code */
- const [phoneCode, setPhoneCode] = useState('')
- const [submitting, setSubmitting] = useState(false)
-
- const isWeb = Taro.getEnv() === Taro.ENV_TYPE.WEB
-
- /** 返回上一页(无页面栈时回首页) */
- const goBack = useCallback(() => {
- const pages = Taro.getCurrentPages()
- if (pages.length > 1) {
- Taro.navigateBack()
- } else {
- Taro.switchTab({ url: '/pages/index/index' })
- }
- }, [])
-
- /** 前往登录页 */
- const goLogin = useCallback(() => {
- const pages = Taro.getCurrentPages()
- if (pages.length > 1) {
- Taro.navigateBack()
- } else {
- Taro.navigateTo({ url: '/pages/login/index' })
- }
- }, [])
-
- /** 已注册成功(登录态就绪)→ 自动返回 */
- useEffect(() => {
- if (isLoggedIn) goBack()
- }, [isLoggedIn, goBack])
-
- /** 发起注册:wx.login 换 code → POST /mini/auth/register */
- const doRegister = useCallback(
- async (phoneCodeValue: string) => {
- if (submitting) return
- if (isWeb) {
- Taro.showToast({ title: '请在微信小程序中注册', icon: 'none' })
- return
- }
- const code = storeCode.trim()
- if (!code) {
- Taro.showToast({ title: '请填写门店编码', icon: 'none' })
- return
- }
- setSubmitting(true)
- try {
- const res = await Taro.login()
- if (!res.code) {
- Taro.showToast({ title: '获取登录凭证失败', icon: 'none' })
- return
- }
- await register({ code: res.code, phoneCode: phoneCodeValue, storeCode: code })
- // 注册成功后由 effect 自动返回
- } catch (e: any) {
- // 该微信已注册:引导前往登录(其余错误已由 request 层提示)
- if (typeof e?.msg === 'string' && e.msg.includes('已经注册')) {
- Taro.showModal({
- title: '提示',
- content: '该微信已经注册,请直接登录',
- confirmText: '去登录',
- cancelText: '取消',
- success: res => {
- if (res.confirm) goLogin()
- },
- })
- }
- } finally {
- setSubmitting(false)
- }
- },
- [register, submitting, isWeb, storeCode, goLogin],
- )
-
- /** 微信手机号授权(openType getPhoneNumber) */
- const handleGetPhoneNumber = useCallback(
- (e: any) => {
- if (isWeb) {
- Taro.showToast({ title: '请在微信小程序中授权手机号', icon: 'none' })
- return
- }
- const detail = e.detail || {}
-
- // 用户拒绝授权
- if (detail.errMsg && !detail.errMsg.includes(':ok')) {
- Taro.showToast({ title: '需要授权手机号才能注册', icon: 'none' })
- return
- }
-
- if (!detail.code) {
- Taro.showToast({ title: '未获取到手机号授权凭证', icon: 'none' })
- return
- }
-
- setPhoneCode(detail.code)
- if (storeCode.trim()) {
- // 门店编码已填 → 直接发起注册
- doRegister(detail.code)
- } else {
- Taro.showToast({ title: '手机号已授权,请填写门店编码', icon: 'none' })
- }
- },
- [isWeb, storeCode, doRegister],
- )
-
- /** 点击注册按钮(门店编码已填 + 手机号已授权) */
- const handleSubmit = useCallback(() => {
- if (!phoneCode) {
- Taro.showToast({ title: '请先授权手机号', icon: 'none' })
- return
- }
- if (!storeCode.trim()) {
- Taro.showToast({ title: '请填写门店编码', icon: 'none' })
- return
- }
- doRegister(phoneCode)
- }, [phoneCode, storeCode, doRegister])
-
- /** 查看用户协议 */
- const handleShowAgreement = useCallback(() => {
- Taro.showToast({ title: '用户协议即将上线', icon: 'none' })
- }, [])
-
- /** 查看隐私政策 */
- const handleShowPrivacy = useCallback(() => {
- Taro.showToast({ title: '隐私政策即将上线', icon: 'none' })
- }, [])
-
- return (
-
- {/* ========== 导航栏 ========== */}
-
-
- {/* ========== 内容区域 ========== */}
-
- {/* 品牌区域 */}
-
-
- 订
-
- 订货采购
- 注册即绑定门店,开启订货之旅
-
-
- {/* 注册表单 */}
-
- {/* 门店编码 */}
-
- 门店编码
- setStoreCode(e.detail.value)}
- />
-
-
- {/* 手机号授权 */}
-
- 手机号
- {phoneCode ? (
-
- 已授权
-
- ) : (
-
- )}
-
-
-
- {/* 注册操作 */}
-
-
-
- {/* 已注册用户入口 */}
-
- 已有账号?
- 去登录
-
-
-
- 注册即代表同意
-
- 《用户协议》
-
- 和
-
- 《隐私政策》
-
-
-
-
-
- )
-}
diff --git a/src/services/auth.ts b/src/services/auth.ts
index 30229a1..89460ac 100644
--- a/src/services/auth.ts
+++ b/src/services/auth.ts
@@ -1,39 +1,42 @@
-import { get, post } from '@/utils/request'
+import { get, post, put } from '@/utils/request'
import type { User } from '@/types/user'
-/** 微信登录参数 */
-export interface WxLoginParams {
- /** wx.login 的临时凭证 */
- code: string
+/** 账号密码登录参数 */
+export interface LoginParams {
+ /** 登录账号(商家后台分配,4~20 位) */
+ username: string
+ /** 登录密码 */
+ password: string
}
-/** 微信注册参数 */
-export interface RegisterParams {
- /** wx.login 的临时凭证 */
- code: string
- /** wx.getPhoneNumber 授权得到的 code */
- phoneCode: string
- /** 门店编码(后台门店管理维护) */
- storeCode: string
-}
-
-/** 登录 / 注册返回 */
+/** 登录返回 */
export interface AuthResult {
token: string
+ /** 门店即用户(扁平结构) */
user: User
}
-/** 微信登录(仅已注册用户可登录):POST /mini/auth/login */
-export function wxLoginApi(params: WxLoginParams) {
+/** 修改密码参数 */
+export interface ChangePasswordParams {
+ /** 原密码 */
+ oldPassword: string
+ /** 新密码(6~20 位) */
+ newPassword: string
+ /** 确认新密码(须与 newPassword 一致) */
+ rePassword: string
+}
+
+/** 账号密码登录:POST /mini/auth/login */
+export function loginApi(params: LoginParams) {
return post('/mini/auth/login', params)
}
-/** 微信注册(code 换 openid + phoneCode 换手机号 + storeCode 绑定门店):POST /mini/auth/register */
-export function registerApi(params: RegisterParams) {
- return post('/mini/auth/register', params)
-}
-
-/** 当前用户信息(含门店客户等级):GET /mini/auth/info */
+/** 当前门店信息(含客户等级):GET /mini/auth/info */
export function getUserInfoApi() {
return get('/mini/auth/info')
}
+
+/** 修改密码(成功后现有 token 仍有效):PUT /mini/auth/password */
+export function changePasswordApi(params: ChangePasswordParams) {
+ return put('/mini/auth/password', params)
+}
diff --git a/src/stores/auth/useAuthStore.ts b/src/stores/auth/useAuthStore.ts
index 24a5d81..053f19b 100644
--- a/src/stores/auth/useAuthStore.ts
+++ b/src/stores/auth/useAuthStore.ts
@@ -1,7 +1,7 @@
import { create } from 'zustand'
import Taro from '@tarojs/taro'
-import { registerApi, wxLoginApi } from '@/services/auth'
-import type { RegisterParams, WxLoginParams } from '@/services/auth'
+import { loginApi } from '@/services/auth'
+import type { LoginParams } from '@/services/auth'
import type { User } from '@/types/user'
/** 存储 key */
@@ -26,7 +26,7 @@ function loadFromStorage(): { user: User | null; token: string | null } {
return { user: null, token: null }
}
-/** 登录 / 注册成功后持久化 token 与用户信息 */
+/** 登录成功后持久化 token 与门店信息 */
function persistAuth(token: string, user: User): void {
try {
Taro.setStorageSync(STORAGE_KEYS.TOKEN, token)
@@ -40,11 +40,10 @@ interface AuthState {
user: User | null
token: string | null
loading: boolean
- login: (params: WxLoginParams) => Promise
- /** 微信注册(手机号授权 + 门店编码绑定门店) */
- register: (params: RegisterParams) => Promise
+ /** 账号密码登录(门店账号由商家后台分配) */
+ login: (params: LoginParams) => Promise
logout: () => void
- /** 更新用户信息(用于编辑资料后同步 store) */
+ /** 更新门店信息(用于编辑资料后同步 store) */
setUser: (user: User) => void
}
@@ -57,17 +56,9 @@ const useAuthStore = create((set) => {
token: initial.token,
loading: !!(initial.token && initial.user), // 已恢复则立即 ready
- /** 登录(仅已注册用户可登录,未注册由页面引导去注册) */
- login: async (params: WxLoginParams) => {
- const res = await wxLoginApi(params)
- const { token, user } = res.data
- set({ user, token })
- persistAuth(token, user)
- },
-
- /** 注册:POST /mini/auth/register */
- register: async (params: RegisterParams) => {
- const res = await registerApi(params)
+ /** 账号密码登录:POST /mini/auth/login */
+ login: async (params: LoginParams) => {
+ const res = await loginApi(params)
const { token, user } = res.data
set({ user, token })
persistAuth(token, user)
diff --git a/src/types/user.ts b/src/types/user.ts
index 3786e9d..f638deb 100644
--- a/src/types/user.ts
+++ b/src/types/user.ts
@@ -4,54 +4,33 @@ export interface StoreLevel {
name: string
}
-/** 门店信息 */
-export interface StoreInfo {
- id: number
- name: string
- /** 客户等级(level_id > 0 才可展示价格) */
- level: StoreLevel | null
-}
-
-/** 供应商信息 */
-export interface SupplierInfo {
- id: number
- name: string
-}
-
-/** 用户类型:0 待绑定 / 1 门店 / 2 供应商 */
-export type UserType = 0 | 1 | 2
-
-export const USER_TYPE_MAP: Record = {
- 0: '待绑定',
- 1: '门店',
- 2: '供应商',
-}
-
-/** 用户信息(user 表实际返回字段) */
+/**
+ * 登录门店信息(门店即用户)
+ * 用户表与门店表已合并:登录 / auth/info 返回的 user 就是门店本身(扁平结构)
+ */
export interface User {
id: number
- /** 用户名(注册时生成 wx_xxxx) */
+ /** 门店名称 */
+ name: string
+ /** 门店编码(后台分配) */
+ code: string
+ /** 登录账号(后台分配,4~20 位) */
username: string
- /** 昵称(注册默认「微信用户」) */
- nickname: string
+ /** 头像(可能为空) */
avatar: string
- /** 手机号(未绑定为空) */
+ level_id: number
+ /** 客户等级(level_id > 0 才可展示价格) */
+ level: StoreLevel | null
+ /** 联系人 */
+ contact: string
+ /** 联系电话 */
phone: string
- /** 绑定门店ID(0 未绑定) */
- store_id: number
+ /** 地址 */
+ address: string
+ /** 回款周期天数 */
+ payment_cycle_days: number
/** 1 正常 / 0 停用 */
status: number
- /** 微信标识 */
- openid: string
- unionid: string
- email: string
last_login_at: string | null
created_at: string | null
- updated_at: string | null
- /** 兼容旧 /mini/auth/info 返回(身份类型) */
- type?: UserType
- /** 兼容旧 /mini/auth/info 返回(门店信息) */
- store?: StoreInfo | null
- /** 兼容旧 /mini/auth/info 返回(供应商信息) */
- supplier?: SupplierInfo | null
}