页面
This commit is contained in:
@@ -36,7 +36,7 @@ export default function LoginPage() {
|
||||
try {
|
||||
setRolesLoading(true)
|
||||
const result = await apiGet('/back/getRoutersInfo')
|
||||
|
||||
|
||||
if (result.code === 200 && result.data) {
|
||||
setRoles(result.data)
|
||||
} else {
|
||||
@@ -44,7 +44,7 @@ export default function LoginPage() {
|
||||
// 如果接口失败,使用默认角色列表作为备选
|
||||
setRoles([
|
||||
{ roleId: "admin", roleName: "总部管理员", roleKey: "admin", remark: "", admin: true },
|
||||
{ roleId: "dealer", roleName: "经销商", roleKey: "dealer", remark: "", admin: false },
|
||||
{ roleId: "dealer", roleName: "区域负责人", roleKey: "dealer", remark: "", admin: false },
|
||||
{ roleId: "mall", roleName: "商场管理员", roleKey: "mall", remark: "", admin: false },
|
||||
{ roleId: "merchant", roleName: "商户", roleKey: "merchant", remark: "", admin: false },
|
||||
{ roleId: "worker", roleName: "维修工人", roleKey: "worker", remark: "", admin: false },
|
||||
@@ -55,7 +55,7 @@ export default function LoginPage() {
|
||||
// 网络错误时使用默认角色列表
|
||||
setRoles([
|
||||
{ roleId: "admin", roleName: "总部管理员", roleKey: "admin", remark: "", admin: true },
|
||||
{ roleId: "dealer", roleName: "经销商", roleKey: "dealer", remark: "", admin: false },
|
||||
{ roleId: "dealer", roleName: "区域负责人", roleKey: "dealer", remark: "", admin: false },
|
||||
{ roleId: "mall", roleName: "商场管理员", roleKey: "mall", remark: "", admin: false },
|
||||
{ roleId: "merchant", roleName: "商户", roleKey: "merchant", remark: "", admin: false },
|
||||
{ roleId: "worker", roleName: "维修工人", roleKey: "worker", remark: "", admin: false },
|
||||
@@ -72,7 +72,7 @@ export default function LoginPage() {
|
||||
|
||||
const handleLogin = async (e: React.FormEvent) => {
|
||||
e.preventDefault()
|
||||
|
||||
|
||||
try {
|
||||
// 构建登录请求参数,包含 roleId
|
||||
const loginData = {
|
||||
@@ -106,14 +106,14 @@ export default function LoginPage() {
|
||||
|
||||
// 登录成功后,验证该角色的路由数据是否有效
|
||||
const routeValidationResult = await apiGet(`/getRoutersByRoleId?roleId=${formData.role}`)
|
||||
|
||||
|
||||
if (routeValidationResult.code !== 200) {
|
||||
alert(`路由验证失败: ${routeValidationResult.msg || '未知错误'},请联系管理员`)
|
||||
// 清除临时保存的用户信息
|
||||
setStorageItem("user", "")
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
// 检查路由数据是否存在
|
||||
if (!routeValidationResult.data) {
|
||||
alert('路由数据不存在,请联系管理员配置角色权限')
|
||||
@@ -121,50 +121,50 @@ export default function LoginPage() {
|
||||
setStorageItem("user", "")
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
// 验证路由数据格式
|
||||
const routeData = routeValidationResult.data
|
||||
console.log("获取到的路由数据:", routeData)
|
||||
|
||||
|
||||
if (!Array.isArray(routeData) || routeData.length === 0) {
|
||||
alert('路由数据格式错误或为空,请联系管理员')
|
||||
// 清除临时保存的用户信息
|
||||
setStorageItem("user", "")
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
// 验证路由数据的基本字段(放宽验证条件)
|
||||
const hasInvalidRoute = routeData.some((route: any) => {
|
||||
console.log("验证路由项:", route)
|
||||
|
||||
|
||||
// 必须有 path 字段
|
||||
if (!route.path || typeof route.path !== 'string') {
|
||||
console.error('无效的路由数据,缺少或错误的 path 字段:', route)
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
// name 字段不是必需的(某些布局路由可能没有 name)
|
||||
// 只验证如果有 name 字段,它必须是字符串类型
|
||||
if (route.name !== undefined && typeof route.name !== 'string') {
|
||||
console.error('无效的路由数据,name 字段类型错误:', route)
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
return false
|
||||
})
|
||||
|
||||
|
||||
if (hasInvalidRoute) {
|
||||
alert('路由数据包含错误信息,请联系管理员检查配置')
|
||||
// 清除临时保存的用户信息
|
||||
setStorageItem("user", "")
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
console.log("路由数据验证通过,保存用户信息并跳转")
|
||||
|
||||
// 获取选择的角色信息
|
||||
const selectedRole = roles.find(role => role.roleId === formData.role)
|
||||
|
||||
|
||||
// 登录成功且路由验证通过,保存用户信息(包含 token 和角色信息)
|
||||
const userData = {
|
||||
username: formData.username,
|
||||
@@ -176,7 +176,7 @@ export default function LoginPage() {
|
||||
token: result.token, // 保存后端返回的 token
|
||||
...result.data // 保存后端返回的其他用户信息
|
||||
}
|
||||
|
||||
|
||||
setStorageItem("user", JSON.stringify(userData))
|
||||
|
||||
// 刷新路由配置(根据新登录的用户角色获取路由)
|
||||
@@ -239,8 +239,8 @@ export default function LoginPage() {
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="role">角色</Label>
|
||||
<Select
|
||||
value={formData.role}
|
||||
<Select
|
||||
value={formData.role}
|
||||
onValueChange={(value) => setFormData({ ...formData, role: value })}
|
||||
disabled={rolesLoading}
|
||||
>
|
||||
|
||||
@@ -78,6 +78,13 @@ export default function MerchantsPage() {
|
||||
const [userRole, setUserRole] = useState<string>("")
|
||||
const [currentPage, setCurrentPage] = useState(1)
|
||||
const [pageSize, setPageSize] = useState(10)
|
||||
const [userEquipmentCount, setUserEquipmentCount] = useState({
|
||||
count: 0,
|
||||
totalCount: 0,
|
||||
countEnd: 0,
|
||||
countExpire: 0
|
||||
})
|
||||
const [loadingUserEquipmentCount, setLoadingUserEquipmentCount] = useState(false)
|
||||
|
||||
const [newMerchant, setNewMerchant] = useState({
|
||||
name: "",
|
||||
@@ -120,6 +127,26 @@ export default function MerchantsPage() {
|
||||
}
|
||||
}
|
||||
|
||||
// 获取用户设备统计数量
|
||||
const fetchUserEquipmentCount = async () => {
|
||||
setLoadingUserEquipmentCount(true)
|
||||
try {
|
||||
const response = await apiGet('/back/equipment/user/count')
|
||||
if (response.code === 200) {
|
||||
setUserEquipmentCount({
|
||||
count: response.data?.count || 0,
|
||||
totalCount: response.data?.totalCount || 0,
|
||||
countEnd: response.data?.countEnd || 0,
|
||||
countExpire: response.data?.countExpire || 0
|
||||
})
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取用户设备统计失败:', error)
|
||||
} finally {
|
||||
setLoadingUserEquipmentCount(false)
|
||||
}
|
||||
}
|
||||
|
||||
// 处理省份变化
|
||||
const handleProvinceChange = (province: string) => {
|
||||
setNewMerchant({
|
||||
@@ -263,6 +290,7 @@ export default function MerchantsPage() {
|
||||
useEffect(() => {
|
||||
fetchUserRole()
|
||||
fetchMerchants()
|
||||
fetchUserEquipmentCount()
|
||||
}, [])
|
||||
|
||||
const [newEquipment, setNewEquipment] = useState({
|
||||
@@ -404,6 +432,18 @@ export default function MerchantsPage() {
|
||||
if (merchant.province) {
|
||||
fetchMalls(merchant.province)
|
||||
}
|
||||
// 加载总商户列表(如果为空,或者商户有总商户ID但列表中没有对应的项)
|
||||
if (!loadingTotalMerchants) {
|
||||
if (totalMerchants.length === 0) {
|
||||
fetchTotalMerchants()
|
||||
} else if (merchant.totalMerchantId) {
|
||||
// 如果商户有总商户ID,但列表中找不到对应的项,重新加载
|
||||
const found = totalMerchants.find(tm => tm.userId === merchant.totalMerchantId)
|
||||
if (!found) {
|
||||
fetchTotalMerchants()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 处理编辑省份变化
|
||||
@@ -544,10 +584,18 @@ export default function MerchantsPage() {
|
||||
<SelectValue placeholder="筛选状态" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="all">全部状态</SelectItem>
|
||||
<SelectItem value="normal">设备正常</SelectItem>
|
||||
<SelectItem value="expiring">有设备即将到期</SelectItem>
|
||||
<SelectItem value="expired">有设备过期</SelectItem>
|
||||
<SelectItem value="all">
|
||||
全部状态 {loadingUserEquipmentCount ? '' : `(${userEquipmentCount.totalCount})`}
|
||||
</SelectItem>
|
||||
<SelectItem value="normal">
|
||||
设备正常 {loadingUserEquipmentCount ? '' : `(${userEquipmentCount.count})`}
|
||||
</SelectItem>
|
||||
<SelectItem value="expiring">
|
||||
有设备即将到期 {loadingUserEquipmentCount ? '' : `(${userEquipmentCount.countEnd})`}
|
||||
</SelectItem>
|
||||
<SelectItem value="expired">
|
||||
有设备过期 {loadingUserEquipmentCount ? '' : `(${userEquipmentCount.countExpire})`}
|
||||
</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
|
||||
@@ -639,11 +687,9 @@ export default function MerchantsPage() {
|
||||
<Eye className="h-4 w-4 mr-1" />
|
||||
查看设备({merchant.equipmentCount})
|
||||
</Button>
|
||||
{userRole !== "merchant" && (
|
||||
<Button variant="outline" size="sm" onClick={() => handleEditMerchant(merchant)}>
|
||||
编辑
|
||||
</Button>
|
||||
)}
|
||||
<Button variant="outline" size="sm" onClick={() => handleEditMerchant(merchant)}>
|
||||
编辑
|
||||
</Button>
|
||||
</div>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
@@ -679,11 +725,9 @@ export default function MerchantsPage() {
|
||||
<Eye className="h-3 w-3 mr-1" />
|
||||
{merchant.equipmentCount}
|
||||
</Button>
|
||||
{userRole !== "merchant" && (
|
||||
<Button variant="outline" size="sm" onClick={() => handleEditMerchant(merchant)}>
|
||||
<Edit className="h-4 w-4" />
|
||||
</Button>
|
||||
)}
|
||||
<Button variant="outline" size="sm" onClick={() => handleEditMerchant(merchant)}>
|
||||
<Edit className="h-4 w-4" />
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -891,32 +935,36 @@ export default function MerchantsPage() {
|
||||
placeholder="请输入联系电话"
|
||||
/>
|
||||
</div>
|
||||
{userRole === "admin" && (
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="totalMerchant">选择总商户(可选)</Label>
|
||||
<Select
|
||||
value={newMerchant.totalMerchant}
|
||||
onValueChange={(value) => setNewMerchant({ ...newMerchant, totalMerchant: value })}
|
||||
disabled={loadingTotalMerchants}
|
||||
onOpenChange={(open) => {
|
||||
if (open && totalMerchants.length === 0 && !loadingTotalMerchants) {
|
||||
fetchTotalMerchants()
|
||||
}
|
||||
}}
|
||||
>
|
||||
<SelectTrigger className="w-full">
|
||||
<SelectValue placeholder={loadingTotalMerchants ? "加载中..." : "选择总商户(可选)"} />
|
||||
</SelectTrigger>
|
||||
<SelectContent className="max-h-[300px]">
|
||||
{totalMerchants.map((merchant) => (
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="totalMerchant">选择总商户(可选)</Label>
|
||||
<Select
|
||||
value={newMerchant.totalMerchant}
|
||||
onValueChange={(value) => setNewMerchant({ ...newMerchant, totalMerchant: value })}
|
||||
disabled={loadingTotalMerchants}
|
||||
onOpenChange={(open) => {
|
||||
if (open && totalMerchants.length === 0 && !loadingTotalMerchants) {
|
||||
fetchTotalMerchants()
|
||||
}
|
||||
}}
|
||||
>
|
||||
<SelectTrigger className="w-full">
|
||||
<SelectValue placeholder={loadingTotalMerchants ? "加载中..." : "选择总商户(可选)"} />
|
||||
</SelectTrigger>
|
||||
<SelectContent className="max-h-[300px]">
|
||||
{totalMerchants.length === 0 && !loadingTotalMerchants ? (
|
||||
<SelectItem value="no-data" disabled>
|
||||
点击加载总商户数据
|
||||
</SelectItem>
|
||||
) : (
|
||||
totalMerchants.map((merchant) => (
|
||||
<SelectItem key={merchant.userId} value={merchant.userId}>
|
||||
{merchant.nickName}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
)}
|
||||
))
|
||||
)}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
<div className="col-span-2 space-y-2">
|
||||
<Label htmlFor="detailedAddress">详细地址</Label>
|
||||
<Textarea
|
||||
@@ -1124,32 +1172,54 @@ export default function MerchantsPage() {
|
||||
placeholder="请输入联系电话"
|
||||
/>
|
||||
</div>
|
||||
{userRole === "admin" && (
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="edit-totalMerchant">选择总商户(可选)</Label>
|
||||
<Select
|
||||
value={editMerchant.totalMerchant}
|
||||
onValueChange={(value) => setEditMerchant({ ...editMerchant, totalMerchant: value })}
|
||||
disabled={loadingTotalMerchants}
|
||||
onOpenChange={(open) => {
|
||||
if (open && totalMerchants.length === 0 && !loadingTotalMerchants) {
|
||||
fetchTotalMerchants()
|
||||
}
|
||||
}}
|
||||
>
|
||||
<SelectTrigger className="w-full">
|
||||
<SelectValue placeholder={loadingTotalMerchants ? "加载中..." : "选择总商户(可选)"} />
|
||||
</SelectTrigger>
|
||||
<SelectContent className="max-h-[300px]">
|
||||
{totalMerchants.map((merchant) => (
|
||||
<SelectItem key={merchant.userId} value={merchant.userId}>
|
||||
{merchant.nickName}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
)}
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="edit-totalMerchant">选择总商户(可选)</Label>
|
||||
<Select
|
||||
value={editMerchant.totalMerchant || undefined}
|
||||
onValueChange={(value) => {
|
||||
if (value === "clear") {
|
||||
setEditMerchant({ ...editMerchant, totalMerchant: "" })
|
||||
} else {
|
||||
setEditMerchant({ ...editMerchant, totalMerchant: value })
|
||||
}
|
||||
}}
|
||||
disabled={loadingTotalMerchants}
|
||||
onOpenChange={(open) => {
|
||||
if (open && totalMerchants.length === 0 && !loadingTotalMerchants) {
|
||||
fetchTotalMerchants()
|
||||
}
|
||||
}}
|
||||
>
|
||||
<SelectTrigger className="w-full">
|
||||
<SelectValue placeholder={loadingTotalMerchants ? "加载中..." : editMerchant.totalMerchant ? "已选择总商户" : "选择总商户(可选)"} />
|
||||
</SelectTrigger>
|
||||
<SelectContent className="max-h-[300px]">
|
||||
{editMerchant.totalMerchant && !totalMerchants.find(tm => tm.userId === editMerchant.totalMerchant) && (
|
||||
<SelectItem value={editMerchant.totalMerchant} disabled>
|
||||
{editMerchant.totalMerchant} (加载中...)
|
||||
</SelectItem>
|
||||
)}
|
||||
{totalMerchants.length === 0 && !loadingTotalMerchants ? (
|
||||
<SelectItem value="no-data" disabled>
|
||||
{editMerchant.totalMerchant ? "当前值: " + editMerchant.totalMerchant : "点击加载总商户数据"}
|
||||
</SelectItem>
|
||||
) : (
|
||||
<>
|
||||
{editMerchant.totalMerchant && (
|
||||
<SelectItem value="clear">
|
||||
清除选择
|
||||
</SelectItem>
|
||||
)}
|
||||
{totalMerchants.map((merchant) => (
|
||||
<SelectItem key={merchant.userId} value={merchant.userId}>
|
||||
{merchant.nickName}
|
||||
</SelectItem>
|
||||
))}
|
||||
</>
|
||||
)}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
<div className="col-span-2 space-y-2">
|
||||
<Label htmlFor="edit-detailedAddress">详细地址</Label>
|
||||
<Textarea
|
||||
|
||||
@@ -306,7 +306,7 @@ export default function WorkOrderArchivePage() {
|
||||
<Eye className="h-4 w-4 mr-1" />
|
||||
查看详情
|
||||
</Button>
|
||||
{((order.equipmentName?.includes("厨房自动灭火") || order.equipmentName === "厨房自动灭火设备") && (order.workOrderType === "设备安装" || order.workOrderType === "设备检测" || order.workOrderType === "设备改造" || order.workOrderType === "设备维修" || order.workOrderType === "故障维修" || order.workOrderType === "设备拆除" || order.workOrderType === "更换药剂")) && (
|
||||
{(order.workOrderType === "设备安装" || order.workOrderType === "设备检测" || order.workOrderType === "故障检测") && (
|
||||
<Button variant="outline" size="sm" onClick={() => handleDownloadReport(order.workOrderNumber)}>
|
||||
<FileDown className="h-4 w-4 mr-1" />
|
||||
下载报告
|
||||
@@ -341,7 +341,7 @@ export default function WorkOrderArchivePage() {
|
||||
<Eye className="h-3 w-3 mr-1" />
|
||||
查看
|
||||
</Button>
|
||||
{((order.equipmentName?.includes("厨房自动灭火") || order.equipmentName === "厨房自动灭火设备") && (order.workOrderType === "设备安装" || order.workOrderType === "设备检测" || order.workOrderType === "设备改造" || order.workOrderType === "设备维修" || order.workOrderType === "故障维修" || order.workOrderType === "设备拆除" || order.workOrderType === "更换药剂")) && (
|
||||
{(order.workOrderType === "设备安装" || order.workOrderType === "设备检测" || order.workOrderType === "故障检测") && (
|
||||
<Button variant="outline" size="sm" onClick={() => handleDownloadReport(order.workOrderNumber)} className="text-xs">
|
||||
<FileDown className="h-3 w-3 mr-1" />
|
||||
下载
|
||||
|
||||
Reference in New Issue
Block a user