3 changed files with 491 additions and 7 deletions
@ -0,0 +1,459 @@ |
|||||
|
<template> |
||||
|
<div class="page-container"> |
||||
|
<!-- 搜索区域 --> |
||||
|
<div class="search-container"> |
||||
|
<div class="search-form"> |
||||
|
<div class="search-row"> |
||||
|
<div class="search-item"> |
||||
|
<span class="form-label">账号</span> |
||||
|
<el-input |
||||
|
v-model="searchForm.dccode" |
||||
|
placeholder="请输入ID" |
||||
|
clearable |
||||
|
style="width: 140px;" |
||||
|
/> |
||||
|
</div> |
||||
|
<div class="search-item"> |
||||
|
<span class="form-label">姓名</span> |
||||
|
<el-input |
||||
|
v-model="searchForm.name" |
||||
|
placeholder="请输入姓名" |
||||
|
clearable |
||||
|
style="width: 140px;" |
||||
|
/> |
||||
|
</div> |
||||
|
<div class="search-item"> |
||||
|
<span class="form-label">来源</span> |
||||
|
<el-select |
||||
|
v-model="searchForm.origin_id" |
||||
|
placeholder="请选择来源" |
||||
|
clearable |
||||
|
filterable |
||||
|
style="width: 160px;" |
||||
|
:loading="isOriginLoading" |
||||
|
> |
||||
|
<el-option |
||||
|
v-for="origin in originList" |
||||
|
:key="origin.origin_id" |
||||
|
:label="origin.origin_name" |
||||
|
:value="origin.origin_id" |
||||
|
/> |
||||
|
</el-select> |
||||
|
</div> |
||||
|
<div class="search-item"> |
||||
|
<span class="form-label">地区</span> |
||||
|
<el-select |
||||
|
v-model="searchForm.country" |
||||
|
placeholder="请选择地区" |
||||
|
clearable |
||||
|
filterable |
||||
|
style="width: 140px;" |
||||
|
:loading="isRegionLoading" |
||||
|
> |
||||
|
<el-option |
||||
|
v-for="region in regionList" |
||||
|
:key="region.ID" |
||||
|
:label="region.Name" |
||||
|
:value="region.Name" |
||||
|
/> |
||||
|
</el-select> |
||||
|
</div> |
||||
|
<div class="search-item"> |
||||
|
<span class="form-label">登录</span> |
||||
|
<el-select |
||||
|
v-model="searchForm.is_login" |
||||
|
placeholder="请选择是否登录" |
||||
|
clearable |
||||
|
style="width: 140px;" |
||||
|
> |
||||
|
<el-option label="已登录" :value="1" /> |
||||
|
<el-option label="未登录" :value="0" /> |
||||
|
</el-select> |
||||
|
</div> |
||||
|
<div class="search-item"> |
||||
|
<span class="form-label">注册方式</span> |
||||
|
<el-input |
||||
|
v-model="searchForm.register_type" |
||||
|
placeholder="请输入手机号/邮箱" |
||||
|
clearable |
||||
|
style="width: 180px;" |
||||
|
/> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="search-row"> |
||||
|
<div class="search-item"> |
||||
|
<span class="form-label">注册时间</span> |
||||
|
<el-date-picker |
||||
|
v-model="searchForm.regTimeRange" |
||||
|
type="datetimerange" |
||||
|
range-separator="至" |
||||
|
start-placeholder="开始时间" |
||||
|
end-placeholder="结束时间" |
||||
|
value-format="YYYY-MM-DD HH:mm:ss" |
||||
|
style="width: 320px;" |
||||
|
/> |
||||
|
</div> |
||||
|
<div class="search-item"> |
||||
|
<span class="form-label">登录时间</span> |
||||
|
<el-date-picker |
||||
|
v-model="searchForm.loginTimeRange" |
||||
|
type="datetimerange" |
||||
|
range-separator="至" |
||||
|
start-placeholder="开始时间" |
||||
|
end-placeholder="结束时间" |
||||
|
value-format="YYYY-MM-DD HH:mm:ss" |
||||
|
style="width: 320px;" |
||||
|
/> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="button-group"> |
||||
|
<el-button type="primary" @click="handleSearch">搜索</el-button> |
||||
|
<el-button type="success" @click="handleExport">导出Excel列表</el-button> |
||||
|
<el-button color="#626aef" @click="handleViewExport">查看导出列表</el-button> |
||||
|
<el-button @click="handleReset">重置</el-button> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<!-- 数据表格 --> |
||||
|
<el-table |
||||
|
:data="tableData" |
||||
|
style="width: 100%; margin-top: 20px;" |
||||
|
header-cell-class-name="table-header" |
||||
|
class="table-rounded" |
||||
|
:loading="tableLoading" |
||||
|
:header-cell-style="{background:'#f5f7fa', color:'#606266', fontWeight:'600'}" |
||||
|
> |
||||
|
<el-table-column prop="id" label="序号" align="center" header-align="center" width="60"> |
||||
|
<template #default="scope"> |
||||
|
{{ (currentPage - 1) * pageSize + scope.$index + 1 }} |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
<el-table-column prop="dccode" label="ID" align="center" header-align="center" width="100"/> |
||||
|
<el-table-column prop="name" label="姓名" align="center" header-align="center" width="120"> |
||||
|
<template #default="scope"> |
||||
|
<span>{{ scope.row.name || '-' }}</span> |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
<el-table-column prop="country" label="地区" align="center" header-align="center" width="120"/> |
||||
|
<el-table-column prop="origin" label="来源" align="center" header-align="center" width="160"> |
||||
|
<template #default="scope"> |
||||
|
<span class="ellipsis-text" :title="scope.row.origin">{{ scope.row.origin }}</span> |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
<el-table-column prop="phone" label="手机号" align="center" header-align="center" width="120"> |
||||
|
<template #default="scope"> |
||||
|
<span>{{ scope.row.phone || '-' }}</span> |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
<el-table-column prop="emails" label="邮箱" align="center" header-align="center" width="200"> |
||||
|
<template #default="scope"> |
||||
|
<span class="ellipsis-text" :title="scope.row.emails">{{ scope.row.emails || '-' }}</span> |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
<el-table-column prop="inviter" label="邀请人" align="center" header-align="center" width="100"> |
||||
|
<template #default="scope"> |
||||
|
<span>{{ scope.row.inviter || '-' }}</span> |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
<el-table-column prop="is_login" label="是否登录" align="center" header-align="center" width="90"> |
||||
|
<template #default="scope"> |
||||
|
<el-tag v-if="scope.row.is_login == 1" type="success" size="small" effect="light" class="login-tag">登录过</el-tag> |
||||
|
<el-tag v-else type="info" size="small" effect="light">未登录</el-tag> |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
<el-table-column prop="reg_time" label="注册时间" align="center" header-align="center" width="160"> |
||||
|
<template #default="scope"> |
||||
|
{{ scope.row.reg_time }} |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
<el-table-column prop="last_login_time" label="登录时间" align="center" header-align="center" width="160"> |
||||
|
<template #default="scope"> |
||||
|
{{ scope.row.last_login_time }} |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
</el-table> |
||||
|
|
||||
|
<!-- 分页组件 --> |
||||
|
<div class="demo-pagination-block"> |
||||
|
<el-pagination |
||||
|
@size-change="handleSizeChange" |
||||
|
@current-change="handleCurrentChange" |
||||
|
:current-page="currentPage" |
||||
|
:page-sizes="[10, 20, 50, 100]" |
||||
|
:page-size="pageSize" |
||||
|
layout="total, sizes, prev, pager, next, jumper" |
||||
|
:total="total" |
||||
|
/> |
||||
|
</div> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script setup> |
||||
|
import { ref, reactive, onMounted } from 'vue'; |
||||
|
import { ElMessage } from 'element-plus'; |
||||
|
import router from '../../router'; |
||||
|
import { |
||||
|
marketListApi, |
||||
|
getOriginListApi, |
||||
|
userListApi, |
||||
|
exportUserListApi |
||||
|
} from '../../api/userPermissions'; |
||||
|
|
||||
|
// token |
||||
|
const token = localStorage.getItem('token') |
||||
|
|
||||
|
// 搜索表单 |
||||
|
const searchForm = reactive({ |
||||
|
dccode: '', |
||||
|
name: '', |
||||
|
origin_id: '', |
||||
|
country: '', |
||||
|
is_login: '', |
||||
|
register_type: '', |
||||
|
regTimeRange: [], |
||||
|
loginTimeRange: [] |
||||
|
}); |
||||
|
|
||||
|
// 地区列表 |
||||
|
const regionList = ref([]); |
||||
|
const isRegionLoading = ref(false); |
||||
|
|
||||
|
// 来源列表 |
||||
|
const originList = ref([]); |
||||
|
const isOriginLoading = ref(false); |
||||
|
|
||||
|
// 表格数据 |
||||
|
const tableData = ref([]); |
||||
|
const tableLoading = ref(false); |
||||
|
const total = ref(0); |
||||
|
|
||||
|
// 分页参数 |
||||
|
const currentPage = ref(1); |
||||
|
const pageSize = ref(10); |
||||
|
|
||||
|
// 获取地区列表 |
||||
|
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; |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
// 获取来源列表 |
||||
|
const fetchOriginList = async () => { |
||||
|
try { |
||||
|
isOriginLoading.value = true; |
||||
|
const data = await getOriginListApi({ token: token }); |
||||
|
originList.value = data.list || []; |
||||
|
} catch (error) { |
||||
|
console.error('获取来源列表失败:', error); |
||||
|
originList.value = []; |
||||
|
} finally { |
||||
|
isOriginLoading.value = false; |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
// 获取表格数据 |
||||
|
const fetchTableData = async () => { |
||||
|
try { |
||||
|
tableLoading.value = true; |
||||
|
const requestParams = { |
||||
|
token: token, |
||||
|
page: currentPage.value, |
||||
|
page_size: pageSize.value, |
||||
|
dccode: searchForm.dccode, |
||||
|
name: searchForm.name, |
||||
|
origin_id: searchForm.origin_id, |
||||
|
country: searchForm.country, |
||||
|
is_login: searchForm.is_login, |
||||
|
phone: searchForm.register_type, |
||||
|
is_phone: searchForm.register_type ? 1 : 0, |
||||
|
email: searchForm.register_type, |
||||
|
reg_time_start: searchForm.regTimeRange && searchForm.regTimeRange[0] ? searchForm.regTimeRange[0] : '', |
||||
|
reg_time_end: searchForm.regTimeRange && searchForm.regTimeRange[1] ? searchForm.regTimeRange[1] : '', |
||||
|
list_login_time_start: searchForm.loginTimeRange && searchForm.loginTimeRange[0] ? searchForm.loginTimeRange[0] : '', |
||||
|
list_login_time_end: searchForm.loginTimeRange && searchForm.loginTimeRange[1] ? searchForm.loginTimeRange[1] : '', |
||||
|
reg_time_asc: '', |
||||
|
list_login_time_asc: '' |
||||
|
}; |
||||
|
|
||||
|
const data = await userListApi(requestParams); |
||||
|
tableData.value = data.list || []; |
||||
|
total.value = data.total || 0; |
||||
|
} catch (error) { |
||||
|
console.error('获取表格数据失败:', error); |
||||
|
tableData.value = []; |
||||
|
total.value = 0; |
||||
|
} finally { |
||||
|
tableLoading.value = false; |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
// 搜索 |
||||
|
const handleSearch = () => { |
||||
|
currentPage.value = 1; |
||||
|
fetchTableData(); |
||||
|
}; |
||||
|
|
||||
|
// 导出Excel |
||||
|
const handleExport = async () => { |
||||
|
try { |
||||
|
const requestParams = { |
||||
|
token: token, |
||||
|
dccode: searchForm.dccode, |
||||
|
name: searchForm.name, |
||||
|
origin_id: searchForm.origin_id, |
||||
|
country: searchForm.country, |
||||
|
is_login: searchForm.is_login, |
||||
|
phone: searchForm.register_type, |
||||
|
is_phone: searchForm.register_type ? 1 : 0, |
||||
|
email: searchForm.register_type, |
||||
|
reg_time_start: searchForm.regTimeRange && searchForm.regTimeRange[0] ? searchForm.regTimeRange[0] : '', |
||||
|
reg_time_end: searchForm.regTimeRange && searchForm.regTimeRange[1] ? searchForm.regTimeRange[1] : '', |
||||
|
list_login_time_start: searchForm.loginTimeRange && searchForm.loginTimeRange[0] ? searchForm.loginTimeRange[0] : '', |
||||
|
list_login_time_end: searchForm.loginTimeRange && searchForm.loginTimeRange[1] ? searchForm.loginTimeRange[1] : '' |
||||
|
}; |
||||
|
|
||||
|
await exportUserListApi(requestParams); |
||||
|
ElMessage.success('导出任务已创建,请查看导出列表'); |
||||
|
} catch (error) { |
||||
|
console.error('导出失败:', error); |
||||
|
ElMessage.error('导出失败,请重试'); |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
// 查看导出列表 |
||||
|
const handleViewExport = () => { |
||||
|
router.push({ |
||||
|
path: "/userPermissions/export" |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
// 重置 |
||||
|
const handleReset = () => { |
||||
|
searchForm.dccode = ''; |
||||
|
searchForm.name = ''; |
||||
|
searchForm.origin_id = ''; |
||||
|
searchForm.country = ''; |
||||
|
searchForm.is_login = ''; |
||||
|
searchForm.register_type = ''; |
||||
|
searchForm.regTimeRange = []; |
||||
|
searchForm.loginTimeRange = []; |
||||
|
currentPage.value = 1; |
||||
|
pageSize.value = 10; |
||||
|
fetchTableData(); |
||||
|
}; |
||||
|
|
||||
|
// 分页方法 |
||||
|
const handleSizeChange = (val) => { |
||||
|
pageSize.value = val; |
||||
|
currentPage.value = 1; |
||||
|
fetchTableData(); |
||||
|
}; |
||||
|
|
||||
|
const handleCurrentChange = (val) => { |
||||
|
currentPage.value = val; |
||||
|
fetchTableData(); |
||||
|
}; |
||||
|
|
||||
|
// 组件挂载时 |
||||
|
onMounted(() => { |
||||
|
fetchRegionList(); |
||||
|
fetchOriginList(); |
||||
|
fetchTableData(); |
||||
|
}); |
||||
|
</script> |
||||
|
|
||||
|
<style scoped> |
||||
|
/* 页面容器 */ |
||||
|
.page-container { |
||||
|
padding: 20px; |
||||
|
background: #fff; |
||||
|
min-height: calc(100vh - 40px); |
||||
|
} |
||||
|
|
||||
|
/* 搜索区域 */ |
||||
|
.search-container { |
||||
|
background: #fefaf9; |
||||
|
border-radius: 8px; |
||||
|
padding: 20px; |
||||
|
box-shadow: 0 0 4px 0 rgba(0, 0, 0, 0.1); |
||||
|
} |
||||
|
|
||||
|
.search-form { |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
gap: 15px; |
||||
|
} |
||||
|
|
||||
|
.search-row { |
||||
|
display: flex; |
||||
|
flex-wrap: wrap; |
||||
|
gap: 15px; |
||||
|
align-items: center; |
||||
|
} |
||||
|
|
||||
|
.search-item { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
gap: 8px; |
||||
|
} |
||||
|
|
||||
|
.form-label { |
||||
|
font-size: 14px; |
||||
|
color: #333; |
||||
|
white-space: nowrap; |
||||
|
font-weight: 500; |
||||
|
} |
||||
|
|
||||
|
.button-group { |
||||
|
display: flex; |
||||
|
gap: 10px; |
||||
|
margin-top: 10px; |
||||
|
} |
||||
|
|
||||
|
/* 表格样式 */ |
||||
|
.table-rounded { |
||||
|
border-radius: 8px; |
||||
|
overflow: hidden; |
||||
|
border: 1px solid #e4e7ed; |
||||
|
} |
||||
|
|
||||
|
.table-header { |
||||
|
background-color: #f5f7fa !important; |
||||
|
color: #606266; |
||||
|
font-weight: 600; |
||||
|
} |
||||
|
|
||||
|
.ellipsis-text { |
||||
|
display: inline-block; |
||||
|
max-width: 100%; |
||||
|
overflow: hidden; |
||||
|
text-overflow: ellipsis; |
||||
|
white-space: nowrap; |
||||
|
} |
||||
|
|
||||
|
.login-tag { |
||||
|
background-color: #f0f9eb; |
||||
|
border-color: #e1f3d8; |
||||
|
color: #67c23a; |
||||
|
} |
||||
|
|
||||
|
/* 分页 */ |
||||
|
.demo-pagination-block { |
||||
|
display: flex; |
||||
|
justify-content: center; |
||||
|
margin-top: 20px; |
||||
|
padding: 10px 0; |
||||
|
} |
||||
|
</style> |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue