| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833 |
- <template>
- <div class="layout-container">
- <!-- 菜单栏 -->
- <From :form-items="dynamicFormItems" @formSubmitted="handleFormSubmitted" @formReset="handleFormReset" />
- <div class="btn">
- <el-button type="" v-if="formSearch.appIds && selectData.length > 0" @click="clearSelection">取消全选</el-button>
- <!-- <el-button type="primary" :disabled="!selectData.length > 0" @click="userCheck">批量审核</el-button> -->
- <el-button type="danger" :disabled="!selectData.length > 0" @click="edit({}, true)">批量封禁</el-button>
- <el-button type="primary" :disabled="!selectData.length > 0" @click="editUserType({}, true)">批量解封</el-button>
- <el-button type="success" :disabled="!selectData.length > 0" @click="exportUserList">批量导出</el-button>
- <el-tooltip class="box-item" effect="dark" content="慎用 比较占用服务器资源!!! 导出数量(根据左下角条数)" placement="bottom">
- <el-button type="warning" :disabled="!page.total > 0" @click="allExportUserList">全部导出</el-button>
- </el-tooltip>
- </div>
- <!-- 表格 -->
- <div class="layout-container">
- <Table @getTableData="changeTableData" v-model:page="page" ref="table" :data="tableData" :showSelection="true"
- @selection-change="handleSelectionChange" @select-all="handleSelectAll" @select="handleSelect"
- :revenue="totalRevenue">
- <el-table-column prop="userId" label="查看ECPM" width="130" fixed="left">
- <template #default="scope">
- <el-button type="primary" @click="lookEcpm(scope.row)">查看ECPM</el-button>
- </template>
- </el-table-column>
- <el-table-column prop="userId" label="用户ID" width="120" fixed="left" />
- <el-table-column prop="nickName" label="用户昵称" fixed="left" width="100" />
- <el-table-column prop="userStatus" label="用户状态" width="90">
- <template #default="scope">
- {{ getDictionaryName('user_status', Number(scope.row.userStatus)) }}
- </template>
- </el-table-column>
- <!-- <el-table-column prop="userType" label="用户类型" width="90" />-->
- <!-- <el-table-column prop="appId" label="应用ID" width="150" /> -->
- <!-- <el-table-column prop="appName" label="应用名称" width="150" /> -->
- <!-- <el-table-column prop="appType" label="应用类型" width="90">
- <template #default="scope">
- {{ getDictionaryName('app_type',scope.row.appType) }}
- </template>
- </el-table-column> -->
- <el-table-column prop="ditchName" label="渠道来源" width="150" />
- <el-table-column prop="todayVideo" label="今日视频播放数" width="130" />
- <el-table-column prop="totalVideo" label="视频播放总数" width="110" />
- <el-table-column prop="totalIncome" label="用户贡献(当日/总共)" sortable width="200">
- <template #default="scope">
- {{ roundPrice(scope.row.todayIncome === 0 ? '0.000' : scope.row.todayIncome ?? '0.000', 3) }} /
- {{ roundPrice(scope.row.totalIncome === 0 ? '0.000' : scope.row.totalIncome ?? '0.000', 3) }}
- </template>
- </el-table-column>
- <el-table-column prop="communicationOperator" label="通信运营商" width="130" />
- <el-table-column prop="loginRecordList" label="用户设备" width="200">
- <template #default="scope">
- {{ scope.row.loginRecordList ? scope.row.loginRecordList[0].deviceBrand : '' }} {{
- scope.row.loginRecordList ? scope.row.loginRecordList[0].deviceModel : '' }}
- </template>
- </el-table-column>
- <el-table-column prop="deviceRepeatCount" label="设备重复数量" width="110" />
- <el-table-column prop="ipRepeatCount" label="IP重复数量" width="100" />
- <el-table-column prop="lastLoginIp" label="最新登录IP" width="150" />
- <el-table-column prop="lastLoginTime" label="最新登录时间" width="160">
- <template #default="scope">
- {{ convertUTCToBeijing(scope.row.lastLoginTime) }}
- </template>
- </el-table-column>
- <el-table-column prop="loginDays" label="登录天数" width="90" />
- <!-- <el-table-column prop="pointsBalance" label="积分余额" width="90" />
- <el-table-column prop="pointsTotal" label="积分总额" width="90" />
- <el-table-column prop="redPacketAmount" label="红包总额" width="90" />
- <el-table-column prop="redPacketBalance" label="红包余额" width="90" /> -->
- <el-table-column prop="registryTime" label="注册时间" width="160">
- <template #default="scope">
- {{ convertUTCToBeijing(scope.row.registryTime) }}
- </template>
- </el-table-column>
- <!-- <el-table-column prop="versionCode" label="版本号" /> -->
- <!-- <el-table-column prop="withdrawCount" label="提现笔数" width="90" /> -->
- <!-- <el-table-column prop="withdrawTotal" label="提现总额" width="90" /> -->
- <el-table-column v-if="false" label="操作" width="220" v-permission="'permission'" fixed="right">
- <template #default="scope">
- <div class="button">
- <el-link class="button-item" type="primary" @click="editUserType(scope.row)">
- 风控解除
- </el-link>
- <el-link v-if="scope.row.userStatus < 3" class="button-item" type="danger" @click="edit(scope.row)">
- 封禁用户
- </el-link>
- <el-popconfirm title="确认锁定该用户?" @confirm="lockUser(scope.row)">
- <template #reference>
- <el-link v-if="scope.row.userStatus < 2" class="button-item" type="warning">锁定用户</el-link>
- </template>
- </el-popconfirm>
- </div>
- </template>
- </el-table-column>
- </Table>
- </div>
- <!-- 操作弹窗 -->
- <Layer :layer="layer" @confirm="submit(ruleForm)" @close="layer.show = false">
- <el-form :model="formEdit" :rules="rules" ref="ruleForm" label-width="140px" style="margin-right:30px;">
- <el-form-item label="封禁时间(天):" required prop="bannedLimit">
- <!-- <el-input v-model="formEdit.bannedLimit" type="number" placeholder="请输入封禁期限" clearable /> -->
- <el-input-number step-strictly v-model="formEdit.bannedLimit" :step="1" :min="0" :precision="0" />
- </el-form-item>
- <el-form-item label="封禁原因:" required prop="bannedReason">
- <el-input v-model="formEdit.bannedReason" placeholder="请输入封禁原因" clearable />
- </el-form-item>
- </el-form>
- </Layer>
- <Layer :layer="layer1" @confirm="submit1(ruleForm1)" @close="layer.show = false">
- <el-form :model="formEdit1" :rules="rules1" ref="ruleForm1" label-width="120px" style="margin-right:30px;">
- <el-form-item v-if="!layer1.isMulty" label="用户状态:" required prop="userStatus">
- <el-select v-model="formEdit1.userStatus" placeholder="请选择状态" filterable>
- <el-option v-for="option in getOptions('user_status')" :key="option.label" :label="option.label"
- :value="option.value">
- </el-option>
- </el-select>
- </el-form-item>
- <el-form-item label="原因:" prop="reason">
- <el-input v-model="formEdit1.reason" placeholder="请输入原因" clearable />
- </el-form-item>
- </el-form>
- </Layer>
- <el-dialog v-model="ecpmLayer.show" :title="`查看用户《${ecpmData.nickName}》的ECPM`" :width="ecpmLayer.width" align-center
- center :fullscreen="isFullscreen">
- <el-icon class=" full-icon" @click="isFullscreen = !isFullscreen">
- <FullScreen />
- </el-icon>
- <EcpmDialog v-if="ecpmLayer.show" v-model:isFullscreen="isFullscreen" :ecpmData="ecpmData" />
- </el-dialog>
- <!-- 审核备注 -->
- <Layer :layer="layer2" @confirm="submit2(ruleForm2)" @close="layer2.show = false">
- <el-form :model="formEdit2" :rules="rules2" ref="ruleForm2" label-width="140px" style="margin-right:30px;">
- <el-form-item label="封禁时间(天)" required prop="bannedLimit">
- <el-input-number v-model="formEdit2.bannedLimit" :min="1" :step="1" step-strictly style="width: 100%;" />
- </el-form-item>
- <el-form-item label="生效时间(小时)" required prop="effectTime">
- <el-input-number v-model="formEdit2.effectTime" :min="0" :step="1" step-strictly style="width: 100%;" />
- <el-alert title="单位为小时,0表示立即执行" type="error" center :closable="false" style="margin-top: 5px;height: 30px;" />
- </el-form-item>
- <el-form-item label="审核备注" required prop="remark">
- <el-input v-model="formEdit2.remark" type="textarea" rows="4" placeholder="请输入审核备注内容" clearable />
- </el-form-item>
- </el-form>
- </Layer>
- </div>
- </template>
- <script setup>
- import { onBeforeMount, ref, reactive, nextTick } from "vue";
- import From from "@/components/from/index.vue";
- import Table from "@/components/table/index.vue";
- import Layer from '@/components/layer/index.vue'
- import { FullScreen } from '@element-plus/icons'
- import { ElMessage, ElLoading } from 'element-plus'
- import {
- getUserList, riskBannedUser, riskLockUser, appUserEcpm, getRevenueByTime,
- batchAudit, batchBanned, batchDeblock
- } from '@/api/userModule.js'
- import { ditchList } from '@/api/outBagModule.js'
- import { appList } from "@/api/formworkErection.js";
- import { riskChangeUserStatus } from '@/api/riskModule.js'
- import { convertUTCToBeijing, roundPrice, getTodayRangeLocal } from '@/utils/index.js'
- import { useGetDictList } from '@/hooks/useGetDictList.js'
- import { useStore } from 'vuex'
- import { exportToExcel } from '@/utils/exportExcel.js'
- import EcpmDialog from "./components/ecpmDialog.vue";
- const store = useStore()
- const { loadDictData, getOptions, getDictionaryName } = useGetDictList();
- const tableData = ref([]);
- const table = ref(null)
- // 分页参数, 供table使用
- const page = reactive({
- pageNum: 1,
- pageSize: 20,
- total: 0,
- });
- const formSearch = ref({
- // lastLoginTime: undefined,// 最新登录时间
- nickName: undefined,// 用户昵称
- userId: undefined,// 用户ID
- ditchId: undefined,// 渠道来源
- userStatus: 1,// 用户状态
- appIds: undefined, //所属应用
- registryTimeBegin: getTodayRangeLocal(),// 注册时间
- registryTimeEnd: undefined,// 注册时间
- page: 1,// 当前页码
- limit: 20,// 当前页数量(查询量)
- });
- const dynamicFormItems = ref([])
- onBeforeMount(() => {
- settingData()
- // getList();
- });
- // 获取缓存数据设置筛选数据
- const settingData = async () => {
- loadDictData().then(() => {
- dynamicFormItems.value = [
- {
- label: '用户昵称',
- prop: 'nickName',
- type: 'input',
- needEnterEvent: true
- },
- {
- label: '用户ID',
- prop: 'userId',
- type: 'input',
- needEnterEvent: true
- },
- {
- label: '所属应用',
- prop: 'appIds',
- type: 'select',
- clearable: false,
- options: [],
- },
- {
- label: '渠道来源',
- prop: 'ditchId',
- type: 'select',
- options: getOptions('channel_origin'),
- },
- {
- label: '用户状态',
- prop: 'userStatus',
- type: 'select',
- defaultVal: 1,
- options: getOptions('user_status'),
- },
- { label: '注册时间开始', prop: 'registryTimeBegin', type: 'date', defaultVal: getTodayRangeLocal() },
- { label: '注册时间结束', prop: 'registryTimeEnd', type: 'date' },
- ]
- // 设置动态选项
- getApiOptions()
- })
- }
- const firstApp = ref('')
- //渠道来源
- const getApiOptions = async () => {
- try {
- // 并发获取数据
- const [{ data: ditchData }, { data: appData }] = await Promise.all([
- ditchList({ page: 1, limit: 9999 }),
- appList({ page: 1, limit: 9999 })
- ])
- const ditchOptions = ditchData.map(item => ({
- label: item.ditchName,
- value: item.ditchId
- }))
- const appsOptions = appData.map(item => ({
- label: item.appName,
- value: item.appId
- }))
- // 赋值到表单项
- dynamicFormItems.value[3].options = ditchOptions
- dynamicFormItems.value[2].options = appsOptions
- // 如果有应用列表,默认选第一个
- if (appsOptions.length > 0) {
- // const firstApp = appsOptions[0].value
- firstApp.value = appsOptions[0].value
- dynamicFormItems.value[2].defaultVal = firstApp.value
- formSearch.value.appIds = firstApp.value
- }
- // 获取列表数据
- getList(0)
- } catch (err) {
- console.error('获取选项失败:', err)
- }
- }
- const totalRevenue = ref(0)
- // 分页数据
- const getList = async (timeout = 5000) => {
- openFullScreen('数据请求中,请勿重复点击!!!')
- return new Promise((resolve) => {
- setTimeout(async () => {
- try {
- /* //处理根据时间获取收益参数
- const param = {...formSearch.value}
- delete param.page
- delete param.limit
- //并发获取数据
- const [listRes, revenueRes] = await Promise.all([
- getUserList({ ...formSearch.value }),
- // getRevenueByTime({ ...param })
- ]) */
- const listRes = await getUserList({ ...formSearch.value })
- // 列表当日总收益
- const totalEarnings = listRes.data.reduce((acc, cur) => acc + (cur.todayIncome || 0), 0)
- tableData.value = listRes.data;
- page.total = listRes.pageMeta.total;
- totalRevenue.value = roundPrice(totalEarnings, 2, true)
- resolve(true);
- } catch (e) {
- console.log('数据请求超时或报错', e)
- resolve(false);
- } finally {
- closeFullScreen()
- }
- }, timeout)
- });
- };
- const changeTableData = (type) => {
- formSearch.value.page = type ? 1 : page.pageNum;
- formSearch.value.limit = page.pageSize;
- // 分页切换
- getList(0);
- };
- // 搜索
- const handleFormSubmitted = (formData) => {
- // console.log("接收到子组件传递的数据", formData);
- formSearch.value.page = page.pageNum;
- formSearch.value.limit = page.pageSize;
- formSearch.value.nickName = formData.nickName;
- formSearch.value.userId = formData.userId;
- formSearch.value.ditchId = formData.ditchId;
- formSearch.value.userStatus = formData.userStatus;
- formSearch.value.appIds = formData.appIds;
- formSearch.value.registryTimeBegin = convertUTCToBeijing(formData.registryTimeBegin, false) || undefined
- formSearch.value.registryTimeEnd = convertUTCToBeijing(formData.registryTimeEnd, false) || undefined
- getList(0);
- };
- // 表单重置
- const handleFormReset = () => {
- formSearch.value = {
- nickName: undefined,// 用户昵称
- userId: undefined,// 用户ID
- ditchId: undefined,// 渠道来源
- userStatus: 1,// 用户状态
- appIds: undefined, //所属应用
- registryTimeBegin: getTodayRangeLocal(),// 注册时间
- registryTimeEnd: undefined,// 注册时间
- page: 1,// 当前页码
- limit: 20,// 当前页数量(查询量)
- };
- page.pageNum = 1
- page.pageSize = 20
- page.total = 0
- // getList();
- settingData()
- };
- const selectData = ref([])
- const currentAppName = ref(null) // 存储允许全选的 appName
- // 选择监听器
- const handleSelectionChange = (val) => {
- selectData.value = val
- }
- // 全选
- const handleSelectAll = (selection) => {
- if (selection.length === 0) {
- // 全选取消
- currentAppName.value = null
- return
- }
- // 取第一个选中的 appName 作为基准
- const firstAppName = selection[0].appName
- // 先全部取消
- table.value.table.clearSelection()
- // 再只选中同一 appName 的行
- tableData.value.forEach(row => {
- if (row.appName === firstAppName) {
- table.value.table.toggleRowSelection(row, true)
- }
- })
- currentAppName.value = firstAppName
- }
- // 取消全选
- const clearSelection = () => {
- currentAppName.value = null
- table.value.table.clearSelection()
- }
- // 单选
- const handleSelect = (selection, row) => {
- // 如果是单选时第一次选中,就记录当前 appName
- if (selection.length === 1) {
- currentAppName.value = selection[0].appName
- }
- // 如果选了不同 appName 的数据,则取消
- if (selection.length > 0 && row.appName !== currentAppName.value) {
- table.value.table.toggleRowSelection(row, false)
- ElMessage.warning('只能选择同一个应用的用户哦')
- }
- }
- const loading = ref(null)
- // 加载信息
- const openFullScreen = (loadText) => {
- loading.value = ElLoading.service({
- lock: true,
- text: loadText,
- background: 'rgba(0, 0, 0, 0.7)',
- })
- }
- const closeFullScreen = () => {
- loading.value.close()
- }
- // 弹窗
- const layer = ref({
- show: false,
- title: "封禁用户",
- showButton: true,
- width: '300px',
- isMulty: false
- });
- const formEdit = ref({
- bannedLimit: undefined, //封禁期限
- bannedReason: undefined,//封禁原因
- bannedTargetId: undefined,//封禁目标ID
- bannedType: undefined,//封禁类型 1-渠道 2-平台
- operator: undefined,//操作人
- operatorName: undefined,//操作人名称
- userId: undefined, //用户ID
- appId: undefined,//应用ID
- userIds: undefined, //用户ID
- })
- const edit = (row, isMulty = false) => {
- ruleForm.value?.resetFields()
- layer.value.isMulty = isMulty
- if (isMulty) {
- layer.value.title = '批量封禁用户'
- formEdit.value = {}
- } else {
- layer.value.title = '封禁用户'
- formEdit.value.bannedTargetId = row.appId
- formEdit.value.bannedType = row.channelType
- formEdit.value.operator = store.state.user.info.loginName
- formEdit.value.operatorName = store.state.user.info.nickName
- formEdit.value.userId = row.userId
- formEdit.value.appId = row.appId
- }
- layer.value.show = true
- }
- const ruleForm = ref(null);
- const rules = reactive({
- formEditbannedLimit: [
- { required: true, message: "请输入封禁期限", trigger: "blur" },
- ],
- bannedReason: [
- {
- required: true,
- message: "请输入封禁原因",
- trigger: "blur",
- },
- ],
- });
- const submit = async (formEl) => {
- await formEl.validate(async (valid, fields) => {
- if (valid) {
- if (layer.value.isMulty) {
- formEdit.value.appId = selectData.value[0].appId
- formEdit.value.userIds = selectData.value.map((item) => item.userId).join(",")
- // 批量封禁
- batchBanned({ ...formEdit.value }).then((res) => {
- layer.value.show = false
- getList().then(() => {
- ElMessage.success('批量封禁用户成功,如未更新状态,请手动刷新')
- })
- })
- } else {
- // 提交内容
- riskBannedUser({ ...formEdit.value }).then((res) => {
- layer.value.show = false
- getList().then(() => {
- ElMessage.success('封禁用户成功,如未更新状态,请手动刷新')
- })
- })
- }
- } else {
- console.log("error submit!", fields);
- }
- })
- }
- // 弹窗2
- const layer1 = ref({
- show: false,
- title: "更改用户状态",
- showButton: true,
- width: '300px',
- isMulty: false
- });
- const formEdit1 = ref({
- bannedType: undefined,//封禁类型 1-渠道 2-平台
- operator: undefined,//操作人
- operatorName: undefined,//操作人名称
- reason: undefined,//原因
- userId: undefined, //用户ID
- appId: undefined, //应用ID
- userStatus: undefined, //用户状态
- deblockingReason: undefined,//批量解封原因
- agentId: undefined, //加盟商ID
- userIds: undefined, //用户ID
- })
- const editUserType = (row, isMulty = false) => {
- ruleForm1.value?.resetFields()
- layer1.value.isMulty = isMulty
- if (isMulty) {
- layer1.value.title = '批量解封用户'
- formEdit1.value = {}
- } else {
- layer1.value.title = '解封用户'
- formEdit1.value.bannedType = row.channelType
- formEdit1.value.operator = store.state.user.info.loginName
- formEdit1.value.operatorName = store.state.user.info.nickName
- formEdit1.value.userId = row.userId
- formEdit1.value.appId = row.appId
- }
- layer1.value.show = true
- }
- const ruleForm1 = ref(null);
- const rules1 = reactive({
- userStatus: [
- {
- required: true,
- message: "请选择用户状态",
- trigger: "change",
- },
- ],
- reason: [
- {
- required: true,
- message: "请输入更改原因",
- trigger: ["blur"],
- },
- ],
- });
- const submit1 = async (formEl) => {
- await formEl.validate(async (valid, fields) => {
- if (valid) {
- if (layer1.value.isMulty) {
- // 批量解封
- formEdit1.value.deblockingReason = formEdit1.value.reason
- formEdit1.value.appId = selectData.value[0].appId
- formEdit1.value.userIds = selectData.value.map((item) => item.userId).join(",")
- delete formEdit1.value.reason
- batchDeblock(formEdit1.value).then((res) => {
- layer1.value.show = false
- getList().then(() => {
- ElMessage.success('批量解封用户成功,如未更新状态,请手动刷新')
- })
- })
- } else {
- // 提交内容
- riskChangeUserStatus(formEdit1.value).then((res) => {
- layer1.value.show = false
- getList().then(() => {
- ElMessage.success('更改用户状态成功,如未更新状态,请手动刷新')
- })
- })
- }
- } else {
- console.log("error submit!", fields);
- }
- })
- }
- // 锁定用户
- const lockUser = async (row) => {
- riskLockUser({ userId: row.userId, appId: row.appId }).then((res) => {
- getList().then(() => {
- ElMessage.success('锁定用户成功,如未更新状态,请手动刷新')
- })
- })
- }
- // 查看ECPM
- const ecpmData = ref({})
- const isFullscreen = ref(false)
- const ecpmLayer = ref({
- show: false,
- title: "查看ECPM",
- showButton: true,
- width: '95vw',
- });
- const lookEcpm = async (row) => {
- ecpmData.value = row
- ecpmLayer.value.show = true
- }
- // #region 审核备注
- const userCheck = async () => {
- ruleForm2.value?.resetFields()
- layer2.value.show = true
- formEdit2.value = []
- }
- // 弹窗
- const layer2 = ref({
- show: false,
- title: "批量审核",
- showButton: true,
- width: '300px'
- });
- const formEdit2 = ref({
- appId: undefined, //应用ID
- ditchId: undefined,//渠道ID
- userIds: undefined, //用户ID
- bannedLimit: undefined, //封禁时间(天)
- effectTime: undefined,//生效时间(小时)
- remark: undefined, //备注
- })
- const ruleForm2 = ref(null);
- const rules2 = reactive({
- remark: [
- { required: true, message: "请输入审核备注内容", trigger: "blur" },
- ],
- bannedLimit: [
- { required: true, message: "请选择封禁时间", trigger: "change" },
- ],
- effectTime: [
- { required: true, message: "请选择生效时间", trigger: "change" },
- ],
- });
- const submit2 = async (formEl) => {
- await formEl.validate(async (valid, fields) => {
- if (valid) {
- formEdit2.value.appId = selectData.value[0].appId
- formEdit2.value.ditchId = selectData.value[0].ditchId
- formEdit2.value.userIds = selectData.value.map((item) => item.userId).join(",")
- // 提交内容
- await batchAudit({ ...formEdit2.value }).then((res) => {
- layer2.value.show = false
- getList().then(() => {
- ElMessage.success('审核提交成功,如未更新状态,请手动刷新')
- })
- })
- } else {
- console.log("error submit!", fields);
- }
- })
- }
- // #endregion
- // #region 数据导出
- // 批量导出
- const exportUserList = async () => {
- if (!selectData.value || selectData.value.length === 0) {
- ElMessage.warning('没有可导出的数据')
- return;
- }
- exportToExcel(getData(selectData.value), tableHeader, 20, '用户列表数据', true).then(() => {
- ElMessage.success('导出成功')
- })
- .catch(() => {
- ElMessage.error('导出失败,请重试')
- })
- }
- // 全部导出
- const allExportUserList = async () => {
- // 请求数据
- try {
- openFullScreen('数据导出中,请勿操作!!!')
- const params = formSearch.value
- params.page = 1
- params.limit = page.total - 1
- const res = await getUserList({ ...params })
- if (res.data.length > 0) {
- exportToExcel(getData(res.data), tableHeader, 20, '用户列表数据', true).then(() => {
- ElMessage.success('导出成功')
- })
- .catch(() => {
- ElMessage.error('导出失败,请重试')
- })
- }
- } catch (e) {
- console.log('数据请求超时或报错', e)
- } finally {
- closeFullScreen()
- }
- }
- // 处理数据
- const getData = (data) => {
- return data.map((item) => ({
- userId: item.userId,
- nickName: item.nickName,
- userStatus: getDictionaryName('user_status', Number(item.userStatus)),
- ditchName: item.ditchName,
- todayVideo: item.todayVideo,
- totalVideo: item.totalVideo,
- totalIncome: `${roundPrice(item.todayIncome === 0 ? '0.000' : item.todayIncome ?? '0.000', 3)} / ${roundPrice(item.totalIncome === 0 ? '0.000' : item.totalIncome ?? '0.000',3)}`,
- communicationOperator: item.communicationOperator,
- loginRecordList: item.loginRecordList?.length
- ? `${item.loginRecordList[0].deviceBrand} ${item.loginRecordList[0].deviceModel}`
- : "",
- deviceRepeatCount: item.deviceRepeatCount,
- ipRepeatCount: item.ipRepeatCount,
- lastLoginIp: item.lastLoginIp,
- lastLoginTime: convertUTCToBeijing(item.lastLoginTime),
- loginDays: item.loginDays,
- registryTime: convertUTCToBeijing(item.registryTime),
- }))
- }
- // 表头
- const tableHeader = {
- "userId": "用户ID",
- "nickName": "用户昵称",
- "userStatus": "用户状态",
- "ditchName": "渠道来源",
- "todayVideo": "今日视频播放数",
- "totalVideo": "视频播放总数",
- "totalIncome": "用户贡献(当日/总共)",
- "communicationOperator": "通信运营商",
- "loginRecordList": "用户设备",
- "deviceRepeatCount": "设备重复数量",
- "ipRepeatCount": "IP重复数量",
- "lastLoginIp": "最新登录IP",
- "lastLoginTime": "最新登录时间",
- "loginDays": "登录天数",
- "registryTime": "注册时间",
- }
- // #endregion
- </script>
- <style scoped lang="scss">
- .layout-container {
- .card {
- .title {
- margin-bottom: 10px;
- font-weight: 600;
- }
- display: flex;
- flex-direction: column;
- align-items: start;
- width: calc(100% - 60px);
- margin: 30px 30px 0;
- }
- .button {
- display: flex;
- //flex-direction: column;
- .button-item {
- margin: 4px;
- }
- }
- }
- .btn {
- display: flex;
- margin: 10px 0 -10px 30px;
- }
- .full-icon {
- position: absolute;
- right: 40px;
- top: 15px;
- cursor: pointer;
- padding: 8px;
- border-radius: 5px;
- }
- </style>
|