Files
martial-mini/src/pages/common-info/common-info.vue
T

434 lines
12 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view class="common-info-page">
<!-- Tab切换 -->
<custom-tabs :tabs="tabs" :current="currentTab" @change="handleTabChange"></custom-tabs>
<!-- 新增按钮 -->
<view class="add-btn-wrapper" @click="handleAdd">
<text class="add-icon"></text>
<text class="add-text">{{ addButtonText }}</text>
</view>
<!-- 选手列表 (Tab 0) -->
<view class="player-list" v-if="currentTab === 0 && playerList.length > 0">
<view class="player-item" v-for="(item, index) in playerList" :key="index">
<view class="player-info">
<view class="player-name">{{ item.name }}</view>
<view class="player-id">身份证{{ item.idCard }}</view>
</view>
<view class="player-actions">
<view class="action-btn edit-btn" @click.stop="handleEdit(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, 'player')">
<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 === 0 && playerList.length === 0">
<text class="empty-text">暂无选手信息</text>
</view>
<!-- 集体列表 (Tab 1) -->
<view class="player-list" v-if="currentTab === 1 && teamList.length > 0">
<view class="player-item" v-for="(item, index) in teamList" :key="index">
<view class="player-info">
<view class="player-name">{{ item.name }}</view>
<view class="player-id">成员数{{ item.memberCount || 0 }}</view>
</view>
<view class="player-actions">
<view class="action-btn edit-btn" @click.stop="handleEditTeam(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, 'team')">
<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 === 1 && teamList.length === 0">
<text class="empty-text">暂无集体信息</text>
</view>
<!-- 联系人列表 (Tab 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>
</view>
<!-- 删除确认弹窗 -->
<confirm-modal
:show="showDeleteModal"
:title="deleteModalTitle"
:content="deleteModalContent"
@cancel="showDeleteModal = false"
@confirm="confirmDelete"
></confirm-modal>
<!-- 删除成功提示 -->
<view class="delete-success-toast" v-if="showSuccessToast">
<text class="toast-icon"></text>
<text class="toast-text">删除成功</text>
</view>
</view>
</template>
<script>
import CustomTabs from '../../components/custom-tabs/custom-tabs.vue';
import ConfirmModal from '../../components/confirm-modal/confirm-modal.vue';
import athleteAPI from '@/api/athlete.js';
import { getUserInfo } from '@/utils/auth.js';
export default {
components: {
CustomTabs,
ConfirmModal
},
data() {
return {
tabs: ['选手', '集体', '联系人'],
currentTab: 0,
playerList: [],
teamList: [],
contactList: [],
showDeleteModal: false,
showSuccessToast: false,
currentItem: null,
deleteType: 'player'
};
},
computed: {
addButtonText() {
if (this.currentTab === 0) return '新增选手'
if (this.currentTab === 1) return '新增集体'
return '新增联系人'
},
deleteModalTitle() {
if (this.deleteType === 'team') return '删除集体'
if (this.deleteType === 'contact') return '删除联系人'
return '删除选手'
},
deleteModalContent() {
if (this.deleteType === 'team') return '确定要删除该集体吗?'
if (this.deleteType === 'contact') return '确定要删除该联系人吗?'
return '确定要删除该选手吗?'
}
},
onLoad() {
this.loadPlayerList()
this.loadTeamList()
this.loadContactList()
},
onShow() {
this.loadPlayerList()
this.loadTeamList()
this.loadContactList()
},
methods: {
async loadPlayerList() {
try {
const userInfo = getUserInfo()
if (!userInfo || !userInfo.userId) return
const res = await athleteAPI.getAthleteList({
current: 1,
size: 100,
createUser: userInfo.userId
})
let list = res.records || (Array.isArray(res) ? res : [])
// Deduplicate by idCard
const seen = new Set()
const uniqueList = list.filter(item => {
const idCard = item.idCard || item.idCardNumber
if (idCard && seen.has(idCard)) return false
if (idCard) seen.add(idCard)
return true
})
this.playerList = uniqueList.map(item => ({
id: item.id,
name: item.name || item.playerName,
idCard: item.idCard || item.idCardNumber,
gender: item.gender,
team: item.team || item.teamName,
phone: item.phone || item.contactPhone
}))
} catch (err) {
console.error('加载选手列表失败:', err)
}
},
async loadTeamList() {
try {
const userInfo = getUserInfo()
if (!userInfo || !userInfo.userId) return
if (athleteAPI.getTeamList) {
const res = await athleteAPI.getTeamList({
current: 1,
size: 100,
createUser: userInfo.userId
})
let list = res.records || (Array.isArray(res) ? res : [])
this.teamList = list.map(item => ({
id: item.id,
name: item.name || item.teamName,
memberCount: item.memberCount || item.members?.length || 0
}))
}
} catch (err) {
console.error('加载集体列表失败:', err)
this.teamList = []
}
},
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) {
this.currentTab = index;
},
handleAdd() {
if (this.currentTab === 0) {
uni.navigateTo({ url: '/pages/add-player/add-player' });
} else if (this.currentTab === 1) {
uni.navigateTo({ url: '/pages/add-team/add-team' });
} else if (this.currentTab === 2) {
uni.navigateTo({ url: '/pages/add-contact/add-contact' });
}
},
handleEdit(item) {
uni.navigateTo({ url: '/pages/edit-player/edit-player?id=' + item.id });
},
handleEditTeam(item) {
uni.navigateTo({ 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) {
this.currentItem = item;
this.deleteType = type;
this.showDeleteModal = true;
},
async confirmDelete() {
this.showDeleteModal = false;
try {
if (this.deleteType === 'team') {
if (athleteAPI.removeTeam) {
await athleteAPI.removeTeam(this.currentItem.id)
}
const index = this.teamList.findIndex(item => item.id === this.currentItem.id);
if (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 {
await athleteAPI.removeAthlete(this.currentItem.id)
const index = this.playerList.findIndex(item => item.id === this.currentItem.id);
if (index > -1) this.playerList.splice(index, 1);
}
this.showSuccessToast = true;
setTimeout(() => { this.showSuccessToast = false; }, 2000);
} catch (err) {
console.error('删除失败:', err)
uni.showToast({ title: '删除失败', icon: 'none' })
}
}
}
};
</script>
<style lang="scss" scoped>
.common-info-page {
min-height: 100vh;
background-color: #f5f5f5;
}
.add-btn-wrapper {
background-color: #fff;
padding: 30rpx;
display: flex;
align-items: center;
justify-content: center;
gap: 10rpx;
border-bottom: 1rpx solid #f5f5f5;
}
.add-icon {
font-size: 36rpx;
color: #C93639;
}
.add-text {
font-size: 30rpx;
color: #C93639;
}
.player-list {
padding: 30rpx;
}
.player-item {
background-color: #fff;
border-radius: 16rpx;
padding: 30rpx;
margin-bottom: 20rpx;
}
.player-info {
margin-bottom: 20rpx;
}
.player-name {
font-size: 32rpx;
font-weight: bold;
color: #333333;
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 {
font-size: 26rpx;
color: #666666;
}
.player-actions {
display: flex;
justify-content: flex-end;
gap: 20rpx;
}
.action-btn {
display: flex;
align-items: center;
gap: 5rpx;
padding: 12rpx 30rpx;
border-radius: 8rpx;
font-size: 26rpx;
border: 2rpx solid;
}
.edit-btn {
color: #C93639;
border-color: #C93639;
}
.delete-btn {
color: #C93639;
border-color: #C93639;
}
.action-icon {
width: 28rpx;
height: 28rpx;
}
.empty-state {
padding: 200rpx 0;
text-align: center;
}
.empty-text {
font-size: 28rpx;
color: #999999;
}
.delete-success-toast {
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: 10000;
}
.toast-icon {
font-size: 40rpx;
}
.toast-text {
font-size: 28rpx;
}
</style>