完善前端项目结构和依赖配置
- 更新 package.json 中的依赖版本号,包括 element-plus、axios、pinia、vue-router 等 - 删除 HelloWorld 组件,替换为 router-view 以支持路由功能 - 添加 auth、category、customer、dashboard、medicine、role、stock、stockIn、stockOut、 supplier、user 等多个 API 接口文件 - 创建权限指令、主布局组件和全局样式 - 集成 Element Plus UI 框架并注册图标组件 - 实现应用状态管理和用户状态管理 Store - 配置 Vue Router 路由系统,支持动态菜单路由生成 - 移除旧的 CSS 样式文件,改用 SCSS 全局样式 ```
This commit is contained in:
72
frontend/src/views/user/UserList.vue
Normal file
72
frontend/src/views/user/UserList.vue
Normal file
@@ -0,0 +1,72 @@
|
||||
<script setup>
|
||||
import { ref, reactive, onMounted } from 'vue'
|
||||
import { getUserList, createUser, updateUser, deleteUser, assignRoles } from '@/api/user'
|
||||
import { getAllRoles } from '@/api/role'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import { Search, Refresh } from '@element-plus/icons-vue'
|
||||
|
||||
const query = reactive({ page: 1, size: 10, username: '' })
|
||||
const tableData = ref([])
|
||||
const total = ref(0)
|
||||
const dialogVisible = ref(false)
|
||||
const dialogTitle = ref('新增用户')
|
||||
const form = reactive({ id: null, username: '', password: '', realName: '', phone: '', email: '', status: 1 })
|
||||
const roleVisible = ref(false)
|
||||
const roleForm = reactive({ userId: null, roleIds: [] })
|
||||
const allRoles = ref([])
|
||||
|
||||
async function loadData() { try { const r = await getUserList(query); tableData.value = r.data?.records || []; total.value = r.data?.total || 0 } catch { /* */ } }
|
||||
function handleAdd() { dialogTitle.value = '新增用户'; Object.keys(form).forEach(k => form[k] = k === 'status' ? 1 : ''); form.id = null; dialogVisible.value = true }
|
||||
function handleEdit(row) { dialogTitle.value = '编辑用户'; Object.assign(form, row); form.password = ''; dialogVisible.value = true }
|
||||
async function handleDelete(row) { await ElMessageBox.confirm('确定删除?', '确认', { type: 'warning' }); await deleteUser(row.id); ElMessage.success('删除成功'); loadData() }
|
||||
async function handleSubmit() { const d = { ...form }; delete d.id; if (!d.password) delete d.password; if (form.id) { await updateUser(form.id, d); ElMessage.success('编辑成功') } else { await createUser(d); ElMessage.success('新增成功') }; dialogVisible.value = false; loadData() }
|
||||
async function handleRole(row) { roleForm.userId = row.id; roleForm.roleIds = row.roleIds || []; roleVisible.value = true }
|
||||
async function saveRoles() { await assignRoles(roleForm.userId, { roleIds: roleForm.roleIds }); ElMessage.success('角色分配成功'); roleVisible.value = false; loadData() }
|
||||
|
||||
onMounted(async () => { try { allRoles.value = (await getAllRoles()).data || [] } catch { /* */ }; loadData() })
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="page-container">
|
||||
<div class="search-bar">
|
||||
<el-input v-model="query.username" placeholder="用户名" clearable />
|
||||
<el-button type="primary" :icon="Search" @click="loadData">搜索</el-button>
|
||||
<el-button :icon="Refresh" @click="query.username='';loadData()">重置</el-button>
|
||||
</div>
|
||||
<div class="tool-bar">
|
||||
<el-button type="primary" v-permission="'user:add'" @click="handleAdd">+ 新增用户</el-button>
|
||||
</div>
|
||||
<el-table :data="tableData" border stripe>
|
||||
<el-table-column prop="username" label="用户名" width="120" />
|
||||
<el-table-column prop="realName" label="姓名" width="100" />
|
||||
<el-table-column prop="phone" label="手机号" width="130" />
|
||||
<el-table-column prop="email" label="邮箱" width="180" show-overflow-tooltip />
|
||||
<el-table-column prop="status" label="状态" width="80" align="center"><template #default="{row}"><el-tag :type="row.status===1?'success':'danger'" size="small">{{row.status===1?'启用':'停用'}}</el-tag></template></el-table-column>
|
||||
<el-table-column label="操作" width="220" fixed="right">
|
||||
<template #default="{row}"><div class="table-actions"><el-button size="small" v-permission="'user:edit'" @click="handleEdit(row)">编辑</el-button><el-button size="small" v-permission="'user:assign-role'" @click="handleRole(row)">角色</el-button><el-button size="small" type="danger" v-permission="'user:delete'" @click="handleDelete(row)">删除</el-button></div></template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div style="display:flex;justify-content:flex-end;margin-top:16px"><el-pagination v-model:current-page="query.page" v-model:page-size="query.size" :total="total" :page-sizes="[10,20,50]" layout="total,sizes,prev,pager,next" @current-change="loadData" @size-change="query.page=1;loadData()" /></div>
|
||||
|
||||
<!-- 用户弹窗 -->
|
||||
<el-dialog v-model="dialogVisible" :title="dialogTitle" width="500px">
|
||||
<el-form :model="form" label-width="80px">
|
||||
<el-form-item label="用户名" required><el-input v-model="form.username" /></el-form-item>
|
||||
<el-form-item label="密码" :required="!form.id"><el-input v-model="form.password" type="password" show-password :placeholder="form.id?'留空则不修改':''" /></el-form-item>
|
||||
<el-form-item label="姓名"><el-input v-model="form.realName" /></el-form-item>
|
||||
<el-form-item label="手机号"><el-input v-model="form.phone" /></el-form-item>
|
||||
<el-form-item label="邮箱"><el-input v-model="form.email" /></el-form-item>
|
||||
<el-form-item label="状态"><el-switch v-model="form.status" :active-value="1" :inactive-value="0" active-text="启用" inactive-text="停用" /></el-form-item>
|
||||
</el-form>
|
||||
<template #footer><el-button @click="dialogVisible=false">取消</el-button><el-button type="primary" @click="handleSubmit">确定</el-button></template>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 角色分配弹窗 -->
|
||||
<el-dialog v-model="roleVisible" title="分配角色" width="450px">
|
||||
<el-checkbox-group v-model="roleForm.roleIds">
|
||||
<el-checkbox v-for="r in allRoles" :key="r.id" :label="r.id" :value="r.id">{{ r.name }}</el-checkbox>
|
||||
</el-checkbox-group>
|
||||
<template #footer><el-button @click="roleVisible=false">取消</el-button><el-button type="primary" @click="saveRoles">保存</el-button></template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
Reference in New Issue
Block a user