feat: 平台管理员创建企业客户功能 + deploy.sh 跳过 tsc
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
* 企业租户管理页 — 列表、搜索、查看详情、编辑套餐、删除
|
||||
*/
|
||||
import { useEffect, useState } from 'react'
|
||||
import { Search, Building2, Eye, Trash2, Edit2 } from 'lucide-react'
|
||||
import { Search, Building2, Eye, Trash2, Edit2, Plus } from 'lucide-react'
|
||||
import api from '../../lib/api'
|
||||
import { Input, Select, Label } from '../../components/ui/Input'
|
||||
import Button from '../../components/ui/Button'
|
||||
@@ -28,6 +28,13 @@ export default function PlatformOrgs() {
|
||||
const [loading, setLoading] = useState(true)
|
||||
const [editOrg, setEditOrg] = useState<Org | null>(null)
|
||||
const [deleteOrg, setDeleteOrg] = useState<Org | null>(null)
|
||||
const [createOpen, setCreateOpen] = useState(false)
|
||||
const [createForm, setCreateForm] = useState({
|
||||
name: '', plan: 'FREE', maxEmployees: 20, city: '',
|
||||
contactName: '', contactPhone: '',
|
||||
adminName: '管理员', adminPhone: '', adminPassword: '12345678',
|
||||
})
|
||||
const [creating, setCreating] = useState(false)
|
||||
|
||||
const fetchOrgs = async () => {
|
||||
setLoading(true)
|
||||
@@ -66,6 +73,28 @@ export default function PlatformOrgs() {
|
||||
}
|
||||
}
|
||||
|
||||
const handleCreate = async () => {
|
||||
if (!createForm.name || !createForm.adminPhone || !createForm.adminPassword) {
|
||||
alert('企业名称、管理员手机号、密码不能为空')
|
||||
return
|
||||
}
|
||||
setCreating(true)
|
||||
try {
|
||||
await api.post('/platform/orgs', createForm)
|
||||
setCreateOpen(false)
|
||||
setCreateForm({
|
||||
name: '', plan: 'FREE', maxEmployees: 20, city: '',
|
||||
contactName: '', contactPhone: '',
|
||||
adminName: '管理员', adminPhone: '', adminPassword: '12345678',
|
||||
})
|
||||
fetchOrgs()
|
||||
} catch (err: any) {
|
||||
alert(err.response?.data?.error?.message || '创建失败')
|
||||
} finally {
|
||||
setCreating(false)
|
||||
}
|
||||
}
|
||||
|
||||
const handleDelete = async () => {
|
||||
if (!deleteOrg) return
|
||||
try {
|
||||
@@ -109,6 +138,10 @@ export default function PlatformOrgs() {
|
||||
<Button variant="secondary" onClick={fetchOrgs} className="bg-slate-800 text-slate-200 border border-slate-700 hover:bg-slate-700">
|
||||
搜索
|
||||
</Button>
|
||||
<Button onClick={() => setCreateOpen(true)} className="bg-amber-400 text-slate-950 hover:bg-amber-300">
|
||||
<Plus className="w-4 h-4 mr-1" />
|
||||
创建企业
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
{/* 表格 */}
|
||||
@@ -182,6 +215,73 @@ export default function PlatformOrgs() {
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* 创建企业弹窗 */}
|
||||
{createOpen && (
|
||||
<div className="fixed inset-0 bg-black/60 z-50 flex items-center justify-center p-4" onClick={() => setCreateOpen(false)}>
|
||||
<div className="bg-slate-900 border border-slate-700 rounded-lg p-6 w-full max-w-lg max-h-[90vh] overflow-y-auto" onClick={(e) => e.stopPropagation()}>
|
||||
<h2 className="text-lg font-semibold text-white mb-4">创建企业客户</h2>
|
||||
<div className="space-y-3">
|
||||
<div className="border-b border-slate-700 pb-3">
|
||||
<h3 className="text-xs text-amber-400 font-medium mb-3">企业信息</h3>
|
||||
<div className="grid grid-cols-2 gap-3">
|
||||
<div className="col-span-2">
|
||||
<Label className="text-slate-300">企业名称 *</Label>
|
||||
<Input className="bg-slate-800 border-slate-700 text-white" placeholder="如:北京XX科技有限公司" value={createForm.name} onChange={(e) => setCreateForm({ ...createForm, name: e.target.value })} />
|
||||
</div>
|
||||
<div>
|
||||
<Label className="text-slate-300">套餐</Label>
|
||||
<Select className="bg-slate-800 border-slate-700 text-white" value={createForm.plan} onChange={(e) => setCreateForm({ ...createForm, plan: e.target.value })}>
|
||||
<option value="FREE">免费版</option>
|
||||
<option value="PRO">专业版</option>
|
||||
<option value="ENTERPRISE">企业版</option>
|
||||
</Select>
|
||||
</div>
|
||||
<div>
|
||||
<Label className="text-slate-300">员工上限</Label>
|
||||
<Input type="number" className="bg-slate-800 border-slate-700 text-white" value={createForm.maxEmployees} onChange={(e) => setCreateForm({ ...createForm, maxEmployees: parseInt(e.target.value) || 0 })} />
|
||||
</div>
|
||||
<div>
|
||||
<Label className="text-slate-300">城市</Label>
|
||||
<Input className="bg-slate-800 border-slate-700 text-white" placeholder="如:北京" value={createForm.city} onChange={(e) => setCreateForm({ ...createForm, city: e.target.value })} />
|
||||
</div>
|
||||
<div>
|
||||
<Label className="text-slate-300">联系人</Label>
|
||||
<Input className="bg-slate-800 border-slate-700 text-white" value={createForm.contactName} onChange={(e) => setCreateForm({ ...createForm, contactName: e.target.value })} />
|
||||
</div>
|
||||
<div className="col-span-2">
|
||||
<Label className="text-slate-300">联系电话</Label>
|
||||
<Input className="bg-slate-800 border-slate-700 text-white" value={createForm.contactPhone} onChange={(e) => setCreateForm({ ...createForm, contactPhone: e.target.value })} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="border-b border-slate-700 pb-3">
|
||||
<h3 className="text-xs text-amber-400 font-medium mb-3">管理员账号</h3>
|
||||
<div className="grid grid-cols-2 gap-3">
|
||||
<div>
|
||||
<Label className="text-slate-300">管理员姓名</Label>
|
||||
<Input className="bg-slate-800 border-slate-700 text-white" value={createForm.adminName} onChange={(e) => setCreateForm({ ...createForm, adminName: e.target.value })} />
|
||||
</div>
|
||||
<div>
|
||||
<Label className="text-slate-300">手机号 *</Label>
|
||||
<Input className="bg-slate-800 border-slate-700 text-white" placeholder="13800000000" maxLength={11} value={createForm.adminPhone} onChange={(e) => setCreateForm({ ...createForm, adminPhone: e.target.value })} />
|
||||
</div>
|
||||
<div className="col-span-2">
|
||||
<Label className="text-slate-300">密码 *(至少8位)</Label>
|
||||
<Input className="bg-slate-800 border-slate-700 text-white" value={createForm.adminPassword} onChange={(e) => setCreateForm({ ...createForm, adminPassword: e.target.value })} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex gap-2 pt-2">
|
||||
<Button className="bg-amber-400 text-slate-950 hover:bg-amber-300 flex-1" onClick={handleCreate} disabled={creating}>
|
||||
{creating ? '创建中...' : '确认创建'}
|
||||
</Button>
|
||||
<Button variant="secondary" className="bg-slate-800 text-slate-200 border border-slate-700" onClick={() => setCreateOpen(false)}>取消</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* 编辑弹窗 */}
|
||||
{editOrg && (
|
||||
<div className="fixed inset-0 bg-black/60 z-50 flex items-center justify-center p-4" onClick={() => setEditOrg(null)}>
|
||||
|
||||
Reference in New Issue
Block a user