|
|
|
@ -78,7 +78,7 @@ |
|
|
|
<el-table-column label="操作" width="180" align="center" header-align="center"> |
|
|
|
<template #default="scope"> |
|
|
|
<el-button type="text" @click="handleEdit(scope.row)">编辑</el-button> |
|
|
|
<el-button type="text" @click="handleLog(scope.row.id)">操作日志</el-button> |
|
|
|
<el-button type="text" @click="handleLog(scope.row.dccode)">操作日志</el-button> |
|
|
|
</template> |
|
|
|
</el-table-column> |
|
|
|
</el-table> |
|
|
|
@ -89,18 +89,102 @@ |
|
|
|
@size-change="handleSizeChange" |
|
|
|
@current-change="handleCurrentChange" |
|
|
|
:current-page="currentPage" |
|
|
|
:page-sizes="[10, 20, 50, 100]" |
|
|
|
:page-size="10" |
|
|
|
:page-sizes="[15, 20, 50, 100]" |
|
|
|
:page-size="pageSize" |
|
|
|
layout="total, sizes, prev, pager, next, jumper" |
|
|
|
:total= "datatotal" |
|
|
|
/> |
|
|
|
</div> |
|
|
|
|
|
|
|
<el-dialog v-model="dialogVisible" :title="addOrUpdata === 1 ? '添加权限' : '设置'" width="500px" :before-close="cancel"> |
|
|
|
<!-- 设置用户 --> |
|
|
|
<div class="form-item" v-if="addOrUpdata === 1"> |
|
|
|
<label class="form-label">设置用户</label> |
|
|
|
<el-input type="textarea" v-model="hlidsInput" rows=10 |
|
|
|
placeholder="请输入HLid... |
|
|
|
示例: |
|
|
|
HL30454647 |
|
|
|
HL30454648 |
|
|
|
HL30454649" |
|
|
|
/> |
|
|
|
<div class="tip">支持批量输入,每次最多1000个(手动/Excel粘贴均可)</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
<!-- 编辑回显 --> |
|
|
|
<div class="info-container" v-if="addOrUpdata === 0"> |
|
|
|
<span class="info-item">HLid:{{ hlidsInput }}</span> |
|
|
|
<span class="info-item">当前到期时间:{{ deadline.split(' ')[0] }}</span> |
|
|
|
</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="cancel">取消</el-button> |
|
|
|
<el-button type="primary" @click="submitForm" style="background-color: #ff0000; border-color: #ff0000;">提交</el-button> |
|
|
|
</div> |
|
|
|
</el-dialog> |
|
|
|
</div> |
|
|
|
</template> |
|
|
|
|
|
|
|
<script setup> |
|
|
|
import { ref, reactive, computed, onMounted } from 'vue'; |
|
|
|
import { marketListApi, userMListApi } from '../../api/userPermissions' |
|
|
|
import { ref, reactive, onMounted } from 'vue'; |
|
|
|
import { ElMessage } from 'element-plus'; |
|
|
|
import { marketListApi, userMListApi, exportCreateApi, exitMApi } from '../../api/userPermissions' |
|
|
|
import router from '../../router'; |
|
|
|
|
|
|
|
// token |
|
|
|
const token = localStorage.getItem('token') |
|
|
|
|
|
|
|
// 搜索表单 |
|
|
|
const searchForm = reactive({ |
|
|
|
@ -120,18 +204,181 @@ const tableLoading = ref(false); |
|
|
|
const datatotal = ref(0) |
|
|
|
|
|
|
|
// 分页参数 |
|
|
|
const currentPage = ref(1); // 对应分页当前页 |
|
|
|
const pageSize = ref(10); // 对应分页每页条数 |
|
|
|
const currentPage = ref(1); |
|
|
|
const pageSize = ref(15); |
|
|
|
|
|
|
|
// 地区下拉框相关 |
|
|
|
// 地区下拉框 |
|
|
|
const regionList = ref([]); |
|
|
|
const isRegionLoading = ref(false); |
|
|
|
|
|
|
|
// 弹框显隐控制 |
|
|
|
const dialogVisible = ref(false); |
|
|
|
|
|
|
|
// 开通权限表单 |
|
|
|
const hlidsInput = ref(''); |
|
|
|
const timeType = ref(''); |
|
|
|
const expireTime = ref(''); |
|
|
|
const delayValue = ref(''); |
|
|
|
const delayUnit = ref(''); |
|
|
|
const remark = ref(''); |
|
|
|
const operator = ref(''); |
|
|
|
|
|
|
|
// 判断开通还是编辑 |
|
|
|
const addOrUpdata = ref(0); |
|
|
|
|
|
|
|
// 编辑回显内容 |
|
|
|
const deadline = ref(''); |
|
|
|
|
|
|
|
// 禁用当前日期之前的日期(当天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}`; |
|
|
|
}; |
|
|
|
|
|
|
|
// 校验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; |
|
|
|
} |
|
|
|
// 格式校验(HL开头+8位数字) |
|
|
|
const hlidReg = /^DC\d{8}$/; |
|
|
|
for (const hlid of hlidList) { |
|
|
|
if (!hlidReg.test(hlid)) { |
|
|
|
ElMessage.error(`HLid格式错误:${hlid},请重新输入`); |
|
|
|
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; |
|
|
|
} |
|
|
|
} else { |
|
|
|
ElMessage.error('请设置权限时间'); |
|
|
|
return false; |
|
|
|
} |
|
|
|
return true; |
|
|
|
}; |
|
|
|
|
|
|
|
// 禁止为小数 |
|
|
|
const handleDelayInput = () => { |
|
|
|
if (delayValue.value !== null && delayValue.value !== undefined) { |
|
|
|
delayValue.value = Math.floor(delayValue.value); |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
// 校验备注 |
|
|
|
const checkRemark = () => { |
|
|
|
if (!remark.value.trim()) { |
|
|
|
ElMessage.error('请输入备注'); |
|
|
|
return false; |
|
|
|
} |
|
|
|
return true; |
|
|
|
}; |
|
|
|
|
|
|
|
// 提交表单 |
|
|
|
const submitForm = async () => { |
|
|
|
// 表单校验 |
|
|
|
if (!checkHlids() || !checkTime() || !checkRemark()) { |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
try { |
|
|
|
// 组装后端要求的参数格式 |
|
|
|
const requestParams = { |
|
|
|
token: token, |
|
|
|
// HLid |
|
|
|
hlids: hlidsInput.value.split('\n') |
|
|
|
.map(item => item.trim()) |
|
|
|
.filter(item => item) |
|
|
|
.join('\n'), |
|
|
|
// 备注 |
|
|
|
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); |
|
|
|
|
|
|
|
// 调用后端接口 |
|
|
|
const res = await exitMApi(requestParams); |
|
|
|
ElMessage.success('成功添加用户权限'); |
|
|
|
|
|
|
|
// 重置表单并关闭弹框 |
|
|
|
resetForm(); |
|
|
|
dialogVisible.value = false; |
|
|
|
addOrUpdata.value = 0; |
|
|
|
|
|
|
|
// 重新获取表格 |
|
|
|
fetchTableData(); |
|
|
|
} catch (error) { |
|
|
|
ElMessage.error('添加权限失败,请重试'); |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
// 取消表单 |
|
|
|
const cancel = () => { |
|
|
|
resetForm(); |
|
|
|
dialogVisible.value = false; |
|
|
|
addOrUpdata.value = 0; |
|
|
|
}; |
|
|
|
|
|
|
|
// 重置表单数据 |
|
|
|
const resetForm = () => { |
|
|
|
hlidsInput.value = ''; |
|
|
|
timeType.value = ''; |
|
|
|
expireTime.value = ''; |
|
|
|
delayValue.value = ''; |
|
|
|
delayUnit.value = ''; |
|
|
|
remark.value = ''; |
|
|
|
operator.value = ''; |
|
|
|
}; |
|
|
|
|
|
|
|
// 获取地区列表 |
|
|
|
const fetchRegionList = async () => { |
|
|
|
try { |
|
|
|
isRegionLoading.value = true; |
|
|
|
const data = await marketListApi(); |
|
|
|
const data = await marketListApi({token: token}); |
|
|
|
regionList.value = data.list; |
|
|
|
} catch (error) { |
|
|
|
console.error('获取地区列表失败:', error); |
|
|
|
@ -146,6 +393,7 @@ const fetchTableData = async () => { |
|
|
|
try { |
|
|
|
tableLoading.value = true; |
|
|
|
const requestParams = { |
|
|
|
token: token, |
|
|
|
dccode: searchForm.dccode, |
|
|
|
dcname: searchForm.dcname, |
|
|
|
market: searchForm.market, |
|
|
|
@ -161,6 +409,7 @@ const fetchTableData = async () => { |
|
|
|
} catch (error) { |
|
|
|
console.error('获取表格数据失败:', error); |
|
|
|
tableData.value = []; |
|
|
|
datatotal.value = 0 |
|
|
|
} finally { |
|
|
|
tableLoading.value = false; |
|
|
|
} |
|
|
|
@ -180,17 +429,32 @@ const search = () => { |
|
|
|
|
|
|
|
// 开通权限按钮 |
|
|
|
const enableAccess = () => { |
|
|
|
console.log('开通权限操作'); |
|
|
|
dialogVisible.value = true; |
|
|
|
addOrUpdata.value = 1; |
|
|
|
}; |
|
|
|
|
|
|
|
// 导出Excel列表按钮 |
|
|
|
const exportExcel = () => { |
|
|
|
console.log('导出Excel列表'); |
|
|
|
const exportExcel = async () => { |
|
|
|
const requestParams = { |
|
|
|
token: token, |
|
|
|
dccode: searchForm.dccode, |
|
|
|
dcname: searchForm.dcname, |
|
|
|
market: searchForm.market, |
|
|
|
register_type: searchForm.register_type, |
|
|
|
sort_field: sortProp.value, |
|
|
|
sort_order: sortOrder.value |
|
|
|
}; |
|
|
|
const data = await exportCreateApi(requestParams); |
|
|
|
if (data != '') { |
|
|
|
ElMessage.success('已导出'); |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
// 查看导出列表按钮 |
|
|
|
const exportList = () => { |
|
|
|
console.log('查看导出列表'); |
|
|
|
router.push({ |
|
|
|
path: "/userPermissions/export" |
|
|
|
}); |
|
|
|
}; |
|
|
|
|
|
|
|
// 重置按钮 |
|
|
|
@ -208,12 +472,17 @@ const resetBn = () => { |
|
|
|
|
|
|
|
// 编辑 |
|
|
|
const handleEdit = (row) => { |
|
|
|
console.log('编辑用户:', row); |
|
|
|
dialogVisible.value = true; |
|
|
|
hlidsInput.value = row.dccode; |
|
|
|
deadline.value = row.expire_time; |
|
|
|
}; |
|
|
|
|
|
|
|
// 操作日志 |
|
|
|
const handleLog = (id) => { |
|
|
|
console.log('操作日志:', id); |
|
|
|
const handleLog = (dccode) => { |
|
|
|
router.push({ |
|
|
|
path: "/userPermissions/logMarket", |
|
|
|
query: { dccode: dccode } |
|
|
|
}); |
|
|
|
}; |
|
|
|
|
|
|
|
// 分页方法 |
|
|
|
@ -233,7 +502,7 @@ const handleCurrentChange = (val) => { |
|
|
|
const handleSortChange = (sort) => { |
|
|
|
const { prop, order } = sort; |
|
|
|
|
|
|
|
// 仅允许created_at(注册时间)和expire_time(到期时间)排序 |
|
|
|
// 仅允许注册时间和到期时间排序 |
|
|
|
if (!['created_at', 'expire_time'].includes(prop)) return; |
|
|
|
|
|
|
|
// 覆盖排序状态(实现二选一) |
|
|
|
@ -290,6 +559,7 @@ const handleSortChange = (sort) => { |
|
|
|
font-size: 15px; |
|
|
|
text-align: left; |
|
|
|
color: #333; |
|
|
|
margin-top: 13px; |
|
|
|
} |
|
|
|
|
|
|
|
/* 按钮组 */ |
|
|
|
@ -351,4 +621,74 @@ const handleSortChange = (sort) => { |
|
|
|
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; |
|
|
|
} |
|
|
|
</style> |