|
|
@@ -3,17 +3,23 @@
|
|
|
<!-- 菜单栏 -->
|
|
|
<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>
|
|
|
+ </div>
|
|
|
+
|
|
|
<!-- 表格 -->
|
|
|
<div class="layout-container">
|
|
|
- <Table @getTableData="changeTableData" v-model:page="page" ref="table" :data="tableData"
|
|
|
- @selection-change="handleSelectionChange" :revenue="totalRevenue">
|
|
|
+ <Table @getTableData="changeTableData" v-model:page="page" ref="table" :data="tableData" showSelection
|
|
|
+ @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.userId)">查看ECPM</el-button>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
- <el-table-column prop="userId" label="用户ID" width="100" fixed="left" />
|
|
|
- <el-table-column prop="nickName" label="用户昵称" fixed="left" width="90" />
|
|
|
+ <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)) }}
|
|
|
@@ -36,7 +42,7 @@
|
|
|
{{ roundPrice(scope.row.totalIncome === 0 ? '0.00' : scope.row.totalIncome ?? '0.00') }}
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
- <el-table-column prop="communicationOperator" label="通信运营商" width="100" />
|
|
|
+ <el-table-column prop="communicationOperator" label="通信运营商" width="130" />
|
|
|
<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" />
|
|
|
@@ -81,7 +87,7 @@
|
|
|
<!-- 操作弹窗 -->
|
|
|
<Layer :layer="layer" @confirm="submit(ruleForm)" @close="layer.show = false">
|
|
|
<el-form :model="formEdit" :rules="rules" ref="ruleForm" label-width="120px" style="margin-right:30px;">
|
|
|
- <el-form-item label="封禁期限:" required prop="bannedLimit">
|
|
|
+ <el-form-item label="封禁时间(天):" required prop="bannedLimit">
|
|
|
<el-input v-model="formEdit.bannedLimit" type="number" placeholder="请输入封禁期限" clearable />
|
|
|
</el-form-item>
|
|
|
<el-form-item label="封禁原因:" required prop="bannedReason">
|
|
|
@@ -109,10 +115,10 @@
|
|
|
<From :form-items="dynamicFormItems1" @formSubmitted="handleFormSubmitted1" @formReset="handleFormReset1" />
|
|
|
<el-divider></el-divider>
|
|
|
<Table :showPage="false" ref="ecpmTable" :data="ecpmData" :height="ecpmLayer.height">
|
|
|
- <el-table-column prop="userId" label="用户ID" width="100" />
|
|
|
+ <el-table-column prop="userId" label="用户ID" width="120" />
|
|
|
<el-table-column prop="adSourceId" label="广告源ID" width="100" />
|
|
|
- <el-table-column prop="beginTime" label="开始时间" />
|
|
|
- <el-table-column prop="finishTime" label="完成时间" />
|
|
|
+ <el-table-column prop="beginTime" label="开始时间" width="100" />
|
|
|
+ <el-table-column prop="finishTime" label="完成时间" width="100" />
|
|
|
<el-table-column prop="ecpm" label="ECPM" width="100" >
|
|
|
<template #default="scope">
|
|
|
{{ roundPrice(scope.row.ecpm) || 0.00 }}
|
|
|
@@ -127,9 +133,9 @@
|
|
|
<el-table-column prop="networkFormId" label="广告平台ID" width="100" />
|
|
|
<el-table-column prop="networkName" label="广告平台名称" width="120" />
|
|
|
<el-table-column prop="networkPlacementId" label="广告平台广告位ID" width="160" />
|
|
|
- <el-table-column prop="nickName" label="用户昵称" width="100" />
|
|
|
+ <el-table-column prop="nickName" label="用户昵称" min-width="100" />
|
|
|
<el-table-column prop="placementId" label="广告位ID" width="100" />
|
|
|
- <el-table-column prop="recordId" label="广告记录ID" width="100" />
|
|
|
+ <el-table-column prop="recordId" label="广告记录ID" width="160" />
|
|
|
<el-table-column prop="revenue" label="收益" width="100">
|
|
|
<template #default="scope">
|
|
|
{{ roundPrice(scope.row.revenue) || 0.00 }}
|
|
|
@@ -142,16 +148,32 @@
|
|
|
</div>
|
|
|
</template>
|
|
|
</Layer>
|
|
|
+
|
|
|
+ <!-- 审核备注 -->
|
|
|
+ <Layer :layer="layer2" @confirm="submit2(ruleForm2)" @close="layer2.show = false">
|
|
|
+ <el-form :model="formEdit2" :rules="rules2" ref="ruleForm2" label-width="120px" 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 } from "vue";
|
|
|
+ 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 { ElMessage } from 'element-plus'
|
|
|
- import { getUserList, riskBannedUser, riskLockUser, appUserEcpm, getRevenueByTime } from '@/api/userModule.js'
|
|
|
+ import { getUserList, riskBannedUser, riskLockUser, appUserEcpm, getRevenueByTime, batchAudit } from '@/api/userModule.js'
|
|
|
import { ditchList } from '@/api/outBagModule.js'
|
|
|
import { appList } from "@/api/formworkErection.js";
|
|
|
import { riskChangeUserStatus } from '@/api/riskModule.js'
|
|
|
@@ -162,6 +184,7 @@
|
|
|
const store = useStore()
|
|
|
const { loadDictData, getOptions, getDictionaryName } = useGetDictList();
|
|
|
const tableData = ref([]);
|
|
|
+ const table = ref(null)
|
|
|
|
|
|
// 分页参数, 供table使用
|
|
|
const page = reactive({
|
|
|
@@ -187,13 +210,12 @@
|
|
|
const dynamicFormItems1 = ref([])
|
|
|
|
|
|
onBeforeMount(() => {
|
|
|
- settingData()
|
|
|
- getList();
|
|
|
- getApiOptions()
|
|
|
+ settingData()
|
|
|
+ // getList();
|
|
|
});
|
|
|
|
|
|
// 获取缓存数据设置筛选数据
|
|
|
- const settingData = () => {
|
|
|
+ const settingData = async() => {
|
|
|
loadDictData().then(() => {
|
|
|
dynamicFormItems.value = [
|
|
|
{
|
|
|
@@ -241,32 +263,47 @@
|
|
|
options: getOptions('ad_source_type'),
|
|
|
},
|
|
|
]
|
|
|
+ // 设置动态选项
|
|
|
+ getApiOptions()
|
|
|
})
|
|
|
}
|
|
|
|
|
|
|
|
|
//渠道来源
|
|
|
const getApiOptions = async() => {
|
|
|
- let ditchOptions = []
|
|
|
- let appsOptions = []
|
|
|
- let res = await ditchList({page:1,limit:9999})
|
|
|
- res.data.map((item)=>{
|
|
|
- ditchOptions.push({
|
|
|
+ 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
|
|
|
- })
|
|
|
- })
|
|
|
- dynamicFormItems.value[3].options = ditchOptions
|
|
|
+ }))
|
|
|
|
|
|
-
|
|
|
- let app = await appList({page:1,limit:9999})
|
|
|
- app.data.map((item)=>{
|
|
|
- appsOptions.push({
|
|
|
+ const appsOptions = appData.map(item => ({
|
|
|
label: item.appName,
|
|
|
value: item.appId
|
|
|
- })
|
|
|
- })
|
|
|
- dynamicFormItems.value[2].options = appsOptions
|
|
|
+ }))
|
|
|
+
|
|
|
+ // 赋值到表单项
|
|
|
+ dynamicFormItems.value[3].options = ditchOptions
|
|
|
+ dynamicFormItems.value[2].options = appsOptions
|
|
|
+
|
|
|
+ // 如果有应用列表,默认选第一个
|
|
|
+ if (appsOptions.length > 0) {
|
|
|
+ const firstApp = appsOptions[0].value
|
|
|
+ dynamicFormItems.value[2].defaultVal = firstApp
|
|
|
+ formSearch.value.appIds = firstApp
|
|
|
+ }
|
|
|
+
|
|
|
+ // 获取列表数据
|
|
|
+ getList()
|
|
|
+ } catch (err) {
|
|
|
+ console.error('获取选项失败:', err)
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
const totalRevenue = ref(0)
|
|
|
@@ -325,9 +362,54 @@
|
|
|
getList();
|
|
|
};
|
|
|
|
|
|
+ const selectData = ref([])
|
|
|
+ const currentAppName = ref(null) // 存储允许全选的 appName
|
|
|
// 选择监听器
|
|
|
const handleSelectionChange = (val) => {
|
|
|
- context.emit("selection-change", 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('只能选择同一个应用的用户哦')
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
// 弹窗
|
|
|
@@ -467,7 +549,7 @@
|
|
|
show: false,
|
|
|
title: "查看ECPM",
|
|
|
showButton: true,
|
|
|
- width: '90vw',
|
|
|
+ width: '95vw',
|
|
|
height: '60vh'
|
|
|
});
|
|
|
|
|
|
@@ -503,6 +585,65 @@
|
|
|
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) => {
|
|
|
+ ElMessage.success('审核提交成功')
|
|
|
+ layer2.value.show = false
|
|
|
+ getList();
|
|
|
+ })
|
|
|
+
|
|
|
+ } else {
|
|
|
+ console.log("error submit!", fields);
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ // #endregion
|
|
|
+
|
|
|
</script>
|
|
|
|
|
|
<style scoped lang="scss">
|
|
|
@@ -530,4 +671,9 @@
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ .btn {
|
|
|
+ display: flex;
|
|
|
+ margin: 10px 0 -10px 30px;
|
|
|
+ }
|
|
|
</style>
|