init: 管理会计OS初始代码

包含前后端完整代码:
- 前端:Vue3+Vite+ElementPlus
- 后端:FastAPI+SQLAlchemy
- 模块:驾驶舱/KPI/战略地图/预警/预算/成本/预测/改善行动
- 当前版本:v1.0.0
This commit is contained in:
Hermes CI Fix
2026-05-28 17:32:22 +08:00
commit 3dddd36866
142 changed files with 18533 additions and 0 deletions
+131
View File
@@ -0,0 +1,131 @@
<template>
<div>
<div style="display:flex;justify-content:space-between;margin-bottom:16px;">
<h3>用户管理</h3>
<el-button type="primary" @click="openForm(null)">新建用户</el-button>
</div>
<el-table :data="users" v-loading="loading" style="width:100%" 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" @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>({})
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() {
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('用户名和密码必填')
return
}
await userApi.create(form.value)
ElMessage.success('创建成功')
}
showForm.value = false
load()
} catch (e) {
ElMessage.error('操作失败')
}
}
async function handleDelete(row: any) {
try {
await ElMessageBox.confirm(`确定删除用户"${row.name}"?`, '确认')
await userApi.delete(row.id)
ElMessage.success('已删除')
load()
} catch (e) {}
}
onMounted(load)
</script>