卡片,下拉框添加

This commit is contained in:
pengxiaolong
2025-11-10 20:26:18 +08:00
parent 345b0d1025
commit c157542ec1
9 changed files with 313 additions and 76 deletions

View File

@@ -246,13 +246,14 @@ export enum DICT_TYPE {
IOT_PLUGIN_TYPE = 'iot_plugin_type', // IOT 插件类型
IOT_DATA_BRIDGE_DIRECTION_ENUM = 'iot_data_bridge_direction_enum', // 桥梁方向
IOT_DATA_BRIDGE_TYPE_ENUM = 'iot_data_bridge_type_enum', // 桥梁类型
HOSTS_INVITATION_TYPE = 'hosts_Invitation_type' ,// 桥梁类型
INT_TRUE_FLASE = 'int_true_false',// 桥梁类型HOST_LEVEL
HOSTS_INVITATION_TYPE = 'hosts_Invitation_type', // 桥梁类型
INT_TRUE_FLASE = 'int_true_false', // 桥梁类型HOST_LEVEL
HOST_LEVEL = 'host_level', // 桥梁类型country_group
COUNTRY_GROUP = 'country_group', // 桥梁类型
OPERATION_STATE = 'operational_state', // 是否转化
BIGBIOTHER_NEGOTIATION = 'bigBiother_negotiation', // 是否洽谈
SORT_STATE = 'sort_state',// 升序降序
SORT_TYPE = 'sort_type',// 排序类型
FLAG_TYPE = 'flag_type', // 旗帜
SORT_STATE = 'sort_state', // 升序降序
SORT_TYPE = 'sort_type', // 排序类型
FLAG_TYPE = 'flag_type', // 旗帜
HOSTS_KIND = 'hosts_type' // 直播类型
}

View File

@@ -1,12 +1,6 @@
<template>
<Dialog :title="dialogTitle" v-model="dialogVisible">
<el-form
ref="formRef"
:model="formData"
:rules="formRules"
label-width="100px"
v-loading="formLoading"
>
<el-form ref="formRef" :model="formData" :rules="formRules" label-width="100px" v-loading="formLoading">
<el-form-item label="大哥的display_id" prop="displayId">
<el-input v-model="formData.displayId" placeholder="请输入大哥的display_id" />
</el-form-item>

View File

