Browse Source

Merge branch 'cfclub' of https://git.iwintrue.com/liaoxg/cfc into cfclub

# Conflicts:
#	cfc-web/.last_build_commit
#	cfc-web/package.json
#	cfc-web/public/CHANGELOG-v1.0.md
#	cfc-web/public/CHANGELOG.md
Xiaogang Liao 1 tháng trước cách đây
mục cha
commit
eb2016b561

+ 54 - 71
cfc-frontend/pages/login/login.vue

@@ -28,13 +28,13 @@
     <!-- 手机号快捷登录 -->
     <view class="login-form">
       <view class="phone-section">
-        <button
-          class="phone-btn"
-          :loading="loading"
-          @click="handleWechatLogin"
-        >
-          <text>手机号快捷登录</text>
-        </button>
+          <button
+            class="phone-btn"
+            open-type="getPhoneNumber"
+            @getphonenumber="getPhoneNumber"
+          >
+            <text>手机号快捷登录</text>
+          </button>
       </view>
 
       <!-- 暂不登录 -->
@@ -58,7 +58,7 @@
 </template>
 
 <script>
-import { wechatLogin, checkTeamInviteStatus, joinTeamByInvite, bindReferral } from '../../utils/api.js'
+import { wechatPhoneLogin, checkTeamInviteStatus, joinTeamByInvite, bindReferral } from '../../utils/api.js'
 
 export default {
   data() {
@@ -67,7 +67,8 @@ export default {
       agreed: false,
       nickname: '',
       avatar: '',
-      redirectUrl: ''
+      redirectUrl: '',
+      loginCode: ''
     }
   },
   onLoad(options) {
@@ -80,6 +81,13 @@ export default {
     if (options.redirect) {
       this.redirectUrl = decodeURIComponent(options.redirect)
     }
+    // 预获取微信登录code(有效期5分钟,用户操作通常在时限内)
+    var self = this
+    uni.login({
+      provider: 'weixin',
+      success: function(res) { self.loginCode = res.code },
+      fail: function() {}
+    })
   },
   methods: {
     handleImageError(e) {
@@ -102,76 +110,51 @@ export default {
       // 不登录直接进入首页
       uni.switchTab({ url: '/pages/index-home/index' })
     },
-    handleWechatLogin() {
+    getPhoneNumber: function(e) {
       if (!this.agreed) {
         uni.showToast({ title: '请先同意用户协议', icon: 'none' })
         return
       }
-
-      this.loading = true
+      if (!e.detail || !e.detail.code) {
+        uni.showToast({ title: '授权失败,请重试', icon: 'none' })
+        return
+      }
       var self = this
-
-      // 超时保护:10秒强制结束登录流程,避免 uni.login 挂死时按钮 loading 卡死
-      var loginTimeout = new Promise(function(_, reject) {
-        setTimeout(function() {
-          reject(new Error('微信登录超时'))
-        }, 10000)
-      })
-
-      Promise.race([loginTimeout, new Promise(function(resolve, reject) {
-        uni.login({
-          provider: 'weixin',
-          success: function(loginRes) { resolve(loginRes) },
-          fail: function() { reject(new Error('微信登录失败')) }
-        })
-      })]).then(function(loginRes) {
-        // 静默登录:仅获取 openid,不强制索取手机号
-        wechatLogin(loginRes.code, {
-          nickname: self.nickname || '用户',
-          avatar: self.avatar || ''
-        }, '').then(function(res) {
-          // 保存 token 和用户信息(只写一次)
-          uni.setStorageSync('token', res.data.token)
-          uni.setStorageSync('userId', res.data.userId)
-          uni.setStorageSync('role', res.data.role)
-          uni.setStorageSync('currentRole', res.data.role)
-          uni.setStorageSync('isSwitchedChild', false)
-          uni.setStorageSync('isSwitchedTeacher', false)
-          if (res.data.openid) {
-            uni.setStorageSync('openid', res.data.openid)
-          }
-          uni.setStorageSync('userInfo', {
-            nickname: res.data.nickname,
-            userId: res.data.userId
-          })
-          if (res.data.teacherStatus) {
-            uni.setStorageSync('teacherStatus', res.data.teacherStatus)
-          }
-          if (res.data.teacherRejectReason) {
-            uni.setStorageSync('teacherRejectReason', res.data.teacherRejectReason)
-          }
-          // 同步 familyId 到 store(hasFamily getter 依赖,8ddc5b55 移除存储后此数据流断裂)
-          self.$store.commit('setFamilyId', res.data.familyId)
-
-          uni.showToast({ title: '登录成功', icon: 'success' })
-
-          if (res.data.needsRoleSelect) {
-            // 首次登录:跳过角色选择,默认 parent,直接进入信息补充页
-            uni.redirectTo({
-              url: '/pages/user-edit/user-edit?token=' + res.data.token + '&userId=' + res.data.userId + '&autoParent=true'
-            })
-          } else {
-            self.handlePostLoginRouting()
-          }
-        }).catch(function(e) {
-          uni.showToast({ title: e.message || '登录失败', icon: 'none' })
-          self.loading = false
-        })
-      }).catch(function(e) {
-        uni.showToast({ title: e.message || '微信登录失败', icon: 'none' })
+      self.loading = true
+      if (!self.loginCode) {
+        uni.showToast({ title: '网络异常,请重试', icon: 'none' })
+        self.loading = false
+        return
+      }
+      wechatPhoneLogin({ code: self.loginCode, phoneCode: e.detail.code }).then(function(res) {
+        self.completeLogin(res.data)
+      }).catch(function(err) {
+        uni.showToast({ title: err.message || '登录失败', icon: 'none' })
         self.loading = false
       })
     },
+    completeLogin: function(data) {
+      var self = this
+      uni.setStorageSync('token', data.token)
+      uni.setStorageSync('userId', data.userId)
+      uni.setStorageSync('role', data.role)
+      uni.setStorageSync('currentRole', data.role)
+      uni.setStorageSync('isSwitchedChild', false)
+      uni.setStorageSync('isSwitchedTeacher', false)
+      if (data.openid) uni.setStorageSync('openid', data.openid)
+      uni.setStorageSync('userInfo', { nickname: data.nickname, userId: data.userId })
+      if (data.phone) uni.setStorageSync('phone', data.phone)
+      if (data.teacherStatus) uni.setStorageSync('teacherStatus', data.teacherStatus)
+      if (data.teacherRejectReason) uni.setStorageSync('teacherRejectReason', data.teacherRejectReason)
+      self.$store.commit('setFamilyId', data.familyId)
+      uni.showToast({ title: '登录成功', icon: 'success' })
+      self.loading = false
+      if (data.needsRoleSelect) {
+        uni.redirectTo({ url: '/pages/user-edit/user-edit?token=' + data.token + '&userId=' + data.userId + '&autoParent=true' })
+      } else {
+        self.handlePostLoginRouting()
+      }
+    },
     handlePostLoginRouting() {
       const inviteCode = uni.getStorageSync('inviteCode')
       const inviteType = uni.getStorageSync('inviteType')

+ 1 - 1
cfc-web/.last_build_commit

@@ -1 +1 @@
-04ce3625608218520b80db7367ec66bf1bead775
+c4aadcdfd7fa33ec86995845d9ad39ccda5f340c

+ 2 - 2
cfc-web/package-lock.json

@@ -1,12 +1,12 @@
 {
   "name": "cfc-web",
-  "version": "1.0.892",
+  "version": "1.0.895",
   "lockfileVersion": 3,
   "requires": true,
   "packages": {
     "": {
       "name": "cfc-web",
-      "version": "1.0.892",
+      "version": "1.0.895",
       "dependencies": {
         "@wangeditor/editor": "^5.1.23",
         "@wangeditor/editor-for-vue": "^1.0.2",

+ 1 - 1
cfc-web/package.json

@@ -1,6 +1,6 @@
 {
   "name": "cfc-web",
-  "version": "1.0.891",
+  "version": "1.0.895",
   "private": true,
   "scripts": {
     "dev": "vue-cli-service serve",

+ 46 - 30
cfc-web/public/CHANGELOG-v1.0.md

@@ -4,6 +4,51 @@
 
 ---
 
+## v1.0.895 (2026-08-09)
+
+### 新功能
+- 手机号快捷登录 - 使用微信 getPhoneNumber 授权获取手机号
+
+
+## v1.0.894 (2026-08-09)
+
+### 文档
+- 推荐组件移除维度参数设计
+
+### 新功能
+- 推荐商品/推荐阅读改四列网格; fix(backend): 家庭成员列表按userId去重
+- 管理端CF值余额与流水查询页面
+- 新增管理端CF值余额与流水查询接口
+- 购买商品发放CF值并激活推荐人分润
+- 活动签到发放CF值
+
+### 其他
+- - ArticleBookshelf 组件: 书册横滑改四列网格, 显示4篇文章
+- - index-home: 推荐阅读移到推荐商品下方, 推荐商品请求数量 2->4
+- - FamilyMemberStrip: 无 props 用法时自我加载可见家庭成员
+- - UserService: 家庭成员列表按 userId 去重(创建者双表记录)
+- 
+
+### 重构
+- 标记旧佣金结算链路为@Deprecated
+- 提现流程改为基于CF值余额
+
+
+## v1.0.893 (2026-08-09)
+
+### 重构
+- 清理重复的 loadAllData 调用
+
+### 新功能
+- 去掉'我的'页面 Tab 切换过渡页
+
+
+## v1.0.892 (2026-08-09)
+
+### Bug 修复
+- 添加家庭成员数量校验 - 任务分配需≥2人/挑战需≥2参与者/互动双方不能同一人
+
+
 ## v1.0.891 (2026-08-09)
 
 ### 新功能
@@ -20,7 +65,6 @@
 - 新增订单确认页 pay.vue(明细/优惠券/拆单提示/虚拟支付逐期)
 - /api/membership/plans 返回原价字段(originalYearly/Monthly/Quarterly)
 - 会员原价配置(sys_config 新增4键: family/premium 年费月费原价)
-- 商城首页搜索栏加购物车入口(带角标) 财富页移除购物车服务项
 
 ### 重构
 - upgrade页移除支付/优惠券逻辑,改下一步跳转pay,修复会员状态判断bug,支持划线原价
@@ -35,11 +79,8 @@
 
 ## v1.0.889 (2026-08-09)
 
-### 样式
-- 添加商城订单快捷和推广中心快捷样式
-
 ### 新功能
-- 商城订单快捷+推广中心快捷+购物车/订单角标
+- 商城首页搜索栏加购物车入口(带角标) 财富页移除购物车服务项
 
 
 ## v1.0.888 (2026-08-09)
@@ -58,31 +99,6 @@
 - 重设计'我的'页面为信息集散中心 - 用户卡片+数据概览+五维能量+待办提醒+功能菜单
 
 
-## v1.0.886 (2026-08-09)
-
-### Bug 修复
-- modifyColumnToText 跳过不存在的表,消除启动日志WARN
-- unify section headers + quick bar + task shortcuts; fix(tab-bar): center button position; fix(backend): ClassCastException in purchase field save
-- 修复DBI启动日志WARN(RENAME语法+不存在表/列的迁移)
-
-### 其他
-- - 8 个不存在的表(user_operation_log/daily_health_checkin等)不再产生噪声
-- 
--   → 改用 tableExists() 前置检查 + RENAME TABLE(无 IF EXISTS)
-- - 修复 1 处 CHANGE COLUMN min_quantity(列已不存在时报错)
--   → 改用 columnExists() 前置检查,不存在则跳过
-- - 新增 tableExists() + columnExists() 辅助方法
-- - 不影响业务,仅消除启动日志噪声
-- 
-
-### 重构
-- 重设计家庭挑战主页 - 移除重复的快速创建区,模板移至弹窗内,简化布局
-
-### 新功能
-- 任务首页重设计 - 三Tab布局 + 家庭成员任务分配 + 接受/拒绝 + 关系分数调整
-- 任务首页重设计 - 支持分配任务给家庭成员,接受/拒绝机制及关系分数调整
-
-
 ## v1.0.885 (2026-08-09)
 
 ### Bug 修复

+ 47 - 31
cfc-web/public/CHANGELOG.md

@@ -1,6 +1,6 @@
 # 更新日志
 
-> 当前版本: v1.0.891
+> 当前版本: v1.0.895
 
 ## 历史版本
 
@@ -8,6 +8,51 @@
 
 ---
 
+## v1.0.895 (2026-08-09)
+
+### 新功能
+- 手机号快捷登录 - 使用微信 getPhoneNumber 授权获取手机号
+
+
+## v1.0.894 (2026-08-09)
+
+### 文档
+- 推荐组件移除维度参数设计
+
+### 新功能
+- 推荐商品/推荐阅读改四列网格; fix(backend): 家庭成员列表按userId去重
+- 管理端CF值余额与流水查询页面
+- 新增管理端CF值余额与流水查询接口
+- 购买商品发放CF值并激活推荐人分润
+- 活动签到发放CF值
+
+### 其他
+- - ArticleBookshelf 组件: 书册横滑改四列网格, 显示4篇文章
+- - index-home: 推荐阅读移到推荐商品下方, 推荐商品请求数量 2->4
+- - FamilyMemberStrip: 无 props 用法时自我加载可见家庭成员
+- - UserService: 家庭成员列表按 userId 去重(创建者双表记录)
+- 
+
+### 重构
+- 标记旧佣金结算链路为@Deprecated
+- 提现流程改为基于CF值余额
+
+
+## v1.0.893 (2026-08-09)
+
+### 重构
+- 清理重复的 loadAllData 调用
+
+### 新功能
+- 去掉'我的'页面 Tab 切换过渡页
+
+
+## v1.0.892 (2026-08-09)
+
+### Bug 修复
+- 添加家庭成员数量校验 - 任务分配需≥2人/挑战需≥2参与者/互动双方不能同一人
+
+
 ## v1.0.891 (2026-08-09)
 
 ### 新功能
@@ -24,7 +69,6 @@
 - 新增订单确认页 pay.vue(明细/优惠券/拆单提示/虚拟支付逐期)
 - /api/membership/plans 返回原价字段(originalYearly/Monthly/Quarterly)
 - 会员原价配置(sys_config 新增4键: family/premium 年费月费原价)
-- 商城首页搜索栏加购物车入口(带角标) 财富页移除购物车服务项
 
 ### 重构
 - upgrade页移除支付/优惠券逻辑,改下一步跳转pay,修复会员状态判断bug,支持划线原价
@@ -39,11 +83,8 @@
 
 ## v1.0.889 (2026-08-09)
 
-### 样式
-- 添加商城订单快捷和推广中心快捷样式
-
 ### 新功能
-- 商城订单快捷+推广中心快捷+购物车/订单角标
+- 商城首页搜索栏加购物车入口(带角标) 财富页移除购物车服务项
 
 
 ## v1.0.888 (2026-08-09)
@@ -62,31 +103,6 @@
 - 重设计'我的'页面为信息集散中心 - 用户卡片+数据概览+五维能量+待办提醒+功能菜单
 
 
-## v1.0.886 (2026-08-09)
-
-### Bug 修复
-- modifyColumnToText 跳过不存在的表,消除启动日志WARN
-- unify section headers + quick bar + task shortcuts; fix(tab-bar): center button position; fix(backend): ClassCastException in purchase field save
-- 修复DBI启动日志WARN(RENAME语法+不存在表/列的迁移)
-
-### 其他
-- - 8 个不存在的表(user_operation_log/daily_health_checkin等)不再产生噪声
-- 
--   → 改用 tableExists() 前置检查 + RENAME TABLE(无 IF EXISTS)
-- - 修复 1 处 CHANGE COLUMN min_quantity(列已不存在时报错)
--   → 改用 columnExists() 前置检查,不存在则跳过
-- - 新增 tableExists() + columnExists() 辅助方法
-- - 不影响业务,仅消除启动日志噪声
-- 
-
-### 重构
-- 重设计家庭挑战主页 - 移除重复的快速创建区,模板移至弹窗内,简化布局
-
-### 新功能
-- 任务首页重设计 - 三Tab布局 + 家庭成员任务分配 + 接受/拒绝 + 关系分数调整
-- 任务首页重设计 - 支持分配任务给家庭成员,接受/拒绝机制及关系分数调整
-
-
 ## v1.0.885 (2026-08-09)
 
 ### Bug 修复