12 changed files with 3099 additions and 501 deletions
-
3app.json
-
4pagesA/pages/askingSy/askingSy.js
-
2pagesA/pages/askingSy/askingSy.wxml
-
472pagesA/pages/attestation/attestation.js
-
4pagesA/pages/attestation/attestation.json
-
285pagesA/pages/attestation/attestation.wxml
-
1392pagesA/pages/attestation/attestation.wxss
-
224pagesA/pages/precept/precept.js
-
1pagesA/pages/precept/precept.json
-
177pagesA/pages/precept/precept.wxml
-
1026pagesA/pages/precept/precept.wxss
-
8utils/api.js
@ -0,0 +1,472 @@ |
|||
// pages/auth/real-name-auth.js
|
|||
import http from '../../../utils/api' |
|||
|
|||
Page({ |
|||
data: { |
|||
// 表单数据
|
|||
name: '', |
|||
idNumber: '', |
|||
|
|||
// 焦点状态
|
|||
nameFocus: false, |
|||
idNumberFocus: false, |
|||
|
|||
// 错误提示
|
|||
nameError: '', |
|||
idNumberError: '', |
|||
|
|||
// 提示显示控制
|
|||
showNameHint: false, |
|||
showIdNumberHint: false, |
|||
|
|||
// 验证状态
|
|||
isNameValid: false, |
|||
isIdNumberValid: false, |
|||
|
|||
// 协议状态
|
|||
agreed: false, |
|||
|
|||
// 提交状态
|
|||
canSubmit: false, |
|||
isSubmitting: false, |
|||
|
|||
// 进度条
|
|||
currentStep: 1, |
|||
lineProgress1: 0, |
|||
lineProgress2: 0, |
|||
|
|||
// 弹窗数据
|
|||
showModal: false, |
|||
modalTitle: '', |
|||
modalContent: '', |
|||
|
|||
// 成功弹窗数据
|
|||
showSuccessModal: false, |
|||
maskedIdNumber: '', |
|||
|
|||
// 错误弹窗数据
|
|||
showErrorModal: false, |
|||
errorTitle: '', |
|||
errorMessage: '' |
|||
}, |
|||
|
|||
onLoad() { |
|||
// 页面加载时启动进度条动画
|
|||
setTimeout(() => { |
|||
this.setData({ lineProgress1: 50 }); |
|||
}, 600); |
|||
}, |
|||
|
|||
// 姓名输入处理
|
|||
onNameInput(e) { |
|||
const value = e.detail.value.trim(); |
|||
let error = ''; |
|||
let showHint = true; |
|||
let isValid = false; |
|||
|
|||
if (value) { |
|||
if (!/^[\u4e00-\u9fa5]{2,10}$/.test(value)) { |
|||
error = '姓名应为2-10个汉字'; |
|||
} else { |
|||
isValid = true; |
|||
// 验证通过时保持提示显示,但无错误
|
|||
} |
|||
} else { |
|||
// 内容为空时显示正常提示
|
|||
error = ''; |
|||
} |
|||
|
|||
this.setData({ |
|||
name: value, |
|||
nameError: error, |
|||
showNameHint: showHint, |
|||
isNameValid: isValid |
|||
}, () => { |
|||
this.checkForm(); |
|||
}); |
|||
}, |
|||
|
|||
onNameFocus() { |
|||
this.setData({ |
|||
nameFocus: true, |
|||
showNameHint: true // 获得焦点时显示提示
|
|||
}); |
|||
}, |
|||
|
|||
onNameBlur() { |
|||
const { name } = this.data; |
|||
|
|||
this.setData({ |
|||
nameFocus: false, |
|||
// 失去焦点时,如果内容为空或验证失败,保持提示显示
|
|||
showNameHint: !!(name && !this.data.isNameValid) |
|||
}); |
|||
}, |
|||
|
|||
// 清除姓名
|
|||
clearName() { |
|||
this.setData({ |
|||
name: '', |
|||
nameError: '', |
|||
showNameHint: false, |
|||
isNameValid: false |
|||
}, () => { |
|||
this.checkForm(); |
|||
}); |
|||
}, |
|||
|
|||
// 身份证号输入处理
|
|||
onIdNumberInput(e) { |
|||
const value = e.detail.value.trim().toUpperCase(); |
|||
let error = ''; |
|||
let showHint = true; |
|||
let isValid = false; |
|||
|
|||
if (value) { |
|||
if (value.length < 18) { |
|||
error = '还需输入' + (18 - value.length) + '位'; |
|||
} else if (value.length === 18) { |
|||
if (this.validateIdNumber(value)) { |
|||
isValid = true; |
|||
// 验证通过时保持提示显示,但无错误
|
|||
} else { |
|||
error = '身份证号格式不正确'; |
|||
} |
|||
} |
|||
} else { |
|||
// 内容为空时显示正常提示
|
|||
error = ''; |
|||
} |
|||
|
|||
this.setData({ |
|||
idNumber: value, |
|||
idNumberError: error, |
|||
showIdNumberHint: showHint, |
|||
isIdNumberValid: isValid |
|||
}, () => { |
|||
this.checkForm(); |
|||
}); |
|||
}, |
|||
|
|||
onIdNumberFocus() { |
|||
this.setData({ |
|||
idNumberFocus: true, |
|||
showIdNumberHint: true // 获得焦点时显示提示
|
|||
}); |
|||
}, |
|||
|
|||
onIdNumberBlur() { |
|||
const { idNumber } = this.data; |
|||
let error = ''; |
|||
let isValid = false; |
|||
|
|||
// 最终验证
|
|||
if (idNumber) { |
|||
if (idNumber.length < 18) { |
|||
error = '还需输入' + (18 - idNumber.length) + '位'; |
|||
} else if (idNumber.length === 18) { |
|||
if (this.validateIdNumber(idNumber)) { |
|||
isValid = true; |
|||
} else { |
|||
error = '身份证号格式不正确'; |
|||
} |
|||
} |
|||
} |
|||
|
|||
this.setData({ |
|||
idNumberFocus: false, |
|||
idNumberError: error, |
|||
isIdNumberValid: isValid, |
|||
// 失去焦点时,如果内容为空或验证失败,保持提示显示
|
|||
showIdNumberHint: !!(idNumber && !isValid) |
|||
}); |
|||
}, |
|||
|
|||
// 清除身份证号
|
|||
clearIdNumber() { |
|||
this.setData({ |
|||
idNumber: '', |
|||
idNumberError: '', |
|||
showIdNumberHint: false, |
|||
isIdNumberValid: false |
|||
}, () => { |
|||
this.checkForm(); |
|||
}); |
|||
}, |
|||
|
|||
// 身份证验证函数
|
|||
validateIdNumber(idNumber) { |
|||
// 基础格式验证
|
|||
if (!/^\d{17}[\dXx]$/.test(idNumber)) { |
|||
return false; |
|||
} |
|||
|
|||
// 地区码验证(简化的验证,实际应该更严谨)
|
|||
const areaCode = idNumber.substring(0, 2); |
|||
const validAreaCodes = ['11', '12', '13', '14', '15', '21', '22', '23', |
|||
'31', '32', '33', '34', '35', '36', '37', '41', |
|||
'42', '43', '44', '45', '46', '50', '51', '52', |
|||
'53', '54', '61', '62', '63', '64', '65']; |
|||
|
|||
if (!validAreaCodes.includes(areaCode)) { |
|||
return false; |
|||
} |
|||
|
|||
// 出生日期验证
|
|||
const year = parseInt(idNumber.substring(6, 10)); |
|||
const month = parseInt(idNumber.substring(10, 12)); |
|||
const day = parseInt(idNumber.substring(12, 14)); |
|||
|
|||
const currentYear = new Date().getFullYear(); |
|||
if (year < 1900 || year > currentYear) return false; |
|||
if (month < 1 || month > 12) return false; |
|||
if (day < 1 || day > 31) return false; |
|||
|
|||
// 校验码验证
|
|||
const checkCode = idNumber.charAt(17).toUpperCase(); |
|||
const weights = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]; |
|||
const checkCodes = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2']; |
|||
|
|||
let sum = 0; |
|||
for (let i = 0; i < 17; i++) { |
|||
sum += parseInt(idNumber.charAt(i)) * weights[i]; |
|||
} |
|||
|
|||
const mod = sum % 11; |
|||
return checkCode === checkCodes[mod]; |
|||
}, |
|||
|
|||
// 协议处理
|
|||
toggleAgreement() { |
|||
const newAgreed = !this.data.agreed; |
|||
this.setData({ |
|||
agreed: newAgreed |
|||
}, () => { |
|||
this.checkForm(); |
|||
}); |
|||
}, |
|||
|
|||
// 显示协议弹窗
|
|||
showAgreementModal() { |
|||
const title = '用户服务协议'; |
|||
const content = `欢迎您使用"与牧同行"服务!\n\n在使用我们的服务前,请您仔细阅读并同意以下协议:\n\n1. 服务条款\n您在使用与牧同行提供的各项服务时,应当遵守相关法律法规,不得从事任何非法行为。\n\n2. 用户责任\n您需要保证所提供信息的真实性、准确性和完整性。\n\n3. 服务变更\n我们保留随时修改、暂停或终止服务的权利。\n\n4. 免责声明\n在法律法规允许的最大范围内,我们对因使用服务而产生的任何间接损失不承担责任。\n\n5. 法律适用\n本协议的订立、执行和解释及争议的解决均适用中华人民共和国法律。\n\n请您确保已阅读并理解以上条款。`; |
|||
|
|||
this.showModal(title, content); |
|||
}, |
|||
|
|||
// 显示隐私弹窗
|
|||
showPrivacyModal() { |
|||
const title = '隐私保护协议'; |
|||
const content = `我们非常重视您的隐私保护,请您仔细阅读以下隐私政策:\n\n1. 信息收集\n我们仅收集为您提供服务所必需的信息,包括姓名、身份证号等实名信息。\n\n2. 信息使用\n您的信息仅用于身份验证和服务提供,不会用于其他商业用途。\n\n3. 信息保护\n我们采用先进的安全技术保护您的信息,防止未经授权的访问、使用或泄露。\n\n4. 信息共享\n除非获得您的明确同意,我们不会向第三方共享您的个人信息。\n\n5. 您的权利\n您可以随时查看、更正或删除您的个人信息。\n\n6. 政策更新\n我们可能会不时更新本隐私政策,更新后的政策将在本页面公布。\n\n我们承诺严格遵守相关法律法规,保护您的个人信息安全。`; |
|||
|
|||
this.showModal(title, content); |
|||
}, |
|||
|
|||
// 显示弹窗
|
|||
showModal(title, content) { |
|||
this.setData({ |
|||
modalTitle: title, |
|||
modalContent: content, |
|||
showModal: true |
|||
}); |
|||
}, |
|||
|
|||
// 关闭弹窗
|
|||
closeModal() { |
|||
this.setData({ showModal: false }); |
|||
}, |
|||
|
|||
// 显示错误弹窗
|
|||
showErrorModal(title, message) { |
|||
this.setData({ |
|||
errorTitle: title || '认证失败', |
|||
errorMessage: message || '请检查信息后重试', |
|||
showErrorModal: true |
|||
}); |
|||
}, |
|||
|
|||
// 关闭错误弹窗
|
|||
closeErrorModal() { |
|||
this.setData({ |
|||
showErrorModal: false, |
|||
isSubmitting: false // 关闭错误弹窗时重置提交状态
|
|||
}); |
|||
}, |
|||
|
|||
// 阻止事件冒泡
|
|||
stopPropagation(e) { |
|||
// 阻止冒泡
|
|||
}, |
|||
|
|||
// 检查表单
|
|||
checkForm() { |
|||
const { |
|||
isNameValid, |
|||
isIdNumberValid, |
|||
agreed |
|||
} = this.data; |
|||
|
|||
const isValid = isNameValid && |
|||
isIdNumberValid && |
|||
agreed; |
|||
|
|||
this.setData({ |
|||
canSubmit: isValid |
|||
}); |
|||
}, |
|||
|
|||
// 提交认证
|
|||
async submitAuth() { |
|||
if (!this.data.canSubmit || this.data.isSubmitting) return; |
|||
|
|||
// 最终验证
|
|||
const { name, idNumber } = this.data; |
|||
|
|||
if (!/^[\u4e00-\u9fa5]{2,10}$/.test(name)) { |
|||
this.setData({ |
|||
nameError: '姓名应为2-10个汉字', |
|||
showNameHint: true, |
|||
canSubmit: false |
|||
}); |
|||
return; |
|||
} |
|||
|
|||
if (!this.validateIdNumber(idNumber)) { |
|||
this.setData({ |
|||
idNumberError: '身份证号格式不正确', |
|||
showIdNumberHint: true, |
|||
canSubmit: false |
|||
}); |
|||
return; |
|||
} |
|||
|
|||
this.setData({ |
|||
isSubmitting: true, |
|||
currentStep: 2, |
|||
lineProgress1: 100, |
|||
lineProgress2: 50 |
|||
}); |
|||
|
|||
// 显示加载动画
|
|||
wx.showLoading({ |
|||
title: '正在验证...', |
|||
mask: true |
|||
}); |
|||
|
|||
try { |
|||
// 调用实名认证接口
|
|||
const result = await this.callRealNameApi(name, idNumber); |
|||
|
|||
wx.hideLoading(); |
|||
|
|||
if (result.success) { |
|||
// 处理身份证号脱敏显示
|
|||
const maskedId = idNumber.substring(0, 4) + '**********' + idNumber.substring(14); |
|||
|
|||
// 显示成功弹窗
|
|||
this.showSuccessModal(maskedId); |
|||
|
|||
this.setData({ |
|||
isSubmitting: false, |
|||
currentStep: 3, |
|||
lineProgress2: 100 |
|||
}); |
|||
} else { |
|||
// 接口返回失败
|
|||
this.handleApiError(result); |
|||
} |
|||
|
|||
} catch (error) { |
|||
wx.hideLoading(); |
|||
this.setData({ |
|||
isSubmitting: false, |
|||
currentStep: 1, |
|||
lineProgress2: 0 |
|||
}); |
|||
|
|||
this.showErrorModal('网络错误', '认证请求失败,请检查网络连接后重试'); |
|||
console.error('实名认证错误:', error); |
|||
} |
|||
}, |
|||
|
|||
// 调用实名认证API
|
|||
async callRealNameApi(realName, idCard) { |
|||
return new Promise((resolve, reject) => { |
|||
http.realName({ |
|||
data: { |
|||
realName: realName, // 姓名字段
|
|||
idCard: idCard // 身份证号字段
|
|||
}, |
|||
success: (res) => { |
|||
console.log('API响应:', res); |
|||
|
|||
// 根据实际API响应结构调整
|
|||
if (res.code === 200 || res.code === 0) { |
|||
resolve({ |
|||
success: true, |
|||
data: res.data || {} |
|||
}); |
|||
} else { |
|||
resolve({ |
|||
success: false, |
|||
code: res.code, |
|||
message: res.msg || '认证失败' |
|||
}); |
|||
} |
|||
}, |
|||
fail: (err) => { |
|||
reject(err); |
|||
} |
|||
}); |
|||
}); |
|||
}, |
|||
|
|||
// 处理API错误
|
|||
handleApiError(result) { |
|||
console.log('API错误:', result); |
|||
|
|||
this.setData({ |
|||
isSubmitting: false, |
|||
currentStep: 1, |
|||
lineProgress2: 0 |
|||
}); |
|||
|
|||
// 根据错误码显示不同提示
|
|||
let title = '认证失败'; |
|||
let message = result.message || '请检查信息后重试'; |
|||
|
|||
// 根据不同的错误码定制提示信息
|
|||
if (result.code === 500) { |
|||
message = result.message || '服务器内部错误,请稍后重试'; |
|||
} else if (result.code === 400) { |
|||
message = result.message || '请求参数错误,请检查填写的信息'; |
|||
} else if (result.code === 401) { |
|||
message = result.message || '身份验证失败,请重新登录'; |
|||
} else if (result.code === 403) { |
|||
message = result.message || '认证信息不正确,请核对姓名和身份证号'; |
|||
} |
|||
|
|||
this.showErrorModal(title, message); |
|||
}, |
|||
|
|||
// 显示成功弹窗
|
|||
showSuccessModal(maskedId) { |
|||
this.setData({ |
|||
maskedIdNumber: maskedId, |
|||
showSuccessModal: true |
|||
}); |
|||
}, |
|||
|
|||
// 关闭成功弹窗
|
|||
closeSuccessModal() { |
|||
this.setData({ showSuccessModal: false }); |
|||
}, |
|||
|
|||
// 返回
|
|||
goToHome() { |
|||
this.closeSuccessModal(); |
|||
wx.switchTab({ |
|||
url: '/pages/personal/personal' |
|||
}); |
|||
} |
|||
}); |
|||
@ -0,0 +1,4 @@ |
|||
{ |
|||
"navigationBarTitleText":"实名认证", |
|||
"usingComponents": {} |
|||
} |
|||
@ -0,0 +1,285 @@ |
|||
<view class="auth-container"> |
|||
<!-- 背景装饰 --> |
|||
<view class="background-design"> |
|||
<view class="bg-circle circle-1"></view> |
|||
<view class="bg-circle circle-2"></view> |
|||
<view class="bg-wave"></view> |
|||
</view> |
|||
|
|||
<!-- 头部区域 --> |
|||
<view class="header-section"> |
|||
<view class="brand-header"> |
|||
<view class="brand-text"> |
|||
<view class="brand-name">与牧同行</view> |
|||
<view class="brand-slogan">专业牧业,贴心同行</view> |
|||
</view> |
|||
</view> |
|||
|
|||
<view class="auth-header"> |
|||
<view class="auth-title"> |
|||
<text class="title-text">实名认证</text> |
|||
<view class="title-badge">必填</view> |
|||
</view> |
|||
<view class="auth-description"> |
|||
为了更好的服务体验,请完成实名认证 |
|||
</view> |
|||
</view> |
|||
</view> |
|||
|
|||
<!-- 进度指示 --> |
|||
<view class="progress-indicator"> |
|||
<view class="progress-step active"> |
|||
<view class="step-bubble"> |
|||
<view class="step-number">1</view> |
|||
</view> |
|||
<view class="step-label">填写信息</view> |
|||
</view> |
|||
|
|||
<view class="progress-line"> |
|||
<view class="line-progress" style="width: {{lineProgress1}}%;"></view> |
|||
</view> |
|||
|
|||
<view class="progress-step {{currentStep >= 2 ? 'active' : ''}}"> |
|||
<view class="step-bubble"> |
|||
<view class="step-number">2</view> |
|||
</view> |
|||
<view class="step-label">信息验证</view> |
|||
</view> |
|||
|
|||
<view class="progress-line"> |
|||
<view class="line-progress" style="width: {{lineProgress2}}%;"></view> |
|||
</view> |
|||
|
|||
<view class="progress-step {{currentStep >= 3 ? 'active' : ''}}"> |
|||
<view class="step-bubble"> |
|||
<view class="step-number">3</view> |
|||
</view> |
|||
<view class="step-label">完成认证</view> |
|||
</view> |
|||
</view> |
|||
|
|||
<!-- 表单区域 --> |
|||
<view class="form-section"> |
|||
<!-- 姓名输入 --> |
|||
<view class="input-card"> |
|||
<view class="input-label"> |
|||
<image class="label-icon" src="/pagesA/images/name.png" mode="aspectFit"></image> |
|||
<text class="label-text">真实姓名</text> |
|||
<text class="required-star">*</text> |
|||
</view> |
|||
|
|||
<view class="input-container"> |
|||
<input |
|||
class="input-field {{nameFocus ? 'focused' : ''}} {{nameError ? 'error' : ''}} {{name ? 'has-value' : ''}} {{isNameValid ? 'valid' : ''}}" |
|||
placeholder="请输入您的真实姓名" |
|||
placeholder-class="placeholder" |
|||
value="{{name}}" |
|||
bindinput="onNameInput" |
|||
bindfocus="onNameFocus" |
|||
bindblur="onNameBlur" |
|||
maxlength="10" |
|||
/> |
|||
|
|||
<!-- 删除按钮 --> |
|||
<view class="clear-wrapper" wx:if="{{name}}"> |
|||
<button class="clear-btn" bindtap="clearName" hover-class="btn-hover"> |
|||
<image class="clear-icon" src="/pagesA/images/ch.png" mode="aspectFit"></image> |
|||
</button> |
|||
</view> |
|||
|
|||
<!-- 输入框下划线 --> |
|||
<view class="input-underline"> |
|||
<view class="underline-bg"></view> |
|||
<view class="underline-progress {{nameFocus ? 'active' : ''}}"></view> |
|||
</view> |
|||
|
|||
<!-- 字符计数 --> |
|||
<view class="char-count {{name.length > 8 ? 'warning' : ''}}"> |
|||
{{name.length}}/10 |
|||
</view> |
|||
</view> |
|||
|
|||
<!-- 提示信息 --> |
|||
<view class="hint-container" wx:if="{{showNameHint || nameError}}"> |
|||
<text class="hint-text {{nameError ? 'error' : 'normal'}}"> |
|||
{{nameError || '请输入与身份证一致的姓名(2-10个汉字)'}} |
|||
</text> |
|||
</view> |
|||
</view> |
|||
|
|||
<!-- 身份证号输入 --> |
|||
<view class="input-card"> |
|||
<view class="input-label"> |
|||
<image class="label-icon" src="/pagesA/images/sfz.png" mode="aspectFit"></image> |
|||
<text class="label-text">身份证号</text> |
|||
<text class="required-star">*</text> |
|||
</view> |
|||
|
|||
<view class="input-container"> |
|||
<input |
|||
class="input-field {{idNumberError ? 'error' : ''}} {{isIdNumberValid ? 'valid' : ''}} {{idNumber ? 'has-value' : ''}}" |
|||
placeholder="请输入18位身份证号码" |
|||
placeholder-class="placeholder" |
|||
value="{{idNumber}}" |
|||
bindinput="onIdNumberInput" |
|||
bindfocus="onIdNumberFocus" |
|||
bindblur="onIdNumberBlur" |
|||
maxlength="18" |
|||
type="idcard" |
|||
/> |
|||
|
|||
<!-- 删除按钮 --> |
|||
<view class="clear-wrapper" wx:if="{{idNumber}}"> |
|||
<button class="clear-btn" bindtap="clearIdNumber" hover-class="btn-hover"> |
|||
<image class="clear-icon" src="/pagesA/images/ch.png" mode="aspectFit"></image> |
|||
</button> |
|||
</view> |
|||
|
|||
<!-- 输入框下划线 --> |
|||
<view class="input-underline"> |
|||
<view class="underline-bg"></view> |
|||
<view class="underline-progress {{idNumberFocus ? 'active' : ''}}"></view> |
|||
</view> |
|||
|
|||
<!-- 分段显示 --> |
|||
<view class="id-segments {{idNumberFocus || idNumber ? 'show' : ''}}"> |
|||
<view class="id-segment {{idNumber.length >= 6 ? 'filled' : ''}}">{{idNumber.substring(0, 6) || '地区'}}</view> |
|||
<view class="id-segment {{idNumber.length >= 14 ? 'filled' : ''}}">{{idNumber.substring(6, 14) || '出生'}}</view> |
|||
<view class="id-segment {{idNumber.length >= 17 ? 'filled' : ''}}">{{idNumber.substring(14, 17) || '顺序'}}</view> |
|||
<view class="id-segment last {{idNumber.length === 18 ? 'filled' : ''}}">{{idNumber.substring(17) || '校验'}}</view> |
|||
</view> |
|||
</view> |
|||
|
|||
<!-- 提示信息 --> |
|||
<view class="hint-container" wx:if="{{showIdNumberHint || idNumberError}}"> |
|||
<text class="hint-text {{idNumberError ? 'error' : 'normal'}}"> |
|||
{{idNumberError || '请输入有效的18位身份证号码'}} |
|||
</text> |
|||
</view> |
|||
</view> |
|||
|
|||
<!-- 协议条款 --> |
|||
<view class="agreement-card"> |
|||
<label class="agreement-item" bindtap="toggleAgreement"> |
|||
<view class="agreement-checkbox {{agreed ? 'checked' : ''}}"> |
|||
<image |
|||
wx:if="{{agreed}}" |
|||
class="checkmark" |
|||
src="/pagesA/images/duig.png" |
|||
mode="aspectFit" |
|||
></image> |
|||
</view> |
|||
<view class="agreement-content"> |
|||
<text>我已阅读并同意</text> |
|||
<text class="link-text" bindtap="showAgreementModal">《用户服务协议》</text> |
|||
<text>和</text> |
|||
<text class="link-text" bindtap="showPrivacyModal">《隐私保护协议》</text> |
|||
</view> |
|||
</label> |
|||
</view> |
|||
</view> |
|||
|
|||
<!-- 提交区域 --> |
|||
<view class="submit-section"> |
|||
<button |
|||
class="submit-button {{canSubmit ? 'active' : 'disabled'}}" |
|||
bindtap="submitAuth" |
|||
disabled="{{!canSubmit}}" |
|||
hover-class="button-hover" |
|||
loading="{{isSubmitting}}" |
|||
> |
|||
验证 |
|||
</button> |
|||
</view> |
|||
|
|||
<!-- 协议弹窗 --> |
|||
<view class="modal-overlay {{showModal ? 'show' : ''}}" bindtap="closeModal"> |
|||
<view class="modal-container" catchtap="stopPropagation"> |
|||
<view class="modal-header"> |
|||
<view class="modal-title">{{modalTitle}}</view> |
|||
<button class="modal-close" bindtap="closeModal"> |
|||
<image class="close-icon" src="/pagesA/images/ch.png" mode="aspectFit"></image> |
|||
</button> |
|||
</view> |
|||
|
|||
<scroll-view class="modal-content" scroll-y> |
|||
<view class="modal-text"> |
|||
{{modalContent}} |
|||
</view> |
|||
</scroll-view> |
|||
|
|||
<view class="modal-footer"> |
|||
<button class="modal-confirm" bindtap="closeModal"> |
|||
我已阅读并理解 |
|||
</button> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
|
|||
<!-- 成功弹窗 --> |
|||
<view class="success-modal {{showSuccessModal ? 'show' : ''}}"> |
|||
<view class="success-overlay" bindtap="closeSuccessModal"></view> |
|||
<view class="success-container"> |
|||
<view class="success-icon"> |
|||
<image class="success-badge" src="/pagesA/images/duig.png" mode="aspectFit"></image> |
|||
<view class="success-ring ring-1"></view> |
|||
<view class="success-ring ring-2"></view> |
|||
</view> |
|||
|
|||
<view class="success-body"> |
|||
<view class="success-title">认证成功!</view> |
|||
<view class="success-message"> |
|||
欢迎加入<text class="brand">与牧同行</text>大家庭 |
|||
</view> |
|||
|
|||
<view class="success-details"> |
|||
<view class="detail-item"> |
|||
<view class="detail-label"> |
|||
<image class="detail-icon" src="/pagesA/images/name.png" mode="aspectFit"></image> |
|||
<text>姓名</text> |
|||
</view> |
|||
<view class="detail-value">{{name}}</view> |
|||
</view> |
|||
|
|||
<view class="detail-item"> |
|||
<view class="detail-label"> |
|||
<image class="detail-icon" src="/pagesA/images/sfz.png" mode="aspectFit"></image> |
|||
<text>身份证号</text> |
|||
</view> |
|||
<view class="detail-value">{{maskedIdNumber}}</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
|
|||
<view class="success-footer"> |
|||
<button class="success-button" bindtap="goToHome"> |
|||
<text>开始使用</text> |
|||
</button> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
|
|||
<!-- 错误弹窗(新增) --> |
|||
<view class="modal-overlay {{showErrorModal ? 'show' : ''}}" bindtap="closeErrorModal"> |
|||
<view class="modal-container error-modal" catchtap="stopPropagation"> |
|||
<view class="modal-header"> |
|||
<view class="modal-title error-title">{{errorTitle}}</view> |
|||
<button class="modal-close" bindtap="closeErrorModal"> |
|||
<image class="close-icon" src="/pagesA/images/ch.png" mode="aspectFit"></image> |
|||
</button> |
|||
</view> |
|||
|
|||
<view class="modal-content error-content"> |
|||
<view class="error-message"> |
|||
{{errorMessage}} |
|||
</view> |
|||
</view> |
|||
|
|||
<view class="modal-footer"> |
|||
<button class="modal-confirm error-confirm" bindtap="closeErrorModal"> |
|||
确定 |
|||
</button> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
1392
pagesA/pages/attestation/attestation.wxss
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -1,66 +1,218 @@ |
|||
import http from '../../../utils/api' |
|||
const baseUrl = require('../../../utils/baseUrl') |
|||
Page({ |
|||
data: { |
|||
diagnosisList: [] |
|||
diagnosisList: [], |
|||
// 弹窗相关
|
|||
showPlanPopup: false, |
|||
consultationId: null, |
|||
baseUrl:baseUrl, |
|||
planForm: { |
|||
title: '', // 新增方案标题
|
|||
diagnosis: '', |
|||
treatmentMethod: '', |
|||
treatmentDesc: '', |
|||
precautions: '' |
|||
} |
|||
}, |
|||
|
|||
onLoad: function () { |
|||
|
|||
onLoad: function() { |
|||
// 页面加载时可做一些初始化
|
|||
}, |
|||
|
|||
onShow:function(){ |
|||
onShow: function() { |
|||
this.getwzd() |
|||
}, |
|||
|
|||
|
|||
// 问诊单
|
|||
// 获取问诊列表
|
|||
getwzd() { |
|||
http.wzd({ |
|||
data: {}, |
|||
success: res => { |
|||
console.log(1111, res); |
|||
console.log('问诊列表:', res); |
|||
this.setData({ |
|||
diagnosisList: res.rows |
|||
diagnosisList: res.rows || [] |
|||
}) |
|||
}, |
|||
fail: err => { |
|||
console.error('获取问诊列表失败', err); |
|||
wx.showToast({ |
|||
title: '加载失败', |
|||
icon: 'none' |
|||
}); |
|||
} |
|||
}) |
|||
}, |
|||
|
|||
// 制定方案(打开弹窗)
|
|||
bindPlan(e) { |
|||
const consultationId = e.currentTarget.dataset.id; |
|||
console.log('当前咨询ID:', consultationId); |
|||
|
|||
// 重置表单(包含title字段)
|
|||
this.setData({ |
|||
consultationId: consultationId, |
|||
planForm: { |
|||
title: '', |
|||
diagnosis: '', |
|||
treatmentMethod: '', |
|||
treatmentDesc: '', |
|||
precautions: '' |
|||
}, |
|||
showPlanPopup: true |
|||
}); |
|||
}, |
|||
|
|||
// 格式化日期显示
|
|||
formatDate: function (dateString) { |
|||
const date = new Date(dateString); |
|||
const now = new Date(); |
|||
const diff = now - date; |
|||
const diffDays = Math.floor(diff / (1000 * 60 * 60 * 24)); |
|||
const diffHours = Math.floor(diff / (1000 * 60 * 60)); |
|||
const diffMinutes = Math.floor(diff / (1000 * 60)); |
|||
|
|||
if (diffMinutes < 60) { |
|||
return `${diffMinutes}分钟前`; |
|||
} else if (diffHours < 24) { |
|||
return `${diffHours}小时前`; |
|||
} else if (diffDays === 1) { |
|||
return '昨天'; |
|||
} else if (diffDays === 2) { |
|||
return '前天'; |
|||
} else if (diffDays < 7) { |
|||
return `${diffDays}天前`; |
|||
} else { |
|||
const month = date.getMonth() + 1; |
|||
const day = date.getDate(); |
|||
return `${month}月${day}日`; |
|||
} |
|||
// 关闭弹窗
|
|||
closePlanPopup() { |
|||
this.setData({ |
|||
showPlanPopup: false, |
|||
consultationId: null |
|||
}); |
|||
}, |
|||
|
|||
// 表单输入处理函数
|
|||
onTitleInput(e) { |
|||
this.setData({ |
|||
'planForm.title': e.detail.value |
|||
}); |
|||
}, |
|||
|
|||
onDiagnosisInput(e) { |
|||
this.setData({ |
|||
'planForm.diagnosis': e.detail.value |
|||
}); |
|||
}, |
|||
|
|||
onTreatmentMethodInput(e) { |
|||
this.setData({ |
|||
'planForm.treatmentMethod': e.detail.value |
|||
}); |
|||
}, |
|||
|
|||
onTreatmentDescInput(e) { |
|||
this.setData({ |
|||
'planForm.treatmentDesc': e.detail.value |
|||
}); |
|||
}, |
|||
|
|||
onPrecautionsInput(e) { |
|||
this.setData({ |
|||
'planForm.precautions': e.detail.value |
|||
}); |
|||
}, |
|||
|
|||
// 提交方案
|
|||
submitPlan() { |
|||
const { title, diagnosis, treatmentMethod, treatmentDesc } = this.data.planForm; |
|||
const consultationId = this.data.consultationId; |
|||
|
|||
// 必填校验(包含标题)
|
|||
if (!title || !title.trim()) { |
|||
wx.showToast({ |
|||
title: '请填写方案标题', |
|||
icon: 'none', |
|||
duration: 2000 |
|||
}); |
|||
return; |
|||
} |
|||
|
|||
if (!diagnosis || !diagnosis.trim()) { |
|||
wx.showToast({ |
|||
title: '请填写诊断结果', |
|||
icon: 'none', |
|||
duration: 2000 |
|||
}); |
|||
return; |
|||
} |
|||
|
|||
if (!treatmentMethod || !treatmentMethod.trim()) { |
|||
wx.showToast({ |
|||
title: '请填写治疗方式', |
|||
icon: 'none', |
|||
duration: 2000 |
|||
}); |
|||
return; |
|||
} |
|||
|
|||
if (!treatmentDesc || !treatmentDesc.trim()) { |
|||
wx.showToast({ |
|||
title: '请填写治疗方案描述', |
|||
icon: 'none', |
|||
duration: 2000 |
|||
}); |
|||
return; |
|||
} |
|||
|
|||
if (!consultationId) { |
|||
wx.showToast({ |
|||
title: '咨询ID缺失,请重试', |
|||
icon: 'none' |
|||
}); |
|||
return; |
|||
} |
|||
|
|||
// 显示加载
|
|||
wx.showLoading({ |
|||
title: '提交中...', |
|||
mask: true |
|||
}); |
|||
|
|||
// 构建提交数据(包含title)
|
|||
const submitData = { |
|||
consultationId: consultationId, |
|||
title: title.trim(), // 新增标题字段
|
|||
diagnosis: diagnosis.trim(), |
|||
treatmentMethod: treatmentMethod.trim(), |
|||
treatmentDesc: treatmentDesc.trim(), |
|||
precautions: this.data.planForm.precautions?.trim() || '' |
|||
}; |
|||
|
|||
console.log('提交数据:', submitData); |
|||
|
|||
// 调用API
|
|||
http.fazdAdd({ |
|||
data: submitData, |
|||
success: (res) => { |
|||
wx.hideLoading(); |
|||
// 根据实际接口返回结构调整判断条件
|
|||
if (res.code === 200 || res.code === 0 || res.success) { |
|||
wx.showToast({ |
|||
title: '方案提交成功', |
|||
icon: 'success', |
|||
duration: 2000 |
|||
}); |
|||
|
|||
// 关闭弹窗
|
|||
this.closePlanPopup(); |
|||
|
|||
// 刷新列表(可选)
|
|||
setTimeout(() => { |
|||
this.getwzd(); |
|||
}, 500); |
|||
} else { |
|||
wx.showToast({ |
|||
title: res.msg || '提交失败', |
|||
icon: 'none' |
|||
}); |
|||
} |
|||
}, |
|||
fail: (err) => { |
|||
wx.hideLoading(); |
|||
console.error('提交失败', err); |
|||
wx.showToast({ |
|||
title: '网络错误,请重试', |
|||
icon: 'none' |
|||
}); |
|||
} |
|||
}); |
|||
}, |
|||
|
|||
// 查看详情
|
|||
viewDetail: function (e) { |
|||
const data = e.currentTarget.dataset.value |
|||
viewDetail: function(e) { |
|||
const data = e.currentTarget.dataset.value; |
|||
wx.navigateTo({ |
|||
url: `/pagesA/pages/askingSyDetails/askingSyDetails?data=${encodeURIComponent(JSON.stringify(data))}`, |
|||
}); |
|||
}, |
|||
|
|||
} |
|||
}); |
|||
@ -1,3 +1,4 @@ |
|||
{ |
|||
"navigationBarTitleText":"制定方案", |
|||
"usingComponents": {} |
|||
} |
|||
1026
pagesA/pages/precept/precept.wxss
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
Write
Preview
Loading…
Cancel
Save
Reference in new issue