aslan-h5/src/views/AdminCenter/MyAgencyTeams.vue

525 lines
15 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 gradient-background-circles">
<!-- 顶部导航 -->
<GeneralHeader
:showLanguageList="true"
:title="t('my_agency_teams')"
color="black"
style="box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); z-index: 999"
/>
<!-- 主要内容 -->
<div
style="
padding: 16px;
position: relative;
z-index: 2;
display: flex;
flex-direction: column;
gap: 12px;
"
>
<!-- 总收入信息 -->
<div
style="
background-color: white;
border-radius: 12px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
padding: 16px;
border: 1px solid #e5e7eb;
display: flex;
flex-direction: column;
gap: 10px;
"
>
<div style="display: flex; align-items: flex-end">
<div style="font-weight: 600; font-size: 0.9em">{{ t('total_income') }}</div>
<div style="font-weight: 700">${{ TeamOverview?.totalIncome || 0 }}</div>
</div>
<div style="display: flex; align-items: flex-end">
<div style="font-weight: 600; font-size: 0.9em">{{ t('previous_period_income') }}</div>
<div style="font-weight: 700">${{ TeamOverview?.previousPeriodIncome || 0 }}</div>
</div>
</div>
<!-- Agency团队收入信息 -->
<div
style="
background-color: white;
border-radius: 12px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
padding: 16px;
border: 1px solid #e5e7eb;
display: flex;
flex-direction: column;
gap: 10px;
"
>
<!-- 团队信息 -->
<div style="font-weight: 700">
{{ t('agencies_label') }} {{ TeamOverview?.memberCount || 0 }}
</div>
<div style="font-size: 0.9em; font-weight: 600">
{{ t('team_total_income_label') }} ${{ TeamOverview?.teamTotalIncome || 0 }}
</div>
<!-- Agency成员列表 -->
<div
v-for="AgencyInfo in TeamOverview?.members"
style="
position: relative;
background-color: white;
padding: 14px 10px;
border-radius: 12px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
display: flex;
align-items: center;
justify-content: space-around;
gap: 4px;
"
>
<!-- 头像 -->
<div
style="
width: 15%;
align-self: stretch;
display: flex;
align-items: center;
justify-content: center;
"
>
<img
:src="AgencyInfo.avatar || ''"
alt=""
style="
display: block;
width: 100%;
aspect-ratio: 1/1;
border-radius: 50%;
object-fit: cover;
"
@error="handleAvatarImageError"
/>
</div>
<!-- 基本信息 -->
<div
style="
flex: 1;
min-width: 0;
align-self: stretch;
display: flex;
flex-direction: column;
justify-content: space-around;
gap: 4px;
"
>
<div
style="
font-weight: 700;
width: 100%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
"
>
{{ AgencyInfo.userName || '-' }}
</div>
<div style="color: rgba(0, 0, 0, 0.4); font-size: 0.8em; font-weight: 500">
{{ t('user_id_prefix') }}{{ AgencyInfo.account || '-' }}
</div>
</div>
<!-- 收入信息 -->
<div
style="
width: auto;
min-width: 0;
align-self: stretch;
display: flex;
flex-direction: column;
justify-content: center;
"
>
<div style="font-size: 0.8em; font-weight: 500; text-align: end">
{{ t('number_of_hosts_personnel_label') }} {{ AgencyInfo?.subMemberCount || 0 }}
</div>
<div style="font-size: 0.8em; font-weight: 500; text-align: end">
{{ t('total_income') }} ${{ AgencyInfo?.totalIncome || 0 }}
</div>
</div>
<!-- 更多按钮 -->
<div class="moreBt" @click="incomeShow(AgencyInfo)">
{{ t('more') }}
</div>
</div>
</div>
</div>
<!-- 遮罩层 -->
<maskLayer :maskLayerShow="maskLayerShow" @click="closedPopup">
<div style="position: fixed; bottom: 0; width: 100%">
<!-- 某个Agency的收益 -->
<div
v-if="showIncome"
style="
background: white;
border-radius: 16px 16px 0 0;
max-height: 80vh;
display: flex;
flex-direction: column;
gap: 10px;
padding: 10px 12px 30px;
"
class="overflow-y-auto"
@click.stop
>
<div style="display: flex; justify-content: center; align-items: center">
<div style="margin: 0; font-weight: 600; color: #333">
{{ t('agency_id_label') }} {{ moreUserAccount }}
</div>
</div>
<!-- 总体信息 -->
<div
style="
box-shadow: 0 0 4px 0 rgba(0, 0, 0, 0.25);
border-radius: 8px;
padding: 12px;
margin: 0 4px;
"
>
<div>
<div style="display: grid; gap: 4px">
<div style="font-size: 0.9em; font-weight: 600">
{{ t('total_income') }} ${{ moreDetail?.totalIncome || 0 }}
</div>
<div style="font-size: 0.9em; font-weight: 600">
{{ t('previous_period_income') }}: ${{ moreDetail?.previousPeriodIncome || 0 }}
</div>
</div>
</div>
</div>
<div style="font-weight: 600">{{ t('income_details_label') }}</div>
<!-- 历史薪资列表 -->
<div style="overflow-y: auto" class="salaryList">
<div
style="display: flex; flex-direction: column; gap: 8px"
v-for="incomeInfo in moreDetail?.incomeDetails"
>
<!-- 进行中 -->
<historySalary
v-if="incomeInfo.status === 'In Progress'"
type="In Progress"
@showMore="historyShow(incomeInfo)"
>
<template v-slot:content>
<div>{{ incomeInfo.settlementPeriod }}</div>
<div style="display: grid; grid-template-columns: repeat(2, 1fr); gap: 8px">
<div>{{ t('host_label') }} {{ incomeInfo.memberCount }}</div>
<!-- 团队收入 -->
<div>{{ t('team_total_income_text') }} ${{ incomeInfo.teamTotalIncome }}</div>
</div>
</template>
</historySalary>
<!-- 已完成 -->
<historySalary
v-if="incomeInfo.status === 'Completed'"
type="Completed"
@showMore="historyShow(incomeInfo)"
>
<template v-slot:content>
<div>{{ incomeInfo.settlementPeriod }}</div>
<div>{{ t('host_label') }} {{ incomeInfo.memberCount }}</div>
<!-- 团队收入 -->
<div>{{ t('team_total_income_text') }} ${{ incomeInfo.teamTotalIncome }}</div>
</template>
</historySalary>
</div>
</div>
</div>
<!-- 某个时期的Host收益详情 -->
<div
v-if="showHistory"
style="
background: white;
border-radius: 16px 16px 0 0;
max-height: 60vh;
display: flex;
flex-direction: column;
gap: 10px;
padding: 10px 12px 30px;
"
class="overflow-y-auto"
@click.stop
>
<div style="font-weight: 600">{{ incomeDetailsItem.settlementPeriod }}</div>
<div style="display: flex; justify-content: space-between">
<div style="font-size: 0.8em; font-weight: 600">
{{ t('host_label') }}{{ incomeDetailsItem.memberCount }}
</div>
<div style="font-size: 0.8em; font-weight: 600">
{{ t('team_total_income_text_capitalized') }} ${{ incomeDetailsItem.teamTotalIncome }}
</div>
</div>
<!-- Host列表 -->
<div
v-for="member in incomeDetailsItem.members"
style="
background-color: white;
padding: 14px 10px;
border-radius: 12px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
display: flex;
align-items: center;
justify-content: space-between;
gap: 4px;
"
>
<!-- 头像 -->
<div
style="
width: 15%;
align-self: stretch;
display: flex;
align-items: center;
justify-content: center;
"
>
<img
:src="member.avatar || ''"
alt=""
style="
display: block;
width: 100%;
aspect-ratio: 1/1;
border-radius: 50%;
object-fit: cover;
"
@error="handleAvatarImageError"
/>
</div>
<!-- 基本信息 -->
<div
style="
flex: 1;
min-width: 0;
align-self: stretch;
display: flex;
flex-direction: column;
justify-content: space-around;
gap: 4px;
"
>
<div
style="
font-weight: 700;
width: 100%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
"
>
{{ member.userName }}
</div>
<div style="color: rgba(0, 0, 0, 0.4); font-size: 0.8em; font-weight: 500">
{{ t('user_id_prefix') }}{{ member.account }}
</div>
</div>
<!-- 收入信息 -->
<div
style="
width: auto;
min-width: 0;
align-self: stretch;
display: flex;
flex-direction: column;
justify-content: space-around;
"
>
<div style="font-size: 0.8em; font-weight: 500">{{ t('host_income_label') }}</div>
<div style="font-size: 0.8em; font-weight: 500">${{ member.income }}</div>
</div>
</div>
</div>
</div>
</maskLayer>
</div>
</template>
<script setup>
import { computed, onMounted, ref } from 'vue'
import { useI18n } from 'vue-i18n'
import { setDocumentDirection } from '@/locales/i18n'
import { handleAvatarImageError } from '@/utils/imageHandler.js'
import {
apiGetTeamOverview, //查询BD团队概览
apiGetTeamMemberDetail, // 查询BD团队成员详情More弹框
} from '@/api/admin.js'
import GeneralHeader from '@/components/GeneralHeader.vue'
import maskLayer from '@/components/MaskLayer.vue'
import historySalary from './components/historySalary.vue'
const { t, locale } = useI18n()
// 监听语言变化并设置文档方向
locale.value && setDocumentDirection(locale.value)
const TeamOverview = ref(null) //团队概览
const moreUserAccount = ref('') //选中的成员id
const moreDetail = ref(null) //某个成员的详情
const incomeDetailsItem = ref(null) //某个时期的收益详情
const showIncome = ref(false)
const showHistory = ref(false)
// 遮罩层显示状态
const maskLayerShow = computed(() => showIncome.value || showHistory.value)
const incomeShow = (AgencyInfo) => {
console.log('点击了收入按钮')
console.log('AgencyInfo.userId:', AgencyInfo.userId)
moreUserAccount.value = AgencyInfo.account
getTeamMemberDetail(AgencyInfo.userId)
showIncome.value = true
}
const historyShow = (incomeInfo) => {
console.log('点击了历史薪资按钮')
console.log('incomeInfo:', incomeInfo)
incomeDetailsItem.value = incomeInfo
showIncome.value = false
showHistory.value = true
}
// 关闭弹窗
const closedPopup = () => {
showIncome.value = false
showHistory.value = false
moreUserAccount.value = ''
moreDetail.value = null
incomeDetailsItem.value = null
}
// 获取任务列表
const getTeamOverview = async () => {
let data = {
type: 'AGENCY',
}
const resInvitedList = await apiGetTeamOverview(data)
console.log('任务列表:', resInvitedList)
if (resInvitedList.status && resInvitedList.body) {
TeamOverview.value = resInvitedList.body
}
}
// 查询AGENCY团队成员详情More弹框
const getTeamMemberDetail = async (userId) => {
let data = {
targetId: userId,
type: 'AGENCY',
}
const resInvitedList = await apiGetTeamMemberDetail(data)
console.log('任务列表:', resInvitedList)
if (resInvitedList.status && resInvitedList.body) {
moreDetail.value = resInvitedList.body
}
}
// 初始化数据
const init = () => {
getTeamOverview()
}
onMounted(() => {
init()
})
</script>
<style lang="scss" scoped>
* {
color: rgba(0, 0, 0, 0.8);
font-family: 'SF Pro Text';
}
.fullPage {
max-height: 100vh;
overflow-y: auto;
font-family: -apple-system, BlinkMacSystemFont, sans-serif;
background-color: #ffffff;
background-image: url(../../assets/images/secondBg.png);
}
.fullPage::-webkit-scrollbar {
display: none;
}
.overflow-y-auto {
overflow-y: auto;
}
.overflow-y-auto::-webkit-scrollbar {
display: none;
}
.salaryList::-webkit-scrollbar {
display: none;
}
.moreBt {
font-size: 0.8em;
position: absolute;
bottom: 4%;
right: 4%;
color: #bb92ff;
font-weight: 500;
}
[dir='rtl'] .moreBt {
left: 4%;
right: auto;
}
@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;
}
}
@media screen and (min-width: 1024px) {
* {
font-size: 32px;
}
}
</style>