Files
tkPage/src/views/hosts/hostsList.vue
2025-12-18 20:09:21 +08:00

608 lines
17 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="hostList">
<div>
<div style="display: flex;">
<el-select v-model="searchForm.country" filterable :placeholder="$t('hostList.placeCountry')" size="large"
style="width: 160px">
<el-option :label="$t('hostList.selectAll')" :value="''" />
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
<div></div>
<el-date-picker v-model="searchForm.createTime" type="date" value-format="YYYY-MM-DD"
:placeholder="$t('hostList.placeSeletTime')" size="large" style="margin-left: 50px;width: 160px;" />
<el-input v-model="searchForm.hostsId" :placeholder="$t('hostList.placeHostId')" size="large"
style="width: 160px; margin-left: 50px;" clearable />
<el-button class="serch-button" style="margin-left: 50px;" type="primary" @click="serch">{{
$t('hostList.query') }}</el-button>
<!-- <el-button class="put-button" :disabled="tableData.length == 0" type="primary" @click="exportList">{{
$t('hostList.export') }}</el-button> -->
<!-- <el-button class="put-button" type="primary" @click="dialogFormVisible = true">分配给指定员工</el-button> -->
<el-button @click="filterdialogVisible = true" style="width: 50px;" class="put-button" type="primary"><img
style="height: 30px;" src="@/assets/filter.png"></el-button>
</div>
<div class="hostTable center-justify">
<el-table ref="multipleTableRef" :data="tableData" stripe v-loading="loading" height="500"
@selection-change="handleSelectionChange">
<el-table-column type="selection" width="35" />
<el-table-column fixed prop="hostId" :label="$t('hostList.hostId')" width="160">
<template #default="scope">
<div class="hostIdText" @click="openHTML(scope.row.hostId)"> {{
scope.row.hostId }}</div>
</template>
</el-table-column>
<el-table-column prop="hostlevel" :label="$t('hostList.grade')" width="80">
<template #default="scope">
{{ scope.row.hostlevel }}
</template>
</el-table-column>
<el-table-column prop="invitationType" :label="$t('hostList.invitationType')" width="80">
<template #default="scope">
<el-tag :type="scope.row.invitationType == 1 ? 'success' : 'warning'" @click="getliveHost">
{{ scope.row.invitationType == 1 ? $t('hostList.invitationType1') : $t('hostList.invitationType2') }}
</el-tag>
</template>
</el-table-column>
<el-table-column v-for="label in labelList" :key="label.paramCode" :prop="label.paramCode"
:label="label.paramCodeMeaning" width="120">
<template v-if="label.paramCode != 'createDt'" #default="scope">
</template>
</el-table-column>
<!-- <el-table-column label="操作">
<template #default="scope">
<div style="display: flex; align-items: center">
<el-button type="primary" @click="getTkhostdetail(scope.row.hostId)">查看</el-button>
</div>
</template>
</el-table-column> -->
</el-table>
</div>
<!-- 分页 -->
<div class="center-justify" style="margin-top: 30px;">
<el-pagination v-model:current-page="page" v-model:page-size="pageSize" background
layout="sizes, prev, pager, next" :total="total" :page-sizes="[10, 20, 50, 100]"
@size-change="handleSizeChange" @current-change="handleCurrentChange" />
</div>
</div>
<el-dialog v-model="filterdialogVisible" width="800px" :before-close="handleClose">
<el-row v-for="(field, index) in fields" :key="index" :gutter="20" style="margin-bottom: 10px">
<el-col :span="4">
<div style="height: 100%; padding-top: 10px" class="center-justify">
{{ field.label }}
</div>
</el-col>
<el-col :span="10">
<div><label>{{ $t('hostList.min') }}</label></div>
<el-input type="number" :oninput="'if(value.length>9)value=value.slice(0,9)'"
v-model.number="searchForm[field.minModel]" :placeholder="$t('hostList.placeMin')" />
</el-col>
<el-col :span="10">
<div><label>{{ $t('hostList.max') }}</label></div>
<el-input type="number" :oninput="'if(value.length>9)value=value.slice(0,9)'"
v-model.number="searchForm[field.maxModel]" :placeholder="$t('hostList.placeMax')" />
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="4">
<!-- <label>选择筛选条件</label> -->
<div style="height: 100%;padding-top: 10px;" class="center-justify">
{{ $t('hostList.sort') }}
</div>
</el-col>
<el-col :span="10">
<div><label>{{ $t('hostList.sortType') }}</label></div>
<el-select v-model="sortData.sortType" filterable placeholder="请选择" style="width: 240px">
<el-option v-for="item in sortNameOptions" :key="item.type" :label="item.label" :value="item.type" />
</el-select>
</el-col>
<el-col :span="10">
<div><label>{{ $t('hostList.ascending') }}/{{ $t('hostList.descending') }}</label></div>
<el-select v-model="sortData.sortForm" filterable placeholder="请选择" style="width: 240px">
<el-option
v-for="item in [{ label: $t('hostList.ascending'), value: 'asc' }, { label: $t('hostList.descending'), value: 'desc' }]"
:key="item.value" :label="item.label" :value="item.value" />
</el-select>
</el-col>
</el-row>
<template #footer>
<span class="dialog-footer">
<el-button type="primary" @click="reset">
{{ $t('hostList.reset') }}
</el-button>
<!-- <el-button @click="filterdialogVisible = false">取消</el-button> -->
<el-button type="primary" @click="handelClick">
{{ $t('hostList.sure') }}
</el-button>
</span>
</template>
</el-dialog>
</div>
</template>
<script setup>
// import { getToken, setToken, removeToken } from '@/utils/storage'
import { tkhostdata, dicts, tkhostdetail, downList, getStaffList, managerhosts, upholdinfo, getCountryinfo, accountName, liveHostDetail } from '@/api/account';
import { usePythonBridge, } from '@/utils/pythonBridge'
import { getUser, setSerch, getSerch } from '@/utils/storage'
import { ref, reactive, onMounted } from 'vue';
// import EChartsComponent from '@/components/EChartsComponent.vue';
// import { ElMessage, ElMessageBox } from 'element-plus'
// import { color } from 'echarts';
import { useI18n } from 'vue-i18n'
const { t } = useI18n()
const loading = ref(false)
//py方法
const { givePyAnchorId, exportToExcel } = usePythonBridge();
let num = ref(0)
//账号信息
const userInfo = ref(getUser())
//主播列表DOM
const multipleTableRef = ref(null)
let labelList = ref([
{ paramCode: 'country', paramCodeMeaning: t('hostList.country') },
{ paramCode: 'createTime', paramCodeMeaning: t('hostList.creationTime') },
{ paramCode: 'hostsCoins', paramCodeMeaning: t('hostList.anchorcoins') },
{ paramCode: 'yesterdayCoins', paramCodeMeaning: t('hostList.yesterdayGoldCoins') },
{ paramCode: 'fans', paramCodeMeaning: t('hostList.fansNum') },
{ paramCode: 'fllowernum', paramCodeMeaning: t('hostList.followersNum') },
{ paramCode: 'onlineFans', paramCodeMeaning: t('hostList.onlineFans') },
{ paramCode: 'hostsKind', paramCodeMeaning: t('hostList.anchorType') },
// { paramCode: 'invitationType', paramCodeMeaning: t('hostList.invitationType') },
]);
const tableData = ref([])
//主播列表传参
const searchForm = ref({})
const fields = [
{ label: t('hostList.fansNum'), minModel: 'fansMin', maxModel: 'fansMax' },
{ label: t('hostList.onlineFans'), minModel: 'onlineFansMin', maxModel: 'onlineFansMax' },
{ label: t('hostList.anchorcoins'), minModel: 'hostsCoinsMin', maxModel: 'hostsCoinsMax' },
{ label: t('hostList.followersNum'), minModel: 'fllowernumMin', maxModel: 'fllowernumMax' },
]
//排序
let sortData = ref({ sortForm: 'desc', sortType: "createTime" })
//排序类型
let sortNameOptions = ref([
{ label: t('hostList.creationTime'), type: 'createTime' },
{ label: t('hostList.anchorcoins'), type: 'hostsCoins' },
{ label: t('hostList.fansNum'), type: 'fans' },
{ label: t('hostList.yesterdayGoldCoins'), type: 'yesterdayCoins' },
{ label: t('hostList.onlineFans'), type: 'onlineFans' },
{ label: t('hostList.followersNum'), type: 'fllowernum' },
])
//员工选择列表
let staffOptions = ref([])
//筛选条件选择列表
//选择的员工
let staffValue = ref('')
//选择的主播列表
let selectHostList = ref([])
//分配弹窗是否弹出
let dialogFormVisible = ref(false)
//分配情况弹窗是否弹出
let hostNameVisible = ref(false)
//备注弹窗是否弹出
let commentVisible = ref(false)
//筛选弹窗是否弹出
let filterdialogVisible = ref(false)
//分配的员工
let staffId = ref({})
//备注信息
let commentInfo = ref('')
//备注信息主播
let commentHost = ref('')
//分页
let pageSize = ref(10)
let page = ref(1)
let total = ref(0)
//是否渲染
const isPopoverVisible = reactive({})
let options = ref([])
let version = ref('0.0.0');
onMounted(() => {
getCountry(); //获取国家
// getSerchStorage();//获取搜索条件
getlist();//获取主播列表
})
function serch() {
page.value = 1
console.log(t('hostList.yesterdayGoldCoins'))
getlist();
}
function exportList() {
if (searchForm.value.dataType == 'InvitationType') {
searchForm.value.dataEnd = searchForm.value.dataStart
}
exportToExcel({})
// //浏览器导出方法
// downList('export/hostsinfo',
// {
// searchTime: searchForm.value.time,
// region: searchForm.value.country,
// pageSize: pageSize.value,
// page: page.value,
// userId: userInfo.value.userId,
// }
// );
}
//分页每页条数
function handleSizeChange(val) {
console.log(`${val} items per page`)
getlist();
}
//分页页数
function handleCurrentChange(val) {
console.log(`current page: ${val}`)
getlist();
}
//选择行
function handleSelectionChange(data) {
console.log(data)
selectHostList.value = []
data.forEach(item => {
selectHostList.value.push(item.hostId)
})
// multipleTableRef.value = data
// console.log(multipleTableRef.value)
}
//获取主播列表
const getlist = () => {
loading.value = true
console.log(searchForm.value)
tkhostdata({
tenantId: Number(userInfo.value.tenantId),
sort: sortData.value.sortForm,//正序倒序
sortName: sortData.value.sortType,//排序类型
"current": page.value,
"pageSize": pageSize.value,
...searchForm.value,//筛选条件
}).then(res => {
loading.value = false
if (res) {
console.log('主播列表', res)
total.value = Number(res.total)
tableData.value = res.records.map(item => ({
hostId: item.hostsId, // 注意:原字段是 hostId你的数据是 hostsId需手动映射
hostlevel: item.hostsLevel, // 原字段 hostlevel 对应你的数据 hostsLevel
country: item.country,
createTime: item.createTime,
fans: item.fans,
fllowernum: item.fllowernum,
hostsCoins: item.hostsCoins,
hostsKind: item.hostsKind,
onlineFans: item.onlineFans,
yesterdayCoins: item.yesterdayCoins,
// 保留原有字段(如 belongBy、useable 等)
belongBy: item.belongBy,
useable: item.useable,
invitationType: item.invitationType,
}));
}
})
}
function handelClick() {
filterdialogVisible.value = false
}
function reset() {
searchForm.value.fansMin = null
searchForm.value.fansMax = null
searchForm.value.onlineFansMin = null
searchForm.value.onlineFansMax = null
searchForm.value.hostsCoinsMin = null
searchForm.value.hostsCoinsMax = null
searchForm.value.fllowernumMin = null
searchForm.value.fllowernumMax = null
}
function handleClose(done) {
console.log('关闭')
// searchForm.value = {
// dataType: '',
// dataStart: '',
// dataEnd: '',
// }
done()
}
function getliveHost() {
liveHostDetail(
{
"hostsId": "1296peahh",
"tenantId": userInfo.value.tenantId
}
).then(res => {
console.log("直播间信息列表", JSON.stringify(res))
})
}
//修改主播维护状态
// function handleSelectChange(event, data) {
// upholdinfo({
// "hostId": data.hostId,
// "userId": userInfo.value.userId,
// "tenantId": userInfo.value.tenantId,
// // "comment": "我已经尽力维护,但是失败了",
// "useable": event.target.value
// }).then(res => {
// console.log(res)
// })
// }
//更改主播维护备注
// function uphostcomment() {
// upholdinfo({
// "hostId": commentHost.value,
// "userId": userInfo.value.userId,
// "tenantId": userInfo.value.tenantId,
// "comment": commentInfo.value,
// }).then(res => {
// console.log(res)
// serch()
// commentVisible.value = false
// })
// }
function filterTag(value, row) {
console.log(row.useable, value)
return row.useable === value;
}
//获取国家
function getCountry() {
getCountryinfo({}).then(res => {
// console.log(res)
res.forEach(item => {
if (item.countryGroupName) {
options.value.push({ value: item.countryGroupName, label: item.countryGroupName })
}
})
// console.log(options.value)
}).catch(err => {
console.log('getCountry', err)
})
}
//获取下级员工
// const getStaff = () => {
// getStaffList({
// userId: userInfo.value.userId,
// activeYn: userInfo.value.activeYn,
// tenantId: userInfo.value.tenantId,
// }).then(res => {
// console.log(res)
// res.forEach(item => {
// staffOptions.value.push({
// value: item.userId,
// label: item.userName
// })
// })
// })
// }
// //分配主播给员工
// function allocation() {
// managerhosts({
// "manaId": userInfo.value.userId,
// "userId": staffValue.value,
// "tenantId": userInfo.value.tenantId,
// "hostIds": selectHostList.value
// }).then(res => {
// if (res) {
// dialogFormVisible.value = false
// }
// })
// }
//获取主播信息
// const getTkhostdetail = (id) => {
// tkhostdetail({
// hostId: id,
// // page: 1,
// searchTimeStart: '20250401',
// searchTimeEnd: '20250403'
// }).then(res => {
// console.log(labelList.value)
// })
// }
function openPopover(hostId, paramCode) {
isPopoverVisible[`${hostId}-${paramCode}`] = true;
}
function closePopover(hostId, paramCode) {
// isPopoverVisible[`${hostId}-${paramCode}`] = false;
}
function openHTML(id) {
givePyAnchorId(id)
// upholdinfo({
// "hostId": id,
// "userId": userInfo.value.userId,
// "tenantId": userInfo.value.tenantId,
// // "comment": "我已经尽力维护,但是失败了",
// "useable": "Y"
// }).then(res => {
// getlist();
// })
}
// function openAccountName(idStr) {
// if (idStr) {
// hostNameVisible.value = true
// accountName(idStr).then(res => {
// staffId.value = JSON.stringify(res).replace(/[{}"]/g, '') // 移除所有 {} 和 "
// .split(',') // 按逗号分割成数组
// console.log(res)
// })
// }
// }
</script>
<style lang="less">
.hostList {
box-sizing: border-box;
// height: 100vh;
padding: 40px;
/* 页面无法选中 */
// -webkit-user-select: none;
// -moz-user-select: none;
// -ms-user-select: none;
// user-select: none;
.hostTable {
width: 100%;
padding: 40px 0;
.hostIdText {
text-decoration: underline;
cursor: pointer;
}
}
.serch-button {
width: 80px;
height: 47px;
background: @btn-bg-color;
border-radius: 10px;
border: none;
}
.put-button {
width: 132px;
height: 47px;
background: @btn-bg-color;
border-radius: 10px;
border: none;
}
}
.el-dialog {
--el-dialog-font-line-height: 50px;
--el-dialog-width: 600px;
--el-dialog-border-radius: 8px;
// border: 10px solid @bg-color-light;
}
.center-line {
display: flex;
flex-direction: column;
align-items: center;
// justify-content: center;
}
.center-justify {
display: flex;
justify-content: space-around;
align-items: center;
}
.center-align {
display: flex;
justify-content: space-between;
}
.center-flex {
display: flex;
justify-content: center;
align-items: center;
}
</style>
<style scoped lang="less">
::v-deep(.el-input__wrapper) {
background-color: #F2FAF9;
border: 1px solid @bg-color;
height: 44px;
}
::v-deep(.el-select__wrapper) {
background-color: #F2FAF9;
border: 1px solid @bg-color;
height: 48px;
}
::v-deep(.el-pagination.is-background .el-pager li.is-active) {
background-color: @bg-color;
}
</style>