feat: 员工端密码登录完整支持
1. createEmployee 创建员工时自动设置默认密码(手机号后6位) 2. 管理员重置密码接口 POST /employees/:id/reset-password (重置为手机号后6位) 3. 员工自己修改密码接口 POST /portal/change-password (需验证旧密码,新密码至少6位) 4. 花名册详情添加"重置密码"按钮,显示默认密码提示 5. 员工端导航栏添加"修改密码"入口,弹窗修改密码 Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
@@ -9,7 +9,7 @@ import api from '../../lib/api'
|
||||
import Card from "../../components/ui/Card"
|
||||
import Button from "../../components/ui/Button"
|
||||
import { Input, Label, Select } from "../../components/ui/Input"
|
||||
import { AlertTriangle, Paperclip, Trash2, Eye, Download, Copy } from "lucide-react"
|
||||
import { AlertTriangle, Paperclip, Trash2, Eye, Download, Copy, KeyRound } from "lucide-react"
|
||||
import { fmt } from "./shared"
|
||||
|
||||
export default function BasicInfo({ profile, employeeId, attachments }: { profile: any; employeeId: string; attachments: any[] }) {
|
||||
@@ -29,6 +29,13 @@ export default function BasicInfo({ profile, employeeId, attachments }: { profil
|
||||
onSuccess: () => queryClient.invalidateQueries({ queryKey: ['roster-profile', employeeId] }),
|
||||
})
|
||||
|
||||
/** 重置员工密码(重置为手机号后6位) */
|
||||
const resetPasswordMutation = useMutation({
|
||||
mutationFn: () => employeeApi.resetPassword(employeeId),
|
||||
onSuccess: (data: any) => toast.success(data?.message || '密码已重置'),
|
||||
onError: (err: any) => toast.error(err?.response?.data?.error?.message || '重置失败'),
|
||||
})
|
||||
|
||||
const handleFileUpload = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const file = e.target.files?.[0]
|
||||
if (!file) return
|
||||
@@ -493,12 +500,29 @@ export default function BasicInfo({ profile, employeeId, attachments }: { profil
|
||||
<div className="mt-4 pt-4 border-t">
|
||||
<div className="flex items-center justify-between mb-3">
|
||||
<h3 className="text-xs font-medium text-gray-600">员工端入口</h3>
|
||||
<Button size="sm" variant="secondary" onClick={() => {
|
||||
const url = `${window.location.origin}/portal/login`
|
||||
navigator.clipboard?.writeText(url)
|
||||
}}>
|
||||
复制链接
|
||||
</Button>
|
||||
<div className="flex gap-2">
|
||||
<Button size="sm" variant="secondary" onClick={() => {
|
||||
const url = `${window.location.origin}/portal/login`
|
||||
navigator.clipboard?.writeText(url)
|
||||
}}>
|
||||
复制链接
|
||||
</Button>
|
||||
<Button
|
||||
size="sm"
|
||||
variant="secondary"
|
||||
onClick={async () => {
|
||||
const ok = await confirm({
|
||||
title: '重置员工密码',
|
||||
message: `将重置「${profile.name}」的员工端密码为手机号后6位(${profile.phone?.slice(-6)}),确认操作?`,
|
||||
})
|
||||
if (ok) resetPasswordMutation.mutate()
|
||||
}}
|
||||
disabled={resetPasswordMutation.isPending}
|
||||
>
|
||||
<KeyRound className="w-3.5 h-3.5 mr-1" />
|
||||
重置密码
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-center gap-4">
|
||||
<div className="bg-white p-3 rounded-lg border">
|
||||
@@ -509,7 +533,8 @@ export default function BasicInfo({ profile, employeeId, attachments }: { profil
|
||||
/>
|
||||
</div>
|
||||
<div className="text-xs text-gray-500 space-y-1">
|
||||
<p>员工扫码进入员工端,使用手机号登录</p>
|
||||
<p>员工扫码进入员工端,使用手机号+密码登录</p>
|
||||
<p>默认密码:手机号后6位({profile.phone?.slice(-6)}),员工可在端内自行修改</p>
|
||||
<p>可查看工资条、合同信息、确认签署</p>
|
||||
<p className="text-gray-400">链接:{window.location.origin}/portal/login</p>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user