为什么:这些改动在前几轮就已完成并在 :3005 验证过,但一直留在工作区没有入库。 下一步 3-4 的四个页面依赖其中的公共样式入口(src/styles/business/index.css)与 api/admin 的公共类型(PageResult 等),如果不先收口,新页面的提交就会夹带旧改动, 既说不清 diff 边界,也让 index.css 这类多轮共用的文件长期处于半提交状态。 本提交只做归档,不改行为: - 品牌与接口基址改成 FruitShorts / 短剧服务(.env.*、README、vite 代理) - 去掉前端 mock 数据目录(src/data、src/permissions、stores/auth),改为走真实接口 - 新增 api/admin 下的接口封装与 src/utils/uploader.ts(媒资分片直传) - 新增/改造:轮播图管理、类型管理、操作日志、App 用户管理、后台布局与公共样式
203 lines
4.8 KiB
JavaScript
203 lines
4.8 KiB
JavaScript
import { onMounted, reactive, ref } from 'vue'
|
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
|
import {
|
|
createAdminUserApi,
|
|
deleteAdminUserApi,
|
|
pageAdminUsersApi,
|
|
resetAdminUserPasswordApi,
|
|
updateAdminUserApi,
|
|
updateAdminUserStatusApi
|
|
} from '@/api/admin/user'
|
|
import { listRolesApi } from '@/api/admin/role'
|
|
|
|
export function useAdminUsers() {
|
|
const roles = ref([])
|
|
const users = ref([])
|
|
const total = ref(0)
|
|
const loading = ref(false)
|
|
|
|
const keyword = ref('')
|
|
const roleFilter = ref(undefined)
|
|
const currentPage = ref(1)
|
|
const pageSize = ref(10)
|
|
|
|
const dialogVisible = ref(false)
|
|
const saving = ref(false)
|
|
const editingId = ref(null)
|
|
const form = reactive({
|
|
username: '',
|
|
password: '',
|
|
name: '',
|
|
roleId: undefined,
|
|
ipWhitelist: '',
|
|
status: 1
|
|
})
|
|
|
|
async function loadRoles() {
|
|
const res = await listRolesApi()
|
|
roles.value = res.data || []
|
|
}
|
|
|
|
async function load() {
|
|
loading.value = true
|
|
try {
|
|
const res = await pageAdminUsersApi({
|
|
pageIndex: currentPage.value,
|
|
pageSize: pageSize.value,
|
|
username: keyword.value.trim() || undefined,
|
|
roleId: roleFilter.value
|
|
})
|
|
users.value = res.data?.list || []
|
|
total.value = res.data?.total || 0
|
|
} finally {
|
|
loading.value = false
|
|
}
|
|
}
|
|
|
|
function queryUsers() {
|
|
currentPage.value = 1
|
|
load()
|
|
}
|
|
|
|
function handleSizeChange() {
|
|
currentPage.value = 1
|
|
load()
|
|
}
|
|
|
|
function openCreate() {
|
|
editingId.value = null
|
|
Object.assign(form, {
|
|
username: '',
|
|
password: '',
|
|
name: '',
|
|
roleId: undefined,
|
|
ipWhitelist: '',
|
|
status: 1
|
|
})
|
|
dialogVisible.value = true
|
|
}
|
|
|
|
function openEdit(row) {
|
|
editingId.value = row.id
|
|
Object.assign(form, {
|
|
username: row.username,
|
|
password: '',
|
|
name: row.name,
|
|
roleId: row.roleId || undefined,
|
|
ipWhitelist: row.ipWhitelist === '不限' ? '' : row.ipWhitelist,
|
|
status: row.status
|
|
})
|
|
dialogVisible.value = true
|
|
}
|
|
|
|
async function saveUser() {
|
|
if (!form.name.trim()) return ElMessage.warning('请填写姓名')
|
|
if (!form.roleId) return ElMessage.warning('请选择权限角色')
|
|
if (!editingId.value) {
|
|
if (!form.username.trim()) return ElMessage.warning('请填写登录账号')
|
|
if (!form.password || form.password.length < 6) {
|
|
return ElMessage.warning('初始密码不能少于 6 位')
|
|
}
|
|
}
|
|
const payload = {
|
|
name: form.name.trim(),
|
|
roleId: form.roleId,
|
|
ipWhitelist: form.ipWhitelist.trim(),
|
|
status: form.status
|
|
}
|
|
saving.value = true
|
|
try {
|
|
if (editingId.value) {
|
|
await updateAdminUserApi(editingId.value, payload)
|
|
ElMessage.success('管理员已更新')
|
|
} else {
|
|
await createAdminUserApi({
|
|
...payload,
|
|
username: form.username.trim(),
|
|
password: form.password
|
|
})
|
|
ElMessage.success('管理员已添加')
|
|
currentPage.value = 1
|
|
}
|
|
dialogVisible.value = false
|
|
await load()
|
|
} finally {
|
|
saving.value = false
|
|
}
|
|
}
|
|
|
|
async function toggleStatus(row) {
|
|
const next = row.status === 1 ? 0 : 1
|
|
await updateAdminUserStatusApi(row.id, next)
|
|
ElMessage.success(next === 1 ? '账号已启用' : '账号已停用')
|
|
await load()
|
|
}
|
|
|
|
async function removeUser(row) {
|
|
try {
|
|
await ElMessageBox.confirm(`确定删除管理员「${row.name}」吗?`, '删除确认', {
|
|
confirmButtonText: '确认删除',
|
|
cancelButtonText: '取消',
|
|
type: 'warning',
|
|
confirmButtonClass: 'el-button--danger'
|
|
})
|
|
} catch {
|
|
return
|
|
}
|
|
await deleteAdminUserApi(row.id)
|
|
ElMessage.success('管理员已删除')
|
|
if (users.value.length === 1 && currentPage.value > 1) currentPage.value -= 1
|
|
await load()
|
|
}
|
|
|
|
async function resetPassword(row) {
|
|
let password = ''
|
|
try {
|
|
const { value } = await ElMessageBox.prompt(
|
|
`为「${row.username}」设置新密码(至少 6 位)`,
|
|
'重置密码',
|
|
{
|
|
confirmButtonText: '确认重置',
|
|
cancelButtonText: '取消',
|
|
inputPlaceholder: '请输入新密码',
|
|
inputValidator: (val) => (val && val.length >= 6 ? true : '密码不能少于 6 位')
|
|
}
|
|
)
|
|
password = value
|
|
} catch {
|
|
return
|
|
}
|
|
await resetAdminUserPasswordApi(row.id, password)
|
|
ElMessage.success('密码已重置')
|
|
}
|
|
|
|
onMounted(async () => {
|
|
await loadRoles()
|
|
await load()
|
|
})
|
|
|
|
return {
|
|
roles,
|
|
keyword,
|
|
roleFilter,
|
|
currentPage,
|
|
pageSize,
|
|
loading,
|
|
total,
|
|
dialogVisible,
|
|
saving,
|
|
editingId,
|
|
form,
|
|
users,
|
|
load,
|
|
queryUsers,
|
|
handleSizeChange,
|
|
openCreate,
|
|
openEdit,
|
|
saveUser,
|
|
toggleStatus,
|
|
removeUser,
|
|
resetPassword
|
|
}
|
|
}
|