first commit

This commit is contained in:
wang_yp 2024-11-23 02:37:42 +08:00
parent 2a8e134fd4
commit 5afd6e3933
32 changed files with 440 additions and 165 deletions

View File

@ -13,6 +13,7 @@ export enum FormType {
cehckbox = "checkbox", cehckbox = "checkbox",
cehckboxGroup = "checkboxGroup", cehckboxGroup = "checkboxGroup",
password = "password", password = "password",
treeVideo = "treeVideo",
fetchList = "fetchList", fetchList = "fetchList",
} }

View File

@ -5,6 +5,7 @@ import { FormSelect } from "./select";
import AliUpload from "../ali_upload"; import AliUpload from "../ali_upload";
import MyEditor from "../edittor"; import MyEditor from "../edittor";
import MapFrom from "../map/MapFrom"; import MapFrom from "../map/MapFrom";
import VideoSelect from "../video_select";
const { TextArea } = Input; const { TextArea } = Input;
const SimpleForm = (props: SimpleFormData) => { const SimpleForm = (props: SimpleFormData) => {
const [form] = Form.useForm(); const [form] = Form.useForm();
@ -104,6 +105,21 @@ const SimpleForm = (props: SimpleFormData) => {
/> />
</Form.Item> </Form.Item>
); );
case FormType.treeVideo:
return (
<Form.Item
key={v.label}
label={v.label}
name={v.name}
rules={v.rules}
>
<VideoSelect
changes={(v) => {
form?.setFieldsValue({ task_video: v });
}}
/>
</Form.Item>
);
case FormType.select: case FormType.select:
return FormSelect(v); return FormSelect(v);
case FormType.upload: case FormType.upload:

View File

@ -10,7 +10,7 @@ class MapUtl {
static addMaker(data: any) { static addMaker(data: any) {
const { lng, lat, title, users } = data; const { lng, lat, title, users } = data;
if (MapUtl.loadMap === null) return; // if (MapUtl.loadMap === null) return;
const marker = new MapUtl.loadMap.Marker({ const marker = new MapUtl.loadMap.Marker({
position: new MapUtl.loadMap.LngLat(lng, lat), position: new MapUtl.loadMap.LngLat(lng, lat),
title: title, title: title,

View File

@ -1,5 +1,4 @@
// 档案管理 // 档案管理
import { import {
Button, Button,
Space, Space,
@ -9,6 +8,8 @@ import {
Tree, Tree,
Row, Row,
Col, Col,
Popconfirm,
PopconfirmProps,
} from "antd"; } from "antd";
import { inject, observer } from "mobx-react"; import { inject, observer } from "mobx-react";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
@ -71,6 +72,9 @@ const ArchivesFolder = (props: Store) => {
setFolderId(info.node.identity); setFolderId(info.node.identity);
}; };
const cancel: PopconfirmProps['onCancel'] = (e) => {
console.log(e);
};
const onExpand: DirectoryTreeProps["onExpand"] = (keys, info) => { const onExpand: DirectoryTreeProps["onExpand"] = (keys, info) => {
// console.log("Trigger Expand", keys, info); // console.log("Trigger Expand", keys, info);
}; };
@ -96,6 +100,7 @@ const ArchivesFolder = (props: Store) => {
return ( return (
<> <>
{nodeData.folder_name} {nodeData.folder_name}
<Space>
<span <span
style={{ marginLeft: "10px", color: "blue" }} style={{ marginLeft: "10px", color: "blue" }}
onClick={(e) => { onClick={(e) => {
@ -107,15 +112,21 @@ const ArchivesFolder = (props: Store) => {
> >
</span> </span>
<span <Popconfirm
style={{ marginLeft: "10px", color: "red" }} title="Delete the task"
onClick={(e) => { description="Are you sure to delete this task?"
e?.stopPropagation(); onConfirm={()=>{
remove(nodeData.id); remove(nodeData.id);
}} }}
onCancel={cancel}
okText="Yes"
cancelText="No"
> >
<Button danger variant="solid" size="small"></Button>
</span> </Popconfirm>
</Space>
</> </>
); );
}} }}

View File

@ -2,6 +2,7 @@ import {
Button, Button,
message, message,
Modal, Modal,
Popconfirm,
Space, Space,
Upload, Upload,
UploadFile, UploadFile,
@ -38,10 +39,13 @@ const FileListPage = (props: any) => {
} }
}, },
}; };
useEffect(() => { const getFileList =()=>{
folderStore.getAlist(id).then((res) => { folderStore.getAlist(id).then((res) => {
setFileList(folderStore.alist); setFileList(folderStore.alist);
}); });
}
useEffect(() => {
getFileList()
}, [folderStore, id]); }, [folderStore, id]);
const getFileTypeFromUrl = (url) => { const getFileTypeFromUrl = (url) => {
if (url === "" || url.length === 0) return; if (url === "" || url.length === 0) return;
@ -120,10 +124,7 @@ const FileListPage = (props: any) => {
</div> </div>
{fileList?.map((item: any) => { {fileList?.map((item: any) => {
return ( return (
<div <div key={item?.identity} style={{ display: "flex", margin: "10px" }}>
key={item?.identity}
style={{ display: "flex", margin: "10px" }}
>
<Space> <Space>
<span className="text-overflow"> {item?.file_name}</span> <span className="text-overflow"> {item?.file_name}</span>
<Button <Button
@ -134,7 +135,24 @@ const FileListPage = (props: any) => {
> >
</Button> </Button>
<a href={item?.file_url} download={item.file_name}></a> <a href={item?.file_url} download={item.file_name}>
</a>
<Popconfirm
title="删除文件"
description="是否删除文件?"
onConfirm={() => {
archivesStore.deleteItem(item.id)
getFileList()
}}
onCancel={() => {}}
okText="Yes"
cancelText="No"
>
<Button danger variant="solid" size="small">
</Button>
</Popconfirm>
</Space> </Space>
</div> </div>
); );

View File

@ -31,9 +31,16 @@ export const EmConfig = (userList) => [
{ {
type: FormType.cehckboxGroup, type: FormType.cehckboxGroup,
label: "参与队伍", label: "参与队伍",
name: "user_id", name: "team_id",
value: [], value: [],
checkboxData: userList, checkboxData: userList,
rules: [{ required: true, message: "参与队伍不能为空!" }], rules: [{ required: true, message: "参与队伍不能为空!" }],
}, },
{
type: FormType.treeVideo,
label: "视频地址",
name: "task_video",
value: [],
rules: [{ required: true, message: "请选择视频地址!" }],
},
]; ];

View File

@ -147,10 +147,10 @@ const Emergency = (props: Store) => {
}; };
useEffect(() => { useEffect(() => {
emergencyStore.getlist(); emergencyStore.getlist();
baseHttp.get("/user/list", null).then((res) => { baseHttp.get("/team/list", null).then((res) => {
let data = res.data?.record ?? []; let data = res.data?.record ?? [];
data.forEach((item) => { data.forEach((item) => {
item.label = item.user_name; item.label = item.name;
item.value = item.identity; item.value = item.identity;
}); });
setUserList(data ?? []); setUserList(data ?? []);

View File

@ -1,13 +1,18 @@
import BTable from "@/components/b_table"; import BTable from "@/components/b_table";
import { UserDataType } from "@/model/userModel"; import { UserDataType } from "@/model/userModel";
import { Button } from "antd"; import { Button, message, Modal, Space } from "antd";
import { Store } from "antd/es/form/interface"; import { Store } from "antd/es/form/interface";
import TextArea from "antd/lib/input/TextArea";
import { ColumnsType } from "antd/lib/table"; import { ColumnsType } from "antd/lib/table";
import dayjs from "dayjs";
import { inject, observer } from "mobx-react"; import { inject, observer } from "mobx-react";
import { useEffect } from "react"; import { useEffect, useState } from "react";
const ExceCompet = (props: Store) => { const ExceCompet = (props: Store) => {
const { exceCompetStore } = props; const { exceCompetStore } = props;
const [isModalOpen, setIsModalOpen] = useState(false);
const [value, setValue] = useState('');
const [id, setId] = useState('');
useEffect(() => { useEffect(() => {
exceCompetStore.getlist(); exceCompetStore.getlist();
}, [exceCompetStore]); }, [exceCompetStore]);
@ -17,29 +22,73 @@ const ExceCompet = (props: Store) => {
{ {
title: "评优申请人", title: "评优申请人",
dataIndex: "users", dataIndex: "users",
render: (users) => <span>{users?.user_name}</span> render: (users) => <span>{users?.user_name}</span>,
}, },
{ title: "申请积分", dataIndex: "reviewer_score" }, { title: "申请积分", dataIndex: "reviewer_score" },
{ title: "申请时间", dataIndex: "created_at" },
{ title: "描述", dataIndex: "desc" },
{ title: "审核状态", dataIndex: "status" },
{ title: "审核人", dataIndex: "reviewer_identity" },
{ {
title: "操作", title: "申请时间",
dataIndex: "id", dataIndex: "created_at",
render: (any, record) => ( render: (created_at) => (
<Button <span>{dayjs(created_at).format("YYYY-MM-DD")}</span>
type="dashed"
size="small"
onClick={() => {
// edit(record);
}}
>
</Button>
), ),
}, },
{ title: "描述", dataIndex: "desc" },
{
title: "审核状态",
dataIndex: "status",
render: (status) =>
status === 1 ? "已通过" : status === 2 ? "驳回" : "未审核",
width: 200,
},
{
title: "审核人",
dataIndex: "reviewer_users",
render: (reviewer_users) => <span>{reviewer_users?.user_name}</span>,
},
{
title: "操作",
dataIndex: "identity",
render: (any, record) =>
record.status === 0 ? (
<Space>
<Button
type="dashed"
size="small"
onClick={() => {
setId(record.identity)
setIsModalOpen(true);
}}
>
</Button>
<Button
type="dashed"
size="small"
onClick={() => {
exceCompetStore.audit(record.identity, {status: 1});
}}
>
</Button>
</Space>
) : null,
},
]; ];
const handleOk = () => {
if (!value) {
message.error("请输入驳回理由")
return;
}
exceCompetStore.audit(id, {status: 2,remark:value});
setIsModalOpen(false);
};
const handleCancel = () => {
setIsModalOpen(false);
};
return ( return (
<div> <div>
<BTable <BTable
@ -47,6 +96,14 @@ const ExceCompet = (props: Store) => {
columns={columns} columns={columns}
dataSource={exceCompetStore.list} dataSource={exceCompetStore.list}
/> />
<Modal title="驳回" open={isModalOpen} onOk={handleOk} onCancel={handleCancel}>
<TextArea
value={value}
onChange={(e) => setValue(e.target.value)}
placeholder="请输入驳回理由"
autoSize={{ minRows: 3, maxRows: 5 }}
/>
</Modal>
</div> </div>
); );
}; };

View File

@ -152,8 +152,7 @@
.map_video_container { .map_video_container {
position: absolute; position: absolute;
width: 300px; width: 350px;
height: 300px; top: 70px;
top: 60px;
right: 300px; right: 300px;
} }

View File

@ -9,6 +9,7 @@ import { SettingOutlined } from "@ant-design/icons";
import { useNavigate } from "react-router"; import { useNavigate } from "react-router";
import Weather from "./homeLeft/weather"; import Weather from "./homeLeft/weather";
import Timer from "./homeLeft/timer"; import Timer from "./homeLeft/timer";
import HomeVideo from "./home_video";
const Home = observer(() => { const Home = observer(() => {
const navigate = useNavigate(); const navigate = useNavigate();
@ -47,7 +48,7 @@ const Home = observer(() => {
</div> </div>
<MapContainer /> <MapContainer />
<div className="map_video_container"> <div className="map_video_container">
{/* <Video /> */} <HomeVideo />
</div> </div>
<div className="map_container_r"> <div className="map_container_r">
<HomeRight /> <HomeRight />

View File

@ -5,11 +5,12 @@ import {
Form, Form,
FormInstance, FormInstance,
InputNumber, InputNumber,
message,
Modal, Modal,
Select, Select,
SelectProps, SelectProps,
} from "antd"; } from "antd";
import React from "react"; import React, { useEffect } from "react";
import { useState } from "react"; import { useState } from "react";
import baseHttp from "@/service/base"; import baseHttp from "@/service/base";
import "./bot.less"; import "./bot.less";
@ -34,27 +35,36 @@ const Dispath = (props: Store) => {
...traningConfig, ...traningConfig,
{ {
type: FormType.cehckboxGroup, type: FormType.cehckboxGroup,
label: "参与人员选择", label: "参与队伍",
name: "user_id", name: "trem_id",
value: [], value: [],
checkboxData: userList, checkboxData: userList,
rules: [{ required: true, message: "请选择参与人员!" }], rules: [{ required: true, message: "请选择参与队伍!" }],
},
{
type: FormType.treeVideo,
label: "直播视频地址",
name: "task_video",
value: [],
rules: [{ required: true, message: "请选择直播视频地址!" }],
}, },
]); ]);
}; };
useEffect(() => {
baseHttp.get("/team/list", null).then((res) => {
let data = res.data?.record ?? [];
data.forEach((item) => {
item.label = item.name;
item.value = item.identity;
});
setUserList(data ?? []);
});
}, []);
const getList = async () => { const getList = async () => {
try { try {
trainingCatStore.getlist().then(() => { trainingCatStore.getlist().then(() => {
setStashList(trainingCatStore.list); setStashList(trainingCatStore.list);
}); });
baseHttp.get("/user/list", null).then((res) => {
let data = res.data?.record ?? [];
data.forEach((item) => {
item.label = item.account;
item.value = item.identity;
});
setUserList(data ?? []);
});
} catch (error) { } catch (error) {
console.log(error); console.log(error);
} }
@ -67,11 +77,32 @@ const Dispath = (props: Store) => {
}; };
const onFinish = (values: any) => { const onFinish = (values: any) => {
let task_video: any = [];
for (let i = 0; i < values.task_video.length; i++) {
let item = values.task_video[i];
task_video.push({
device: item.split("-")[0],
channel: item.split("-")[1],
});
}
if (!task_video || task_video.length === 0) {
message.error("请选择视频设备");
return;
}
if (values.score === 0 || values.score === null) {
message.error("请完善训练积分");
return;
}
if (values.count === 0 || values.count === null) {
message.error("请完善训练次数");
return;
}
let data = { let data = {
...values, ...values,
score: Number(values.score), score: Number(values.score),
count: Number(values.count), count: Number(values.count),
}; };
data.task_video = task_video;
trainingStore.add(data); trainingStore.add(data);
setIsModalOpen(false); setIsModalOpen(false);
}; };
@ -98,9 +129,7 @@ const Dispath = (props: Store) => {
centered centered
width={1000} width={1000}
open={isModalOpen} open={isModalOpen}
afterClose={() => { afterClose={() => {}}
}}
onOk={() => {}} onOk={() => {}}
okText="确定" okText="确定"
cancelText="取消" cancelText="取消"
@ -122,7 +151,10 @@ const Dispath = (props: Store) => {
setIsModalOpen(false); setIsModalOpen(false);
}} }}
> >
<div className="disPatch" style={{ fontSize: "#fff",height:"600px",overflowY:"auto" }}> <div
className="disPatch"
style={{ fontSize: "#fff", height: "600px", overflowY: "auto" }}
>
<SimpleForm <SimpleForm
formRef={formRef} formRef={formRef}
createCallback={() => {}} createCallback={() => {}}

View File

@ -15,7 +15,6 @@ import baseHttp from "@/service/base";
import MinusCircleOutlined from "@ant-design/icons/lib/icons/MinusCircleOutlined"; import MinusCircleOutlined from "@ant-design/icons/lib/icons/MinusCircleOutlined";
import { EmConfig } from "@/pages/emergency/em_column"; import { EmConfig } from "@/pages/emergency/em_column";
import { inject, observer } from "mobx-react"; import { inject, observer } from "mobx-react";
import VideoSelect from "@/components/video_select";
const Emr = (props: Store) => { const Emr = (props: Store) => {
const { emergencyStore, homeStore } = props; const { emergencyStore, homeStore } = props;
@ -36,8 +35,15 @@ const Emr = (props: Store) => {
long: values.marker["lng"], long: values.marker["lng"],
lat: values.marker["lat"], lat: values.marker["lat"],
}; };
console.log(data); let task_video: any = [];
return; for (let i = 0; i < values.task_video.length; i++) {
let item = values.task_video[i];
task_video.push({
device: item.split("-")[0],
channel: item.split("-")[1],
});
}
data.task_video = task_video;
emergencyStore.add(data); emergencyStore.add(data);
setIsModalOpen(false); setIsModalOpen(false);
homeStore.getNewTask(); homeStore.getNewTask();
@ -159,18 +165,6 @@ const Emr = (props: Store) => {
</> </>
)} )}
</Form.List> </Form.List>
<Form.Item
key="task_video"
label="视频地址"
name="task_video"
rules={[{ required: true, message: "请选择视频地址" }]}
>
<VideoSelect
changes={(v) => {
formRef.current?.setFieldsValue({ task_video: v });
}}
/>
</Form.Item>
</> </>
</SimpleForm> </SimpleForm>
</div> </div>

View File

@ -25,7 +25,6 @@ const WhichVideo = (props) => {
let reqs = await homeStore.getChannerStrem(deviceId, id); let reqs = await homeStore.getChannerStrem(deviceId, id);
if (!reqs.EasyDarwin) return; if (!reqs.EasyDarwin) return;
let url = Config.videoApis + reqs.EasyDarwin.Body.URL let url = Config.videoApis + reqs.EasyDarwin.Body.URL
console.log(url)
setVideoUrl(url); setVideoUrl(url);
}; };
return ( return (

View File

@ -1,8 +1,39 @@
import { Store } from "antd/es/form/interface";
import { inject, observer } from "mobx-react";
import { useEffect, useState } from "react";
import Video from "./video";
import "./video.less";
const HomeVideo = () => { const HomeVideo = (props: Store) => {
const { homeStore } = props;
const [videoUrls, setVideoUrl] = useState<[] | null>([]);
useEffect(() => {
// 获取最新任务
homeStore.getNewTask().then((res) => {
setVideoUrl(res);
});
}, [homeStore]);
return ( return (
<div>csacas</div> <div>
<span style={{ color: "#fff" }}></span>
{homeStore.showVideo ? (
<div
className="homeVideoBox"
style={{
width: "350px",
}}
>
{videoUrls?.map((videoUrl, index) => {
return (
<div key={videoUrl} style={{ flex: "1", margin: "5px" }}>
<Video url={videoUrl} className="homeVideo" />;
</div>
);
})}
</div>
) : null}
</div>
); );
}; };
export default HomeVideo; export default inject("homeStore")(observer(HomeVideo));

View File

@ -0,0 +1,5 @@
.homeVideoBox{
width: 100%;
display: flex;
flex-wrap: wrap;
}

View File

@ -28,7 +28,7 @@ export const leaveColumns: ColumnsType<UserDataType> = [
}, },
{ {
title: "驳回原因", title: "驳回原因",
dataIndex: "reject", dataIndex: "reject_mark",
}, },
{ {
title: "审批人", title: "审批人",
@ -56,7 +56,7 @@ export const defaultConfig = [
{ {
type: FormType.input, type: FormType.input,
label: "驳回原因", label: "驳回原因",
name: "reject", name: "reject_mark",
value: "", value: "",
rules: [{ required: true, message: "请输入驳回原因!" }], rules: [{ required: true, message: "请输入驳回原因!" }],
}, },
@ -64,7 +64,6 @@ export const defaultConfig = [
export const defaultCatConfig = [ export const defaultCatConfig = [
{ {
type: FormType.input, type: FormType.input,
label: "分类名称", label: "分类名称",

View File

@ -1,6 +1,7 @@
import { FormType } from "@/components/form/interface"; import { FormType } from "@/components/form/interface";
import { UserDataType } from "@/model/userModel"; import { UserDataType } from "@/model/userModel";
import { ColumnsType } from "antd/lib/table"; import { ColumnsType } from "antd/lib/table";
import dayjs from "dayjs";
export const columns: ColumnsType<UserDataType> = [ export const columns: ColumnsType<UserDataType> = [
{ {
title: "物资名称", title: "物资名称",
@ -13,6 +14,7 @@ export const columns: ColumnsType<UserDataType> = [
{ {
title: "过期时间", title: "过期时间",
dataIndex: "expiry_date", dataIndex: "expiry_date",
render: (expiry_date) => <>{ <span>{dayjs(expiry_date).format("YYYY-MM-DD")}</span>}</>,
}, },
{ {
title: "货架名称", title: "货架名称",

View File

@ -160,6 +160,13 @@ const Patrol = (props: Store) => {
value: "", value: "",
rules: [{ required: true, message: "请输入任务积分!" }], rules: [{ required: true, message: "请输入任务积分!" }],
}, },
{
type: FormType.treeVideo,
label: "视频地址",
name: "task_video",
value: [],
rules: [{ required: true, message: "请选择视频地址!" }],
},
// { // {
// type: FormType.cehckboxGroup, // type: FormType.cehckboxGroup,
// label: "任务参与人", // label: "任务参与人",

View File

@ -83,7 +83,7 @@ const PatrolBrigade = (props: Store) => {
</Button> </Button>
</Space> </Space>
<BTable <BTable
store={usrStore} store={patrolBrigadeStore}
scroll={{ x: "max-content" }} scroll={{ x: "max-content" }}
columns={[ columns={[
...columns, ...columns,

View File

@ -0,0 +1,21 @@
import base from "@/service/base";
import { QRCode, Space } from "antd";
import { useEffect, useState } from "react";
const ErCode = () => {
const [url, setUrl] = useState("");
useEffect(() => {
base.gets("/sys/version", {}).then((res) => {
setUrl(res.data.record.url);
});
}, []);
return (
<div>
<Space direction="vertical" align="center">
<QRCode value={url} />
</Space>
</div>
);
};
export default ErCode;

View File

@ -1,6 +1,7 @@
import { Tabs, TabsProps } from "antd"; import { Tabs, TabsProps } from "antd";
import Banner from "./banner"; import Banner from "./banner";
import Dict from "./dict"; import Dict from "./dict";
import ErCode from "./er_code";
const SystemPage = () => { const SystemPage = () => {
const items: TabsProps["items"] = [ const items: TabsProps["items"] = [
@ -14,6 +15,11 @@ const SystemPage = () => {
label: "数据字典", label: "数据字典",
children: <Dict />, children: <Dict />,
}, },
{
key: "3",
label: "app二维码",
children: <ErCode />,
},
]; ];
return ( return (
<> <>

View File

@ -94,7 +94,7 @@ const TeamMgmt = (props: Store) => {
/> />
<Modal <Modal
title={!record?.id ? "添加团队" : "编辑团队"} title={!record?.id ? "添加团队" : "编辑团队"}
width={1200} width={600}
open={isModalOpen} open={isModalOpen}
afterClose={() => formRef.current?.resetFields()} afterClose={() => formRef.current?.resetFields()}
onOk={() => formRef.current?.submit()} onOk={() => formRef.current?.submit()}

View File

@ -3,11 +3,11 @@ import { UserDataType } from "@/model/userModel";
import { ColumnsType } from "antd/lib/table"; import { ColumnsType } from "antd/lib/table";
export const columns: ColumnsType<UserDataType> = [ export const columns: ColumnsType<UserDataType> = [
{ {
title: "团队属性名称", title: "团队名称",
dataIndex: "name", dataIndex: "name",
}, },
{ {
title: "团队属性描述", title: "团队描述",
dataIndex: "desc", dataIndex: "desc",
}, },
]; ];
@ -15,14 +15,14 @@ export const columns: ColumnsType<UserDataType> = [
export const defaultConfig = [ export const defaultConfig = [
{ {
type: FormType.input, type: FormType.input,
label: "团队属性名称", label: "团队名称",
name: "name", name: "name",
value: "", value: "",
rules: [{ required: true, message: "请输入仓库名称!" }], rules: [{ required: true, message: "请输入仓库名称!" }],
}, },
{ {
type: FormType.input, type: FormType.input,
label: "团队属性描述", label: "团队描述",
name: "desc", name: "desc",
value: "", value: "",
rules: [{ required: true, message: "请输入仓库位置信息!" }], rules: [{ required: true, message: "请输入仓库位置信息!" }],

View File

@ -34,11 +34,9 @@ const TaskArchives = (props: TaskArchivesProps) => {
const formRef = React.useRef<FormInstance>(null); const formRef = React.useRef<FormInstance>(null);
const getFolderList = () => { const getFolderList = () => {
folderStore folderStore?.getFolderList(category_identity).then((res) => {
?.getFolderList(category_identity) setfolderList(res?.data?.record ?? []);
.then((res) => { });
setfolderList(res?.data?.record ?? []);
});
}; };
const onFinish = async (values: any) => { const onFinish = async (values: any) => {
let data = values; let data = values;
@ -51,8 +49,8 @@ const TaskArchives = (props: TaskArchivesProps) => {
}; };
const save = async () => { const save = async () => {
let imlist = imageList let imlist = imageList;
imlist.forEach(element => { imlist.forEach((element) => {
element.file_url = element.url; element.file_url = element.url;
element.file_name = element.name; element.file_name = element.name;
}); });
@ -62,15 +60,15 @@ const TaskArchives = (props: TaskArchivesProps) => {
list: imlist, list: imlist,
category_identity: category_identity, category_identity: category_identity,
}; };
await trainingStore?.addAcieves(data); await trainingStore?.addAcieves(data);
message.success("档案已保存到当前文件夹"); message.success("档案已保存到当前文件夹");
}; };
const handleSelect = async (identity) => { const handleSelect = async (identity) => {
await folderStore?.getAlist(identity).then(() => { await folderStore?.getAlist(identity).then(() => {
folderStore.alist?.forEach(elem=>{ folderStore.alist?.forEach((elem) => {
elem.url = elem.file_url elem.url = elem.file_url;
elem.name = elem.file_name elem.name = elem.file_name;
}) });
setImageList(folderStore.alist ?? []); setImageList(folderStore.alist ?? []);
}); });
setIdentity(identity); setIdentity(identity);

View File

@ -7,6 +7,7 @@ import {
Select, Select,
InputNumber, InputNumber,
SelectProps, SelectProps,
message,
} from "antd"; } from "antd";
import { inject, observer } from "mobx-react"; import { inject, observer } from "mobx-react";
import type { ColumnsType } from "antd/es/table"; import type { ColumnsType } from "antd/es/table";
@ -39,20 +40,31 @@ const Trainings = (props: Store) => {
const [data, setData] = useState<SelectProps["options"]>([]); const [data, setData] = useState<SelectProps["options"]>([]);
const columns: ColumnsType<UserDataType> = [ const columns: ColumnsType<UserDataType> = [
{ title: "任务标题", dataIndex: "title" ,width:200}, { title: "任务标题", dataIndex: "title", width: 200 },
{ title: "任务描述", dataIndex: "desc" ,width:200}, { title: "任务描述", dataIndex: "desc", width: 200 },
{ title: "任务地点", dataIndex: "address" ,width:200}, { title: "任务地点", dataIndex: "address", width: 200 },
{ title: "任务开始时间", dataIndex: "start_time" ,width:200}, { title: "任务开始时间", dataIndex: "start_time", width: 200 },
{ title: "任务结束时间", dataIndex: "end_time" ,width:200}, { title: "任务结束时间", dataIndex: "end_time", width: 200 },
{ title: "任务积分设置", dataIndex: "score" ,width:200}, { title: "任务积分设置", dataIndex: "score", width: 200 },
{ title: "任务类别", dataIndex: "category_name",width:200 }, { title: "任务类别", dataIndex: "category_name", width: 200 },
{ title: "任务状态", dataIndex: "status",render: (status) => status===2?"已完成":"未完成",width:200}, {
{ title: "物资归还状态",width:200, dataIndex: "supplies_status",render: (supplies_status) => supplies_status===2?"已归还":"未归还"}, title: "任务状态",
dataIndex: "status",
render: (status) => (status === 2 ? "已完成" : "未完成"),
width: 200,
},
{
title: "物资归还状态",
width: 200,
dataIndex: "supplies_status",
render: (supplies_status) =>
supplies_status === 2 ? "已归还" : "未归还",
},
{ {
title: "操作", title: "操作",
dataIndex: "id", dataIndex: "id",
width:200, width: 200,
fixed:"right", fixed: "right",
render: (any, record) => ( render: (any, record) => (
<Space wrap> <Space wrap>
<Button <Button
@ -64,17 +76,17 @@ const Trainings = (props: Store) => {
> >
</Button> </Button>
{ {record.status !== 2 ? (
record.status !==2 ?<Button <Button
type="dashed" type="dashed"
size="small" size="small"
onClick={() => { onClick={() => {
trainingStore.fish(record.identity); trainingStore.fish(record.identity);
}} }}
> >
</Button>:null </Button>
} ) : null}
<Button <Button
type="dashed" type="dashed"
danger danger
@ -99,18 +111,17 @@ const Trainings = (props: Store) => {
taskId={record?.identity} taskId={record?.identity}
category_identity={record.archives_category_identity} category_identity={record.archives_category_identity}
/> />
{ {record.supplies_status === 1 ? (
record.supplies_status===1 ?<Button <Button
type="dashed" type="dashed"
size="small" size="small"
onClick={() => { onClick={() => {
trainingStore.back(record?.identity,2); trainingStore.back(record?.identity, 2);
}} }}
> >
</Button>:null </Button>
} ) : null}
</Space> </Space>
), ),
}, },
@ -141,7 +152,6 @@ const Trainings = (props: Store) => {
setId(record.id); setId(record.id);
}; };
useEffect(() => { useEffect(() => {
trainingStore.getlist(); trainingStore.getlist();
}, [trainingStore]); }, [trainingStore]);
@ -149,10 +159,10 @@ const Trainings = (props: Store) => {
trainingCatStore.getlist().then(() => { trainingCatStore.getlist().then(() => {
setStash(trainingCatStore.list); setStash(trainingCatStore.list);
}); });
baseHttp.get("/user/list", null).then((res) => { baseHttp.get("/team/list", null).then((res) => {
let data = res.data?.record ?? []; let data = res.data?.record ?? [];
data.forEach((item) => { data.forEach((item) => {
item.label = item.user_name; item.label = item.name;
item.value = item.identity; item.value = item.identity;
}); });
setUserList(data ?? []); setUserList(data ?? []);
@ -160,11 +170,32 @@ const Trainings = (props: Store) => {
}, [trainingCatStore]); }, [trainingCatStore]);
const onFinish = (values: any) => { const onFinish = (values: any) => {
let task_video: any = [];
for (let i = 0; i < values.task_video.length; i++) {
let item = values.task_video[i];
task_video.push({
device: item.split("-")[0],
channel: item.split("-")[1],
});
}
if (!task_video || task_video.length === 0) {
message.error("请选择视频设备");
return;
}
if (values.score === 0 || values.score === null) {
message.error("请完善训练积分");
return;
}
if (values.count === 0 || values.count === null) {
message.error("请完善训练次数");
return;
}
let data = { let data = {
...values, ...values,
score: Number(values.score), score: Number(values.score),
count: Number(values.count), count: Number(values.count),
}; };
data.task_video = task_video;
if (!tagId) { if (!tagId) {
trainingStore.add(data); trainingStore.add(data);
} else { } else {
@ -193,11 +224,11 @@ const Trainings = (props: Store) => {
...traningConfig, ...traningConfig,
{ {
type: FormType.cehckboxGroup, type: FormType.cehckboxGroup,
label: "参与人员选择", label: "参与队伍选择",
name: "user_id", name: "team_id",
value: [], value: [],
checkboxData: userList, checkboxData: userList,
rules: [{ required: true, message: "请选择参与人员!" }], rules: [{ required: true, message: "请选择参与队伍!" }],
}, },
]); ]);
setId(null); setId(null);

View File

@ -49,5 +49,11 @@ export const traningConfig = [
value: 0, value: 0,
rules: [{ required: true, message: "请输入训练次数!" }], rules: [{ required: true, message: "请输入训练次数!" }],
}, },
{
type: FormType.treeVideo,
label: "视频地址",
name: "task_video",
value: [],
rules: [{ required: true, message: "请选择视频地址!" }],
},
]; ];

View File

@ -2,7 +2,7 @@ import { FormType } from "@/components/form/interface";
import { UserDataType } from "@/model/userModel"; import { UserDataType } from "@/model/userModel";
import { ColumnsType } from "antd/lib/table"; import { ColumnsType } from "antd/lib/table";
import { Image } from "antd"; import { Image } from "antd";
import Config from "@/util/config"; import { getAgeByIDCard, getBirthDateAndGender } from "@/util/util";
export const defaultConfig =(team,per)=> export const defaultConfig =(team,per)=>
[ [
{ {
@ -92,6 +92,7 @@ export const defaultConfig =(team,per)=>
label: "身份证", label: "身份证",
name: "id_card", name: "id_card",
value: "", value: "",
rules: [{ required: true, message: "请输入身份证" }],
}, },
{ {
type: FormType.input, type: FormType.input,
@ -221,7 +222,6 @@ export const defaultConfig =(team,per)=>
label: "头像", label: "头像",
name: "head_img", name: "head_img",
value: [], value: [],
// rules: [{ required: true, message: "请上传头像" }],
}, },
]; ];
@ -234,21 +234,20 @@ export const columns: ColumnsType<UserDataType> = [
}, },
{ {
title: "性别", title: "性别",
dataIndex: "sex",
width: 150, width: 150,
render: (sex) => <span>{sex === 1 ? "男" : "女"}</span>, render: (render) => <span>{getBirthDateAndGender(render.id_card)?.gender}</span>,
}, },
{ {
title: "年龄", title: "年龄",
width: 150, width: 150,
dataIndex: "age", render: (render) => <span>{getAgeByIDCard(render.id_card)}</span>,
}, },
{ {
title: "头像", title: "头像",
dataIndex: "head_img", dataIndex: "head_img",
width: 150, width: 150,
render: (headImg) =>{ render: (head_img) =>{
return <Image src={Config.userStatic+headImg+'.jpg'}></Image> return <Image src={head_img}></Image>
}, },
}, },

View File

@ -9,17 +9,23 @@ class ExceCompetConfig {
static ADD: string = "exceCompet" static ADD: string = "exceCompet"
static DELETE: string = "exceCompet" static DELETE: string = "exceCompet"
static EDIT: string = "exceCompet" static EDIT: string = "exceCompet"
static Audit: string = "exceCompet/audit"
} }
class ExceCompetStore extends BaseStore<TagDataType> { class ExceCompetStore extends BaseStore<TagDataType> {
constructor() { constructor() {
super(ExceCompetConfig) super(ExceCompetConfig)
makeObservable(this, { makeObservable(this, {
save: action save: action,
audit: action
}) })
} }
async audit(id: string, param: Object) {
await baseHttp.put(ExceCompetConfig.Audit + "/" + id, param)
this.getlist();
}
async save(id: string, list: Array<any>) { async save(id: string, list: Array<any>) {
return await baseHttp.post(ExceCompetConfig.ADD +"/"+ id, {"list":list}); return await baseHttp.post(ExceCompetConfig.ADD + "/" + id, { "list": list });
} }
} }
export const exceCompetStore = new ExceCompetStore() export const exceCompetStore = new ExceCompetStore()

View File

@ -74,7 +74,7 @@ class HomeStore extends BaseStore<TagDataType> {
let data = await baseHttp.gets(Config.videoApi + HomeConfig.channerList, { let data = await baseHttp.gets(Config.videoApi + HomeConfig.channerList, {
start: 0, start: 0,
limit: 30, limit: 30,
device:deviceId device: deviceId
}) })
return data; return data;
} catch (error) { } catch (error) {
@ -83,14 +83,13 @@ class HomeStore extends BaseStore<TagDataType> {
} }
} }
// 获取通道流 // 获取通道流
async getChannerStrem(deviceId,channel) { async getChannerStrem(deviceId, channel) {
try { try {
let data = await baseHttp.gets(Config.videoApi + HomeConfig.channelstream, { let data = await baseHttp.gets(Config.videoApi + HomeConfig.channelstream, {
device:deviceId, device: deviceId,
channel:channel, channel: channel,
protocol:"HLS" protocol: "HLS"
}) })
console.log(data)
return data; return data;
} catch (error) { } catch (error) {
console.log(error) console.log(error)
@ -98,10 +97,20 @@ class HomeStore extends BaseStore<TagDataType> {
} }
} }
async getNewTask() { async getNewTask() {
let res = await baseHttp.get(HomeConfig.newTask, {}); let urls: any = []
if (res.data?.record) { try {
this.getTaskUserList() let res = await baseHttp.get(HomeConfig.newTask, {});
this.showVideoHandler(true) if (res.data?.record) {
for await (const element of res.data?.record.videos) {
let res = await this.getChannerStrem(element.device, element.channel)
urls.push(Config.videoApis + res.EasyDarwin?.Body.URL)
}
this.getTaskUserList()
this.showVideoHandler(true)
}
return urls;
} catch (error) {
return []
} }
} }
async getTaskUserList() { async getTaskUserList() {
@ -109,8 +118,8 @@ class HomeStore extends BaseStore<TagDataType> {
if (res.data?.record?.ulist && res.data?.record.ulist.length > 0) { if (res.data?.record?.ulist && res.data?.record.ulist.length > 0) {
res.data?.record?.ulist.forEach(element => { res.data?.record?.ulist.forEach(element => {
MapUtl.addMaker({ MapUtl.addMaker({
lng: element.long, lng: element.long ?? 116.478935,
lat: element.lat, lat: element.lat ?? 39.997761,
title: element.user_name, title: element.user_name,
users: element users: element
}) })

View File

@ -9,6 +9,7 @@ class SysConfig {
static ADDBanner: string = "sys/banner" static ADDBanner: string = "sys/banner"
static LIST: string = "sys/drop" static LIST: string = "sys/drop"
static ADD: string = "sys/drop" static ADD: string = "sys/drop"
static DELETE: string = "sys/drop"
} }
class SysStore extends BaseStore<TagDataType> { class SysStore extends BaseStore<TagDataType> {
constructor() { constructor() {

View File

@ -1,8 +1,8 @@
class Config { class Config {
static baseUrl = "http://127.0.0.1:12214/"; static baseUrl = "https://www.hswzct.cn:12016/";
static uploadUrl = "https://rw.quwanya.cn"; static uploadUrl = "https://www.hswzct.cn:12016";
static ws = "wss://rw.quwanya.cn/wsadmin?id=admin"; static ws = "wss://www.hswzct.cn:12016/wsadmin?id=admin";
static userStatic = "https://rw.quwanya.cn/uploads/user/"; static userStatic = "https://hswzct.cn:12016/uploads/user/";
static videoApi = "https://sprh.hswzct.cn:4443/"; // static videoApi = "https://sprh.hswzct.cn:4443/"; //
static videoApis = "https://sprh.hswzct.cn:4443"; // static videoApis = "https://sprh.hswzct.cn:4443"; //
} }

19
src/util/util.ts Normal file
View File

@ -0,0 +1,19 @@
function getBirthDateAndGender(idNumber) {
if (idNumber && idNumber.length === 18) {
const birthDate = idNumber.substring(6, 14);
const gender = parseInt(idNumber.substring(16, 17), 10) % 2 === 0 ? '女' : '男';
return { birthDate, gender };
}
return null;
}
function getAgeByIDCard(idCard) {
if(!idCard)return 0
const birthYear = idCard.substring(6, 10);
const currentYear = new Date().getFullYear();
const age = currentYear - parseInt(birthYear);
return age;
}
export { getAgeByIDCard, getBirthDateAndGender }