322dceef by lttnew

密码

1 parent 4377830a
1 # CLAUDE.md
2
3 This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
5 ## Project Overview
6
7 This is a **uni-app** (Vue 3) WeChat mini-program project for the **China Taekwondo Association (中国跆拳道协会)** membership management system.
8
9 - **Platform**: mp-weixin (WeChat Mini-Program)
10 - **Vue Version**: Vue 3 with `<script setup>` syntax
11 - **State Management**: Pinia
12 - **UI Framework**: uni-ui (components in `uni_modules/`)
13 - **Key Dependencies**: dayjs, underscore, lodash, crypto-js
14
15 ## Development Commands
16
17 ### Running the Project
18 - Use **HBuilderX** to open this project
19 - Or use CLI: `npm run dev:mp-weixin`
20 - Build: `npm run build:mp-weixin`
21
22 ### Key Configurations
23 - `config.js` - API base URLs (dev/prod switching)
24 - `pages.json` - Page routing and global settings
25 - `manifest.json` - App configuration (appid, platform settings)
26
27 ## Architecture
28
29 ### Directory Structure
30 ```
31 ├── common/ # Shared utilities
32 │ ├── api.js # API functions (imported as @/common/api.js)
33 │ ├── request.js # HTTP request wrapper
34 │ ├── login.js # Login logic
35 │ ├── utils.js # Utility functions
36 │ └── pay.js # Payment logic
37 ├── config.js # Environment config (API endpoints)
38 ├── pages/ # Main package pages (index, exam, invoice, rank, webview)
39 ├── login/ # Login sub-package
40 ├── personal/ # Personal member sub-package
41 ├── personalVip/ # VIP member sub-package
42 ├── group/ # Group/Organization sub-package
43 ├── level/ # Level examination sub-package
44 ├── myCenter/ # User center sub-package
45 ├── uni_modules/ # uni-ui components
46 └── static/ # Static assets
47 ```
48
49 ### API Pattern
50 All API functions are defined in `common/api.js` using a consistent pattern:
51 ```js
52 export function apiFunctionName(data) {
53 return request({
54 url: '/path/to/endpoint',
55 method: 'post', // or 'get', 'put', 'delete'
56 params: data
57 })
58 }
59 ```
60
61 ### Page Sub-packages
62 Pages are organized into sub-packages defined in `pages.json` to optimize loading. Each sub-package has its own root directory (e.g., `level/`, `myCenter/`).
63
64 ### Component Auto-import
65 uni-ui components are auto-imported via easycom in `pages.json`:
66 ```json
67 "easycom": {
68 "autoscan": true,
69 "custom": {
70 "^uni-(.*)": "uni_modules/uni-$1/components/uni-$1/uni-$1.vue"
71 }
72 }
73 ```
74
75 ### Global Data
76 `app.globalData` contains shared state (from `App.vue`):
77 - `memberInfo` - Current member info
78 - `isLogin` - Login status
79 - `deptType` - Department type
80
81 Access via: `const app = getApp(); app.globalData.memberInfo`
82
83 ### Form Handling Pattern
84 For forms with `uni-forms`, use `Object.assign(form.value, data)` instead of `form.value = data` to preserve reactive bindings.
85
86 ### DateTime Picker
87 `uni-datetime-picker` requires ISO format strings or timestamps for v-model values.
88
89 ### File Upload Pattern
90 Use `api.uploadFile(e)` or `api.uploadImg(e)` from `common/api.js` which return `{ code, msg }` - the file URL is in `res.msg`.
91
92 ## Common Issues
93
94 ### uni-data-select not working
95 If `uni-data-select` dropdowns don't appear, ensure:
96 1. easycom is properly configured in `pages.json`
97 2. The component is not blocked by CSS `overflow: hidden` on parent containers
98
99 ### Responsive Data Binding
100 When updating form data from API responses, use `Object.assign()` to maintain Vue 3 reactivity:
101 ```js
102 // Instead of: form.value = res.data
103 Object.assign(form.value, res.data)
104 ```
...@@ -61,7 +61,14 @@ function getCodeImg() { ...@@ -61,7 +61,14 @@ function getCodeImg() {
61 method: 'get' 61 method: 'get'
62 }) 62 })
63 } 63 }
64 64 function getSmsCodeImg(data) {
65 return request({
66 url: '/captchaSmsWithCaptchaImage',
67 // url: '/captchaSmsWithCaptchaImageForMiniApp',
68 method: 'post',
69 params: data
70 })
71 }
65 // 代退图形认证的获取手机验证码 72 // 代退图形认证的获取手机验证码
66 function getSmsCode(data) { 73 function getSmsCode(data) {
67 return request({ 74 return request({
...@@ -241,6 +248,7 @@ export { ...@@ -241,6 +248,7 @@ export {
241 pcLogin, 248 pcLogin,
242 getCodeImg, 249 getCodeImg,
243 getSmsCode, 250 getSmsCode,
251 getSmsCodeImg,
244 h5Login, 252 h5Login,
245 h5LoginAuto, 253 h5LoginAuto,
246 loginByPhone, 254 loginByPhone,
......
...@@ -4,13 +4,13 @@ page { ...@@ -4,13 +4,13 @@ page {
4 background: #ecf0f6; 4 background: #ecf0f6;
5 } 5 }
6 /* uni-data-checkbox 选中色全局覆盖为红色 */ 6 /* uni-data-checkbox 选中色全局覆盖为红色 */
7 uni-data-checkbox .checklist-box.is-checked { 7 // uni-data-checkbox .checklist-box.is-checked {
8 border-color: #C4121B !important; 8 // border-color: #C4121B !important;
9 background-color: #C4121B !important; 9 // background-color: #C4121B !important;
10 } 10 // }
11 uni-data-checkbox .checklist-box.is-checked .checklist-text { 11 // uni-data-checkbox .checklist-box.is-checked .checklist-text {
12 color: #fff !important; 12 // color: #fff !important;
13 } 13 // }
14 .wBox{box-sizing: border-box;} 14 .wBox{box-sizing: border-box;}
15 .h3 {font-weight: bold;line-height: 2;} 15 .h3 {font-weight: bold;line-height: 2;}
16 .text-center{text-align: center;} 16 .text-center{text-align: center;}
......
...@@ -933,7 +933,7 @@ ...@@ -933,7 +933,7 @@
933 padding: 20rpx 0; 933 padding: 20rpx 0;
934 background: #fff; 934 background: #fff;
935 border-top: 1rpx solid #f0f0f0; 935 border-top: 1rpx solid #f0f0f0;
936 z-index: 999; 936 z-index: 98;
937 937
938 .btn-red { 938 .btn-red {
939 background: linear-gradient(135deg, #AD181F 0%, #c42a2a 100%); 939 background: linear-gradient(135deg, #AD181F 0%, #c42a2a 100%);
......
...@@ -68,7 +68,7 @@ import { ...@@ -68,7 +68,7 @@ import {
68 } from 'vue' 68 } from 'vue'
69 import { 69 import {
70 getCodeImg, 70 getCodeImg,
71 getSmsCode, 71 getSmsCodeImg,
72 groupMemberRegister 72 groupMemberRegister
73 } from '@/common/login.js' 73 } from '@/common/login.js'
74 import config from '@/config.js' 74 import config from '@/config.js'
...@@ -113,6 +113,14 @@ function register() { ...@@ -113,6 +113,14 @@ function register() {
113 }) 113 })
114 return 114 return
115 } 115 }
116 // 密码强度校验:8~18位大小写字母加数字加特殊符号组合
117 if (!validPassword(registerForm.value.password)) {
118 uni.showToast({
119 title: '密码必须为8~18位大小写字母、数字和特殊符号组合',
120 icon: 'none'
121 })
122 return
123 }
116 if (registerForm.value.password != registerForm.value.password2) { 124 if (registerForm.value.password != registerForm.value.password2) {
117 uni.showToast({ 125 uni.showToast({
118 title: '两次密码不一致,请重新输入', 126 title: '两次密码不一致,请重新输入',
...@@ -131,13 +139,27 @@ function register() { ...@@ -131,13 +139,27 @@ function register() {
131 groupMemberRegister(registerForm.value) 139 groupMemberRegister(registerForm.value)
132 .then((res) => { 140 .then((res) => {
133 uni.showToast({ 141 uni.showToast({
134 title: `恭喜你,您的账号 ${registerForm.value.telNo} 注册成功!` 142 title: `恭喜你,您的账号 ${registerForm.value.telNo} 注册成功!`,
143 icon: 'none'
135 }) 144 })
136 registerForm.value = {} 145 registerForm.value = {}
137 setTimeout(goLogin, 2000) 146 setTimeout(goLogin, 2000)
138 }) 147 })
139 } 148 }
140 149
150 // 密码校验:8~18位大小写字母加数字加特殊符号组合
151 function validPassword(pwd) {
152 if (!pwd || pwd.length < 8 || pwd.length > 18) {
153 return false
154 }
155 const lowerRegex = /[a-z]+/
156 const upperRegex = /[A-Z]+/
157 const digitRegex = /[0-9]+/
158 const symbolRegex = /[\W_]+/
159 const specific = /.*[~!@#$%^&*()_+`\-={}:";'<>?,.\/].*/
160 return (lowerRegex.test(pwd) && upperRegex.test(pwd) && digitRegex.test(pwd) && symbolRegex.test(pwd) && specific.test(pwd))
161 }
162
141 function goLogin() { 163 function goLogin() {
142 let path = '/login/loginC'; 164 let path = '/login/loginC';
143 uni.navigateTo({ 165 uni.navigateTo({
...@@ -169,7 +191,7 @@ function getCaptchaSms() { ...@@ -169,7 +191,7 @@ function getCaptchaSms() {
169 return 191 return
170 } 192 }
171 193
172 getSmsCode({ 194 getSmsCodeImg({
173 uuid: registerForm.value.uuid, 195 uuid: registerForm.value.uuid,
174 telNo: registerForm.value.telNo, 196 telNo: registerForm.value.telNo,
175 code: registerForm.value.captcha 197 code: registerForm.value.captcha
......
...@@ -264,10 +264,10 @@ ...@@ -264,10 +264,10 @@
264 getTree() 264 getTree()
265 form.value.deptType = res.data.dept.deptType 265 form.value.deptType = res.data.dept.deptType
266 form.value.parentId = form.value.parentId.toString() 266 form.value.parentId = form.value.parentId.toString()
267 creditCode.value = form.value.creditCode 267 // creditCode.value = form.value.creditCode
268 companyName.value = form.value.companyName 268 // form.value.companyName = res.data.memberInfo.companyName
269 belongProvinceId.value = form.value.belongProvinceId 269 // belongProvinceId.value = form.value.belongProvinceId
270 parentId.value = form.value.parentId 270 // parentId.value = form.value.parentId
271 271
272 if (form.value.regionId) { 272 if (form.value.regionId) {
273 form.value.coordinates1 = form.value.regionId 273 form.value.coordinates1 = form.value.regionId
......
1 { 1 {
2 "easycom": {
3 "autoscan": true,
4 "custom": {
5 "^uni-(.*)": "uni_modules/uni-$1/components/uni-$1/uni-$1.vue"
6 }
7 },
2 "pages": [{ 8 "pages": [{
3 "path": "pages/index/index" 9 "path": "pages/index/index"
4 }, 10 },
......
...@@ -219,7 +219,7 @@ ...@@ -219,7 +219,7 @@
219 display: flex; 219 display: flex;
220 /* #endif */ 220 /* #endif */
221 align-items: center; 221 align-items: center;
222 padding: 8px 10px; 222 padding: 18px 10px;
223 padding-right: 5px; 223 padding-right: 5px;
224 padding-left: 10px; 224 padding-left: 10px;
225 } 225 }
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!