@@ -117,7 +117,8 @@
<!-- 列表 -->
<ContentWrap>
<el-table v-loading="loading" :data="list" :stripe="true" @selection-change="handleSelectionChange">
<el-table v-if="!isMobile" v-loading="loading" :data="list" :stripe="true"
@selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" />
<el-table-column label="大哥的用户id" align="center" prop="displayId">
<template #default="scope">
@@ -163,8 +164,37 @@
</template>
</el-table-column> -->
</el-table>
<!-- ···························································································································· -->
<div v-else>
<div v-for="(item, index) in list" :key="index" class="mobile-card">
<div class="card-row" style="color:green;">
<b>大哥的用户id</b><span @click="openHtml(item, item.displayId)"
style=" text-decoration: underline;margin-right: 50px;">{{ item.displayId }}</span>
</div>
<div class="card-row"><b>大哥的uid</b>{{ item.userIdStr }}</div>
<div class="card-row"><b>大哥的用户昵称</b>{{ item.nickname }}</div>
<div class="card-row"><b>大哥的等级</b>{{ item.level }}</div>
<div class="card-row"><b>粉丝团等级:</b>{{ item.fansLevel }}</div>
<div class="card-row"><b>大哥打赏的金币</b>{{ item.hostcoins }}</div>
<div class="card-row"><b>大哥的粉丝数</b>{{ item.followerCount }}</div>
<div class="card-row"><b>大哥的关注数</b>{{ item.followingCount }}</div>
<div class="card-row"><b>大哥所在的地区:</b>{{ item.region }}</div>
<div class="card-row"><b>大哥打赏的历史最高金币:</b>{{ item.historicHighCoins }}</div>
<div class="card-row"><b>大哥历史打赏金币总和:</b>{{ item.totalGiftCoins }}</div>
<div class="card-row" style="color:green;">
<b>大哥所在的直播间的主播id</b><span @click="openHtmlbig(item.hostDisplayId)"
style=" text-decoration: underline;margin-right: 50px;">{{ item.hostDisplayId }}</span>
</div>
<div class="card-row"><b>创建时间</b>{{ formatTimestamp(item.createTime) }}</div>
<div class="card-row"><b>是否洽谈</b>
<el-tag size="small" :type="item.operationStatus == 1 ? 'success' : 'info'">
{{ dictLabelI18n(DICT_TYPE.BIGBIOTHER_NEGOTIATION, item.operationStatus) || '-' }}
</el-tag>
</div>
</div>
</div>
<!-- 分页 -->
<Pagination :total="total" v-model:page="queryParams.pageNo" v-model:limit="queryParams.pageSize"
<Pagination v-if="!isMobile" :total="total" v-model:page="queryParams.pageNo" v-model:limit="queryParams.pageSize"
@pagination="getList" />
</ContentWrap>
@@ -247,6 +277,37 @@ const handleQuery = () => {
getList()
}
// 格式化时间戳
function formatTimestamp(milliseconds) {
const date = new Date(milliseconds); // 直接使用毫秒级时间戳
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
const hours = String(date.getHours()).padStart(2, '0');
const minutes = String(date.getMinutes()).padStart(2, '0');
const seconds = String(date.getSeconds()).padStart(2, '0');
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
}
import { useDictStore } from '@/store/modules/dict' // 如果你项目里有字典 store
const dictStore = useDictStore?.() // 有就用;没有的话把 dictStore 相关行删掉
// 统一用字符串比较,自动识别并翻译 i18n key
function dictLabelI18n(type: string, val: any) {
const v = val == null ? '' : String(val)
// 优先从 store 取若没有就从你现有的工具取getIntDictOptions / getStrDictOptions
const opts =
(dictStore?.getDictOptions?.(type) as any[]) ||
getIntDictOptions(type) ||
getStrDictOptions(type) ||
[]
const hit = opts.find(o => String(o.value) === v)
const label = hit?.label ?? ''
// 形如 a.b 或包含点号的,大概率是 i18n key则用 t() 翻
return label && label.includes('.') ? t(label) : label
}
/** 重置按钮操作 */
const resetQuery = () => {
queryParams.levelMin = undefined
@@ -389,9 +450,49 @@ function exportAi(type) {
copyToClipboard(data)
}
const isMobile = ref(window.innerWidth <= 768)
/** 初始化 **/
onMounted(() => {
getList()
getAllocationList();
//实时监听实际还是电脑
window.addEventListener('resize', () => {
if ((window.innerWidth <= 768) != isMobile.value) {
getList()
}
isMobile.value = window.innerWidth <= 768
})
})
</script>
</script>
<style scoped>
@media screen and (max-width: 768px) {
.mobile-card {
background: #fff;
margin: 12px;
padding: 12px;
border-radius: 10px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
font-size: 14px;
}
.card-row {
margin-bottom: 6px;
word-break: break-word;
}
.card-row b {
color: #555;
font-weight: 500;
margin-right: 4px;
}
.action-row {
display: flex;
justify-content: flex-end;
gap: 10px;
margin-top: 6px;
}
}
</style>

View File

@@ -43,6 +43,7 @@
<el-input v-model="queryParams.fllowernumMax" :placeholder="$t('employee.max')" clearable
@keyup.enter="handleQuery" class="!w-115px" />
</el-form-item>
<el-form-item :label="t('newHosts.hostsCountry')" prop="region">
<el-select v-model="queryParams.region" :placeholder="t('newHosts.placeHostsCountry')" clearable
class="!w-240px" @change="changeCountry(queryParams.region)">
@@ -50,6 +51,7 @@
:label="$t(dict.label)" :value="dict.value" />
</el-select>
</el-form-item>
<el-form-item :label="t('newHosts.hostsCountryinfo')" prop="country">
<el-select v-model="queryParams.country" :placeholder="t('newHosts.placeHostsCountry')" clearable
class="!w-240px">
@@ -57,14 +59,20 @@
:value="dict.countryName" />
</el-select>
</el-form-item>
<el-form-item :label="$t('employee.hostsKind')" prop="hostsKind">
<el-input v-model="queryParams.hostsKind" :placeholder="$t('employee.placeHostsKind')" clearable
@keyup.enter="handleQuery" class="!w-240px" />
<el-select v-model="queryParams.hostsKind" :placeholder="t('newHosts.placeHostsKind')" clearable
class="!w-240px" @change="changeCountry(queryParams.hostsKind)">
<el-option v-for="dict in getStrDictOptions(DICT_TYPE.HOSTS_KIND)" :key="dict.value"
:label="$t(dict.label)" :value="dict.value" />
</el-select>
</el-form-item>
<el-form-item :label="$t('employee.createTime')" prop="createTime">
<el-date-picker v-model="queryParams.createTime" value-format="YYYY-MM-DD HH:mm:ss" type="date"
class="!w-240px" />
</el-form-item>
<el-form-item :label="$t('employee.updataTime')" prop="updataTime">
<el-date-picker v-model="queryParams.updateTime" value-format="YYYY-MM-DD HH:mm:ss" type="date"
class="!w-240px" />
@@ -277,15 +285,15 @@
<div class="card-row"><b>{{ $t('employee.updateTime') }}</b>{{ formatTimestamp(item.updateTime) }}</div>
<div class="card-row action-row">
<el-button link type="primary" @click="openForm('update', item.id, index)">{{ $t('employee.edit')
}}</el-button>
}}</el-button>
<el-button link type="danger" @click="handleDelete(item.id)">{{ $t('employee.delete')
}}</el-button>
}}</el-button>
</div>
</div>
</div>
</div>
<MobilePagination v-if="isMobile" v-model:page="queryParams.pageNo" v-model:limit="queryParams.pageSize"
:total="total" :page-sizes="[10, 20, 30, 50]" @size-change="getList()" @load="getList()" @loadPre="getList()" />
:total="total" :page-sizes="[10, 20, 30, 50]" @size-change="getList()" @load="getList()" @load-pre="getList()" />
<!-- PC 显示分页移动端隐藏 -->
<Pagination v-if="!isMobile" :total="total" v-model:page="queryParams.pageNo" v-model:limit="queryParams.pageSize"

