feat: add contact management and various bug fixes
- Add contact API methods in athlete.js - Add contact list display in common-info.vue - Update add-contact.vue for contact creation - Create edit-contact page for contact editing - Fix event-register.vue with contact picker modal - Fix home.vue registration status display - Fix my-registration.vue cert modal display Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
This commit is contained in:
@@ -41,9 +41,6 @@ export default {
|
|||||||
|
|
||||||
// ========== 集体/团队相关 API ==========
|
// ========== 集体/团队相关 API ==========
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取集体列表
|
|
||||||
*/
|
|
||||||
getTeamList(params = {}) {
|
getTeamList(params = {}) {
|
||||||
return request.get('/martial/team/list', {
|
return request.get('/martial/team/list', {
|
||||||
current: params.current || 1,
|
current: params.current || 1,
|
||||||
@@ -52,24 +49,37 @@ export default {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取集体详情
|
|
||||||
*/
|
|
||||||
getTeamDetail(id) {
|
getTeamDetail(id) {
|
||||||
return request.get('/martial/team/detail', { id })
|
return request.get('/martial/team/detail', { id })
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* 保存集体
|
|
||||||
*/
|
|
||||||
saveTeam(data) {
|
saveTeam(data) {
|
||||||
return request.post('/martial/team/submit', data)
|
return request.post('/martial/team/submit', data)
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除集体
|
|
||||||
*/
|
|
||||||
removeTeam(id) {
|
removeTeam(id) {
|
||||||
return request.post('/martial/team/remove?id=' + id, {})
|
return request.post('/martial/team/remove?id=' + id, {})
|
||||||
|
},
|
||||||
|
|
||||||
|
// ========== 联系人相关 API ==========
|
||||||
|
|
||||||
|
getContactList(params = {}) {
|
||||||
|
return request.get('/martial/contact/list', {
|
||||||
|
current: params.current || 1,
|
||||||
|
size: params.size || 100,
|
||||||
|
...params
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
getContactDetail(id) {
|
||||||
|
return request.get('/martial/contact/detail', { id })
|
||||||
|
},
|
||||||
|
|
||||||
|
saveContact(data) {
|
||||||
|
return request.post('/martial/contact/submit', data)
|
||||||
|
},
|
||||||
|
|
||||||
|
removeContact(id) {
|
||||||
|
return request.post('/martial/contact/remove?ids=' + id, {})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
279
src/pages.json
279
src/pages.json
@@ -1,252 +1,35 @@
|
|||||||
{
|
{
|
||||||
"pages": [
|
"pages": [
|
||||||
{
|
{"path": "pages/login/login", "style": {"navigationBarTitleText": "登录", "navigationStyle": "custom"}},
|
||||||
"path": "pages/login/login",
|
{"path": "pages/register/register", "style": {"navigationBarTitleText": "注册", "navigationStyle": "custom"}},
|
||||||
"style": {
|
{"path": "pages/home/home", "style": {"navigationBarTitleText": "武术赛事通", "navigationBarBackgroundColor": "#C93639", "navigationBarTextStyle": "white"}},
|
||||||
"navigationBarTitleText": "登录",
|
{"path": "pages/profile/profile", "style": {"navigationBarTitleText": "个人中心", "navigationBarBackgroundColor": "#C93639", "navigationBarTextStyle": "white"}},
|
||||||
"navigationStyle": "custom"
|
{"path": "pages/change-password/change-password", "style": {"navigationBarTitleText": "修改密码", "navigationBarBackgroundColor": "#C93639", "navigationBarTextStyle": "white"}},
|
||||||
}
|
{"path": "pages/common-info/common-info", "style": {"navigationBarTitleText": "常用信息", "navigationBarBackgroundColor": "#C93639", "navigationBarTextStyle": "white"}},
|
||||||
},
|
{"path": "pages/add-player/add-player", "style": {"navigationBarTitleText": "新增选手", "navigationBarBackgroundColor": "#C93639", "navigationBarTextStyle": "white"}},
|
||||||
{
|
{"path": "pages/add-team/add-team", "style": {"navigationBarTitleText": "新增集体", "navigationBarBackgroundColor": "#C93639", "navigationBarTextStyle": "white"}},
|
||||||
"path": "pages/register/register",
|
{"path": "pages/edit-team/edit-team", "style": {"navigationBarTitleText": "编辑集体", "navigationBarBackgroundColor": "#C93639", "navigationBarTextStyle": "white"}},
|
||||||
"style": {
|
{"path": "pages/edit-player/edit-player", "style": {"navigationBarTitleText": "编辑选手", "navigationBarBackgroundColor": "#C93639", "navigationBarTextStyle": "white"}},
|
||||||
"navigationBarTitleText": "注册",
|
{"path": "pages/add-contact/add-contact", "style": {"navigationBarTitleText": "新增联系人", "navigationBarBackgroundColor": "#C93639", "navigationBarTextStyle": "white"}},
|
||||||
"navigationStyle": "custom"
|
{"path": "pages/edit-contact/edit-contact", "style": {"navigationBarTitleText": "编辑联系人", "navigationBarBackgroundColor": "#C93639", "navigationBarTextStyle": "white"}},
|
||||||
}
|
{"path": "pages/my-registration/my-registration", "style": {"navigationBarTitleText": "我的报名", "navigationBarBackgroundColor": "#C93639", "navigationBarTextStyle": "white"}},
|
||||||
},
|
{"path": "pages/event-list/event-list", "style": {"navigationBarTitleText": "全部赛事列表", "navigationBarBackgroundColor": "#C93639", "navigationBarTextStyle": "white"}},
|
||||||
{
|
{"path": "pages/event-detail/event-detail", "style": {"navigationBarTitleText": "赛事详情", "navigationBarBackgroundColor": "#C93639", "navigationBarTextStyle": "white"}},
|
||||||
"path": "pages/home/home",
|
{"path": "pages/select-event/select-event", "style": {"navigationBarTitleText": "选择报名项目", "navigationBarBackgroundColor": "#C93639", "navigationBarTextStyle": "white"}},
|
||||||
"style": {
|
{"path": "pages/event-register/event-register", "style": {"navigationBarTitleText": "赛事报名", "navigationBarBackgroundColor": "#C93639", "navigationBarTextStyle": "white"}},
|
||||||
"navigationBarTitleText": "武术赛事通",
|
{"path": "pages/register-type/register-type", "style": {"navigationBarTitleText": "选择报名", "navigationBarBackgroundColor": "#C93639", "navigationBarTextStyle": "white"}},
|
||||||
"navigationBarBackgroundColor": "#C93639",
|
{"path": "pages/event-info/event-info", "style": {"navigationBarTitleText": "信息发布", "navigationBarBackgroundColor": "#C93639", "navigationBarTextStyle": "white"}},
|
||||||
"navigationBarTextStyle": "white"
|
{"path": "pages/event-info-detail/event-info-detail", "style": {"navigationBarTitleText": "信息详情", "navigationBarBackgroundColor": "#C93639", "navigationBarTextStyle": "white"}},
|
||||||
}
|
{"path": "pages/event-rules/event-rules", "style": {"navigationBarTitleText": "赛事规程", "navigationBarBackgroundColor": "#C93639", "navigationBarTextStyle": "white"}},
|
||||||
},
|
{"path": "pages/event-schedule/event-schedule", "style": {"navigationBarTitleText": "活动日程", "navigationBarBackgroundColor": "#C93639", "navigationBarTextStyle": "white"}},
|
||||||
{
|
{"path": "pages/event-players/event-players", "style": {"navigationBarTitleText": "参赛选手", "navigationBarBackgroundColor": "#C93639", "navigationBarTextStyle": "white"}},
|
||||||
"path": "pages/profile/profile",
|
{"path": "pages/event-live/event-live", "style": {"navigationBarTitleText": "比赛实况", "navigationBarBackgroundColor": "#C93639", "navigationBarTextStyle": "white"}},
|
||||||
"style": {
|
{"path": "pages/event-lineup/event-lineup", "style": {"navigationBarTitleText": "出场顺序", "navigationBarBackgroundColor": "#C93639", "navigationBarTextStyle": "white"}},
|
||||||
"navigationBarTitleText": "个人中心",
|
{"path": "pages/event-score/event-score", "style": {"navigationBarTitleText": "成绩", "navigationBarBackgroundColor": "#C93639", "navigationBarTextStyle": "white"}},
|
||||||
"navigationBarBackgroundColor": "#C93639",
|
{"path": "pages/event-medals/event-medals", "style": {"navigationBarTitleText": "奖牌榜", "navigationBarBackgroundColor": "#C93639", "navigationBarTextStyle": "white"}},
|
||||||
"navigationBarTextStyle": "white"
|
{"path": "pages/attachment-view/attachment-view", "style": {"navigationBarTitleText": "附件查看", "navigationBarBackgroundColor": "#C93639", "navigationBarTextStyle": "white"}},
|
||||||
}
|
{"path": "pages/event-photos/event-photos", "style": {"navigationBarTitleText": "图片直播", "navigationBarBackgroundColor": "#C93639", "navigationBarTextStyle": "white"}}
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "pages/change-password/change-password",
|
|
||||||
"style": {
|
|
||||||
"navigationBarTitleText": "修改密码",
|
|
||||||
"navigationBarBackgroundColor": "#C93639",
|
|
||||||
"navigationBarTextStyle": "white"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "pages/common-info/common-info",
|
|
||||||
"style": {
|
|
||||||
"navigationBarTitleText": "常用信息",
|
|
||||||
"navigationBarBackgroundColor": "#C93639",
|
|
||||||
"navigationBarTextStyle": "white"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "pages/add-player/add-player",
|
|
||||||
"style": {
|
|
||||||
"navigationBarTitleText": "新增选手",
|
|
||||||
"navigationBarBackgroundColor": "#C93639",
|
|
||||||
"navigationBarTextStyle": "white"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "pages/add-team/add-team",
|
|
||||||
"style": {
|
|
||||||
"navigationBarTitleText": "新增集体",
|
|
||||||
"navigationBarBackgroundColor": "#C93639",
|
|
||||||
"navigationBarTextStyle": "white"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "pages/edit-team/edit-team",
|
|
||||||
"style": {
|
|
||||||
"navigationBarTitleText": "编辑集体",
|
|
||||||
"navigationBarBackgroundColor": "#C93639",
|
|
||||||
"navigationBarTextStyle": "white"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "pages/edit-player/edit-player",
|
|
||||||
"style": {
|
|
||||||
"navigationBarTitleText": "编辑选手",
|
|
||||||
"navigationBarBackgroundColor": "#C93639",
|
|
||||||
"navigationBarTextStyle": "white"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "pages/add-contact/add-contact",
|
|
||||||
"style": {
|
|
||||||
"navigationBarTitleText": "新增联系人",
|
|
||||||
"navigationBarBackgroundColor": "#C93639",
|
|
||||||
"navigationBarTextStyle": "white"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "pages/my-registration/my-registration",
|
|
||||||
"style": {
|
|
||||||
"navigationBarTitleText": "我的报名",
|
|
||||||
"navigationBarBackgroundColor": "#C93639",
|
|
||||||
"navigationBarTextStyle": "white"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "pages/event-list/event-list",
|
|
||||||
"style": {
|
|
||||||
"navigationBarTitleText": "全部赛事列表",
|
|
||||||
"navigationBarBackgroundColor": "#C93639",
|
|
||||||
"navigationBarTextStyle": "white"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "pages/event-detail/event-detail",
|
|
||||||
"style": {
|
|
||||||
"navigationBarTitleText": "赛事详情",
|
|
||||||
"navigationBarBackgroundColor": "#C93639",
|
|
||||||
"navigationBarTextStyle": "white"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "pages/select-event/select-event",
|
|
||||||
"style": {
|
|
||||||
"navigationBarTitleText": "选择报名项目",
|
|
||||||
"navigationBarBackgroundColor": "#C93639",
|
|
||||||
"navigationBarTextStyle": "white"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "pages/event-register/event-register",
|
|
||||||
"style": {
|
|
||||||
"navigationBarTitleText": "赛事报名",
|
|
||||||
"navigationBarBackgroundColor": "#C93639",
|
|
||||||
"navigationBarTextStyle": "white"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "pages/register-type/register-type",
|
|
||||||
"style": {
|
|
||||||
"navigationBarTitleText": "选择报名",
|
|
||||||
"navigationBarBackgroundColor": "#C93639",
|
|
||||||
"navigationBarTextStyle": "white"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "pages/event-info/event-info",
|
|
||||||
"style": {
|
|
||||||
"navigationBarTitleText": "信息发布",
|
|
||||||
"navigationBarBackgroundColor": "#C93639",
|
|
||||||
"navigationBarTextStyle": "white"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "pages/event-info-detail/event-info-detail",
|
|
||||||
"style": {
|
|
||||||
"navigationBarTitleText": "信息详情",
|
|
||||||
"navigationBarBackgroundColor": "#C93639",
|
|
||||||
"navigationBarTextStyle": "white"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "pages/event-rules/event-rules",
|
|
||||||
"style": {
|
|
||||||
"navigationBarTitleText": "赛事规程",
|
|
||||||
"navigationBarBackgroundColor": "#C93639",
|
|
||||||
"navigationBarTextStyle": "white"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "pages/event-schedule/event-schedule",
|
|
||||||
"style": {
|
|
||||||
"navigationBarTitleText": "活动日程",
|
|
||||||
"navigationBarBackgroundColor": "#C93639",
|
|
||||||
"navigationBarTextStyle": "white"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "pages/event-players/event-players",
|
|
||||||
"style": {
|
|
||||||
"navigationBarTitleText": "参赛选手",
|
|
||||||
"navigationBarBackgroundColor": "#C93639",
|
|
||||||
"navigationBarTextStyle": "white"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "pages/event-live/event-live",
|
|
||||||
"style": {
|
|
||||||
"navigationBarTitleText": "比赛实况",
|
|
||||||
"navigationBarBackgroundColor": "#C93639",
|
|
||||||
"navigationBarTextStyle": "white"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "pages/event-lineup/event-lineup",
|
|
||||||
"style": {
|
|
||||||
"navigationBarTitleText": "出场顺序",
|
|
||||||
"navigationBarBackgroundColor": "#C93639",
|
|
||||||
"navigationBarTextStyle": "white"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "pages/event-score/event-score",
|
|
||||||
"style": {
|
|
||||||
"navigationBarTitleText": "成绩",
|
|
||||||
"navigationBarBackgroundColor": "#C93639",
|
|
||||||
"navigationBarTextStyle": "white"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "pages/event-medals/event-medals",
|
|
||||||
"style": {
|
|
||||||
"navigationBarTitleText": "奖牌榜",
|
|
||||||
"navigationBarBackgroundColor": "#C93639",
|
|
||||||
"navigationBarTextStyle": "white"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "pages/attachment-view/attachment-view",
|
|
||||||
"style": {
|
|
||||||
"navigationBarTitleText": "附件查看",
|
|
||||||
"navigationBarBackgroundColor": "#C93639",
|
|
||||||
"navigationBarTextStyle": "white"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "pages/event-photos/event-photos",
|
|
||||||
"style": {
|
|
||||||
"navigationBarTitleText": "图片直播",
|
|
||||||
"navigationBarBackgroundColor": "#C93639",
|
|
||||||
"navigationBarTextStyle": "white"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
],
|
||||||
"globalStyle": {
|
"globalStyle": {"navigationBarTextStyle": "white", "navigationBarTitleText": "武术赛事", "navigationBarBackgroundColor": "#C93639", "backgroundColor": "#F8F8F8"},
|
||||||
"navigationBarTextStyle": "white",
|
"tabBar": {"color": "#999999", "selectedColor": "#C93639", "backgroundColor": "#ffffff", "borderStyle": "black", "list": [{"pagePath": "pages/home/home", "text": "首页", "iconPath": "static/images/首页灰@3x.png", "selectedIconPath": "static/images/首页亮@3x.png"}, {"pagePath": "pages/profile/profile", "text": "个人中心", "iconPath": "static/images/个人中心灰@3x.png", "selectedIconPath": "static/images/个人中心亮@3x.png"}]}
|
||||||
"navigationBarTitleText": "武术赛事",
|
|
||||||
"navigationBarBackgroundColor": "#C93639",
|
|
||||||
"backgroundColor": "#F8F8F8"
|
|
||||||
},
|
|
||||||
"tabBar": {
|
|
||||||
"color": "#999999",
|
|
||||||
"selectedColor": "#C93639",
|
|
||||||
"backgroundColor": "#ffffff",
|
|
||||||
"borderStyle": "black",
|
|
||||||
"list": [
|
|
||||||
{
|
|
||||||
"pagePath": "pages/home/home",
|
|
||||||
"text": "首页",
|
|
||||||
"iconPath": "static/images/首页灰@3x.png",
|
|
||||||
"selectedIconPath": "static/images/首页亮@3x.png"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"pagePath": "pages/profile/profile",
|
|
||||||
"text": "个人中心",
|
|
||||||
"iconPath": "static/images/个人中心灰@3x.png",
|
|
||||||
"selectedIconPath": "static/images/个人中心亮@3x.png"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,82 +13,46 @@
|
|||||||
<view class="form-item">
|
<view class="form-item">
|
||||||
<view class="form-label">姓名</view>
|
<view class="form-label">姓名</view>
|
||||||
<view class="form-value">
|
<view class="form-value">
|
||||||
<input
|
<input class="form-input" v-model="formData.name" placeholder="请输入姓名" placeholder-class="placeholder" />
|
||||||
class="form-input"
|
|
||||||
v-model="formData.name"
|
|
||||||
placeholder="请输入姓名"
|
|
||||||
placeholder-class="placeholder"
|
|
||||||
/>
|
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view class="form-item">
|
<view class="form-item">
|
||||||
<view class="form-label">证件号码</view>
|
<view class="form-label">证件号码</view>
|
||||||
<view class="form-value">
|
<view class="form-value">
|
||||||
<input
|
<input class="form-input" v-model="formData.idCard" placeholder="请输入身份证号码" placeholder-class="placeholder" />
|
||||||
class="form-input"
|
|
||||||
v-model="formData.idCard"
|
|
||||||
placeholder="请输入身份证号码"
|
|
||||||
placeholder-class="placeholder"
|
|
||||||
/>
|
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view class="form-item">
|
<view class="form-item">
|
||||||
<view class="form-label">手机号码</view>
|
<view class="form-label">手机号码</view>
|
||||||
<view class="form-value">
|
<view class="form-value">
|
||||||
<input
|
<input class="form-input" v-model="formData.phone" placeholder="请输入手机号码" placeholder-class="placeholder" type="number" />
|
||||||
class="form-input"
|
|
||||||
v-model="formData.phone"
|
|
||||||
placeholder="请输入手机号码"
|
|
||||||
placeholder-class="placeholder"
|
|
||||||
type="number"
|
|
||||||
/>
|
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view class="form-item">
|
<view class="form-item">
|
||||||
<view class="form-label">邮箱</view>
|
<view class="form-label">邮箱</view>
|
||||||
<view class="form-value">
|
<view class="form-value">
|
||||||
<input
|
<input class="form-input" v-model="formData.email" placeholder="请输入邮箱" placeholder-class="placeholder" />
|
||||||
class="form-input"
|
|
||||||
v-model="formData.email"
|
|
||||||
placeholder="请输入邮箱"
|
|
||||||
placeholder-class="placeholder"
|
|
||||||
/>
|
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view class="form-item">
|
<view class="form-item">
|
||||||
<view class="form-label">地址</view>
|
<view class="form-label">地址</view>
|
||||||
<view class="form-value">
|
<view class="form-value">
|
||||||
<input
|
<input class="form-input" v-model="formData.address" placeholder="请输入地址" placeholder-class="placeholder" />
|
||||||
class="form-input"
|
|
||||||
v-model="formData.address"
|
|
||||||
placeholder="请输入地址"
|
|
||||||
placeholder-class="placeholder"
|
|
||||||
/>
|
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view class="form-item switch-item">
|
<view class="form-item switch-item">
|
||||||
<view class="form-label">设置为默认联系人</view>
|
<view class="form-label">设置为默认联系人</view>
|
||||||
<view class="form-value">
|
<view class="form-value">
|
||||||
<switch
|
<switch :checked="formData.isDefault" @change="handleSwitchChange" color="#C93639" />
|
||||||
:checked="formData.isDefault"
|
|
||||||
@change="handleSwitchChange"
|
|
||||||
color="#C93639"
|
|
||||||
/>
|
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 提示信息 -->
|
|
||||||
<view class="hint-message" v-if="showHint">
|
|
||||||
<text class="hint-icon">ℹ</text>
|
|
||||||
<text class="hint-text">{{ hintText }}</text>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- Toast提示 -->
|
<!-- Toast提示 -->
|
||||||
<view class="toast-message" v-if="showToast">
|
<view class="toast-message" v-if="showToast">
|
||||||
<text class="toast-text">{{ toastMessage }}</text>
|
<text class="toast-text">{{ toastMessage }}</text>
|
||||||
@@ -96,13 +60,16 @@
|
|||||||
|
|
||||||
<!-- 按钮 -->
|
<!-- 按钮 -->
|
||||||
<view class="btn-wrapper">
|
<view class="btn-wrapper">
|
||||||
<view class="btn save-btn disabled" v-if="!isFormValid">保存</view>
|
<view class="btn save-btn" :class="{ disabled: !isFormValid || saving }" @click="handleSave">
|
||||||
<view class="btn save-btn" v-else @click="handleSave">保存</view>
|
{{ saving ? '保存中...' : '保存' }}
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import athleteAPI from '@/api/athlete.js';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@@ -115,27 +82,20 @@ export default {
|
|||||||
address: '',
|
address: '',
|
||||||
isDefault: false
|
isDefault: false
|
||||||
},
|
},
|
||||||
showHint: false,
|
|
||||||
hintText: '',
|
|
||||||
showToast: false,
|
showToast: false,
|
||||||
toastMessage: '',
|
toastMessage: '',
|
||||||
showIdTypePicker: false
|
saving: false
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
isFormValid() {
|
isFormValid() {
|
||||||
return (
|
return this.formData.name && this.formData.idCard && this.formData.phone &&
|
||||||
this.formData.name &&
|
this.validateIdCard(this.formData.idCard) && this.validatePhone(this.formData.phone);
|
||||||
this.formData.idCard &&
|
|
||||||
this.formData.phone &&
|
|
||||||
this.validateIdCard(this.formData.idCard) &&
|
|
||||||
this.validatePhone(this.formData.phone)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
validateIdCard(idCard) {
|
validateIdCard(idCard) {
|
||||||
return /^\d{18}$/.test(idCard);
|
return /^\d{17}[\dXx]$/.test(idCard);
|
||||||
},
|
},
|
||||||
validatePhone(phone) {
|
validatePhone(phone) {
|
||||||
return /^1\d{10}$/.test(phone);
|
return /^1\d{10}$/.test(phone);
|
||||||
@@ -143,38 +103,34 @@ export default {
|
|||||||
handleSwitchChange(e) {
|
handleSwitchChange(e) {
|
||||||
this.formData.isDefault = e.detail.value;
|
this.formData.isDefault = e.detail.value;
|
||||||
},
|
},
|
||||||
handleSave() {
|
showToastMsg(msg) {
|
||||||
if (!this.isFormValid) {
|
this.toastMessage = msg;
|
||||||
if (this.formData.phone && !this.validatePhone(this.formData.phone)) {
|
|
||||||
this.toastMessage = '手机号码格式不正确';
|
|
||||||
this.showToast = true;
|
this.showToast = true;
|
||||||
setTimeout(() => {
|
setTimeout(() => { this.showToast = false; }, 2000);
|
||||||
this.showToast = false;
|
},
|
||||||
}, 2000);
|
async handleSave() {
|
||||||
} else if (this.formData.idCard && !this.validateIdCard(this.formData.idCard)) {
|
if (!this.isFormValid || this.saving) return;
|
||||||
this.toastMessage = '身份证号码格式不正确';
|
|
||||||
this.showToast = true;
|
if (!this.validatePhone(this.formData.phone)) {
|
||||||
setTimeout(() => {
|
this.showToastMsg('手机号码格式不正确');
|
||||||
this.showToast = false;
|
return;
|
||||||
}, 2000);
|
|
||||||
} else {
|
|
||||||
this.hintText = '请完善信息';
|
|
||||||
this.showHint = true;
|
|
||||||
setTimeout(() => {
|
|
||||||
this.showHint = false;
|
|
||||||
}, 2000);
|
|
||||||
}
|
}
|
||||||
|
if (!this.validateIdCard(this.formData.idCard)) {
|
||||||
|
this.showToastMsg('身份证号码格式不正确');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 实际保存逻辑
|
this.saving = true;
|
||||||
uni.showToast({
|
try {
|
||||||
title: '保存成功',
|
await athleteAPI.saveContact(this.formData);
|
||||||
icon: 'success'
|
uni.showToast({ title: '保存成功', icon: 'success' });
|
||||||
});
|
setTimeout(() => { uni.navigateBack(); }, 1500);
|
||||||
setTimeout(() => {
|
} catch (err) {
|
||||||
uni.navigateBack();
|
console.error('保存联系人失败:', err);
|
||||||
}, 1500);
|
this.showToastMsg('保存失败,请重试');
|
||||||
|
} finally {
|
||||||
|
this.saving = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -201,13 +157,8 @@ export default {
|
|||||||
border-bottom: 1rpx solid #f5f5f5;
|
border-bottom: 1rpx solid #f5f5f5;
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-item:last-child {
|
.form-item:last-child { border-bottom: none; }
|
||||||
border-bottom: none;
|
.switch-item { padding: 30rpx; }
|
||||||
}
|
|
||||||
|
|
||||||
.switch-item {
|
|
||||||
padding: 30rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.form-label {
|
.form-label {
|
||||||
width: 180rpx;
|
width: 180rpx;
|
||||||
@@ -228,38 +179,8 @@ export default {
|
|||||||
color: #333333;
|
color: #333333;
|
||||||
}
|
}
|
||||||
|
|
||||||
.placeholder {
|
.placeholder { color: #cccccc; }
|
||||||
color: #cccccc;
|
.arrow { font-size: 40rpx; color: #cccccc; margin-left: 10rpx; }
|
||||||
}
|
|
||||||
|
|
||||||
.arrow {
|
|
||||||
font-size: 40rpx;
|
|
||||||
color: #cccccc;
|
|
||||||
margin-left: 10rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hint-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;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 15rpx;
|
|
||||||
z-index: 9999;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hint-icon {
|
|
||||||
font-size: 40rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hint-text {
|
|
||||||
font-size: 28rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.toast-message {
|
.toast-message {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
@@ -273,26 +194,7 @@ export default {
|
|||||||
z-index: 9999;
|
z-index: 9999;
|
||||||
}
|
}
|
||||||
|
|
||||||
.toast-text {
|
.toast-text { font-size: 28rpx; }
|
||||||
font-size: 28rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.info-text {
|
|
||||||
margin: 20rpx 30rpx;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.info-hint {
|
|
||||||
font-size: 24rpx;
|
|
||||||
color: #C93639;
|
|
||||||
}
|
|
||||||
|
|
||||||
.warning-text {
|
|
||||||
margin: 20rpx 30rpx;
|
|
||||||
text-align: center;
|
|
||||||
font-size: 24rpx;
|
|
||||||
color: #C93639;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-wrapper {
|
.btn-wrapper {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
|
|||||||
@@ -59,8 +59,31 @@
|
|||||||
<text class="empty-text">暂无集体信息</text>
|
<text class="empty-text">暂无集体信息</text>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 联系人Tab内容 (Tab 2) -->
|
<!-- 联系人列表 (Tab 2) -->
|
||||||
<view class="empty-state" v-if="currentTab === 2">
|
<view class="player-list" v-if="currentTab === 2 && contactList.length > 0">
|
||||||
|
<view class="player-item" v-for="(item, index) in contactList" :key="index">
|
||||||
|
<view class="player-info">
|
||||||
|
<view class="player-name">
|
||||||
|
{{ item.name }}
|
||||||
|
<text class="default-tag" v-if="item.isDefault">默认</text>
|
||||||
|
</view>
|
||||||
|
<view class="player-id">手机:{{ item.phone }}</view>
|
||||||
|
</view>
|
||||||
|
<view class="player-actions">
|
||||||
|
<view class="action-btn edit-btn" @click.stop="handleEditContact(item)">
|
||||||
|
<image class="action-icon" src="/static/images/编辑@3x.png" mode="aspectFit"></image>
|
||||||
|
<text>编辑</text>
|
||||||
|
</view>
|
||||||
|
<view class="action-btn delete-btn" @click.stop="handleDelete(item, 'contact')">
|
||||||
|
<image class="action-icon" src="/static/images/删除@3x.png" mode="aspectFit"></image>
|
||||||
|
<text>删除</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 联系人空状态 -->
|
||||||
|
<view class="empty-state" v-if="currentTab === 2 && contactList.length === 0">
|
||||||
<text class="empty-text">暂无联系人信息</text>
|
<text class="empty-text">暂无联系人信息</text>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
@@ -98,6 +121,7 @@ export default {
|
|||||||
currentTab: 0,
|
currentTab: 0,
|
||||||
playerList: [],
|
playerList: [],
|
||||||
teamList: [],
|
teamList: [],
|
||||||
|
contactList: [],
|
||||||
showDeleteModal: false,
|
showDeleteModal: false,
|
||||||
showSuccessToast: false,
|
showSuccessToast: false,
|
||||||
currentItem: null,
|
currentItem: null,
|
||||||
@@ -111,31 +135,31 @@ export default {
|
|||||||
return '新增联系人'
|
return '新增联系人'
|
||||||
},
|
},
|
||||||
deleteModalTitle() {
|
deleteModalTitle() {
|
||||||
return this.deleteType === 'team' ? '删除集体' : '删除选手'
|
if (this.deleteType === 'team') return '删除集体'
|
||||||
|
if (this.deleteType === 'contact') return '删除联系人'
|
||||||
|
return '删除选手'
|
||||||
},
|
},
|
||||||
deleteModalContent() {
|
deleteModalContent() {
|
||||||
return this.deleteType === 'team' ? '确定要删除该集体吗?' : '确定要删除该选手吗?'
|
if (this.deleteType === 'team') return '确定要删除该集体吗?'
|
||||||
|
if (this.deleteType === 'contact') return '确定要删除该联系人吗?'
|
||||||
|
return '确定要删除该选手吗?'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onLoad() {
|
onLoad() {
|
||||||
this.loadPlayerList()
|
this.loadPlayerList()
|
||||||
this.loadTeamList()
|
this.loadTeamList()
|
||||||
|
this.loadContactList()
|
||||||
},
|
},
|
||||||
onShow() {
|
onShow() {
|
||||||
this.loadPlayerList()
|
this.loadPlayerList()
|
||||||
this.loadTeamList()
|
this.loadTeamList()
|
||||||
|
this.loadContactList()
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
/**
|
|
||||||
* Load player list
|
|
||||||
*/
|
|
||||||
async loadPlayerList() {
|
async loadPlayerList() {
|
||||||
try {
|
try {
|
||||||
const userInfo = getUserInfo()
|
const userInfo = getUserInfo()
|
||||||
if (!userInfo || !userInfo.userId) {
|
if (!userInfo || !userInfo.userId) return
|
||||||
console.error('未获取到用户信息')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const res = await athleteAPI.getAthleteList({
|
const res = await athleteAPI.getAthleteList({
|
||||||
current: 1,
|
current: 1,
|
||||||
@@ -143,13 +167,7 @@ export default {
|
|||||||
createUser: userInfo.userId
|
createUser: userInfo.userId
|
||||||
})
|
})
|
||||||
|
|
||||||
let list = []
|
let list = res.records || (Array.isArray(res) ? res : [])
|
||||||
if (res.records) {
|
|
||||||
list = res.records
|
|
||||||
} else if (Array.isArray(res)) {
|
|
||||||
list = res
|
|
||||||
}
|
|
||||||
|
|
||||||
this.playerList = list.map(item => ({
|
this.playerList = list.map(item => ({
|
||||||
id: item.id,
|
id: item.id,
|
||||||
name: item.name || item.playerName,
|
name: item.name || item.playerName,
|
||||||
@@ -163,17 +181,11 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* Load team list
|
|
||||||
*/
|
|
||||||
async loadTeamList() {
|
async loadTeamList() {
|
||||||
try {
|
try {
|
||||||
const userInfo = getUserInfo()
|
const userInfo = getUserInfo()
|
||||||
if (!userInfo || !userInfo.userId) {
|
if (!userInfo || !userInfo.userId) return
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Try to load team list from API
|
|
||||||
if (athleteAPI.getTeamList) {
|
if (athleteAPI.getTeamList) {
|
||||||
const res = await athleteAPI.getTeamList({
|
const res = await athleteAPI.getTeamList({
|
||||||
current: 1,
|
current: 1,
|
||||||
@@ -181,13 +193,7 @@ export default {
|
|||||||
createUser: userInfo.userId
|
createUser: userInfo.userId
|
||||||
})
|
})
|
||||||
|
|
||||||
let list = []
|
let list = res.records || (Array.isArray(res) ? res : [])
|
||||||
if (res.records) {
|
|
||||||
list = res.records
|
|
||||||
} else if (Array.isArray(res)) {
|
|
||||||
list = res
|
|
||||||
}
|
|
||||||
|
|
||||||
this.teamList = list.map(item => ({
|
this.teamList = list.map(item => ({
|
||||||
id: item.id,
|
id: item.id,
|
||||||
name: item.name || item.teamName,
|
name: item.name || item.teamName,
|
||||||
@@ -200,33 +206,55 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
async loadContactList() {
|
||||||
|
try {
|
||||||
|
const userInfo = getUserInfo()
|
||||||
|
if (!userInfo || !userInfo.userId) return
|
||||||
|
|
||||||
|
if (athleteAPI.getContactList) {
|
||||||
|
const res = await athleteAPI.getContactList({
|
||||||
|
current: 1,
|
||||||
|
size: 100,
|
||||||
|
createUser: userInfo.userId
|
||||||
|
})
|
||||||
|
|
||||||
|
let list = res.records || (Array.isArray(res) ? res : [])
|
||||||
|
this.contactList = list.map(item => ({
|
||||||
|
id: item.id,
|
||||||
|
name: item.name,
|
||||||
|
phone: item.phone,
|
||||||
|
idCard: item.idCard,
|
||||||
|
email: item.email,
|
||||||
|
address: item.address,
|
||||||
|
isDefault: item.isDefault
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error('加载联系人列表失败:', err)
|
||||||
|
this.contactList = []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
handleTabChange(index) {
|
handleTabChange(index) {
|
||||||
this.currentTab = index;
|
this.currentTab = index;
|
||||||
},
|
},
|
||||||
handleAdd() {
|
handleAdd() {
|
||||||
if (this.currentTab === 0) {
|
if (this.currentTab === 0) {
|
||||||
uni.navigateTo({
|
uni.navigateTo({ url: '/pages/add-player/add-player' });
|
||||||
url: '/pages/add-player/add-player'
|
|
||||||
});
|
|
||||||
} else if (this.currentTab === 1) {
|
} else if (this.currentTab === 1) {
|
||||||
uni.navigateTo({
|
uni.navigateTo({ url: '/pages/add-team/add-team' });
|
||||||
url: '/pages/add-team/add-team'
|
|
||||||
});
|
|
||||||
} else if (this.currentTab === 2) {
|
} else if (this.currentTab === 2) {
|
||||||
uni.navigateTo({
|
uni.navigateTo({ url: '/pages/add-contact/add-contact' });
|
||||||
url: '/pages/add-contact/add-contact'
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
handleEdit(item) {
|
handleEdit(item) {
|
||||||
uni.navigateTo({
|
uni.navigateTo({ url: '/pages/edit-player/edit-player?id=' + item.id });
|
||||||
url: '/pages/edit-player/edit-player?id=' + item.id
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
handleEditTeam(item) {
|
handleEditTeam(item) {
|
||||||
uni.navigateTo({
|
uni.navigateTo({ url: '/pages/edit-team/edit-team?id=' + item.id });
|
||||||
url: '/pages/edit-team/edit-team?id=' + item.id
|
},
|
||||||
});
|
handleEditContact(item) {
|
||||||
|
uni.navigateTo({ url: '/pages/edit-contact/edit-contact?id=' + item.id });
|
||||||
},
|
},
|
||||||
handleDelete(item, type) {
|
handleDelete(item, type) {
|
||||||
this.currentItem = item;
|
this.currentItem = item;
|
||||||
@@ -242,27 +270,24 @@ export default {
|
|||||||
await athleteAPI.removeTeam(this.currentItem.id)
|
await athleteAPI.removeTeam(this.currentItem.id)
|
||||||
}
|
}
|
||||||
const index = this.teamList.findIndex(item => item.id === this.currentItem.id);
|
const index = this.teamList.findIndex(item => item.id === this.currentItem.id);
|
||||||
if (index > -1) {
|
if (index > -1) this.teamList.splice(index, 1);
|
||||||
this.teamList.splice(index, 1);
|
} else if (this.deleteType === 'contact') {
|
||||||
|
if (athleteAPI.removeContact) {
|
||||||
|
await athleteAPI.removeContact(this.currentItem.id)
|
||||||
}
|
}
|
||||||
|
const index = this.contactList.findIndex(item => item.id === this.currentItem.id);
|
||||||
|
if (index > -1) this.contactList.splice(index, 1);
|
||||||
} else {
|
} else {
|
||||||
await athleteAPI.removeAthlete(this.currentItem.id)
|
await athleteAPI.removeAthlete(this.currentItem.id)
|
||||||
const index = this.playerList.findIndex(item => item.id === this.currentItem.id);
|
const index = this.playerList.findIndex(item => item.id === this.currentItem.id);
|
||||||
if (index > -1) {
|
if (index > -1) this.playerList.splice(index, 1);
|
||||||
this.playerList.splice(index, 1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.showSuccessToast = true;
|
this.showSuccessToast = true;
|
||||||
setTimeout(() => {
|
setTimeout(() => { this.showSuccessToast = false; }, 2000);
|
||||||
this.showSuccessToast = false;
|
|
||||||
}, 2000);
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('删除失败:', err)
|
console.error('删除失败:', err)
|
||||||
uni.showToast({
|
uni.showToast({ title: '删除失败', icon: 'none' })
|
||||||
title: '删除失败',
|
|
||||||
icon: 'none'
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -315,6 +340,18 @@ export default {
|
|||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: #333333;
|
color: #333333;
|
||||||
margin-bottom: 10rpx;
|
margin-bottom: 10rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.default-tag {
|
||||||
|
font-size: 22rpx;
|
||||||
|
color: #fff;
|
||||||
|
background-color: #C93639;
|
||||||
|
padding: 4rpx 12rpx;
|
||||||
|
border-radius: 6rpx;
|
||||||
|
font-weight: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
.player-id {
|
.player-id {
|
||||||
@@ -348,10 +385,6 @@ export default {
|
|||||||
border-color: #C93639;
|
border-color: #C93639;
|
||||||
}
|
}
|
||||||
|
|
||||||
.icon {
|
|
||||||
font-size: 28rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.action-icon {
|
.action-icon {
|
||||||
width: 28rpx;
|
width: 28rpx;
|
||||||
height: 28rpx;
|
height: 28rpx;
|
||||||
|
|||||||
249
src/pages/edit-contact/edit-contact.vue
Normal file
249
src/pages/edit-contact/edit-contact.vue
Normal file
@@ -0,0 +1,249 @@
|
|||||||
|
<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>
|
||||||
|
|
||||||
|
<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 {
|
||||||
|
contactId: null,
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onLoad(options) {
|
||||||
|
if (options.id) {
|
||||||
|
this.contactId = options.id;
|
||||||
|
this.loadContactDetail();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
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 loadContactDetail() {
|
||||||
|
try {
|
||||||
|
const res = await athleteAPI.getContactDetail(this.contactId);
|
||||||
|
if (res) {
|
||||||
|
this.formData = {
|
||||||
|
idType: res.idType || '身份证',
|
||||||
|
name: res.name || '',
|
||||||
|
idCard: res.idCard || '',
|
||||||
|
phone: res.phone || '',
|
||||||
|
email: res.email || '',
|
||||||
|
address: res.address || '',
|
||||||
|
isDefault: res.isDefault || false
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error('加载联系人详情失败:', err);
|
||||||
|
this.showToastMsg('加载失败');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
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 {
|
||||||
|
const data = { ...this.formData, id: this.contactId };
|
||||||
|
await athleteAPI.saveContact(data);
|
||||||
|
uni.showToast({ title: '保存成功', icon: 'success' });
|
||||||
|
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>
|
||||||
@@ -98,22 +98,22 @@
|
|||||||
<view class="event-info-card">
|
<view class="event-info-card">
|
||||||
<view class="event-title">{{ eventInfo.title }}</view>
|
<view class="event-title">{{ eventInfo.title }}</view>
|
||||||
<view class="divider"></view>
|
<view class="divider"></view>
|
||||||
<view class="info-item">
|
<view class="info-item contact-item" @click="showContactPicker = true">
|
||||||
<text class="label">地点:</text>
|
<text class="label">地点:</text>
|
||||||
<text class="value">{{ eventInfo.location }}</text>
|
<text class="value">{{ eventInfo.location }}</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="info-item">
|
<view class="info-item contact-item" @click="showContactPicker = true">
|
||||||
<text class="label">比赛时间:</text>
|
<text class="label">比赛时间:</text>
|
||||||
<text class="value">{{ eventInfo.matchTime }}</text>
|
<text class="value">{{ eventInfo.matchTime }}</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="info-item">
|
<view class="info-item contact-item" @click="showContactPicker = true">
|
||||||
<text class="label">报名项目:</text>
|
<text class="label">报名项目:</text>
|
||||||
<text class="value">{{ eventInfo.projects }}</text>
|
<text class="value">{{ eventInfo.projects }}</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="info-item">
|
<view class="info-item contact-item" @click="showContactPicker = true">
|
||||||
<text class="label">联系人:</text>
|
<text class="label">联系人:</text>
|
||||||
<text class="value">{{ eventInfo.contact }}</text>
|
<text class="value" :class="{ placeholder: !selectedContact }">{{ selectedContact ? selectedContact.name + " " + selectedContact.phone : "请选择联系人" }}</text>
|
||||||
<text class="edit-icon">📋</text>
|
<text class="arrow">›</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="info-hint">(注意是否用此号码接收信息)</view>
|
<view class="info-hint">(注意是否用此号码接收信息)</view>
|
||||||
<view class="info-item participants-item">
|
<view class="info-item participants-item">
|
||||||
@@ -151,21 +151,21 @@
|
|||||||
<view class="event-info-card">
|
<view class="event-info-card">
|
||||||
<view class="event-title">{{ eventInfo.title }}</view>
|
<view class="event-title">{{ eventInfo.title }}</view>
|
||||||
<view class="divider"></view>
|
<view class="divider"></view>
|
||||||
<view class="info-item">
|
<view class="info-item contact-item" @click="showContactPicker = true">
|
||||||
<text class="label">地点:</text>
|
<text class="label">地点:</text>
|
||||||
<text class="value">{{ eventInfo.location }}</text>
|
<text class="value">{{ eventInfo.location }}</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="info-item">
|
<view class="info-item contact-item" @click="showContactPicker = true">
|
||||||
<text class="label">比赛时间:</text>
|
<text class="label">比赛时间:</text>
|
||||||
<text class="value">{{ eventInfo.matchTime }}</text>
|
<text class="value">{{ eventInfo.matchTime }}</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="info-item">
|
<view class="info-item contact-item" @click="showContactPicker = true">
|
||||||
<text class="label">报名项目:</text>
|
<text class="label">报名项目:</text>
|
||||||
<text class="value">{{ eventInfo.projects }}</text>
|
<text class="value">{{ eventInfo.projects }}</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="info-item">
|
<view class="info-item contact-item" @click="showContactPicker = true">
|
||||||
<text class="label">联系人:</text>
|
<text class="label">联系人:</text>
|
||||||
<text class="value">{{ eventInfo.contact }}</text>
|
<text class="value" :class="{ placeholder: !selectedContact }">{{ selectedContact ? selectedContact.name + " " + selectedContact.phone : "请选择联系人" }}</text>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<template v-if="!isTeamProject">
|
<template v-if="!isTeamProject">
|
||||||
@@ -211,6 +211,32 @@
|
|||||||
</scroll-view>
|
</scroll-view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
|
<!-- 联系人选择弹窗 -->
|
||||||
|
<view class="contact-modal" v-if="showContactPicker" @click="showContactPicker = false">
|
||||||
|
<view class="modal-content" @click.stop>
|
||||||
|
<view class="modal-header">
|
||||||
|
<text class="modal-title">选择联系人</text>
|
||||||
|
<text class="close-icon" @click="showContactPicker = false">✕</text>
|
||||||
|
</view>
|
||||||
|
<view class="add-contact-btn" @click="goToAddContact">
|
||||||
|
<text class="add-icon">⊕</text>
|
||||||
|
<text>新增联系人</text>
|
||||||
|
</view>
|
||||||
|
<scroll-view class="modal-body contact-list" scroll-y>
|
||||||
|
<view class="contact-item" v-for="(item, index) in contactList" :key="index" @click="selectContact(item)">
|
||||||
|
<view class="contact-info">
|
||||||
|
<view class="contact-name">{{ item.name }}</view>
|
||||||
|
<view class="contact-phone">{{ item.phone }}</view>
|
||||||
|
</view>
|
||||||
|
<view class="contact-check" v-if="selectedContact && selectedContact.id === item.id">✓</view>
|
||||||
|
</view>
|
||||||
|
<view class="empty-state" v-if="contactList.length === 0">
|
||||||
|
<text class="empty-text">暂无联系人,请先新增</text>
|
||||||
|
</view>
|
||||||
|
</scroll-view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -240,6 +266,9 @@ export default {
|
|||||||
selectedPlayers: [],
|
selectedPlayers: [],
|
||||||
selectedTeams: [],
|
selectedTeams: [],
|
||||||
showPlayerModal: false,
|
showPlayerModal: false,
|
||||||
|
showContactPicker: false,
|
||||||
|
contactList: [],
|
||||||
|
selectedContact: null,
|
||||||
totalPrice: 0,
|
totalPrice: 0,
|
||||||
registrationId: ''
|
registrationId: ''
|
||||||
};
|
};
|
||||||
@@ -290,6 +319,38 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
// Contact methods
|
||||||
|
async loadContactList() {
|
||||||
|
try {
|
||||||
|
const res = await athleteAPI.getContactList({ current: 1, size: 100 })
|
||||||
|
this.contactList = (res.records || []).map(item => ({
|
||||||
|
id: item.id,
|
||||||
|
name: item.name,
|
||||||
|
phone: item.phone,
|
||||||
|
idCard: item.idCard
|
||||||
|
}))
|
||||||
|
// Auto select default contact if exists
|
||||||
|
if (!this.selectedContact && this.contactList.length > 0) {
|
||||||
|
const defaultContact = this.contactList.find(c => c.isDefault) || this.contactList[0]
|
||||||
|
this.selectedContact = defaultContact
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error('加载联系人列表失败:', err)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
selectContact(contact) {
|
||||||
|
this.selectedContact = contact
|
||||||
|
this.showContactPicker = false
|
||||||
|
},
|
||||||
|
|
||||||
|
goToAddContact() {
|
||||||
|
this.showContactPicker = false
|
||||||
|
uni.navigateTo({
|
||||||
|
url: '/pages/add-contact/add-contact'
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
async loadEventDetail(id) {
|
async loadEventDetail(id) {
|
||||||
try {
|
try {
|
||||||
const res = await competitionAPI.getCompetitionDetail(id)
|
const res = await competitionAPI.getCompetitionDetail(id)
|
||||||
@@ -487,6 +548,7 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.totalPrice = this.calculateTotalPrice()
|
this.totalPrice = this.calculateTotalPrice()
|
||||||
|
this.loadContactList()
|
||||||
this.$nextTick(() => { this.currentStep = 2 })
|
this.$nextTick(() => { this.currentStep = 2 })
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -518,7 +580,7 @@ export default {
|
|||||||
projectIds: this.selectedProjects.map(p => String(p.id)),
|
projectIds: this.selectedProjects.map(p => String(p.id)),
|
||||||
teamIds: selected.map(t => String(t.id)),
|
teamIds: selected.map(t => String(t.id)),
|
||||||
athleteIds: [],
|
athleteIds: [],
|
||||||
contactPhone: this.eventInfo.contact || '',
|
contactPhone: this.selectedContact ? this.selectedContact.phone : '',
|
||||||
totalAmount: parseFloat(this.totalPrice) || 0
|
totalAmount: parseFloat(this.totalPrice) || 0
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -532,7 +594,7 @@ export default {
|
|||||||
competitionId: String(this.eventId),
|
competitionId: String(this.eventId),
|
||||||
projectIds: this.selectedProjects.map(p => String(p.id)),
|
projectIds: this.selectedProjects.map(p => String(p.id)),
|
||||||
athleteIds: selected.map(p => String(p.id)),
|
athleteIds: selected.map(p => String(p.id)),
|
||||||
contactPhone: this.eventInfo.contact || '',
|
contactPhone: this.selectedContact ? this.selectedContact.phone : '',
|
||||||
totalAmount: parseFloat(this.totalPrice) || 0
|
totalAmount: parseFloat(this.totalPrice) || 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1014,6 +1076,84 @@ export default {
|
|||||||
color: #C93639;
|
color: #C93639;
|
||||||
margin-top: 10rpx;
|
margin-top: 10rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Contact Modal Styles */
|
||||||
|
.contact-modal {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background-color: rgba(0, 0, 0, 0.5);
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-end;
|
||||||
|
z-index: 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.contact-modal .modal-content {
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 24rpx 24rpx 0 0;
|
||||||
|
width: 100%;
|
||||||
|
max-height: 70vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.contact-modal .add-contact-btn {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 24rpx;
|
||||||
|
border-bottom: 1rpx solid #eee;
|
||||||
|
color: #C93639;
|
||||||
|
font-size: 28rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.contact-modal .add-contact-btn .add-icon {
|
||||||
|
margin-right: 10rpx;
|
||||||
|
font-size: 32rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.contact-modal .contact-list {
|
||||||
|
max-height: 50vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.contact-modal .contact-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 24rpx 30rpx;
|
||||||
|
border-bottom: 1rpx solid #f5f5f5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.contact-modal .contact-info {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.contact-modal .contact-name {
|
||||||
|
font-size: 30rpx;
|
||||||
|
color: #333;
|
||||||
|
margin-bottom: 8rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.contact-modal .contact-phone {
|
||||||
|
font-size: 26rpx;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
.contact-modal .contact-check {
|
||||||
|
color: #C93639;
|
||||||
|
font-size: 36rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.contact-item.clickable,
|
||||||
|
.info-item.contact-item {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-item .placeholder {
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
.empty-state {
|
.empty-state {
|
||||||
|
|||||||
@@ -138,7 +138,7 @@ export default {
|
|||||||
matchTime: this.formatTimeRange(startTime, endTime) ||
|
matchTime: this.formatTimeRange(startTime, endTime) ||
|
||||||
item.matchTime || item.competitionTime || '待定',
|
item.matchTime || item.competitionTime || '待定',
|
||||||
registerCount: item.registrationCount || item.registerCount || item.signUpCount || item.totalParticipants || '0',
|
registerCount: item.registrationCount || item.registerCount || item.signUpCount || item.totalParticipants || '0',
|
||||||
status: this.getStatus(item.status)
|
status: this.getStatus(item.status, regEndTime)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -174,12 +174,20 @@ export default {
|
|||||||
* @param {Number|String} status 状态码
|
* @param {Number|String} status 状态码
|
||||||
* @returns {String}
|
* @returns {String}
|
||||||
*/
|
*/
|
||||||
getStatus(status) {
|
getStatus(status, regEndTime) {
|
||||||
// 根据后端状态码映射为前端需要的状态
|
// 根据后端状态码映射为前端需要的状态
|
||||||
// 1: 报名中, 2: 进行中, 3: 已结束
|
// 1: 报名中, 2: 进行中, 3: 已结束
|
||||||
if (status === 3 || status === '3' || status === 'finished') {
|
if (status === 3 || status === '3' || status === 'finished') {
|
||||||
return 'finished'
|
return 'finished'
|
||||||
}
|
}
|
||||||
|
// 根据报名结束时间判断是否已结束
|
||||||
|
if (regEndTime) {
|
||||||
|
const endDate = new Date(regEndTime)
|
||||||
|
const now = new Date()
|
||||||
|
if (now > endDate) {
|
||||||
|
return 'finished'
|
||||||
|
}
|
||||||
|
}
|
||||||
return 'open'
|
return 'open'
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -42,8 +42,8 @@
|
|||||||
<text class="value participants">{{ item.participants }}</text>
|
<text class="value participants">{{ item.participants }}</text>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view class="event-footer" v-if="item.status === 'ongoing'">
|
<view class="event-footer">
|
||||||
<view class="register-note">
|
<view class="register-note" v-if="item.status === 'ongoing'">
|
||||||
<text>点击后进入【赛事详情】页面</text>
|
<text>点击后进入【赛事详情】页面</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="view-cert-btn" @click.stop="handleViewCert(item)">
|
<view class="view-cert-btn" @click.stop="handleViewCert(item)">
|
||||||
@@ -58,6 +58,26 @@
|
|||||||
<view class="empty-state" v-if="filteredList.length === 0">
|
<view class="empty-state" v-if="filteredList.length === 0">
|
||||||
<text class="empty-text">暂无报名记录</text>
|
<text class="empty-text">暂无报名记录</text>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
|
<!-- 证件弹窗 -->
|
||||||
|
<view class="cert-modal" v-if="showCertModal" @click="closeCertModal">
|
||||||
|
<view class="cert-modal-content" @click.stop>
|
||||||
|
<view class="cert-modal-header">
|
||||||
|
<text class="cert-modal-title">参赛选手证件</text>
|
||||||
|
<text class="cert-close-icon" @click="closeCertModal">✕</text>
|
||||||
|
</view>
|
||||||
|
<scroll-view class="cert-modal-body" scroll-y>
|
||||||
|
<view class="cert-athlete-item" v-for="(athlete, index) in certAthleteList" :key="index">
|
||||||
|
<view class="cert-athlete-name">{{ athlete.playerName }}</view>
|
||||||
|
<view class="cert-athlete-info">性别:{{ athlete.gender === 1 ? '男' : '女' }}</view>
|
||||||
|
<view class="cert-athlete-info">身份证:{{ athlete.idCard || '暂无' }}</view>
|
||||||
|
</view>
|
||||||
|
<view class="cert-empty" v-if="certAthleteList.length === 0">
|
||||||
|
<text>暂无选手信息</text>
|
||||||
|
</view>
|
||||||
|
</scroll-view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -80,7 +100,9 @@ export default {
|
|||||||
current: 1,
|
current: 1,
|
||||||
size: 20
|
size: 20
|
||||||
},
|
},
|
||||||
hasMore: true
|
hasMore: true,
|
||||||
|
showCertModal: false,
|
||||||
|
certAthleteList: []
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
onLoad() {
|
onLoad() {
|
||||||
@@ -235,7 +257,8 @@ export default {
|
|||||||
) || '',
|
) || '',
|
||||||
projects: item.projectNames || this.formatProjects(item.projects) || '',
|
projects: item.projectNames || this.formatProjects(item.projects) || '',
|
||||||
contact: item.contactPhone || item.contactPerson || '',
|
contact: item.contactPhone || item.contactPerson || '',
|
||||||
participants: item.athleteNames || `${item.totalParticipants || 0}人`
|
participants: item.athleteNames || `${item.totalParticipants || 0}人`,
|
||||||
|
athleteList: item.athleteList || []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -322,11 +345,21 @@ export default {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
handleViewCert(item) {
|
handleViewCert(item) {
|
||||||
|
// Get athlete list from the item
|
||||||
|
if (item.athleteList && item.athleteList.length > 0) {
|
||||||
|
this.certAthleteList = item.athleteList;
|
||||||
|
this.showCertModal = true;
|
||||||
|
} else {
|
||||||
uni.showToast({
|
uni.showToast({
|
||||||
title: '查看证件',
|
title: '暂无选手证件信息',
|
||||||
icon: 'none'
|
icon: 'none'
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
closeCertModal() {
|
||||||
|
this.showCertModal = false;
|
||||||
|
this.certAthleteList = [];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
@@ -446,4 +479,77 @@ export default {
|
|||||||
font-size: 28rpx;
|
font-size: 28rpx;
|
||||||
color: #999999;
|
color: #999999;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Cert Modal Styles */
|
||||||
|
.cert-modal {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background-color: rgba(0, 0, 0, 0.5);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
z-index: 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cert-modal-content {
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 16rpx;
|
||||||
|
width: 85%;
|
||||||
|
max-height: 70vh;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cert-modal-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
padding: 30rpx;
|
||||||
|
border-bottom: 1rpx solid #eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cert-modal-title {
|
||||||
|
font-size: 32rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cert-close-icon {
|
||||||
|
font-size: 36rpx;
|
||||||
|
color: #999;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cert-modal-body {
|
||||||
|
max-height: 50vh;
|
||||||
|
padding: 20rpx 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cert-athlete-item {
|
||||||
|
padding: 20rpx;
|
||||||
|
background-color: #f9f9f9;
|
||||||
|
border-radius: 12rpx;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cert-athlete-name {
|
||||||
|
font-size: 30rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #333;
|
||||||
|
margin-bottom: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cert-athlete-info {
|
||||||
|
font-size: 26rpx;
|
||||||
|
color: #666;
|
||||||
|
margin-bottom: 6rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cert-empty {
|
||||||
|
text-align: center;
|
||||||
|
padding: 40rpx;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Reference in New Issue
Block a user