chore: establish V1.1 recovery baseline

This commit is contained in:
2026-09-09 22:05:00 +08:00
commit b46b48eb33
947 changed files with 155471 additions and 0 deletions
@@ -0,0 +1,66 @@
// pages/local-eligibility-supplement/local-eligibility-supplement.js
Page({
/**
* 页面的初始数据
*/
data: {
},
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady() {
},
/**
* 生命周期函数--监听页面显示
*/
onShow() {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide() {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload() {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh() {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom() {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage() {
}
})
@@ -0,0 +1,4 @@
{
"navigationBarTitleText": "补充本地资格佐证",
"usingComponents": {}
}
@@ -0,0 +1,76 @@
// 本地资格补充核验页 U63
// 用户上传佐证材料(工作证明/居住证明等)
Page({
data: {
eligibilityType: '',
evidenceTypes: [
{ value: 'employment_proof', label: '工作证明', desc: '劳动合同/工牌/在职证明等' },
{ value: 'residence_proof', label: '居住证明', desc: '房产证/租赁合同/水电账单等' },
{ value: 'household_proof', label: '户籍证明', desc: '户口本/户籍页等' },
{ value: 'other', label: '其他材料', desc: '能证明您在丹阳的材料' }
],
selectedType: '',
uploadedFileIds: [] as string[]
},
onLoad(options: Record<string, string>) {
if (options.type) {
this.setData({ eligibilityType: options.type })
}
},
onShow() {
// TODO: P04-V11 加载当前用户的已上传佐证
},
// 选择佐证类型
onEvidenceTypeSelect(e: WechatMiniprogram.TouchEvent) {
this.setData({ selectedType: e.currentTarget.dataset.type })
},
// 上传图片
onChooseImage() {
wx.chooseMedia({
count: 6,
mediaType: ['image'],
sourceType: ['album', 'camera'],
success: (res) => {
// TODO: P04-V11 上传到对象存储,获取fileId
res.tempFiles.forEach(file => {
console.log('选择的图片:', file.tempFilePath)
})
wx.showToast({ title: '上传成功', icon: 'success' })
}
})
},
// 提交审核
onSubmit() {
if (!this.data.selectedType) {
wx.showToast({ title: '请选择佐证类型', icon: 'none' })
return
}
if (this.data.uploadedFileIds.length === 0) {
wx.showToast({ title: '请上传佐证材料', icon: 'none' })
return
}
// TODO: P04-V11 调用API提交
wx.showLoading({ title: '提交中...' })
setTimeout(() => {
wx.hideLoading()
wx.showToast({ title: '已提交审核', icon: 'success' })
setTimeout(() => {
wx.navigateBack()
}, 1500)
}, 1000)
},
// 删除已上传图片
onRemoveImage(e: WechatMiniprogram.TouchEvent) {
const index = e.currentTarget.dataset.index
const ids = this.data.uploadedFileIds
ids.splice(index, 1)
this.setData({ uploadedFileIds: ids })
}
})
@@ -0,0 +1,69 @@
<!-- U63 本地资格补充核验页 -->
<view class="page">
<!-- 说明文案 -->
<view class="header">
<text class="title">为了完成本地资格核验</text>
<text class="desc">
请补充一项能够说明您在丹阳工作或居住的材料。
材料仅用于资格审核,不对其他用户展示。
</text>
</view>
<!-- 已声明的资格类型 -->
<view class="type-tag" wx:if="{{eligibilityType}}">
<text>已声明:{{getEligibilityLabel(eligibilityType)}}</text>
</view>
<!-- 佐证类型选择 -->
<view class="section">
<text class="section-title">选择佐证类型</text>
<view class="evidence-list">
<view
wx:for="{{evidenceTypes}}"
wx:key="value"
class="evidence-card {{selectedType === item.value ? 'active' : ''}}"
bindtap="onEvidenceTypeSelect"
data-type="{{item.value}}"
>
<text class="evidence-label">{{item.label}}</text>
<text class="evidence-desc">{{item.desc}}</text>
</view>
</view>
</view>
<!-- 上传区域 -->
<view class="section">
<text class="section-title">上传佐证材料</text>
<view class="upload-area">
<view class="upload-hint">
<text class="hint-text">支持 JPG/PNG,最多 6 张</text>
</view>
<view class="image-grid">
<view
wx:for="{{uploadedFileIds}}"
wx:key="index"
class="image-item"
>
<image src="{{item}}" mode="aspectFill" class="image-preview" />
<view class="image-remove" bindtap="onRemoveImage" data-index="{{index}}">×</view>
</view>
<view class="upload-btn" bindtap="onChooseImage">
<text class="upload-icon">+</text>
<text class="upload-text">上传</text>
</view>
</view>
</view>
</view>
<!-- 隐私提示 -->
<view class="privacy-note">
<text class="note-text">🔒 仅用于资格审核,不对其他用户展示</text>
</view>
<!-- 提交按钮 -->
<view class="action-bar">
<button class="btn-primary" bindtap="onSubmit">
提交审核
</button>
</view>
</view>
@@ -0,0 +1,200 @@
/* U63 本地资格补充核验页 */
.page {
padding: 24rpx;
background: #FAFAF8;
min-height: 100vh;
padding-bottom: 120rpx;
}
.header {
background: #fff;
border-radius: 16rpx;
padding: 32rpx 24rpx;
margin-bottom: 24rpx;
}
.title {
display: block;
font-size: 32rpx;
font-weight: 600;
color: #1a1a1a;
margin-bottom: 12rpx;
}
.desc {
display: block;
font-size: 26rpx;
color: #666;
line-height: 1.6;
}
.type-tag {
background: #E8F5E9;
border-radius: 8rpx;
padding: 16rpx 20rpx;
margin-bottom: 24rpx;
}
.type-tag text {
font-size: 24rpx;
color: #2E7D32;
}
.section {
background: #fff;
border-radius: 16rpx;
padding: 24rpx;
margin-bottom: 24rpx;
}
.section-title {
font-size: 28rpx;
font-weight: 600;
color: #1a1a1a;
margin-bottom: 20rpx;
display: block;
}
.evidence-list {
display: flex;
flex-direction: column;
gap: 12rpx;
}
.evidence-card {
padding: 24rpx;
border-radius: 12rpx;
border: 2rpx solid #eee;
}
.evidence-card.active {
border-color: #E96B6B;
background: #FFF5F5;
}
.evidence-label {
display: block;
font-size: 28rpx;
font-weight: 500;
color: #333;
margin-bottom: 4rpx;
}
.evidence-desc {
display: block;
font-size: 22rpx;
color: #999;
}
.upload-area {
border: 2rpx dashed #ddd;
border-radius: 12rpx;
padding: 24rpx;
}
.upload-hint {
text-align: center;
margin-bottom: 16rpx;
}
.hint-text {
font-size: 22rpx;
color: #999;
}
.image-grid {
display: flex;
flex-wrap: wrap;
gap: 16rpx;
}
.image-item {
width: 160rpx;
height: 160rpx;
position: relative;
border-radius: 8rpx;
overflow: hidden;
}
.image-preview {
width: 100%;
height: 100%;
object-fit: cover;
}
.image-remove {
position: absolute;
top: 4rpx;
right: 4rpx;
width: 36rpx;
height: 36rpx;
background: rgba(0,0,0,0.5);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
color: #fff;
font-size: 24rpx;
line-height: 1;
}
.upload-btn {
width: 160rpx;
height: 160rpx;
border: 2rpx dashed #ccc;
border-radius: 8rpx;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.upload-icon {
font-size: 48rpx;
color: #ccc;
}
.upload-text {
font-size: 22rpx;
color: #999;
margin-top: 8rpx;
}
.privacy-note {
background: #F0F7FF;
border-radius: 8rpx;
padding: 16rpx 20rpx;
margin-bottom: 24rpx;
}
.note-text {
font-size: 24rpx;
color: #1976D2;
}
.action-bar {
position: fixed;
bottom: 0;
left: 0;
right: 0;
padding: 16rpx 24rpx;
background: #fff;
box-shadow: 0 -2rpx 12rpx rgba(0,0,0,0.05);
padding-bottom: calc(16rpx + env(safe-area-inset-bottom));
}
.btn-primary {
width: 100%;
height: 88rpx;
line-height: 88rpx;
background: #E96B6B;
color: #fff;
border-radius: 12rpx;
font-size: 30rpx;
font-weight: 500;
border: none;
}
.btn-primary:disabled {
background: #ccc;
}