Files
cma-management/frontend/src/views/UserManage.vue
T
wecom-fullstack f51fc72ac7
ci/woodpecker/push/main Pipeline failed
style(page-title): B 全站规范——页面内同名标题清零 + 增量副标题弱化 + 标题 emoji 换 Lucide
- 39+ 页删除与布局标题同名/基本同名的页面内 h1-h4(同屏三标题→两处)
- 增量副标题弱化为 14px #64748B 小字:收付款计划/战略回顾/地图版本/会计科目打标
- 标题 emoji 清零,保留标题处改 Lucide 内联 SVG(bar-chart-3/video/scale/clipboard-list/alert-circle/map/history)
- KPIListView 增加 hideTitle(仅展示),客户/学习看板隐藏组件内重复页头
- 不动 MainLayout、不改接口/业务逻辑、不碰 MapCanvas.vue
2026-10-18 19:33:11 +08:00

143 lines
4.8 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
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>
<div class="user-page">
<div class="page-top">
<el-button type="primary" @click="openForm(null)">新建用户</el-button>
</div>
<el-table :data="users" v-loading="loading" class="full-width-table" border stripe>
<el-table-column prop="id" label="ID" width="60" />
<el-table-column prop="username" label="用户名" width="120" />
<el-table-column prop="name" label="姓名" width="120" />
<el-table-column prop="role" label="角色" width="120">
<template #default="{ row }">
<el-tag :type="roleType(row.role)" size="small">{{ roleLabel(row.role) }}</el-tag>
</template>
</el-table-column>
<el-table-column prop="phone" label="手机号" width="140" />
<el-table-column prop="created_at" label="创建时间" width="180" />
<el-table-column label="操作" width="160" fixed="right">
<template #default="{ row }">
<el-button size="small" @click="openForm(row)">编辑</el-button>
<el-button size="small" type="danger" @click="handleDelete(row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<MyDialog v-model="showForm" :title="isEdit ? '编辑用户' : '新建用户'" :width="480">
<el-form :model="form" label-width="80px">
<el-form-item label="用户名">
<el-input v-model="form.username" :disabled="isEdit" />
</el-form-item>
<el-form-item label="姓名">
<el-input v-model="form.name" />
</el-form-item>
<el-form-item :label="isEdit ? '新密码' : '密码'">
<el-input v-model="form.password" type="password" show-password
:placeholder="isEdit ? '留空则不修改' : '请输入密码'" />
</el-form-item>
<el-form-item label="角色">
<el-select v-model="form.role" style="width:100%">
<el-option label="CEO" value="ceo" />
<el-option label="财务" value="finance" />
<el-option label="业务" value="business" />
<el-option label="IT" value="it" />
</el-select>
</el-form-item>
<el-form-item label="手机号">
<el-input v-model="form.phone" />
</el-form-item>
</el-form>
<template #footer>
<el-button @click="showForm=false">取消</el-button>
<el-button type="primary" :loading="saving" @click="saveUser">保存</el-button>
</template>
</MyDialog>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { userApi } from '../api/index'
import MyDialog from '../components/MyDialog.vue'
const users = ref<any[]>([])
const loading = ref(false)
const showForm = ref(false)
const isEdit = ref(false)
const form = ref<any>({})
const saving = ref(false)
function roleLabel(role: string) {
const map: Record<string, string> = { ceo: 'CEO', finance: '财务', business: '业务', it: 'IT管理' }
return map[role] || role
}
function roleType(role: string) {
const map: Record<string, string> = { ceo: 'danger', finance: 'success', business: 'warning', it: 'info' }
return map[role] || ''
}
async function load() {
loading.value = true
try { const r: any = await userApi.list(); users.value = r.data || [] } catch (e) {}
loading.value = false
}
function openForm(row: any) {
if (row) {
isEdit.value = true
form.value = { ...row, password: '' }
} else {
isEdit.value = false
form.value = { username: '', name: '', password: '', role: 'business', phone: '' }
}
showForm.value = true
}
async function saveUser() {
if (saving.value) return
saving.value = true
try {
if (isEdit.value) {
const payload: any = {}
if (form.value.name) payload.name = form.value.name
if (form.value.password) payload.password = form.value.password
if (form.value.role) payload.role = form.value.role
if (form.value.phone !== undefined) payload.phone = form.value.phone
await userApi.update(form.value.id, payload)
ElMessage.success('已更新')
} else {
if (!form.value.username || !form.value.password) {
ElMessage.warning('用户名和密码必填')
saving.value = false
return
}
await userApi.create(form.value)
ElMessage.success('创建成功')
}
showForm.value = false
load()
} catch (e) {
ElMessage.error('操作失败')
} finally {
saving.value = false
}
}
async function handleDelete(row: any) {
try {
await ElMessageBox.confirm(`确定删除用户"${row.name}"?`, '确认')
await userApi.delete(row.id)
ElMessage.success('已删除')
load()
} catch (e) {}
}
onMounted(load)
</script>
<style scoped>
.user-page { }
.user-page .page-top { display: flex; justify-content: space-between; margin-bottom: 16px; }
.user-page .page-top h3 { margin: 0; }
</style>