- api: /admin/partner/agent/list 연동을 위한 api/agent.js 추가(getAgentList) - router: 에이전트 상세 및 5종 정산 상세 라우트 추가(파라미터 agentId 사용) - AgentDetail.vue와 정산 상세 5개 뷰(플레이스홀더) 추가 - 숫자/통화 포맷 적용 및 클릭 가능한 스타일 클래스 추가
225 lines
6.6 KiB
Vue
225 lines
6.6 KiB
Vue
<template>
|
|
<div>
|
|
<v-toolbar dark>
|
|
<v-spacer />
|
|
<v-toolbar-title>에이전트 리스트</v-toolbar-title>
|
|
<v-spacer />
|
|
</v-toolbar>
|
|
|
|
<br>
|
|
|
|
<v-container>
|
|
<v-row>
|
|
<v-col
|
|
cols="12"
|
|
class="text-right"
|
|
>
|
|
총 에이전트 수: <strong>{{ totalCount | numberFormat }}</strong>
|
|
</v-col>
|
|
</v-row>
|
|
|
|
<v-row>
|
|
<v-col>
|
|
<v-simple-table class="elevation-10">
|
|
<template>
|
|
<thead>
|
|
<tr>
|
|
<th class="text-center">
|
|
에이전트 닉네임
|
|
</th>
|
|
<th class="text-center">
|
|
소속 크리에이터 수
|
|
</th>
|
|
<th class="text-center">
|
|
라이브
|
|
</th>
|
|
<th class="text-center">
|
|
콘텐츠
|
|
</th>
|
|
<th class="text-center">
|
|
커뮤니티
|
|
</th>
|
|
<th class="text-center">
|
|
콘텐츠 후원
|
|
</th>
|
|
<th class="text-center">
|
|
채널 후원
|
|
</th>
|
|
<th class="text-center">
|
|
합계
|
|
</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr
|
|
v-for="item in agentList"
|
|
:key="item.agentId"
|
|
>
|
|
<td
|
|
class="link"
|
|
@click="goAgentDetail(item)"
|
|
>
|
|
{{ item.agentNickname }}
|
|
</td>
|
|
<td class="text-center">
|
|
{{ item.assignedCreatorCount | numberFormat }}
|
|
</td>
|
|
<td
|
|
class="text-right clickable"
|
|
@click="goSettlement(item, 'live')"
|
|
>
|
|
{{ formatCurrency(item.liveAgentSettlementAmount) }}
|
|
</td>
|
|
<td
|
|
class="text-right clickable"
|
|
@click="goSettlement(item, 'content')"
|
|
>
|
|
{{ formatCurrency(item.contentAgentSettlementAmount) }}
|
|
</td>
|
|
<td
|
|
class="text-right clickable"
|
|
@click="goSettlement(item, 'community')"
|
|
>
|
|
{{ formatCurrency(item.communityAgentSettlementAmount) }}
|
|
</td>
|
|
<td
|
|
class="text-right clickable"
|
|
@click="goSettlement(item, 'content-donation')"
|
|
>
|
|
{{ formatCurrency(item.contentDonationAgentSettlementAmount) }}
|
|
</td>
|
|
<td
|
|
class="text-right clickable"
|
|
@click="goSettlement(item, 'channel-donation')"
|
|
>
|
|
{{ formatCurrency(item.channelDonationAgentSettlementAmount) }}
|
|
</td>
|
|
<td class="text-right">
|
|
{{ formatCurrency(totalAmount(item)) }}
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</template>
|
|
</v-simple-table>
|
|
</v-col>
|
|
</v-row>
|
|
|
|
<!-- 페이지네이션은 서버 지원 시 활성화
|
|
<v-row class="text-center">
|
|
<v-col>
|
|
<v-pagination
|
|
v-model="page"
|
|
:length="total_page"
|
|
circle
|
|
@input="fetchList"
|
|
/>
|
|
</v-col>
|
|
</v-row>
|
|
-->
|
|
</v-container>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import { getAgentList } from '@/api/agent'
|
|
|
|
export default {
|
|
name: 'AgentList',
|
|
filters: {
|
|
numberFormat(v) {
|
|
if (v === null || v === undefined) return '-'
|
|
try {
|
|
return new Intl.NumberFormat('ko-KR').format(v)
|
|
} catch (e) {
|
|
return v
|
|
}
|
|
}
|
|
},
|
|
data() {
|
|
return {
|
|
agentList: [],
|
|
totalCount: 0,
|
|
// 페이지네이션(필요 시)
|
|
page: 1,
|
|
total_page: 1,
|
|
page_size: 20,
|
|
is_loading: false,
|
|
}
|
|
},
|
|
created() {
|
|
this.fetchList()
|
|
},
|
|
methods: {
|
|
async fetchList() {
|
|
if (this.is_loading) return
|
|
this.is_loading = true
|
|
try {
|
|
const res = await getAgentList(/* this.page, this.page_size */)
|
|
// 일부 API는 { data: { totalCount, items } } 형태로 한 번 더 래핑됨을 대비
|
|
let payload = (res && res.data) ? res.data : null
|
|
if (payload && payload.data && (!payload.items && !payload.totalCount)) {
|
|
payload = payload.data
|
|
}
|
|
const data = payload || { totalCount: 0, items: [] }
|
|
this.totalCount = data.totalCount || 0
|
|
this.agentList = Array.isArray(data.items) ? data.items : []
|
|
// 서버가 페이지네이션 정보를 주면 설정하도록 남김
|
|
this.total_page = Math.max(1, Math.ceil(this.totalCount / this.page_size))
|
|
} catch (e) {
|
|
this.totalCount = 0
|
|
this.agentList = []
|
|
} finally {
|
|
this.is_loading = false
|
|
}
|
|
},
|
|
formatCurrency(n) {
|
|
const num = Number(n || 0)
|
|
return new Intl.NumberFormat('ko-KR', { style: 'currency', currency: 'KRW', maximumFractionDigits: 0 }).format(num)
|
|
},
|
|
totalAmount(item) {
|
|
const {
|
|
liveAgentSettlementAmount = 0,
|
|
contentAgentSettlementAmount = 0,
|
|
communityAgentSettlementAmount = 0,
|
|
contentDonationAgentSettlementAmount = 0,
|
|
channelDonationAgentSettlementAmount = 0,
|
|
} = item || {}
|
|
return (
|
|
(liveAgentSettlementAmount || 0) +
|
|
(contentAgentSettlementAmount || 0) +
|
|
(communityAgentSettlementAmount || 0) +
|
|
(contentDonationAgentSettlementAmount || 0) +
|
|
(channelDonationAgentSettlementAmount || 0)
|
|
)
|
|
},
|
|
goAgentDetail(item) {
|
|
this.$router.push({ name: 'AgentDetail', params: { agentId: item.agentId } })
|
|
},
|
|
goSettlement(item, type) {
|
|
const id = item.agentId
|
|
const nameMap = {
|
|
'live': 'AgentSettlementLive',
|
|
'content': 'AgentSettlementContent',
|
|
'community': 'AgentSettlementCommunity',
|
|
'content-donation': 'AgentSettlementContentDonation',
|
|
'channel-donation': 'AgentSettlementChannelDonation',
|
|
}
|
|
const name = nameMap[type]
|
|
if (!name) return
|
|
this.$router.push({ name, params: { agentId: id } })
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
.link {
|
|
color: #3f51b5;
|
|
cursor: pointer;
|
|
text-decoration: underline;
|
|
}
|
|
.clickable {
|
|
cursor: pointer;
|
|
}
|
|
</style>
|