256 lines
6.6 KiB
Vue
256 lines
6.6 KiB
Vue
<template>
|
||
<view class="add-contact-page">
|
||
<!-- 表单 -->
|
||
<view class="form-container">
|
||
<view class="form-item" @click="showIdTypePicker = true">
|
||
<view class="form-label">证件类型</view>
|
||
<view class="form-value">
|
||
<text>{{ formData.idType }}</text>
|
||
<text class="arrow">›</text>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="form-item">
|
||
<view class="form-label">姓名</view>
|
||
<view class="form-value">
|
||
<input class="form-input" v-model="formData.name" placeholder="请输入姓名" placeholder-class="placeholder" />
|
||
</view>
|
||
</view>
|
||
|
||
<view class="form-item">
|
||
<view class="form-label">证件号码</view>
|
||
<view class="form-value">
|
||
<input class="form-input" v-model="formData.idCard" placeholder="请输入身份证号码" placeholder-class="placeholder" />
|
||
</view>
|
||
</view>
|
||
|
||
<view class="form-item">
|
||
<view class="form-label">手机号码</view>
|
||
<view class="form-value">
|
||
<input class="form-input" v-model="formData.phone" placeholder="请输入手机号码" placeholder-class="placeholder" type="number" />
|
||
</view>
|
||
</view>
|
||
|
||
<view class="form-item">
|
||
<view class="form-label">邮箱</view>
|
||
<view class="form-value">
|
||
<input class="form-input" v-model="formData.email" placeholder="请输入邮箱" placeholder-class="placeholder" />
|
||
</view>
|
||
</view>
|
||
|
||
<view class="form-item">
|
||
<view class="form-label">地址</view>
|
||
<view class="form-value">
|
||
<input class="form-input" v-model="formData.address" placeholder="请输入地址" placeholder-class="placeholder" />
|
||
</view>
|
||
</view>
|
||
|
||
<view class="form-item switch-item">
|
||
<view class="form-label">设置为默认联系人</view>
|
||
<view class="form-value">
|
||
<switch :checked="formData.isDefault" @change="handleSwitchChange" color="#C93639" />
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- Toast提示 -->
|
||
<view class="toast-message" v-if="showToast">
|
||
<text class="toast-text">{{ toastMessage }}</text>
|
||
</view>
|
||
|
||
<!-- 按钮 -->
|
||
<view class="btn-wrapper">
|
||
<view class="btn save-btn" :class="{ disabled: !isFormValid || saving }" @click="handleSave">
|
||
{{ saving ? '保存中...' : '保存' }}
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
import athleteAPI from '@/api/athlete.js';
|
||
|
||
export default {
|
||
data() {
|
||
return {
|
||
formData: {
|
||
idType: '身份证',
|
||
name: '',
|
||
idCard: '',
|
||
phone: '',
|
||
email: '',
|
||
address: '',
|
||
isDefault: false
|
||
},
|
||
showToast: false,
|
||
toastMessage: '',
|
||
saving: false
|
||
};
|
||
},
|
||
computed: {
|
||
isFormValid() {
|
||
return this.formData.name && this.formData.idCard && this.formData.phone &&
|
||
this.validateIdCard(this.formData.idCard) && this.validatePhone(this.formData.phone);
|
||
}
|
||
},
|
||
methods: {
|
||
validateIdCard(idCard) {
|
||
return /^\d{17}[\dXx]$/.test(idCard);
|
||
},
|
||
validatePhone(phone) {
|
||
return /^1\d{10}$/.test(phone);
|
||
},
|
||
handleSwitchChange(e) {
|
||
this.formData.isDefault = e.detail.value;
|
||
},
|
||
showToastMsg(msg) {
|
||
this.toastMessage = msg;
|
||
this.showToast = true;
|
||
setTimeout(() => { this.showToast = false; }, 2000);
|
||
},
|
||
async handleSave() {
|
||
if (!this.isFormValid || this.saving) return;
|
||
|
||
if (!this.validatePhone(this.formData.phone)) {
|
||
this.showToastMsg('手机号码格式不正确');
|
||
return;
|
||
}
|
||
if (!this.validateIdCard(this.formData.idCard)) {
|
||
this.showToastMsg('身份证号码格式不正确');
|
||
return;
|
||
}
|
||
|
||
this.saving = true;
|
||
try {
|
||
await athleteAPI.saveContact(this.formData);
|
||
uni.showToast({ title: '保存成功', icon: 'success' });
|
||
|
||
// Set flag to notify previous page
|
||
uni.setStorageSync('contactListNeedRefresh', true);
|
||
|
||
// Notify previous page to refresh contact list
|
||
try {
|
||
const pages = getCurrentPages();
|
||
console.log('页面栈长度:', pages.length);
|
||
console.log('页面栈:', pages);
|
||
if (pages.length >= 2) {
|
||
const prevPage = pages[pages.length - 2];
|
||
console.log('上一页:', prevPage);
|
||
// Try different ways to access the component
|
||
const vm = prevPage.$vm || prevPage;
|
||
console.log('vm:', vm);
|
||
if (vm && typeof vm.loadContactList === 'function') {
|
||
console.log('调用 loadContactList');
|
||
vm.loadContactList();
|
||
} else if (vm && vm.$refs && vm.$refs.page && typeof vm.$refs.page.loadContactList === 'function') {
|
||
console.log('通过 $refs 调用');
|
||
vm.$refs.page.loadContactList();
|
||
}
|
||
}
|
||
} catch (e) {
|
||
console.error('通知上一页失败:', e);
|
||
}
|
||
|
||
// Also emit event as backup
|
||
uni.$emit('contactAdded');
|
||
|
||
setTimeout(() => { uni.navigateBack(); }, 1500);
|
||
} catch (err) {
|
||
console.error('保存联系人失败:', err);
|
||
this.showToastMsg('保存失败,请重试');
|
||
} finally {
|
||
this.saving = false;
|
||
}
|
||
}
|
||
}
|
||
};
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.add-contact-page {
|
||
min-height: 100vh;
|
||
background-color: #f5f5f5;
|
||
padding-bottom: 200rpx;
|
||
}
|
||
|
||
.form-container {
|
||
background-color: #fff;
|
||
margin: 30rpx;
|
||
border-radius: 16rpx;
|
||
overflow: hidden;
|
||
}
|
||
|
||
.form-item {
|
||
display: flex;
|
||
align-items: center;
|
||
padding: 35rpx 30rpx;
|
||
border-bottom: 1rpx solid #f5f5f5;
|
||
}
|
||
|
||
.form-item:last-child { border-bottom: none; }
|
||
.switch-item { padding: 30rpx; }
|
||
|
||
.form-label {
|
||
width: 180rpx;
|
||
font-size: 30rpx;
|
||
color: #333333;
|
||
}
|
||
|
||
.form-value {
|
||
flex: 1;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
}
|
||
|
||
.form-input {
|
||
flex: 1;
|
||
font-size: 30rpx;
|
||
color: #333333;
|
||
}
|
||
|
||
.placeholder { color: #cccccc; }
|
||
.arrow { font-size: 40rpx; color: #cccccc; margin-left: 10rpx; }
|
||
|
||
.toast-message {
|
||
position: fixed;
|
||
top: 50%;
|
||
left: 50%;
|
||
transform: translate(-50%, -50%);
|
||
background-color: rgba(0, 0, 0, 0.7);
|
||
color: #fff;
|
||
padding: 30rpx 50rpx;
|
||
border-radius: 16rpx;
|
||
z-index: 9999;
|
||
}
|
||
|
||
.toast-text { font-size: 28rpx; }
|
||
|
||
.btn-wrapper {
|
||
position: fixed;
|
||
bottom: 0;
|
||
left: 0;
|
||
right: 0;
|
||
padding: 30rpx;
|
||
background-color: #f5f5f5;
|
||
}
|
||
|
||
.btn {
|
||
width: 100%;
|
||
text-align: center;
|
||
padding: 30rpx;
|
||
border-radius: 12rpx;
|
||
font-size: 32rpx;
|
||
font-weight: bold;
|
||
}
|
||
|
||
.save-btn {
|
||
background-color: #C93639;
|
||
color: #fff;
|
||
}
|
||
|
||
.save-btn.disabled {
|
||
background-color: rgba(201, 54, 57, 0.5);
|
||
}
|
||
</style>
|