This commit is contained in:
linfeng 2025-03-12 11:45:19 +08:00
commit e5317e15b1
13 changed files with 226 additions and 9 deletions

View File

@ -12,6 +12,7 @@ const StaffWhereInputSchema: ZodType<Prisma.StaffWhereInput> = z.any();
const StaffSelectSchema: ZodType<Prisma.StaffSelect> = z.any();
const StaffUpdateInputSchema: ZodType<Prisma.StaffUpdateInput> = z.any();
const StaffFindManyArgsSchema: ZodType<Prisma.StaffFindManyArgs> = z.any();
const StaffFindUniqueArgsSchema: ZodType<Prisma.StaffFindUniqueArgs> = z.any();
@Injectable()
export class StaffRouter {
constructor(
@ -89,5 +90,10 @@ export class StaffRouter {
.mutation(async ({ input }) => {
return this.staffService.updateOrder(input);
}),
findUnique: this.trpc.procedure
.input(StaffFindUniqueArgsSchema)
.query(async ({ input }) => {
return await this.staffService.findUnique(input);
}),
});
}

View File

@ -421,7 +421,7 @@ export class GenDevService {
return trainSituation
}
private async generateTrainSituations(probability: number = 0.7){
private async generateTrainSituations(probability: number = 0.1){
this.logger.log("Start generating train situations...")
const allTrainContents = await db.trainContent.findMany();
// 这里相当于两次遍历 找到没有parentID的即是

View File

@ -0,0 +1,10 @@
import DailyContext from "@web/src/components/models/daily/DailyContext";
import DailyLayout from "@web/src/components/models/daily/DailyLayout";
export default function DailyPage(){
return <>
<DailyContext>
<DailyLayout></DailyLayout>
</DailyContext>
</>
}

View File

@ -9,7 +9,7 @@ export default function NavigationMenu() {
const menuItems = [
{ key: 'home', label: '首页', path: '/' },
{ key: 'staff', label: '人员总览', path: '/staff' },
{ key: 'day', label: '日统计', path: '/day' },
{ key: 'day', label: '日统计', path: '/daily' },
{ key: 'month', label: '月统计', path: '/month' },
{ key: 'year', label: '年度统计', path: '/year' }
];

View File

@ -0,0 +1,53 @@
import { api } from "@nice/client";
import { useAuth } from "@web/src/providers/auth-provider";
import { UserProfile } from "@nice/common";
import { createContext, ReactNode, useContext, useEffect, useState } from "react";
interface DailyContextProviderProps{
staffsMsg:{
id:string,
showname:string,
username:string
}[],
staffsLoading:boolean,
selectedUserMsg:UserProfile,
setSelectedUserMsg:(userMsg:UserProfile)=>void
}
interface DailyContextProps{
children:ReactNode
}
const DailyContextProvider = createContext<DailyContextProviderProps>(null)
export default function DailyContext({children}:DailyContextProps){
const {user} = useAuth()
const [selectedUserMsg,setSelectedUserMsg] = useState(null)
// 获取当前员工的单位下的所有staff的记录
const {data:staffs,isLoading:staffsLoading} = api.staff.findByDept.useQuery({
deptId:user.deptId
})
const staffsMsg = staffs?.map((staff)=>{
return {
id:staff.id,
showname:staff.showname,
username:staff.username
}
})
return <DailyContextProvider.Provider value={{
staffsMsg,
staffsLoading,
selectedUserMsg,
setSelectedUserMsg
}}>
{children}
</DailyContextProvider.Provider>
}
export function useDaily(){
const daily = useContext(DailyContextProvider)
if(!daily) {throw new Error("useParams must be used within a ParamsProvider");}
return daily
}

View File

@ -0,0 +1,11 @@
import DailyMsgDisplayLayout from "./dailyMsgDisplay/DailyMsgDisplayLayout";
import { DailyMsgFormLayout } from "./dailyMsgForm/DailyMsgFormLayout";
export default function DailyLayout(){
return (
<div className="w-full h-full bg-slate-400">
<DailyMsgFormLayout></DailyMsgFormLayout>
<DailyMsgDisplayLayout></DailyMsgDisplayLayout>
</div>
)
}

View File

@ -0,0 +1,12 @@
import DailyPersonMsg from "../dailyMsgForm/DailyPersonMsg";
import DailyTrainMsg from "../dailyMsgForm/DailyTrainMsg";
import { useDaily } from "../DailyContext";
export default function DailyMsgDisplayLayout(){
const {selectedUserMsg} = useDaily()
return (
<div>
<DailyPersonMsg selectedUserMsg={selectedUserMsg} />
<DailyTrainMsg selectedUserMsg={selectedUserMsg} />
</div>
)
}

View File

@ -0,0 +1,55 @@
import { Form } from "antd";
import StaffSelect from "../../staff/staff-select";
import { useDaily } from "../DailyContext";
import { useEffect, useState } from "react";
import { staffDetailSelect, UserProfile } from "@nice/common";
import { api } from "@nice/client";
import { MonitorOutlined } from "@ant-design/icons";
export function DailyMsgFormLayout() {
const [form] = Form.useForm()
const { staffsMsg ,selectedUserMsg,setSelectedUserMsg} = useDaily()
const [selectedUserId, setSelectedUserId] = useState<string | null>(null);
const { data: selectedUserData } = api.staff.findUnique.useQuery(
{
where: {
id: selectedUserId,
},
select: staffDetailSelect
},
{
enabled: !!selectedUserId, // 只有当selectedUserId存在时才执行查询
}
);
const handleChange = (value: string | string[]) => {
if (!value) {
setSelectedUserId(null);
setSelectedUserMsg(null);
return;
}
setSelectedUserId(Array.isArray(value) ? value[0] : value);
}
useEffect(() => {
if (selectedUserData) {
console.log(selectedUserData)
setSelectedUserMsg(selectedUserData as any as UserProfile);
}
}, [selectedUserData]);
return (
<div className="w-full h-[260px] bg-white flex flex-col items-center">
<Form
form={form}
>
<div className="flex items-center m-8">
<MonitorOutlined className="mr-2" />
<StaffSelect
staffsMsg={staffsMsg}
placeholder="请搜索或选择人员"
onChange={(value) => handleChange(value)}
></StaffSelect>
</div>
</Form>
</div>
)
}

View File

@ -0,0 +1,13 @@
export default function DailyPersonMsg({selectedUserMsg}) {
return (
<div className="">
<span>{selectedUserMsg?.showname ? selectedUserMsg?.showname : "暂无数据"}</span>
<span>{selectedUserMsg?.age ? selectedUserMsg?.age : "暂无数据"}</span>
<span>{selectedUserMsg?.sex ? selectedUserMsg?.sex : "暂无数据"}</span>
<span>{selectedUserMsg?.absent ? selectedUserMsg?.absent : "暂无数据"}</span>
<span>{selectedUserMsg?.department?.name ? selectedUserMsg?.department?.name : "暂无数据"}</span>
<span>{selectedUserMsg?.position?.type ? selectedUserMsg?.position?.type : "暂无数据"}</span>
<span>{selectedUserMsg?.avatar ? selectedUserMsg?.avatar : "暂无数据"}</span>
</div>
)
}

View File

@ -0,0 +1,7 @@
export default function DailyTrainMsg({selectedUserMsg}) {
return (
<div>
<span></span>
</div>
)
}

View File

@ -9,6 +9,13 @@ interface StaffSelectProps {
multiple?: boolean;
domainId?: string;
placeholder?: string;
staffsMsg?: StaffsMsgProps[];
}
interface StaffsMsgProps {
id: string;
showname: string;
username: string;
}
export default function StaffSelect({
@ -16,8 +23,9 @@ export default function StaffSelect({
onChange,
placeholder,
style,
multiple,
multiple = false,
domainId,
staffsMsg,
}: StaffSelectProps) {
const [keyword, setQuery] = useState<string>("");
@ -50,7 +58,7 @@ export default function StaffSelect({
},
select: { id: true, showname: true, username: true },
take: 30,
//take: 30,
orderBy: { order: "asc" }
});
@ -59,6 +67,13 @@ export default function StaffSelect({
};
const options: SelectProps["options"] =
staffsMsg ?
staffsMsg.map((staff)=>{
return {
value:staff.id,
label:staff.showname || staff.username
}
}) :
data?.map((staff: any) => ({
value: staff.id,
label: staff?.showname || staff?.username,
@ -77,7 +92,7 @@ export default function StaffSelect({
options={options}
value={value}
onChange={onChange}
style={{ minWidth: 200, ...style }}
style={{ minWidth: 600, ...style }}
/>{" "}
</>
);

View File

@ -10,6 +10,7 @@ import LoginPage from "../app/login";
import HomePage from "../app/main/home/page";
import StaffMessage from "../app/main/staffpage/page";
import MainLayout from "../app/main/layout/MainLayout";
import DailyPage from "../app/main/dailyPage/page";
interface CustomIndexRouteObject extends IndexRouteObject {
name?: string;
breadcrumb?: string;
@ -52,9 +53,9 @@ export const routes: CustomRouteObject[] = [
element: <StaffMessage></StaffMessage>,
},
{
path: "/day",
element: <StaffMessage></StaffMessage>,
},
path:"/daily",
element:<DailyPage></DailyPage>
}
],
},

View File

@ -163,7 +163,41 @@ export const trainSituationDetailSelect: Prisma.TrainSituationSelect = {
select: {
id: true,
title: true,
},
},
};
export const staffDetailSelect: Prisma.StaffSelect = {
id: true,
showname: true,
username: true,
deptId: true,
avatar: true,
age: true,
sex: true,
absent: true,
trainSituations:{
select:{
id: true,
trainContent:{
select:{
id: true,
title: true,
type: true,
}
}
}
},
department: {
select: {
id: true,
name: true,
}
},
position: {
select: {
id: true,
type: true,
}
}
};