322dceef by lttnew

密码

1 parent 4377830a
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Project Overview
This is a **uni-app** (Vue 3) WeChat mini-program project for the **China Taekwondo Association (中国跆拳道协会)** membership management system.
- **Platform**: mp-weixin (WeChat Mini-Program)
- **Vue Version**: Vue 3 with `<script setup>` syntax
- **State Management**: Pinia
- **UI Framework**: uni-ui (components in `uni_modules/`)
- **Key Dependencies**: dayjs, underscore, lodash, crypto-js
## Development Commands
### Running the Project
- Use **HBuilderX** to open this project
- Or use CLI: `npm run dev:mp-weixin`
- Build: `npm run build:mp-weixin`
### Key Configurations
- `config.js` - API base URLs (dev/prod switching)
- `pages.json` - Page routing and global settings
- `manifest.json` - App configuration (appid, platform settings)
## Architecture
### Directory Structure
```
├── common/ # Shared utilities
│ ├── api.js # API functions (imported as @/common/api.js)
│ ├── request.js # HTTP request wrapper
│ ├── login.js # Login logic
│ ├── utils.js # Utility functions
│ └── pay.js # Payment logic
├── config.js # Environment config (API endpoints)
├── pages/ # Main package pages (index, exam, invoice, rank, webview)
├── login/ # Login sub-package
├── personal/ # Personal member sub-package
├── personalVip/ # VIP member sub-package
├── group/ # Group/Organization sub-package
├── level/ # Level examination sub-package
├── myCenter/ # User center sub-package
├── uni_modules/ # uni-ui components
└── static/ # Static assets
```
### API Pattern
All API functions are defined in `common/api.js` using a consistent pattern:
```js
export function apiFunctionName(data) {
return request({
url: '/path/to/endpoint',
method: 'post', // or 'get', 'put', 'delete'
params: data
})
}
```
### Page Sub-packages
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/`).
### Component Auto-import
uni-ui components are auto-imported via easycom in `pages.json`:
```json
"easycom": {
"autoscan": true,
"custom": {
"^uni-(.*)": "uni_modules/uni-$1/components/uni-$1/uni-$1.vue"
}
}
```
### Global Data
`app.globalData` contains shared state (from `App.vue`):
- `memberInfo` - Current member info
- `isLogin` - Login status
- `deptType` - Department type
Access via: `const app = getApp(); app.globalData.memberInfo`
### Form Handling Pattern
For forms with `uni-forms`, use `Object.assign(form.value, data)` instead of `form.value = data` to preserve reactive bindings.
### DateTime Picker
`uni-datetime-picker` requires ISO format strings or timestamps for v-model values.
### File Upload Pattern
Use `api.uploadFile(e)` or `api.uploadImg(e)` from `common/api.js` which return `{ code, msg }` - the file URL is in `res.msg`.
## Common Issues
### uni-data-select not working
If `uni-data-select` dropdowns don't appear, ensure:
1. easycom is properly configured in `pages.json`
2. The component is not blocked by CSS `overflow: hidden` on parent containers
### Responsive Data Binding
When updating form data from API responses, use `Object.assign()` to maintain Vue 3 reactivity:
```js
// Instead of: form.value = res.data
Object.assign(form.value, res.data)
```
......@@ -61,7 +61,14 @@ function getCodeImg() {
method: 'get'
})
}
function getSmsCodeImg(data) {
return request({
url: '/captchaSmsWithCaptchaImage',
// url: '/captchaSmsWithCaptchaImageForMiniApp',
method: 'post',
params: data
})
}
// 代退图形认证的获取手机验证码
function getSmsCode(data) {
return request({
......@@ -241,6 +248,7 @@ export {
pcLogin,
getCodeImg,
getSmsCode,
getSmsCodeImg,
h5Login,
h5LoginAuto,
loginByPhone,
......
......@@ -4,13 +4,13 @@ page {
background: #ecf0f6;
}
/* uni-data-checkbox 选中色全局覆盖为红色 */
uni-data-checkbox .checklist-box.is-checked {
border-color: #C4121B !important;
background-color: #C4121B !important;
}
uni-data-checkbox .checklist-box.is-checked .checklist-text {
color: #fff !important;
}
// uni-data-checkbox .checklist-box.is-checked {
// border-color: #C4121B !important;
// background-color: #C4121B !important;
// }
// uni-data-checkbox .checklist-box.is-checked .checklist-text {
// color: #fff !important;
// }
.wBox{box-sizing: border-box;}
.h3 {font-weight: bold;line-height: 2;}
.text-center{text-align: center;}
......
......@@ -933,7 +933,7 @@
padding: 20rpx 0;
background: #fff;
border-top: 1rpx solid #f0f0f0;
z-index: 999;
z-index: 98;
.btn-red {
background: linear-gradient(135deg, #AD181F 0%, #c42a2a 100%);
......
......@@ -68,7 +68,7 @@ import {
} from 'vue'
import {
getCodeImg,
getSmsCode,
getSmsCodeImg,
groupMemberRegister
} from '@/common/login.js'
import config from '@/config.js'
......@@ -113,6 +113,14 @@ function register() {
})
return
}
// 密码强度校验:8~18位大小写字母加数字加特殊符号组合
if (!validPassword(registerForm.value.password)) {
uni.showToast({
title: '密码必须为8~18位大小写字母、数字和特殊符号组合',
icon: 'none'
})
return
}
if (registerForm.value.password != registerForm.value.password2) {
uni.showToast({
title: '两次密码不一致,请重新输入',
......@@ -131,13 +139,27 @@ function register() {
groupMemberRegister(registerForm.value)
.then((res) => {
uni.showToast({
title: `恭喜你,您的账号 ${registerForm.value.telNo} 注册成功!`
title: `恭喜你,您的账号 ${registerForm.value.telNo} 注册成功!`,
icon: 'none'
})
registerForm.value = {}
setTimeout(goLogin, 2000)
})
}
// 密码校验:8~18位大小写字母加数字加特殊符号组合
function validPassword(pwd) {
if (!pwd || pwd.length < 8 || pwd.length > 18) {
return false
}
const lowerRegex = /[a-z]+/
const upperRegex = /[A-Z]+/
const digitRegex = /[0-9]+/
const symbolRegex = /[\W_]+/
const specific = /.*[~!@#$%^&*()_+`\-={}:";'<>?,.\/].*/
return (lowerRegex.test(pwd) && upperRegex.test(pwd) && digitRegex.test(pwd) && symbolRegex.test(pwd) && specific.test(pwd))
}
function goLogin() {
let path = '/login/loginC';
uni.navigateTo({
......@@ -169,7 +191,7 @@ function getCaptchaSms() {
return
}
getSmsCode({
getSmsCodeImg({
uuid: registerForm.value.uuid,
telNo: registerForm.value.telNo,
code: registerForm.value.captcha
......
......@@ -264,10 +264,10 @@
getTree()
form.value.deptType = res.data.dept.deptType
form.value.parentId = form.value.parentId.toString()
creditCode.value = form.value.creditCode
companyName.value = form.value.companyName
belongProvinceId.value = form.value.belongProvinceId
parentId.value = form.value.parentId
// creditCode.value = form.value.creditCode
// form.value.companyName = res.data.memberInfo.companyName
// belongProvinceId.value = form.value.belongProvinceId
// parentId.value = form.value.parentId
if (form.value.regionId) {
form.value.coordinates1 = form.value.regionId
......
{
"easycom": {
"autoscan": true,
"custom": {
"^uni-(.*)": "uni_modules/uni-$1/components/uni-$1/uni-$1.vue"
}
},
"pages": [{
"path": "pages/index/index"
},
......
......@@ -219,7 +219,7 @@
display: flex;
/* #endif */
align-items: center;
padding: 8px 10px;
padding: 18px 10px;
padding-right: 5px;
padding-left: 10px;
}
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!