aslan-h5/src/views/BDCenter/inviteAgency.vue
2025-10-15 17:24:48 +08:00

374 lines
10 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>
<div class="fullPage">
<!-- 顶部导航 -->
<MobileHeader title="Invite user to become agency" />
<!-- 内容 -->
<div style="padding: 16px; position: relative">
<!-- 搜索框 -->
<div style="display: flex; align-items: center; gap: 8px; margin-bottom: 8px">
<div
style="
flex: 1;
border-radius: 32px;
border: 1px solid #fff;
box-shadow: 0 0 4px 0 rgba(0, 0, 0, 0.25);
padding: 0 8px;
display: flex;
align-items: center;
height: max-content;
"
>
<img src="../../assets/icon/search.png" alt="" width="24px" style="opacity: 0.6" />
<input
v-model="searchQuery"
type="text"
name=""
id=""
placeholder="Please enter the host lD"
@keyup.enter="handleEnterPress"
@input="handleInputChange"
style="
width: 100%;
color: rgba(0, 0, 0, 0.4);
font-weight: 600;
font-size: 14px;
outline: none;
border: none;
background-color: transparent;
padding: 10px 8px;
"
/>
<button
v-if="searchQuery"
@click="clearSearch"
style="
background: none;
border: none;
font-size: 18px;
color: #9ca3af;
cursor: pointer;
padding: 0 8px;
"
>
×
</button>
</div>
<button
style="font-weight: 600"
class="invite-btn"
@click="inviteAgency"
:disabled="disInvite"
>
invite
</button>
</div>
<!-- 搜索结果 -->
<div
v-if="showUserList.length > 0"
style="margin: 16px 0; display: flex; flex-direction: column; gap: 12px"
>
<div
v-for="user in showUserList"
:key="user.id"
style="
position: relative;
background-color: white;
padding: 4px 10px;
border-radius: 12px;
box-sizing: border-box;
border: 2px solid transparent;
box-shadow: 0 0 4px 0 rgba(0, 0, 0, 0.25);
transition: all 0.2s;
"
@click="toggleUserSelection(user)"
>
<!-- 绝对定位 选中框 -->
<div
style="position: absolute; inset: -2px; border-radius: 12px; z-index: 2"
:class="{ selected: selectedUser?.id === user.userProfile.id }"
></div>
<!-- 绝对定位 状态显示 -->
<div
style="position: absolute; top: -2px; right: -2px"
v-if="user.status == 0 || user.status == 1"
>
<div
v-if="user.status == 0"
style="
background-image: linear-gradient(112deg, #759cff 5.66%, #3d73ff 42.49%);
padding: 4px 8px;
border-radius: 0 12px;
color: white;
font-weight: 600;
"
>
Pending
</div>
<div
v-if="user.status == 1"
style="
background-image: linear-gradient(112deg, #75ff98 5.66%, #3dff54 42.49%);
padding: 4px 8px;
border-radius: 0 12px;
color: white;
font-weight: 600;
"
>
Success
</div>
</div>
<!-- 用户信息 -->
<div style="font-weight: 600">Invited user information:</div>
<div style="display: flex; align-items: center; justify-content: space-between">
<div style="display: flex; align-items: center; flex: 1">
<div
style="
width: 50px;
aspect-ratio: 1/1;
border-radius: 25px;
background-color: #f59e0b;
display: flex;
align-items: center;
justify-content: center;
color: white;
font-size: 18px;
font-weight: 600;
margin-right: 12px;
overflow: hidden;
position: relative;
"
>
<img
v-if="user.userProfile.userAvatar"
:src="user.userProfile.userAvatar"
:alt="user.userProfile.userNickname"
style="width: 100%; aspect-ratio: 1/1; object-fit: cover; border-radius: 25px"
@error="(e) => (e.target.style.display = 'none')"
/>
<span
v-if="!user.userProfile.userAvatar"
style="color: white; font-size: 18px; font-weight: 600"
>{{ user.userProfile.userNickname.charAt(0) }}</span
>
</div>
<div>
<div style="margin-bottom: 4px; font-size: 16px; font-weight: 700">
{{ user.userProfile.userNickname }}
</div>
<div style="font-size: 14px; color: rgba(0, 0, 0, 0.4); font-weight: 500">
ID: {{ user.userProfile.account }}
</div>
</div>
</div>
<div style="display: flex; justify-content: center; align-items: center">
<div
v-if="user.status == 0"
style="
padding: 4px 8px;
border-radius: 32px;
background-color: red;
color: white;
font-size: 16px;
font-weight: 600;
z-index: 5;
"
@click="cancelInviteAgency(user.id)"
>
Cancel
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script setup>
import MobileHeader from '@/components/MobileHeader.vue'
import { showError, showWarning, showInfo, showSuccess } from '@/utils/toast.js'
import { searchUser } from '@/api/userInfo'
import {
invitedList,
beInvitedList,
inviteToBeAgency,
handleInvite,
cancelInvite,
} from '@/api/bdCenter.js'
import { computed, onMounted, ref } from 'vue'
const searchQuery = ref('') //关键词
const invitedUserList = ref([]) //已邀请列表
const searchResults = ref([]) //搜索结果
const disInvite = ref(true) //不可邀请
const selectedUser = ref({}) //选中的用户
//展示的用户列表
const showUserList = computed(() => {
if (searchQuery.value) {
return searchResults.value
} else {
return invitedUserList.value
}
})
// 清空关键词
const clearSearch = () => {
searchQuery.value = ''
searchResults.value = []
selectedUser.value = {}
disInvite.value = true
getInvitedList() //重新获取已邀请列表
}
// 输入框变化
const handleInputChange = () => {
// 输入框为空时,清空搜索结果
if (!searchQuery.value.trim()) {
searchResults.value = []
selectedUser.value = {}
disInvite.value = true
getInvitedList() //重新获取已邀请列表
}
}
// 回车搜索
const handleEnterPress = async () => {
console.log('充值目标用户id', searchQuery.value)
searchResults.value = []
selectedUser.value = {}
disInvite.value = true
if (searchQuery.value.trim()) {
const resSearchUser = await searchUser(searchQuery.value)
if (resSearchUser.status && resSearchUser.body) {
let targetUserInfo = { userProfile: resSearchUser.body }
searchResults.value.push(targetUserInfo)
}
}
}
// 选择用户
const toggleUserSelection = (user) => {
console.log('选择用户:', user)
if (selectedUser.value?.id == user.userProfile.id) {
selectedUser.value = {}
disInvite.value = true
} else {
selectedUser.value = user.userProfile
if (user.status == 0 || user.status == 1) {
disInvite.value = true
} else {
disInvite.value = false
}
}
}
// 邀请代理
const inviteAgency = async () => {
console.log('点击邀请代理')
try {
let data = { inviteUserId: selectedUser.value.id }
const resInvite = await inviteToBeAgency(data)
if (resInvite.status) {
showSuccess('Invitation information submitted successfully!')
}
} catch (error) {
showError(error.response.errorMsg)
}
clearSearch()
}
// 获取已邀请列表
const getInvitedList = async () => {
const resInvitedList = await invitedList()
console.log('已邀请列表:', resInvitedList)
if (resInvitedList.status && resInvitedList.body) {
invitedUserList.value = resInvitedList.body
}
}
// 取消邀请
const cancelInviteAgency = async (userId) => {
console.log('取消邀请用户id:', userId)
try {
const resCancel = await cancelInvite(userId)
if (resCancel.status) {
showSuccess('Cancel invitation successfully!')
getInvitedList()
}
} catch (error) {
let errorMsg = error.response.errorMsg.replace(/^.*\]\s*/, '')
showError(errorMsg)
}
}
onMounted(() => {
getInvitedList()
})
</script>
<style lang="scss" scoped>
* {
color: rgba(0, 0, 0, 0.8);
font-family: 'SF Pro Text';
}
.fullPage {
width: 100vw;
min-height: 100vh;
background-color: #ffffff;
background-image: url(../../assets/images/secondBg.png);
background-size: 100% auto;
background-repeat: no-repeat;
position: relative;
}
.invite-btn {
padding: 10px 12px;
border-radius: 32px;
background: linear-gradient(135deg, #bb92ff 2.82%, #8b45ff 99.15%);
color: white;
border: none;
font-size: 16px;
font-weight: 600;
cursor: pointer;
transition: all 0.2s;
}
.invite-btn:not(:disabled):active {
background: linear-gradient(135deg, #b080ff 2.82%, #6302ff 99.15%);
}
.invite-btn:disabled {
background: #d1d5db;
cursor: not-allowed;
}
.selected {
border: 2px solid #8b5cf6 !important;
}
@media screen and (max-width: 360px) {
* {
font-size: 10px;
}
}
@media screen and (min-width: 360px) {
* {
font-size: 12px;
}
}
@media screen and (min-width: 768px) {
* {
font-size: 24px;
}
}
</style>