View File

@@ -121,7 +121,8 @@
<!-- 列表 -->
<ContentWrap>
<el-table v-loading="loading" :data="list" :stripe="true" @selection-change="handleSelectionChange">
<el-table v-if="!isMobile" v-loading="loading" :data="list" :stripe="true"
@selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" />
<el-table-column label="大哥的用户id" align="center" prop="displayId">
<template #default="scope">
@@ -160,8 +161,38 @@
</template>
</el-table-column>
</el-table>
<div v-else>
<div v-for="(item, index) in list" :key="index" class="mobile-card">
<div class="card-row" style="color:green;">
<b>大哥的用户id</b><span @click="openHtml(item, item.displayId)"
style=" text-decoration: underline;margin-right: 50px;">{{ item.displayId }}</span>
</div>
<div class="card-row"><b>大哥的uid</b>{{ item.userIdStr }}</div>
<div class="card-row"><b>大哥的用户昵称</b>{{ item.nickname }}</div>
<div class="card-row"><b>大哥的等级</b>{{ item.level }}</div>
<div class="card-row"><b>粉丝团等级:</b>{{ item.fansLevel }}</div>
<div class="card-row"><b>大哥打赏的金币</b>{{ item.hostcoins }}</div>
<div class="card-row"><b>大哥的粉丝数</b>{{ item.followerCount }}</div>
<div class="card-row"><b>大哥的关注数</b>{{ item.followingCount }}</div>
<div class="card-row"><b>大哥所在的地区:</b>{{ item.region }}</div>
<div class="card-row"><b>大哥打赏的历史最高金币:</b>{{ item.historicHighCoins }}</div>
<div class="card-row"><b>大哥历史打赏金币总和:</b>{{ item.totalGiftCoins }}</div>
<div class="card-row" style="color:green;">
<b>大哥所在的直播间的主播id</b><span @click="openHtmlbig(item.hostDisplayId)"
style=" text-decoration: underline;margin-right: 50px;">{{ item.hostDisplayId }}</span>
</div>
<div class="card-row"><b>创建时间</b>{{ formatTimestamp(item.createTime) }}</div>
<div class="card-row"><b>是否洽谈</b>
<el-tag size="small" :type="item.operationStatus == 1 ? 'success' : 'info'">
{{ dictLabelI18n(DICT_TYPE.BIGBIOTHER_NEGOTIATION, item.operationStatus) || '-' }}
</el-tag>
</div>
</div>
</div>
<!-- 分页 -->
<Pagination :total="total" v-model:page="queryParams.pageNo" v-model:limit="queryParams.pageSize"
<Pagination v-if="!isMobile" :total="total" v-model:page="queryParams.pageNo" v-model:limit="queryParams.pageSize"
@pagination="getList" />
</ContentWrap>
<el-dialog v-model="dialogAllocation" :title="t('newHosts.allocationUser')">
@@ -273,6 +304,37 @@ const resetQuery = () => {
handleQuery()
}
// 格式化时间戳
function formatTimestamp(milliseconds) {
const date = new Date(milliseconds); // 直接使用毫秒级时间戳
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
const hours = String(date.getHours()).padStart(2, '0');
const minutes = String(date.getMinutes()).padStart(2, '0');
const seconds = String(date.getSeconds()).padStart(2, '0');
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
}
import { useDictStore } from '@/store/modules/dict' // 如果你项目里有字典 store
const dictStore = useDictStore?.() // 有就用;没有的话把 dictStore 相关行删掉
// 统一用字符串比较,自动识别并翻译 i18n key
function dictLabelI18n(type: string, val: any) {
const v = val == null ? '' : String(val)
// 优先从 store 取若没有就从你现有的工具取getIntDictOptions / getStrDictOptions
const opts =
(dictStore?.getDictOptions?.(type) as any[]) ||
getIntDictOptions(type) ||
getStrDictOptions(type) ||
[]
const hit = opts.find(o => String(o.value) === v)
const label = hit?.label ?? ''
// 形如 a.b 或包含点号的,大概率是 i18n key则用 t() 翻
return label && label.includes('.') ? t(label) : label
}
/** 添加/修改操作 */
const formRef = ref()
const openForm = (type: string, id?: number) => {
@@ -428,9 +490,50 @@ function exportAi(type) {
copyToClipboard(data)
}
const isMobile = ref(window.innerWidth <= 768) //是否是移动端
/** 初始化 **/
onMounted(() => {
getList()
getAllocationList();
//实时监听实际还是电脑
window.addEventListener('resize', () => {
if ((window.innerWidth <= 768) != isMobile.value) {
getList()
}
isMobile.value = window.innerWidth <= 768
})
})
</script>
</script>
<style scoped>
@media screen and (max-width: 768px) {
.mobile-card {
background: #fff;
margin: 12px;
padding: 12px;
border-radius: 10px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
font-size: 14px;
}
.card-row {
margin-bottom: 6px;
word-break: break-word;
}
.card-row b {
color: #555;
font-weight: 500;
margin-right: 4px;
}
.action-row {
display: flex;
justify-content: flex-end;
gap: 10px;
margin-top: 6px;
}
}
</style>

View File

@@ -57,10 +57,15 @@
:value="dict.countryName" />
</el-select>
</el-form-item>
<el-form-item :label="$t('employee.hostsKind')" prop="hostsKind">
<el-input v-model="queryParams.hostsKind" :placeholder="$t('employee.placeHostsKind')" clearable
@keyup.enter="handleQuery" class="!w-240px" />
<el-select v-model="queryParams.hostsKind" :placeholder="t('newHosts.placeHostsKind')" clearable
class="!w-240px" @change="changeCountry(queryParams.hostsKind)">
<el-option v-for="dict in getStrDictOptions(DICT_TYPE.HOSTS_KIND)" :key="dict.value"
:label="$t(dict.label)" :value="dict.value" />
</el-select>
</el-form-item>
<el-form-item :label="$t('employee.createTime')" prop="createTime">
<el-date-picker v-model="queryParams.createTime" value-format="YYYY-MM-DD HH:mm:ss" type="date"
class="!w-240px" />
@@ -231,12 +236,12 @@
<div class="card-row"><b>{{ $t('employee.updateTime') }}</b>{{ formatTimestamp(item.updateTime) }}</div>
<div class="card-row action-row">
<el-button link type="primary" @click="openForm('update', item.id, index)">{{ $t('employee.edit')
}}</el-button>
}}</el-button>
</div>
</div>
</div>
<MobilePagination v-if="isMobile" :page="queryParams.pageNo" :limit="queryParams.pageSize" :total="total"
@update:page="val => queryParams.pageNo = val" @load="loadList" @loadPre="loadpreviousList" />
@update:page="val => queryParams.pageNo = val" @load="loadList" @load-pre="loadpreviousList" />
<!-- PC 显示分页移动端隐藏 -->

View File

@@ -89,10 +89,15 @@
:value="dict.countryName" />
</el-select>
</el-form-item>
<el-form-item :label="t('newHosts.hostsKind')" prop="hostsKind">
<el-input v-model="queryParams.hostsKind" :placeholder="t('newHosts.placeHostsKind')" clearable
@keyup.enter="handleQuery" class="!w-240px" />
<el-select v-model="queryParams.hostsKind" :placeholder="t('newHosts.placeHostsKind')" clearable
class="!w-240px" @change="changeCountry(queryParams.hostsKind)">
<el-option v-for="dict in getStrDictOptions(DICT_TYPE.HOSTS_KIND)" :key="dict.value" :label="$t(dict.label)"
:value="dict.value" />
</el-select>
</el-form-item>
<el-form-item :label="t('newHosts.isAssigned')" prop="isAssigned">
<el-select v-model="queryParams.isAssigned" :placeholder="t('newHosts.placeIsAssigned')" clearable
class="!w-240px">