Files
pengchen-exam-vue/src/views/system/tenant/index.vue

358 lines
10 KiB
Vue
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<!-- <doc-alert title="SaaS 多租户" url="https://doc.iocoder.cn/saas-tenant/" /> -->
<!-- 搜索 -->
<ContentWrap>
<el-form
class="-mb-15px"
:model="queryParams"
ref="queryFormRef"
:inline="true"
label-width="68px"
>
<el-form-item label="学校名称" prop="name">
<el-input
v-model="queryParams.name"
placeholder="请输入学校名称"
clearable
@keyup.enter="handleQuery"
class="!w-240px"
/>
</el-form-item>
<el-form-item label="联系人" prop="contactName">
<el-input
v-model="queryParams.contactName"
placeholder="请输入联系人"
clearable
@keyup.enter="handleQuery"
class="!w-240px"
/>
</el-form-item>
<el-form-item label="联系手机" prop="contactMobile">
<el-input
v-model="queryParams.contactMobile"
placeholder="请输入联系手机"
clearable
@keyup.enter="handleQuery"
class="!w-240px"
/>
</el-form-item>
<el-form-item label="租户状态" prop="status">
<el-select
v-model="queryParams.status"
placeholder="请选择租户状态"
clearable
class="!w-240px"
>
<el-option
v-for="dict in getIntDictOptions(DICT_TYPE.COMMON_STATUS)"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="创建时间" prop="createTime">
<el-date-picker
v-model="queryParams.createTime"
value-format="YYYY-MM-DD HH:mm:ss"
type="daterange"
start-placeholder="开始日期"
end-placeholder="结束日期"
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
class="!w-240px"
/>
</el-form-item>
<el-form-item>
<el-button @click="handleQuery">
<Icon icon="ep:search" class="mr-5px" />
搜索
</el-button>
<el-button @click="resetQuery">
<Icon icon="ep:refresh" class="mr-5px" />
重置
</el-button>
<el-button
type="primary"
plain
@click="openForm('create')"
v-hasPermi="['system:tenant:create']"
>
<Icon icon="ep:plus" class="mr-5px" />
新增
</el-button>
<el-button
type="success"
plain
@click="handleExport"
:loading="exportLoading"
v-hasPermi="['system:tenant:export']"
>
<Icon icon="ep:download" class="mr-5px" />
导出
</el-button>
</el-form-item>
</el-form>
</ContentWrap>
<!-- 列表 -->
<ContentWrap>
<el-table v-loading="loading" :data="list">
<el-table-column label="学校用户编号" align="center" prop="id" />
<el-table-column label="学校名称" align="center" prop="name" />
<el-table-column label="学校用户权限" align="center" prop="packageId">
<template #default="scope">
<el-tag v-if="scope.row.packageId === 0" type="danger">中心服务器</el-tag>
<template v-else v-for="item in packageList">
<el-tag type="success" :key="item.id" v-if="item.id === scope.row.packageId">
{{ item.name }}
</el-tag>
</template>
</template>
</el-table-column>
<el-table-column label="联系人" align="center" prop="contactName" />
<el-table-column label="联系手机" align="center" prop="contactMobile" />
<!-- <el-table-column label="账号额度" align="center" prop="accountCount">
<template #default="scope">
<el-tag>{{ scope.row.accountCount }}</el-tag>
</template>
</el-table-column> -->
<el-table-column
label="过期时间"
align="center"
prop="expireTime"
width="180"
:formatter="dateFormatter"
/>
<el-table-column label="绑定MAC地址" align="center" prop="website" width="180" />
<el-table-column label="管理员账号" align="center" prop="username" width="180" />
<el-table-column label="状态" align="center" prop="status">
<template #default="scope">
<dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status" />
</template>
</el-table-column>
<el-table-column
label="创建时间"
align="center"
prop="createTime"
width="180"
:formatter="dateFormatter"
/>
<!-- <el-table-column
label="连接状态(需点击状态刷新)"
align="center"
prop="websiteStatus"
width="180"
/> -->
<el-table-column label="操作" align="center" min-width="110" fixed="right">
<template #default="scope">
<el-button
link
type="primary"
@click="setPassword(scope.row.contactUserId)"
>
重置密码
</el-button>
<el-button
link
type="primary"
@click="openForm('update', scope.row.id)"
v-hasPermi="['system:tenant:update']"
>
编辑
</el-button>
<el-button
link
type="danger"
@click="handleDelete(scope.row.id)"
v-hasPermi="['system:tenant:delete']"
>
删除
</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
<Pagination
:total="total"
v-model:page="queryParams.pageNo"
v-model:limit="queryParams.pageSize"
@pagination="getList"
/>
</ContentWrap>
<!-- 表单弹窗添加/修改 -->
<TenantForm ref="formRef" @success="getList" />
</template>
<script lang="ts" setup>
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
import {dateFormatter} from '@/utils/formatTime'
import download from '@/utils/download'
import * as TenantApi from '@/api/system/tenant'
import * as TenantPackageApi from '@/api/system/tenantPackage'
import * as AuthorizeApi from '@/api/authorize'
import TenantForm from './TenantForm.vue'
defineOptions({ name: 'SystemTenant' })
const message = useMessage() // 消息弹窗
const { t } = useI18n() // 国际化
const loading = ref(true) // 列表的加载中
const total = ref(0) // 列表的总页数
const list = ref([]) // 列表的数据
const queryParams = reactive({
pageNo: 1,
pageSize: 10,
name: undefined,
contactName: undefined,
contactMobile: undefined,
status: undefined,
createTime: []
})
const queryFormRef = ref() // 搜索的表单
const exportLoading = ref(false) // 导出的加载中
const packageList = ref([] as TenantPackageApi.TenantPackageVO[]) //租户套餐列表
/** 查询列表 */
const getList = async () => {
loading.value = true
try {
const data = await TenantApi.getTenantPage(queryParams)
list.value = data.list
total.value = data.total
} finally {
loading.value = false
}
}
/** 搜索按钮操作 */
const handleQuery = () => {
queryParams.pageNo = 1
getList()
}
/** 重置按钮操作 */
const resetQuery = () => {
queryFormRef.value.resetFields()
handleQuery()
}
/** 添加/修改操作 */
const formRef = ref()
const openForm = (type: string, id?: number) => {
formRef.value.open(type, id)
}
/** 连接状态 */
const openStatus = (row: any) => {
AuthorizeApi.getTenantStatus(row.website).then(response => {
console.log(response)
if (response === "强") {
message.notifySuccess(response)
row.websiteStatus = response + " " + getTimeWithAmPm()
} else if (response === "弱") {
message.notifyWarning(response)
row.websiteStatus = response + " " + getTimeWithAmPm()
} else {
message.notifyError(response)
row.websiteStatus = response + " " + getTimeWithAmPm()
}
})
}
const setPassword = async (id) => {
if (!id) return
try {
// 1⃣ 弹出输入框,让管理员输入新密码
const { value: newPassword } = await ElMessageBox.prompt('请输入新的密码:', '重置密码', {
confirmButtonText: '下一步',
cancelButtonText: '取消',
inputType: 'password',
inputPlaceholder: '请输入新密码',
inputValidator: (val) => {
if (!val) return '密码不能为空'
if (val.length < 4) return '密码至少 4 位'
return true
},
})
// 2⃣ 再次确认是否要重置
await ElMessageBox.confirm(
`确认将该用户密码重置为:${newPassword}`,
'确认操作',
{
confirmButtonText: '确认',
cancelButtonText: '取消',
type: 'warning',
}
)
// 3⃣ 调用后端接口发请求
const data = {
id,
password: newPassword,
}
const res = await TenantApi.resetPassword(data)
// 4⃣ 显示成功提示
ElMessage.success(res?.msg || '密码重置成功!')
} catch (err) {
if (err === 'cancel' || err === 'close') {
// 用户取消操作
return
}
console.error('重置密码失败:', err)
ElMessage.error('操作失败,请重试')
}
}
/** 获取时分秒 */
const getTimeWithAmPm = (): string => {
const now = new Date()
let hours = now.getHours()
const minutes = now.getMinutes().toString().padStart(2, '0')
const seconds = now.getSeconds().toString().padStart(2, '0')
const ampm = hours >= 12 ? 'PM' : 'AM'
hours = hours % 12 || 12
return `${hours.toString().padStart(2, '0')}:${minutes}:${seconds} ${ampm}`
}
/** 删除按钮操作 */
const handleDelete = async (id: number) => {
try {
// 删除的二次确认
await message.delConfirm()
// 发起删除
await TenantApi.deleteTenant(id)
message.success(t('common.delSuccess'))
// 刷新列表
await getList()
} catch {}
}
/** 导出按钮操作 */
const handleExport = async () => {
try {
// 导出的二次确认
await message.exportConfirm()
// 发起导出
exportLoading.value = true
const data = await TenantApi.exportTenant(queryParams)
download.excel(data, '学校用户列表.xls')
} catch {
} finally {
exportLoading.value = false
}
}
/** 初始化 **/
onMounted(async () => {
await getList()
packageList.value = await TenantPackageApi.getTenantPackageList()
})
</script>