|
|
<template> <div> <div class="page-container" v-show="taber == 'DeepMate'"> <!-- 搜索区域 --> <div class="search-container"> <div class="search-form"> <div class="search-item"> <span class="form-label">账号</span> <el-input v-model="searchFormDM.dccode" placeholder="请输入账号" clearable style="height: 36px; width: 140px;" /> </div> <div class="search-item"> <span class="form-label">姓名</span> <el-input v-model="searchFormDM.dcname" placeholder="请输入姓名" clearable style="height: 36px; width: 180px;" /> </div> <div class="search-item"> <span class="form-label">客户类型</span> <el-select v-model="searchFormDM.user_role" placeholder="请选择客户类型" clearable style="height: 36px; width: 160px;" > <el-option label="非网" value="2" /> <el-option label="会员" value="1" /> </el-select> </div> <div class="search-item"> <span class="form-label">地区</span> <el-select v-model="searchFormDM.market" placeholder="请选择地区" clearable style="height: 36px; width: 160px;" :loading="isRegionLoading" > <el-option v-for="region in regionList" :key="region.id" :label="region.text_cn" :value="region.market" /> </el-select> </div> <div class="button-group"> <el-button type="primary" @click="searchDM">搜索</el-button> <el-button type="danger" @click="enableAccessDM">开通权限</el-button> <el-button type="success" @click="exportExcelDM">导出Excel列表</el-button> <el-button color="#626aef" @click="exportListDM">查看导出列表</el-button> <el-button type="primary" @click="resetBnDM">重置</el-button> </div> </div> </div>
<!-- tab切换 --> <div class="tab-group"> <button class="tab-btn" :class="{ active: taber === 'DeepMate' }" @click="taber = 'DeepMate'" > DeepMate </button> <button class="tab-btn" :class="{ active: taber === 'DeepExplore' }" @click="taber = 'DeepExplore'" > 深度探索 </button> </div>
<!-- 数据 --> <el-table :data="tableDataDM" style="width: 100%; margin-top: 20px;" header-cell-class-name="table-header" @sort-change="handleSortChangeDM" :default-sort="{ order: null }" class="table-rounded" :loading="tableLoadingDM" > <el-table-column prop="id" label="序号" align="center" header-align="center" width="60"> <template #default="scope"> {{ (currentPageDM - 1) * pageSizeDM + scope.$index + 1 }} </template> </el-table-column> <el-table-column prop="dccode" label="账号" align="center" header-align="center"/> <el-table-column prop="dcname" label="姓名" align="center" header-align="center"/> <el-table-column prop="module_name" label="模块名称" align="center" header-align="center"/> <el-table-column prop="token_num" label="token数量" align="center" header-align="center"/> <el-table-column prop="updated_at" label="操作时间" align="center" header-align="center" sortable="custom"/> <el-table-column label="操作" align="center" header-align="center"> <template #default="scope"> <el-button type="text" @click="handleEditDM(scope.row)">编辑</el-button> <el-button type="text" @click="handleLogDM(scope.row.dccode)">操作日志</el-button> </template> </el-table-column> </el-table>
<!-- 分页组件 --> <div class="demo-pagination-block"> <el-pagination @size-change="handleSizeChangeDM" @current-change="handleCurrentChangeDM" :current-page="currentPageDM" :page-sizes="[10, 20, 50, 100]" :page-size="pageSizeDM" layout="total, sizes, prev, pager, next, jumper" :total= "datatotalDM" /> </div>
<!-- 开通/编辑弹窗 --> <el-dialog v-model="dialogVisibleDM" :title="addOrUpdataDM === 1 ? '添加权限' : '修改'" width="500px" :before-close="cancelDM"> <!-- 设置用户 --> <div class="form-item" v-if="addOrUpdataDM === 1"> <label class="form-label">设置用户</label> <el-input type="textarea" v-model="hlidsInput" rows=10 placeholder="请输入HLid...示例:900480049004800590048006" /> <div class="tip">支持批量输入,每次最多1000个(手动/Excel粘贴均可)</div> </div>
<!-- 编辑回显 --> <div class="info-container" v-if="addOrUpdataDM === 0"> <span class="info-item">HLid: {{ hlidsInput }}</span> <span class="info-item">剩余次数:{{ deadtoken }}</span> </div>
<!-- 设置数量 --> <div class="form-item" v-if="addOrUpdataDM === 1"> <label class="form-label">设置用户次数</label> <div class="count-group"> <!-- Deep Mate:不可编辑文本框 --> <el-input v-model="dmText" disabled style="width: 160px; margin-right: 16px;"/> <!-- token数量:只能正整数 --> <el-input v-model.number="token_num" type="number" style="width: 210px;" placeholder="请输入次数(只能为正)"/> </div> </div>
<div class="form-item" v-if="addOrUpdataDM === 0"> <label class="form-label">修改用户次数</label> <div class="count-group"> <!-- Deep Mate:不可编辑文本框 --> <el-input v-model="dmText" disabled style="width: 160px; margin-right: 16px;"/> <!-- token数量:支持正负整数 --> <el-input v-model.number="token_num" type="number" style="width: 210px;" placeholder="请输入次数(可正负)"/> </div> </div>
<!-- 按钮区域 --> <div class="dialog-footer"> <el-button type="default" plain @click="cancelDM">取消</el-button> <el-button type="primary" @click="submitFormDM" style="background-color: #ff0000; border-color: #ff0000;">提交</el-button> </div> </el-dialog> </div> </div></template>
<script setup>import { ref, reactive, onMounted } from 'vue';import { ElMessage } from 'element-plus';import { marketListApi, userDMListApi, exportDeepMateApi, exitDMApi } from '../../api/userPermissions'import router from '../../router';import { useRoute } from 'vue-router';
// token
const token = localStorage.getItem('token')
// tab切换
const taber = ref('DeepMate')
// 获取路由实例
const route = useRoute();
// 组件挂载时:获取地区列表 + 初始化表格数据
onMounted(() => { const taberQuery = route.query.taber; const TaberValues = ["DeepMate", "DeepExplore"]; taber.value = TaberValues.includes(String(taberQuery)) ? String(taberQuery) : "DeepMate";
fetchRegionList(); DMTableData();});
// 地区下拉框
const regionList = ref([]);const isRegionLoading = ref(false);
// 获取地区列表
const fetchRegionList = async () => { try { isRegionLoading.value = true; const data = await marketListApi({token: token}); regionList.value = data.list; } catch (error) { console.error('获取地区列表失败:', error); regionList.value = []; } finally { isRegionLoading.value = false; }};
// DeepMate搜索表单
const searchFormDM = reactive({ dccode: '', dcname: '', market: '', user_role: ''});
// DeepMate排序参数
const sortOrderDM = ref(null);
// DeepMate表格数据
const tableDataDM = ref([]);const tableLoadingDM = ref(false);const datatotalDM = ref(0)
// DeepMate分页参数
const currentPageDM = ref(1);const pageSizeDM = ref(10);
// DeepMate获取表格数据
const DMTableData = async () => { try { tableLoadingDM.value = true; const requestParams = { token: token, dccode: searchFormDM.dccode, dcname: searchFormDM.dcname, market: searchFormDM.market, user_role: searchFormDM.user_role, sort_order: sortOrderDM.value, page: currentPageDM.value, page_size: pageSizeDM.value }; const data = await userDMListApi(requestParams); tableDataDM.value = data.list datatotalDM.value = data.total } catch (error) { console.error('获取表格数据失败:', error); tableDataDM.value = []; datatotalDM.value = 0 } finally { tableLoadingDM.value = false; }};
// DeepMate分页方法
const handleSizeChangeDM = (val) => { pageSizeDM.value = val; DMTableData(); console.log(`每页 ${val} 条`);};
const handleCurrentChangeDM = (val) => { currentPageDM.value = val; DMTableData(); console.log(`当前页: ${val}`);};
// DeepMate排序事件
const handleSortChangeDM = (sort) => { const { order } = sort; sortOrderDM.value = order; // 保存当前排序方式
DMTableData(); };
// DeepMate搜索按钮
const searchDM = () => { currentPageDM.value = 1; DMTableData();};
// DeepMate重置按钮
const resetBnDM = () => { searchFormDM.dccode = ''; searchFormDM.dcname = ''; searchFormDM.market = ''; searchFormDM.user_role = ''; sortOrderDM.value = null; currentPageDM.value = 1; pageSizeDM.value = 10; DMTableData();};
// DeepMate开通权限按钮
const enableAccessDM = () => { dialogVisibleDM.value = true; addOrUpdataDM.value = 1;};
// DeepMate导出Excel列表按钮
const exportExcelDM = async () => { const requestParams = { token: token, dccode: searchFormDM.dccode, dcname: searchFormDM.dcname, market: searchFormDM.market, user_role: searchFormDM.user_role, sort_order: sortOrderDM.value }; const data = await exportDeepMateApi(requestParams); if (data != '') { ElMessage.success('已导出'); } };
// DeepMate查看导出列表按钮
const exportListDM = () => { router.push({ path: "/userPermissions/export" });};
// 编辑按钮
const handleEditDM = (row) => { dialogVisibleDM.value = true; hlidsInput.value = row.dccode; deadtoken.value = row.token_num;};
// 操作日志按钮
const handleLogDM = (dccode) => { router.push({ path: "/userPermissions/logDeepMate", query: { dccode: dccode } });};
// DeepMate弹框显隐控制
const dialogVisibleDM = ref(false);
// DeepMate开通权限表单
const hlidsInput = ref(''); const dmText = ref('Deep Mate');const token_num = ref('');
// DeepMate编辑回显内容
const deadtoken = ref('');
// DeepMate判断开通还是编辑
const addOrUpdataDM = ref(0);
// 校验HLid
const checkHlids = () => { // 非空
if (!hlidsInput.value.trim()) { ElMessage.error('请输入HLid'); return false; } // 处理输入:去空、去重,转数组
const hlidList = hlidsInput.value.split('\n') .map(item => item.trim()) .filter(item => item) .filter((item, index, self) => self.indexOf(item) === index); // 去重
// 数量校验(最多1000个)
if (hlidList.length > 1000) { ElMessage.error('HLid数量不能超过1000个'); return false; } // 格式校验(8位数字)
const hlidReg = /^\d{8}$/; for (const hlid of hlidList) { if (!hlidReg.test(hlid)) { ElMessage.error(`有HLid格式错误:${hlid},请重新输入`); return false; } } return true;};
// 校验token数量
const checkTokenNum = () => { // 添加权限场景
if (addOrUpdataDM.value === 1) { if (token_num.value === null || token_num.value === '') { ElMessage.error('请输入token数量'); return false; } if (!Number.isInteger(token_num.value) || token_num.value <= 0) { ElMessage.error('token数量必须为正整数'); return false; } } // 修改场景
else if (addOrUpdataDM.value === 0) { if (token_num.value === null || token_num.value === '') { ElMessage.error('请输入token数量'); return false; } if (!Number.isInteger(token_num.value)) { ElMessage.error('token数量必须为整数'); return false; } if (token_num.value < 0 && Math.abs(token_num.value) > deadtoken.value) { ElMessage.error('扣除次数大于当前总次数,请重新输入次数'); return false; } } return true;};
// 提交表单
const submitFormDM = async () => { // 表单校验
if (!checkHlids() || !checkTokenNum()) { return; }
try { const requestParams = { token: token, // HLid
hlids: hlidsInput.value.split('\n') .map(item => item.trim()) .filter(item => item) .join('\n'), // token数量
token_num: token_num.value }; console.log('传给后端的参数:', requestParams);
// 调用后端接口
await exitDMApi(requestParams); ElMessage.success(addOrUpdataDM.value === 1 ? '用户次数设置成功' : '用户次数修改成功');
// 重置表单并关闭弹框
resetFormDM(); dialogVisibleDM.value = false; addOrUpdataDM.value = 0;
// 重新获取表格
DMTableData(); } catch (error) { ElMessage.error('添加权限失败,请重试'); }};
// DeepMate取消表单
const cancelDM = () => { resetFormDM(); dialogVisibleDM.value = false; addOrUpdataDM.value = 0;};
// DeepMate重置表单数据
const resetFormDM = () => { hlidsInput.value = ''; token_num.value = '';};</script>
<style scoped>/* 父容器 */.page-container { position: relative; min-height: 600px; }
/* 搜索区域 */.search-container { display: flex; height: 67px; flex-direction: column; justify-content: center; align-items: flex-start; gap: 10px; align-self: stretch; border-radius: 8px; background: #FEFAF9; box-shadow: 0 0 4px 0 rgba(0, 0, 0, 0.25); padding: 0 15px; margin-bottom: 20px; }
/* 搜索表单 */.search-form { display: flex; align-items: center; width: 100%; gap: 15px; flex-wrap: nowrap;}
/* 单个搜索项 */.search-item { display: flex; align-items: center; gap: 6px;}
/* 搜索标签文字 */.form-label { font-weight: 800 !important; font-size: 15px; text-align: left; color: #333; margin-top: 13px;}
/* 按钮组 */.button-group { display: flex; align-items: center; gap: 0px !important; margin-left: auto;}
/* 按钮样式 */.button-group .el-button { padding: 6px 10px !important; font-size: 14px !important; height: 36px !important;}
/* 表格样式 */.table-rounded { border-radius: 12px !important; overflow: hidden !important; border: 1px solid #e4e7ed !important;}
.table-header { text-align: center !important; font-weight: 800 !important; font-size: 15px !important; color: #333 !important; background-color: #f8f9fa !important;}
.el-table__cell { border-right: none !important; border-bottom: 1px solid #e4e7ed !important;}
.el-table__header th.el-table__cell { border-right: none !important; border-bottom: 1px solid #e4e7ed !important;}
.el-table__row:hover .el-table__cell { background-color: #fafafa !important;}
/* 分页组件样式 */.demo-pagination-block { display: flex; width: 100%; height: 44px; padding: 0 16px; align-items: center; gap: 16px; position: absolute; margin-top: 10px; border-radius: 0 0 3px 3px; border-top: 1px solid #EAEAEA; background: #FEFBFB; box-sizing: border-box;}
/* 添加/修改样式 */.form-item { margin-bottom: 24px; padding-left: 20px; padding-right: 20px; text-align: left;}
.form-label { display: block; margin-bottom: 8px; font-weight: 500;}
.radio-group { display: flex; flex-direction: column; gap: 12px; align-items: flex-start;}
.radio-item { display: flex; align-items: center;}
.radio-item span { margin-right: 8px;}
.tip { font-size: 12px; color: #909399; margin-top: 4px;}
.dialog-footer { display: flex; justify-content: flex-end; gap: 16px; margin-top: 20px;}
.inline-form-item { display: flex; align-items: flex-start; gap: 12px;}
.inline-form-item .form-label { display: inline-block; margin-bottom: 0; width: 60px; text-align: left; padding-right: 12px;}
.info-container { display: flex; align-items: center; gap: 40px; padding: 0 20px 18px; color: #333; font-size: 16px; }
.info-item { white-space: nowrap; }
/* Tab容器 */.tab-group { display: flex; gap: 12px; justify-content: flex-start; margin: 4px 0; padding-left: 2px; }
/* Tab按钮 */.tab-btn { width: 120px; padding: 6px 0; text-align: center; border: 1px solid #ff0000; border-radius: 4px; background-color: #ffffff; color: #ff0000; font-size: 14px; cursor: pointer; transition: all 0.2s; outline: none;}
/* Tab选中样式 */.tab-btn.active { background-color: #ff0000; color: #ffffff; }
/* hover效果优化 */.tab-btn:not(.active):hover { background-color: #fff5f5; }</style>
|