|
|
<template> <div> <div class="page-container" v-show="taber == 'DeepMate'"> <!-- 搜索区域 --> <div class="search-container" @keyup.enter="searchDM"> <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-input v-model="searchFormDM.inviter" 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 filterable style="height: 36px; width: 160px;" :loading="isRegionLoading" > <el-option v-for="region in regionList" :key="region.ID" :label="region.Name" :value="region.ID" /> </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="80"> <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="inviter" 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 class="page-container" v-show="taber == 'DeepExplore'"> <!-- 搜索区域 --> <div class="search-containerDE" @keyup.enter="searchDE"> <!-- 输入项区域 --> <div class="search-formDE"> <div class="search-itemDE"> <span class="form-labelDE">账号</span> <el-input v-model="searchFormDE.dccode" placeholder="请输入账号" clearable style="height: 36px; width: 140px;" /> </div> <div class="search-itemDE"> <span class="form-labelDE">姓名</span> <el-input v-model="searchFormDE.dcname" placeholder="请输入姓名" clearable style="height: 36px; width: 180px;" /> </div> <div class="search-itemDE"> <span class="form-labelDE">归属</span> <el-input v-model="searchFormDE.inviter" placeholder="请输入归属账号" clearable style="height: 36px; width: 180px;" /> </div> <div class="search-itemDE"> <span class="form-labelDE">客户类型</span> <el-select v-model="searchFormDE.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-itemDE"> <span class="form-labelDE">地区</span> <el-select v-model="searchFormDE.market" placeholder="请选择地区" clearable filterable style="height: 36px; width: 160px;" :loading="isRegionLoading" > <el-option v-for="region in regionList" :key="region.ID" :label="region.Name" :value="region.ID" /> </el-select> </div> <div class="search-itemDE"> <span class="form-labelDE">指标名称</span> <el-select v-model="searchFormDE.indicator_id" placeholder="请选择指标名称" clearable style="height: 36px; width: 160px;" > <el-option v-for="item in indicatorOptions" :key="item.id" :label="item.name" :value="item.id" /> </el-select> </div> </div> <!-- 按钮组 --> <div class="button-groupDE"> <el-button type="primary" @click="searchDE">搜索</el-button> <el-button type="danger" @click="enableAccessDE">开通权限</el-button> <el-button type="success" @click="exportExcelDE">导出Excel列表</el-button> <el-button color="#626aef" @click="exportListDE">查看导出列表</el-button> <el-button type="primary" @click="resetBnDE">重置</el-button> </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="tableDataDE" style="width: 100%; margin-top: 20px;" header-cell-class-name="table-header" @sort-change="handleSortChangeDE" :default-sort="{ prop: null, order: null }" class="table-roundedDE" :loading="tableLoadingDE" > <el-table-column prop="id" label="序号" align="center" header-align="center" width="80"> <template #default="scope"> {{ (currentPageDE - 1) * pageSizeDE + 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="inviter" label="归属" align="center" header-align="center"/> <el-table-column prop="name" label="指标名称" align="center" header-align="center" width="200"> <template #default="scope"> <el-tooltip effect="dark" :content="scope.row.name" placement="top" > <span class="ellipsis-text">{{ scope.row.name }}</span> </el-tooltip> </template> </el-table-column> <el-table-column prop="created_at" label="开通时间" align="center" header-align="center" sortable="custom" width="200"/> <el-table-column prop="expire_time" label="到期时间" align="center" header-align="center" sortable="custom" width="200"/> <el-table-column label="操作" align="center" header-align="center" width="200"> <template #default="scope"> <el-button type="text" @click="handleEditDE(scope.row)">编辑</el-button> <el-button type="text" @click="handleDetailsDE(scope.row.dccode)">权限详情</el-button> <el-button type="text" @click="handleLogDE(scope.row.dccode)">操作日志</el-button> </template> </el-table-column> </el-table>
<!-- 分页组件 --> <div class="demo-pagination-block"> <el-pagination @size-change="handleSizeChangeDE" @current-change="handleCurrentChangeDE" :current-page="currentPageDE" :page-sizes="[10, 20, 50, 100]" :page-size="pageSizeDE" layout="total, sizes, prev, pager, next, jumper" :total= "datatotalDE" /> </div>
<!-- 开通/编辑 --> <el-dialog v-model="dialogVisibleDE" :title="addOrUpdataDE === 1 ? '添加权限' : '设置'" width="550px" :before-close="cancelDE"> <!-- 设置用户 --> <div class="form-item" v-if="addOrUpdataDE === 1"> <label class="form-label">设置用户</label> <el-input type="textarea" v-model="hlidsInputDE" rows=10 placeholder="请输入HLid...示例:900480049004800590048006" /> <div class="tip">支持批量输入,每次最多1000个(手动/Excel粘贴均可)</div> </div>
<!-- 编辑回显 --> <div class="info-container" v-if="addOrUpdataDE === 0"> <span class="info-item">Homily ID:{{ hlidsInputDE }}</span> <span class="info-item">当前到期时间:{{ deadline.split(' ')[0] }}</span> </div>
<!-- 设置指标 --> <div class="form-item"> <label class="form-label">选择模板</label> <el-checkbox-group v-model="indicator_id" class="indicator-checkbox-group"> <el-checkbox v-for="item in indicatorOptions" :key="item.id" :label="item.id" class="indicator-checkbox-item" > {{ item.name }} </el-checkbox> </el-checkbox-group> </div>
<!-- 设置权限时间 --> <div class="form-item"> <label class="form-label">设置权限时间</label> <el-radio-group v-model="timeType" class="radio-group"> <el-radio label="expire" class="radio-item"> <span>到期时间</span> <el-date-picker v-model="expireTime" type="date" placeholder="请选择到期日期" :disabled-date="disabledDate" style="width: 220px; margin-left: 8px;" /> </el-radio> <el-radio label="delay" class="radio-item"> <span>延期时间</span> <el-input v-model.number="delayValue" type="number" style="width: 60px; margin: 0 8px;" placeholder="1" @input="handleDelayInput" /> <el-select v-model="delayUnit" placeholder="请选择" style="width: 150px;"> <el-option label="年" value="year"></el-option> <el-option label="月" value="month"></el-option> <el-option label="周" value="week"></el-option> <el-option label="日" value="day"></el-option> </el-select> </el-radio> </el-radio-group> </div>
<!-- 备注--> <div class="form-item inline-form-item"> <label class="form-label">备注</label> <el-input type="textarea" v-model="remark" rows=3 placeholder="请输入备注..." maxlength="150" show-word-limit /> </div>
<!-- 操作人 --> <div class="form-item inline-form-item"> <label class="form-label">操作人</label> <el-input v-model="operator" placeholder="请填写操作人"/> </div>
<!-- 按钮区域 --> <div class="dialog-footer"> <el-button type="default" plain @click="cancelDE">取消</el-button> <el-button type="primary" @click="submitFormDE" style="background-color: #ff0000; border-color: #ff0000;">提交</el-button> </div> </el-dialog>
<!-- 权限详情 --> <el-dialog v-model="showPermissionDetail" title="权限详情" width="400px" :close-on-click-modal="false" :show-close="true" class="permission-detail-dialog" > <div class="detail-container"> <!-- HLid 信息 --> <div class="hlid-item"> <span class="label">Homily ID:</span> <span class="value">{{ HLid }}</span> </div>
<!-- 到期时间区域 --> <div class="expire-section"> <h3 class="section-title">到期时间</h3> <div class="indicator-list"> <div v-for="(item, index) in permissionData" :key="index" class="indicator-item" > <span class="indicator-name">{{ item.name }}:</span> <template v-if="item.is_expired === 1"> <span class="expired-tag">已到期</span> </template> <template v-else> <span class="expire-time">{{ item.expire_time.split(' ')[0] }}</span> </template> </div> </div> </div> </div> </el-dialog> </div> </div></template>
<script setup>import { ref, reactive, onMounted, computed } from 'vue';import { ElMessage } from 'element-plus';import { marketListApi, indicatorListApi, userDMListApi, exportDeepMateApi, exitDMApi, userDEListApi, exportDeepExploreApi, exitDEApi, detailDEApi } 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(); indicatorList(); DMTableData(); DETableData();});
// 地区下拉框
const regionList = ref([]);const isRegionLoading = ref(false);
// 获取地区列表
const fetchRegionList = async () => { try { isRegionLoading.value = true; const data = await marketListApi({ token: token, app_form: "en" }); regionList.value = data.list; } catch (error) { console.error('获取地区列表失败:', error); regionList.value = []; } finally { isRegionLoading.value = false; }};
// DeepMate搜索表单
const searchFormDM = reactive({ dccode: '', dcname: '', inviter:'', 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, inviter: searchFormDM.inviter, 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.inviter = ''; 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, inviter: searchFormDM.inviter, 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" });};
// DeepMate编辑按钮
const handleEditDM = (row) => { dialogVisibleDM.value = true; hlidsInput.value = row.dccode; deadtoken.value = row.token_num;};
// DeepMate操作日志按钮
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 NoshakeDM = ref(false)
// DeepMate提交表单
const submitFormDM = async () => { // 防抖
if (NoshakeDM.value) return; NoshakeDM.value = true;
// 表单校验
if (!checkHlids() || !checkTokenNum()) { NoshakeDM.value = false; 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('添加权限失败,请重试'); } finally { NoshakeDM.value = false; }};
// DeepMate取消表单
const cancelDM = () => { resetFormDM(); dialogVisibleDM.value = false; addOrUpdataDM.value = 0;};
// DeepMate重置表单数据
const resetFormDM = () => { hlidsInput.value = ''; token_num.value = '';};
// 深度探索指标选项
const indicatorOptions = ref([]);
const indicatorList = async () => { try { const data = await indicatorListApi({token: token}); indicatorOptions.value = data.list; } catch (error) { console.error('获取指标列表失败:', error); indicatorOptions.value = []; } }
// 深度探索搜索表单
const searchFormDE = reactive({ dccode: '', dcname: '', inviter: '', market: '', user_role: '', indicator_id: ''});
// 深度探索排序参数
const sortPropDE = ref(null);const sortOrderDE = ref(null);
// 深度探索分页参数
const currentPageDE = ref(1);const pageSizeDE = ref(10);
// 深度探索表格数据
const tableDataDE = ref([]);const tableLoadingDE = ref(false);const datatotalDE = ref(0)
// 深度探索分页方法
const handleSizeChangeDE = (val) => { pageSizeDE.value = val; DETableData(); console.log(`每页 ${val} 条`);};
const handleCurrentChangeDE = (val) => { currentPageDE.value = val; DETableData(); console.log(`当前页: ${val}`);};
// 深度探索排序事件
const handleSortChangeDE = (sort) => { const { prop, order } = sort; if (!['created_at', 'expire_time'].includes(prop)) return;
sortPropDE.value = prop; // 保存当前排序字段
sortOrderDE.value = order; // 保存当前排序方式
DETableData();};
// 深度探索获取表格数据
const DETableData = async () => { try { tableLoadingDE.value = true; const requestParams = { token: token, dccode: searchFormDE.dccode, dcname: searchFormDE.dcname, inviter: searchFormDE.inviter, market: searchFormDE.market, user_role: searchFormDE.user_role, indicator_id: searchFormDE.indicator_id, sort_field: sortPropDE.value, sort_order: sortOrderDE.value, page: currentPageDE.value, page_size: pageSizeDE.value }; const data = await userDEListApi(requestParams); tableDataDE.value = data.list datatotalDE.value = data.total } catch (error) { console.error('获取表格数据失败:', error); tableDataDE.value = []; datatotalDE.value = 0 } finally { tableLoadingDE.value = false; }};
// 深度探索搜索按钮
const searchDE = () => { currentPageDE.value = 1; DETableData();};
// 深度探索重置按钮
const resetBnDE = () => { searchFormDE.dccode = ''; searchFormDE.dcname = ''; searchFormDE.inviter = ''; searchFormDE.market = ''; searchFormDE.user_role = ''; searchFormDE.indicator_id = ''; sortPropDE.value = null; sortOrderDE.value = null; currentPageDE.value = 1; pageSizeDE.value = 10; DETableData();};
// 深度探索导出Excel列表按钮
const exportExcelDE = async () => { const requestParams = { token: token, dccode: searchFormDE.dccode, dcname: searchFormDE.dcname, inviter: searchFormDE.inviter, market: searchFormDE.market, user_role: searchFormDE.user_role, indicator_id: searchFormDE.indicator_id, sort_field: sortPropDE.value, sort_order: sortOrderDE.value }; const data = await exportDeepExploreApi(requestParams); if (data != '') { ElMessage.success('已导出'); } };
// 深度探索查看导出列表按钮
const exportListDE = () => { router.push({ path: "/userPermissions/export" });};
// 深度探索开通权限按钮
const enableAccessDE = () => { dialogVisibleDE.value = true; addOrUpdataDE.value = 1;};
// 深度探索编辑按钮
const handleEditDE = (row) => { dialogVisibleDE.value = true; hlidsInputDE.value = row.dccode; deadline.value = row.expire_time; indicator_id.value = row.indicator_id.split("、").filter(Boolean).map(Number);};
// 深度探索权限详情按钮
const handleDetailsDE = (dccode) =>{ openDetail(dccode)}
// 深度探索操作日志按钮
const handleLogDE = (dccode) => { router.push({ path: "/userPermissions/logDeepExplore", query: { dccode: dccode } });};
// 弹框显隐控制
const dialogVisibleDE = ref(false);
// 开通权限表单
const hlidsInputDE = ref(''); const indicator_id = ref([]);const timeType = ref(''); const expireTime = ref(''); const delayValue = ref(''); const delayUnit = ref('');const remark = ref(''); const operator = ref('');
// 判断开通还是编辑
const addOrUpdataDE = ref(0);
// 编辑回显内容
const deadline = ref('');
// 将数组转为顿号拼接的字符串
const indicatorStr = computed(() => { return indicator_id.value?.join('、') || '';});
// 禁用当前日期之前的日期(当天0点之前的时间)
const disabledDate = (time) => { return time.getTime() < new Date().getTime() - 8.64e7;};
// 格式化日期
const formatDate = (date) => { if (!date) return ''; const year = date.getFullYear(); const month = String(date.getMonth() + 1).padStart(2, '0'); const day = String(date.getDate()).padStart(2, '0'); return `${year}/${month}/${day}`;};
// 禁止为小数
const handleDelayInput = () => { if (delayValue.value !== null && delayValue.value !== undefined) { delayValue.value = Math.floor(delayValue.value); }};
// 校验HLid
const checkHlidsDE = () => { // 非空
if (!hlidsInputDE.value.trim()) { ElMessage.error('请输入HLid'); return false; } // 处理输入:去空、去重,转数组
const hlidList = hlidsInputDE.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;};
// 校验指标
const checkmodel = () => { if (indicator_id.value.length === 0) { ElMessage.error('请至少选择一个指标'); return false; } return true;};
// 校验时间
const checkTime = () => { if (timeType.value === 'expire') { // 到期时间
if (!expireTime.value) { ElMessage.error('请选择到期时间'); return false; } } else if (timeType.value === 'delay') { // 延期时间
if (!delayValue.value || !delayUnit.value) { ElMessage.error('延期时间必须填写完整(数值+单位)'); return false; } const delayNum = Number(delayValue.value); if (isNaN(delayNum) || delayNum < 0) { ElMessage.error('延期时间不能为负数,请输入有效正数'); return false; } if (delayNum === 0) { ElMessage.error('延期时间不能为0,请输入有效正数'); return false; } } else { ElMessage.error('请设置权限时间'); return false; } return true;};
// 校验备注
const checkRemark = () => { if (!remark.value.trim()) { ElMessage.error('请输入备注'); return false; } return true;};
// 防抖
const NoshakeDE = ref(false)
// 提交表单
const submitFormDE = async () => { // 防抖
if (NoshakeDE.value) return; NoshakeDE.value = true;
// 表单校验
if (!checkHlidsDE() || !checkmodel() || !checkTime() || !checkRemark()) { NoshakeDE.value = false; return; }
try { // 组装后端要求的参数格式
const requestParams = { token: token, // HLid
hlids: hlidsInputDE.value.split('\n') .map(item => item.trim()) .filter(item => item) .join('\n'), // 指标
indicator_id: indicatorStr.value, // 备注
remark: remark.value.trim(), // 操作人
...(operator.value.trim() && { operator: operator.value.trim() }), // 时间参数
...(timeType.value === 'expire' ? { expire_time: formatDate(expireTime.value) } : { [delayUnit.value]: Number(delayValue.value) }) }; console.log('传给后端的参数:', requestParams);
// 调用后端接口
await exitDEApi(requestParams); ElMessage.success(addOrUpdataDM.value === 1 ? '成功添加用户权限' : '成功修改用户权限');
// 重置表单并关闭弹框
resetForm(); dialogVisibleDE.value = false; addOrUpdataDE.value = 0;
// 重新获取表格
DETableData(); } catch (error) { ElMessage.error('添加权限失败,请重试'); } finally { NoshakeDE.value = false; }};
// 深度探索重置表单数据
const resetForm = () => { hlidsInputDE.value = ''; indicator_id.value = []; timeType.value = ''; expireTime.value = ''; delayValue.value = ''; delayUnit.value = ''; remark.value = ''; operator.value = '';};
// 深度探索取消表单
const cancelDE = () => { resetForm(); dialogVisibleDE.value = false; addOrUpdataDE.value = 0;};
// 深度探索权限详情弹窗开关
const showPermissionDetail = ref(false);
// 深度探索权限详情弹窗数据
const HLid = ref('');const permissionData = ref([]);
// 深度探索权限详情获取数据并开启弹窗
const openDetail = async(dccode) => { HLid.value = dccode
// 后端调用
const res = await detailDEApi({ token: token, dccode: dccode }) permissionData.value = res
// 显示弹窗
showPermissionDetail.value = true;};</script>
<style scoped>/* 父容器 */.page-container { position: relative; min-height: 600px; }
/* 搜索区域 */.search-container { display: flex; height: auto; flex-direction: column; justify-content: center; align-items: flex-start; gap: 12px; align-self: stretch; border-radius: 8px; background: #FEFAF9; box-shadow: 0 0 4px 0 rgba(0, 0, 0, 0.25); padding: 15px; margin-bottom: 20px; }
/* 搜索表单 */.search-form { display: flex; align-items: center; width: 100%; gap: 15px; flex-wrap: wrap; row-gap: 8px;}
/* 单个搜索项 */.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; font-family: "SimHei", "Heiti SC", "Microsoft YaHei", sans-serif !important;}
/* 按钮组 */.button-group { display: flex; align-items: center; gap: 10px !important;}
/* 按钮样式 */.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; height: 650px;}
.table-roundedDE { border-radius: 12px !important; overflow: hidden !important; border: 1px solid #e4e7ed !important; height: 650px;}
.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; }
/* 搜索区域(深度探索) */.search-containerDE { display: flex; height: auto; flex-direction: column; justify-content: center; align-items: flex-start; gap: 12px; align-self: stretch; border-radius: 8px; background: #FEFAF9; box-shadow: 0 0 4px 0 rgba(0, 0, 0, 0.25); padding: 15px; margin-bottom: 20px; }
/* 搜索表单(深度探索) */.search-formDE { display: flex; align-items: center; width: 100%; gap: 15px; flex-wrap: wrap; row-gap: 8px; }
/* 单个搜索项(深度探索) */.search-itemDE { display: flex; align-items: center; gap: 6px; }
/* 搜索标签文字(深度探索) */.form-labelDE { font-weight: 800 !important; font-size: 15px; text-align: left; color: #333; margin-top: 0; font-family: "SimHei", "Heiti SC", "Microsoft YaHei", sans-serif !important; }
/* 按钮组(深度探索) */.button-groupDE { display: flex; align-items: center; gap: 10px !important; }
/* 按钮样式(深度探索) */.button-groupDE .el-button { padding: 6px 10px !important; font-size: 14px !important; height: 36px !important;}
/* 文本溢出省略样式(深度探索) */.ellipsis-text { display: inline-block; width: 100%; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; vertical-align: middle;}
/* 开通/编辑指标复选(深度探索) */.indicator-checkbox-group { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 8px; width: 100% }
.indicator-checkbox-item { flex: 0 0 calc(20% - 5px); box-sizing: border-box; padding: 4px 0;}
:deep(.el-checkbox__input.is-checked .el-checkbox__inner) { background-color: #ff0000 !important; border-color: #ff0000 !important; }
:deep(.el-checkbox__input.is-checked .el-checkbox__inner::after) { border-color: #fff !important;}
:deep(.el-checkbox__input:hover .el-checkbox__inner) { border-color: #ff0000 !important;}
:deep(.el-checkbox__input:focus .el-checkbox__inner) { box-shadow: 0 0 0 2px rgba(255, 0, 0, 0.2) !important;}
:deep(.el-checkbox__label) { color: #333 !important; font-size: 14px !important;}
/* 权限详情(深度探索) */.permission-detail-dialog { --el-dialog-padding-primary: 15px;}
.detail-container { background-color: #fff1f0; border-radius: 6px; padding: 15px;}
.hlid-item { margin-bottom: 25px; }
.label { color: #666; font-weight: 500;}
.value { color: #333;}
.expire-section { margin-top: 10px;}
.section-title { font-size: 16px; color: #333; margin-bottom: 10px; font-weight: bold; }
.indicator-list { display: flex; flex-direction: column; gap: 8px;}
.indicator-item { padding: 6px 0; display: flex; align-items: center;}
.indicator-name { color: #666; font-size: 14px;}
.expire-time { color: #333; font-size: 14px; margin-left: 8px; }
.expired-tag { background-color: #ffccd5; color: #f56c6c; font-size: 12px; padding: 2px 8px; border-radius: 4px; margin-left: 8px;}</style>
|