first commit
This commit is contained in:
parent
2a8e134fd4
commit
5afd6e3933
|
@ -13,6 +13,7 @@ export enum FormType {
|
|||
cehckbox = "checkbox",
|
||||
cehckboxGroup = "checkboxGroup",
|
||||
password = "password",
|
||||
treeVideo = "treeVideo",
|
||||
fetchList = "fetchList",
|
||||
}
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ import { FormSelect } from "./select";
|
|||
import AliUpload from "../ali_upload";
|
||||
import MyEditor from "../edittor";
|
||||
import MapFrom from "../map/MapFrom";
|
||||
import VideoSelect from "../video_select";
|
||||
const { TextArea } = Input;
|
||||
const SimpleForm = (props: SimpleFormData) => {
|
||||
const [form] = Form.useForm();
|
||||
|
@ -104,6 +105,21 @@ const SimpleForm = (props: SimpleFormData) => {
|
|||
/>
|
||||
</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:
|
||||
return FormSelect(v);
|
||||
case FormType.upload:
|
||||
|
|
|
@ -10,7 +10,7 @@ class MapUtl {
|
|||
|
||||
static addMaker(data: any) {
|
||||
const { lng, lat, title, users } = data;
|
||||
if (MapUtl.loadMap === null) return;
|
||||
// if (MapUtl.loadMap === null) return;
|
||||
const marker = new MapUtl.loadMap.Marker({
|
||||
position: new MapUtl.loadMap.LngLat(lng, lat),
|
||||
title: title,
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
// 档案管理
|
||||
|
||||
import {
|
||||
Button,
|
||||
Space,
|
||||
|
@ -9,6 +8,8 @@ import {
|
|||
Tree,
|
||||
Row,
|
||||
Col,
|
||||
Popconfirm,
|
||||
PopconfirmProps,
|
||||
} from "antd";
|
||||
import { inject, observer } from "mobx-react";
|
||||
import { useEffect, useState } from "react";
|
||||
|
@ -71,6 +72,9 @@ const ArchivesFolder = (props: Store) => {
|
|||
setFolderId(info.node.identity);
|
||||
};
|
||||
|
||||
const cancel: PopconfirmProps['onCancel'] = (e) => {
|
||||
console.log(e);
|
||||
};
|
||||
const onExpand: DirectoryTreeProps["onExpand"] = (keys, info) => {
|
||||
// console.log("Trigger Expand", keys, info);
|
||||
};
|
||||
|
@ -96,6 +100,7 @@ const ArchivesFolder = (props: Store) => {
|
|||
return (
|
||||
<>
|
||||
{nodeData.folder_name}
|
||||
<Space>
|
||||
<span
|
||||
style={{ marginLeft: "10px", color: "blue" }}
|
||||
onClick={(e) => {
|
||||
|
@ -107,15 +112,21 @@ const ArchivesFolder = (props: Store) => {
|
|||
>
|
||||
新建
|
||||
</span>
|
||||
<span
|
||||
style={{ marginLeft: "10px", color: "red" }}
|
||||
onClick={(e) => {
|
||||
e?.stopPropagation();
|
||||
<Popconfirm
|
||||
title="Delete the task"
|
||||
description="Are you sure to delete this task?"
|
||||
onConfirm={()=>{
|
||||
remove(nodeData.id);
|
||||
}}
|
||||
onCancel={cancel}
|
||||
okText="Yes"
|
||||
cancelText="No"
|
||||
>
|
||||
删除
|
||||
</span>
|
||||
<Button danger variant="solid" size="small">删除</Button>
|
||||
</Popconfirm>
|
||||
</Space>
|
||||
|
||||
|
||||
</>
|
||||
);
|
||||
}}
|
||||
|
|
|
@ -2,6 +2,7 @@ import {
|
|||
Button,
|
||||
message,
|
||||
Modal,
|
||||
Popconfirm,
|
||||
Space,
|
||||
Upload,
|
||||
UploadFile,
|
||||
|
@ -38,10 +39,13 @@ const FileListPage = (props: any) => {
|
|||
}
|
||||
},
|
||||
};
|
||||
useEffect(() => {
|
||||
const getFileList =()=>{
|
||||
folderStore.getAlist(id).then((res) => {
|
||||
setFileList(folderStore.alist);
|
||||
});
|
||||
}
|
||||
useEffect(() => {
|
||||
getFileList()
|
||||
}, [folderStore, id]);
|
||||
const getFileTypeFromUrl = (url) => {
|
||||
if (url === "" || url.length === 0) return;
|
||||
|
@ -120,10 +124,7 @@ const FileListPage = (props: any) => {
|
|||
</div>
|
||||
{fileList?.map((item: any) => {
|
||||
return (
|
||||
<div
|
||||
key={item?.identity}
|
||||
style={{ display: "flex", margin: "10px" }}
|
||||
>
|
||||
<div key={item?.identity} style={{ display: "flex", margin: "10px" }}>
|
||||
<Space>
|
||||
<span className="text-overflow"> {item?.file_name}</span>
|
||||
<Button
|
||||
|
@ -134,7 +135,24 @@ const FileListPage = (props: any) => {
|
|||
>
|
||||
预览
|
||||
</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>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -31,9 +31,16 @@ export const EmConfig = (userList) => [
|
|||
{
|
||||
type: FormType.cehckboxGroup,
|
||||
label: "参与队伍",
|
||||
name: "user_id",
|
||||
name: "team_id",
|
||||
value: [],
|
||||
checkboxData: userList,
|
||||
rules: [{ required: true, message: "参与队伍不能为空!" }],
|
||||
},
|
||||
{
|
||||
type: FormType.treeVideo,
|
||||
label: "视频地址",
|
||||
name: "task_video",
|
||||
value: [],
|
||||
rules: [{ required: true, message: "请选择视频地址!" }],
|
||||
},
|
||||
];
|
||||
|
|
|
@ -147,10 +147,10 @@ const Emergency = (props: Store) => {
|
|||
};
|
||||
useEffect(() => {
|
||||
emergencyStore.getlist();
|
||||
baseHttp.get("/user/list", null).then((res) => {
|
||||
baseHttp.get("/team/list", null).then((res) => {
|
||||
let data = res.data?.record ?? [];
|
||||
data.forEach((item) => {
|
||||
item.label = item.user_name;
|
||||
item.label = item.name;
|
||||
item.value = item.identity;
|
||||
});
|
||||
setUserList(data ?? []);
|
||||
|
|
|
@ -1,13 +1,18 @@
|
|||
import BTable from "@/components/b_table";
|
||||
import { UserDataType } from "@/model/userModel";
|
||||
import { Button } from "antd";
|
||||
import { Button, message, Modal, Space } from "antd";
|
||||
import { Store } from "antd/es/form/interface";
|
||||
import TextArea from "antd/lib/input/TextArea";
|
||||
import { ColumnsType } from "antd/lib/table";
|
||||
import dayjs from "dayjs";
|
||||
import { inject, observer } from "mobx-react";
|
||||
import { useEffect } from "react";
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
const ExceCompet = (props: Store) => {
|
||||
const { exceCompetStore } = props;
|
||||
const [isModalOpen, setIsModalOpen] = useState(false);
|
||||
const [value, setValue] = useState('');
|
||||
const [id, setId] = useState('');
|
||||
useEffect(() => {
|
||||
exceCompetStore.getlist();
|
||||
}, [exceCompetStore]);
|
||||
|
@ -17,29 +22,73 @@ const ExceCompet = (props: Store) => {
|
|||
{
|
||||
title: "评优申请人",
|
||||
dataIndex: "users",
|
||||
render: (users) => <span>{users?.user_name}</span>
|
||||
render: (users) => <span>{users?.user_name}</span>,
|
||||
},
|
||||
{ title: "申请积分", dataIndex: "reviewer_score" },
|
||||
{ title: "申请时间", dataIndex: "created_at" },
|
||||
{
|
||||
title: "申请时间",
|
||||
dataIndex: "created_at",
|
||||
render: (created_at) => (
|
||||
<span>{dayjs(created_at).format("YYYY-MM-DD")}</span>
|
||||
),
|
||||
},
|
||||
{ title: "描述", dataIndex: "desc" },
|
||||
{ title: "审核状态", dataIndex: "status" },
|
||||
{ title: "审核人", dataIndex: "reviewer_identity" },
|
||||
{
|
||||
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: "id",
|
||||
render: (any, record) => (
|
||||
dataIndex: "identity",
|
||||
render: (any, record) =>
|
||||
record.status === 0 ? (
|
||||
<Space>
|
||||
<Button
|
||||
type="dashed"
|
||||
size="small"
|
||||
onClick={() => {
|
||||
// edit(record);
|
||||
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 (
|
||||
<div>
|
||||
<BTable
|
||||
|
@ -47,6 +96,14 @@ const ExceCompet = (props: Store) => {
|
|||
columns={columns}
|
||||
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>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -152,8 +152,7 @@
|
|||
|
||||
.map_video_container {
|
||||
position: absolute;
|
||||
width: 300px;
|
||||
height: 300px;
|
||||
top: 60px;
|
||||
width: 350px;
|
||||
top: 70px;
|
||||
right: 300px;
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ import { SettingOutlined } from "@ant-design/icons";
|
|||
import { useNavigate } from "react-router";
|
||||
import Weather from "./homeLeft/weather";
|
||||
import Timer from "./homeLeft/timer";
|
||||
import HomeVideo from "./home_video";
|
||||
|
||||
const Home = observer(() => {
|
||||
const navigate = useNavigate();
|
||||
|
@ -47,7 +48,7 @@ const Home = observer(() => {
|
|||
</div>
|
||||
<MapContainer />
|
||||
<div className="map_video_container">
|
||||
{/* <Video /> */}
|
||||
<HomeVideo />
|
||||
</div>
|
||||
<div className="map_container_r">
|
||||
<HomeRight />
|
||||
|
|
|
@ -5,11 +5,12 @@ import {
|
|||
Form,
|
||||
FormInstance,
|
||||
InputNumber,
|
||||
message,
|
||||
Modal,
|
||||
Select,
|
||||
SelectProps,
|
||||
} from "antd";
|
||||
import React from "react";
|
||||
import React, { useEffect } from "react";
|
||||
import { useState } from "react";
|
||||
import baseHttp from "@/service/base";
|
||||
import "./bot.less";
|
||||
|
@ -34,27 +35,36 @@ const Dispath = (props: Store) => {
|
|||
...traningConfig,
|
||||
{
|
||||
type: FormType.cehckboxGroup,
|
||||
label: "参与人员选择",
|
||||
name: "user_id",
|
||||
label: "参与队伍",
|
||||
name: "trem_id",
|
||||
value: [],
|
||||
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 () => {
|
||||
try {
|
||||
trainingCatStore.getlist().then(() => {
|
||||
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) {
|
||||
console.log(error);
|
||||
}
|
||||
|
@ -67,11 +77,32 @@ const Dispath = (props: Store) => {
|
|||
};
|
||||
|
||||
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 = {
|
||||
...values,
|
||||
score: Number(values.score),
|
||||
count: Number(values.count),
|
||||
};
|
||||
data.task_video = task_video;
|
||||
trainingStore.add(data);
|
||||
setIsModalOpen(false);
|
||||
};
|
||||
|
@ -98,9 +129,7 @@ const Dispath = (props: Store) => {
|
|||
centered
|
||||
width={1000}
|
||||
open={isModalOpen}
|
||||
afterClose={() => {
|
||||
|
||||
}}
|
||||
afterClose={() => {}}
|
||||
onOk={() => {}}
|
||||
okText="确定"
|
||||
cancelText="取消"
|
||||
|
@ -122,7 +151,10 @@ const Dispath = (props: Store) => {
|
|||
setIsModalOpen(false);
|
||||
}}
|
||||
>
|
||||
<div className="disPatch" style={{ fontSize: "#fff",height:"600px",overflowY:"auto" }}>
|
||||
<div
|
||||
className="disPatch"
|
||||
style={{ fontSize: "#fff", height: "600px", overflowY: "auto" }}
|
||||
>
|
||||
<SimpleForm
|
||||
formRef={formRef}
|
||||
createCallback={() => {}}
|
||||
|
|
|
@ -15,7 +15,6 @@ import baseHttp from "@/service/base";
|
|||
import MinusCircleOutlined from "@ant-design/icons/lib/icons/MinusCircleOutlined";
|
||||
import { EmConfig } from "@/pages/emergency/em_column";
|
||||
import { inject, observer } from "mobx-react";
|
||||
import VideoSelect from "@/components/video_select";
|
||||
|
||||
const Emr = (props: Store) => {
|
||||
const { emergencyStore, homeStore } = props;
|
||||
|
@ -36,8 +35,15 @@ const Emr = (props: Store) => {
|
|||
long: values.marker["lng"],
|
||||
lat: values.marker["lat"],
|
||||
};
|
||||
console.log(data);
|
||||
return;
|
||||
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],
|
||||
});
|
||||
}
|
||||
data.task_video = task_video;
|
||||
emergencyStore.add(data);
|
||||
setIsModalOpen(false);
|
||||
homeStore.getNewTask();
|
||||
|
@ -159,18 +165,6 @@ const Emr = (props: Store) => {
|
|||
</>
|
||||
)}
|
||||
</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>
|
||||
</div>
|
||||
|
|
|
@ -25,7 +25,6 @@ const WhichVideo = (props) => {
|
|||
let reqs = await homeStore.getChannerStrem(deviceId, id);
|
||||
if (!reqs.EasyDarwin) return;
|
||||
let url = Config.videoApis + reqs.EasyDarwin.Body.URL
|
||||
console.log(url)
|
||||
setVideoUrl(url);
|
||||
};
|
||||
return (
|
||||
|
|
|
@ -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 (
|
||||
<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));
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
.homeVideoBox{
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
|
@ -28,7 +28,7 @@ export const leaveColumns: ColumnsType<UserDataType> = [
|
|||
},
|
||||
{
|
||||
title: "驳回原因",
|
||||
dataIndex: "reject",
|
||||
dataIndex: "reject_mark",
|
||||
},
|
||||
{
|
||||
title: "审批人",
|
||||
|
@ -56,7 +56,7 @@ export const defaultConfig = [
|
|||
{
|
||||
type: FormType.input,
|
||||
label: "驳回原因",
|
||||
name: "reject",
|
||||
name: "reject_mark",
|
||||
value: "",
|
||||
rules: [{ required: true, message: "请输入驳回原因!" }],
|
||||
},
|
||||
|
@ -64,7 +64,6 @@ export const defaultConfig = [
|
|||
|
||||
|
||||
export const defaultCatConfig = [
|
||||
|
||||
{
|
||||
type: FormType.input,
|
||||
label: "分类名称",
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { FormType } from "@/components/form/interface";
|
||||
import { UserDataType } from "@/model/userModel";
|
||||
import { ColumnsType } from "antd/lib/table";
|
||||
import dayjs from "dayjs";
|
||||
export const columns: ColumnsType<UserDataType> = [
|
||||
{
|
||||
title: "物资名称",
|
||||
|
@ -13,6 +14,7 @@ export const columns: ColumnsType<UserDataType> = [
|
|||
{
|
||||
title: "过期时间",
|
||||
dataIndex: "expiry_date",
|
||||
render: (expiry_date) => <>{ <span>{dayjs(expiry_date).format("YYYY-MM-DD")}</span>}</>,
|
||||
},
|
||||
{
|
||||
title: "货架名称",
|
||||
|
|
|
@ -160,6 +160,13 @@ const Patrol = (props: Store) => {
|
|||
value: "",
|
||||
rules: [{ required: true, message: "请输入任务积分!" }],
|
||||
},
|
||||
{
|
||||
type: FormType.treeVideo,
|
||||
label: "视频地址",
|
||||
name: "task_video",
|
||||
value: [],
|
||||
rules: [{ required: true, message: "请选择视频地址!" }],
|
||||
},
|
||||
// {
|
||||
// type: FormType.cehckboxGroup,
|
||||
// label: "任务参与人",
|
||||
|
|
|
@ -83,7 +83,7 @@ const PatrolBrigade = (props: Store) => {
|
|||
</Button>
|
||||
</Space>
|
||||
<BTable
|
||||
store={usrStore}
|
||||
store={patrolBrigadeStore}
|
||||
scroll={{ x: "max-content" }}
|
||||
columns={[
|
||||
...columns,
|
||||
|
|
|
@ -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;
|
|
@ -1,6 +1,7 @@
|
|||
import { Tabs, TabsProps } from "antd";
|
||||
import Banner from "./banner";
|
||||
import Dict from "./dict";
|
||||
import ErCode from "./er_code";
|
||||
|
||||
const SystemPage = () => {
|
||||
const items: TabsProps["items"] = [
|
||||
|
@ -14,6 +15,11 @@ const SystemPage = () => {
|
|||
label: "数据字典",
|
||||
children: <Dict />,
|
||||
},
|
||||
{
|
||||
key: "3",
|
||||
label: "app二维码",
|
||||
children: <ErCode />,
|
||||
},
|
||||
];
|
||||
return (
|
||||
<>
|
||||
|
|
|
@ -94,7 +94,7 @@ const TeamMgmt = (props: Store) => {
|
|||
/>
|
||||
<Modal
|
||||
title={!record?.id ? "添加团队" : "编辑团队"}
|
||||
width={1200}
|
||||
width={600}
|
||||
open={isModalOpen}
|
||||
afterClose={() => formRef.current?.resetFields()}
|
||||
onOk={() => formRef.current?.submit()}
|
||||
|
|
|
@ -3,11 +3,11 @@ import { UserDataType } from "@/model/userModel";
|
|||
import { ColumnsType } from "antd/lib/table";
|
||||
export const columns: ColumnsType<UserDataType> = [
|
||||
{
|
||||
title: "团队属性名称",
|
||||
title: "团队名称",
|
||||
dataIndex: "name",
|
||||
},
|
||||
{
|
||||
title: "团队属性描述",
|
||||
title: "团队描述",
|
||||
dataIndex: "desc",
|
||||
},
|
||||
];
|
||||
|
@ -15,14 +15,14 @@ export const columns: ColumnsType<UserDataType> = [
|
|||
export const defaultConfig = [
|
||||
{
|
||||
type: FormType.input,
|
||||
label: "团队属性名称",
|
||||
label: "团队名称",
|
||||
name: "name",
|
||||
value: "",
|
||||
rules: [{ required: true, message: "请输入仓库名称!" }],
|
||||
},
|
||||
{
|
||||
type: FormType.input,
|
||||
label: "团队属性描述",
|
||||
label: "团队描述",
|
||||
name: "desc",
|
||||
value: "",
|
||||
rules: [{ required: true, message: "请输入仓库位置信息!" }],
|
||||
|
|
|
@ -34,9 +34,7 @@ const TaskArchives = (props: TaskArchivesProps) => {
|
|||
const formRef = React.useRef<FormInstance>(null);
|
||||
|
||||
const getFolderList = () => {
|
||||
folderStore
|
||||
?.getFolderList(category_identity)
|
||||
.then((res) => {
|
||||
folderStore?.getFolderList(category_identity).then((res) => {
|
||||
setfolderList(res?.data?.record ?? []);
|
||||
});
|
||||
};
|
||||
|
@ -51,8 +49,8 @@ const TaskArchives = (props: TaskArchivesProps) => {
|
|||
};
|
||||
|
||||
const save = async () => {
|
||||
let imlist = imageList
|
||||
imlist.forEach(element => {
|
||||
let imlist = imageList;
|
||||
imlist.forEach((element) => {
|
||||
element.file_url = element.url;
|
||||
element.file_name = element.name;
|
||||
});
|
||||
|
@ -67,10 +65,10 @@ const TaskArchives = (props: TaskArchivesProps) => {
|
|||
};
|
||||
const handleSelect = async (identity) => {
|
||||
await folderStore?.getAlist(identity).then(() => {
|
||||
folderStore.alist?.forEach(elem=>{
|
||||
elem.url = elem.file_url
|
||||
elem.name = elem.file_name
|
||||
})
|
||||
folderStore.alist?.forEach((elem) => {
|
||||
elem.url = elem.file_url;
|
||||
elem.name = elem.file_name;
|
||||
});
|
||||
setImageList(folderStore.alist ?? []);
|
||||
});
|
||||
setIdentity(identity);
|
||||
|
|
|
@ -7,6 +7,7 @@ import {
|
|||
Select,
|
||||
InputNumber,
|
||||
SelectProps,
|
||||
message,
|
||||
} from "antd";
|
||||
import { inject, observer } from "mobx-react";
|
||||
import type { ColumnsType } from "antd/es/table";
|
||||
|
@ -39,20 +40,31 @@ const Trainings = (props: Store) => {
|
|||
const [data, setData] = useState<SelectProps["options"]>([]);
|
||||
|
||||
const columns: ColumnsType<UserDataType> = [
|
||||
{ title: "任务标题", dataIndex: "title" ,width:200},
|
||||
{ title: "任务描述", dataIndex: "desc" ,width:200},
|
||||
{ title: "任务地点", dataIndex: "address" ,width:200},
|
||||
{ title: "任务开始时间", dataIndex: "start_time" ,width:200},
|
||||
{ title: "任务结束时间", dataIndex: "end_time" ,width:200},
|
||||
{ title: "任务积分设置", dataIndex: "score" ,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: "title", width: 200 },
|
||||
{ title: "任务描述", dataIndex: "desc", width: 200 },
|
||||
{ title: "任务地点", dataIndex: "address", width: 200 },
|
||||
{ title: "任务开始时间", dataIndex: "start_time", width: 200 },
|
||||
{ title: "任务结束时间", dataIndex: "end_time", width: 200 },
|
||||
{ title: "任务积分设置", dataIndex: "score", 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: "id",
|
||||
width:200,
|
||||
fixed:"right",
|
||||
width: 200,
|
||||
fixed: "right",
|
||||
render: (any, record) => (
|
||||
<Space wrap>
|
||||
<Button
|
||||
|
@ -64,8 +76,8 @@ const Trainings = (props: Store) => {
|
|||
>
|
||||
编辑
|
||||
</Button>
|
||||
{
|
||||
record.status !==2 ?<Button
|
||||
{record.status !== 2 ? (
|
||||
<Button
|
||||
type="dashed"
|
||||
size="small"
|
||||
onClick={() => {
|
||||
|
@ -73,8 +85,8 @@ const Trainings = (props: Store) => {
|
|||
}}
|
||||
>
|
||||
完成
|
||||
</Button>:null
|
||||
}
|
||||
</Button>
|
||||
) : null}
|
||||
<Button
|
||||
type="dashed"
|
||||
danger
|
||||
|
@ -99,18 +111,17 @@ const Trainings = (props: Store) => {
|
|||
taskId={record?.identity}
|
||||
category_identity={record.archives_category_identity}
|
||||
/>
|
||||
{
|
||||
record.supplies_status===1 ?<Button
|
||||
{record.supplies_status === 1 ? (
|
||||
<Button
|
||||
type="dashed"
|
||||
size="small"
|
||||
onClick={() => {
|
||||
trainingStore.back(record?.identity,2);
|
||||
trainingStore.back(record?.identity, 2);
|
||||
}}
|
||||
>
|
||||
物资归还
|
||||
</Button>:null
|
||||
}
|
||||
|
||||
</Button>
|
||||
) : null}
|
||||
</Space>
|
||||
),
|
||||
},
|
||||
|
@ -141,7 +152,6 @@ const Trainings = (props: Store) => {
|
|||
setId(record.id);
|
||||
};
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
trainingStore.getlist();
|
||||
}, [trainingStore]);
|
||||
|
@ -149,10 +159,10 @@ const Trainings = (props: Store) => {
|
|||
trainingCatStore.getlist().then(() => {
|
||||
setStash(trainingCatStore.list);
|
||||
});
|
||||
baseHttp.get("/user/list", null).then((res) => {
|
||||
baseHttp.get("/team/list", null).then((res) => {
|
||||
let data = res.data?.record ?? [];
|
||||
data.forEach((item) => {
|
||||
item.label = item.user_name;
|
||||
item.label = item.name;
|
||||
item.value = item.identity;
|
||||
});
|
||||
setUserList(data ?? []);
|
||||
|
@ -160,11 +170,32 @@ const Trainings = (props: Store) => {
|
|||
}, [trainingCatStore]);
|
||||
|
||||
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 = {
|
||||
...values,
|
||||
score: Number(values.score),
|
||||
count: Number(values.count),
|
||||
};
|
||||
data.task_video = task_video;
|
||||
if (!tagId) {
|
||||
trainingStore.add(data);
|
||||
} else {
|
||||
|
@ -193,11 +224,11 @@ const Trainings = (props: Store) => {
|
|||
...traningConfig,
|
||||
{
|
||||
type: FormType.cehckboxGroup,
|
||||
label: "参与人员选择",
|
||||
name: "user_id",
|
||||
label: "参与队伍选择",
|
||||
name: "team_id",
|
||||
value: [],
|
||||
checkboxData: userList,
|
||||
rules: [{ required: true, message: "请选择参与人员!" }],
|
||||
rules: [{ required: true, message: "请选择参与队伍!" }],
|
||||
},
|
||||
]);
|
||||
setId(null);
|
||||
|
|
|
@ -49,5 +49,11 @@ export const traningConfig = [
|
|||
value: 0,
|
||||
rules: [{ required: true, message: "请输入训练次数!" }],
|
||||
},
|
||||
|
||||
{
|
||||
type: FormType.treeVideo,
|
||||
label: "视频地址",
|
||||
name: "task_video",
|
||||
value: [],
|
||||
rules: [{ required: true, message: "请选择视频地址!" }],
|
||||
},
|
||||
];
|
|
@ -2,7 +2,7 @@ import { FormType } from "@/components/form/interface";
|
|||
import { UserDataType } from "@/model/userModel";
|
||||
import { ColumnsType } from "antd/lib/table";
|
||||
import { Image } from "antd";
|
||||
import Config from "@/util/config";
|
||||
import { getAgeByIDCard, getBirthDateAndGender } from "@/util/util";
|
||||
export const defaultConfig =(team,per)=>
|
||||
[
|
||||
{
|
||||
|
@ -92,6 +92,7 @@ export const defaultConfig =(team,per)=>
|
|||
label: "身份证",
|
||||
name: "id_card",
|
||||
value: "",
|
||||
rules: [{ required: true, message: "请输入身份证" }],
|
||||
},
|
||||
{
|
||||
type: FormType.input,
|
||||
|
@ -221,7 +222,6 @@ export const defaultConfig =(team,per)=>
|
|||
label: "头像",
|
||||
name: "head_img",
|
||||
value: [],
|
||||
// rules: [{ required: true, message: "请上传头像" }],
|
||||
},
|
||||
];
|
||||
|
||||
|
@ -234,21 +234,20 @@ export const columns: ColumnsType<UserDataType> = [
|
|||
},
|
||||
{
|
||||
title: "性别",
|
||||
dataIndex: "sex",
|
||||
width: 150,
|
||||
render: (sex) => <span>{sex === 1 ? "男" : "女"}</span>,
|
||||
render: (render) => <span>{getBirthDateAndGender(render.id_card)?.gender}</span>,
|
||||
},
|
||||
{
|
||||
title: "年龄",
|
||||
width: 150,
|
||||
dataIndex: "age",
|
||||
render: (render) => <span>{getAgeByIDCard(render.id_card)}岁</span>,
|
||||
},
|
||||
{
|
||||
title: "头像",
|
||||
dataIndex: "head_img",
|
||||
width: 150,
|
||||
render: (headImg) =>{
|
||||
return <Image src={Config.userStatic+headImg+'.jpg'}></Image>
|
||||
render: (head_img) =>{
|
||||
return <Image src={head_img}></Image>
|
||||
},
|
||||
},
|
||||
|
||||
|
|
|
@ -9,17 +9,23 @@ class ExceCompetConfig {
|
|||
static ADD: string = "exceCompet"
|
||||
static DELETE: string = "exceCompet"
|
||||
static EDIT: string = "exceCompet"
|
||||
static Audit: string = "exceCompet/audit"
|
||||
}
|
||||
class ExceCompetStore extends BaseStore<TagDataType> {
|
||||
constructor() {
|
||||
super(ExceCompetConfig)
|
||||
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>) {
|
||||
return await baseHttp.post(ExceCompetConfig.ADD +"/"+ id, {"list":list});
|
||||
return await baseHttp.post(ExceCompetConfig.ADD + "/" + id, { "list": list });
|
||||
}
|
||||
}
|
||||
export const exceCompetStore = new ExceCompetStore()
|
||||
|
|
|
@ -74,7 +74,7 @@ class HomeStore extends BaseStore<TagDataType> {
|
|||
let data = await baseHttp.gets(Config.videoApi + HomeConfig.channerList, {
|
||||
start: 0,
|
||||
limit: 30,
|
||||
device:deviceId
|
||||
device: deviceId
|
||||
})
|
||||
return data;
|
||||
} catch (error) {
|
||||
|
@ -83,14 +83,13 @@ class HomeStore extends BaseStore<TagDataType> {
|
|||
}
|
||||
}
|
||||
// 获取通道流
|
||||
async getChannerStrem(deviceId,channel) {
|
||||
async getChannerStrem(deviceId, channel) {
|
||||
try {
|
||||
let data = await baseHttp.gets(Config.videoApi + HomeConfig.channelstream, {
|
||||
device:deviceId,
|
||||
channel:channel,
|
||||
protocol:"HLS"
|
||||
device: deviceId,
|
||||
channel: channel,
|
||||
protocol: "HLS"
|
||||
})
|
||||
console.log(data)
|
||||
return data;
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
|
@ -98,19 +97,29 @@ class HomeStore extends BaseStore<TagDataType> {
|
|||
}
|
||||
}
|
||||
async getNewTask() {
|
||||
let urls: any = []
|
||||
try {
|
||||
let res = await baseHttp.get(HomeConfig.newTask, {});
|
||||
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() {
|
||||
let res = await baseHttp.get(HomeConfig.taskulist, {});
|
||||
if (res.data?.record?.ulist && res.data?.record.ulist.length > 0) {
|
||||
res.data?.record?.ulist.forEach(element => {
|
||||
MapUtl.addMaker({
|
||||
lng: element.long,
|
||||
lat: element.lat,
|
||||
lng: element.long ?? 116.478935,
|
||||
lat: element.lat ?? 39.997761,
|
||||
title: element.user_name,
|
||||
users: element
|
||||
})
|
||||
|
|
|
@ -9,6 +9,7 @@ class SysConfig {
|
|||
static ADDBanner: string = "sys/banner"
|
||||
static LIST: string = "sys/drop"
|
||||
static ADD: string = "sys/drop"
|
||||
static DELETE: string = "sys/drop"
|
||||
}
|
||||
class SysStore extends BaseStore<TagDataType> {
|
||||
constructor() {
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
class Config {
|
||||
static baseUrl = "http://127.0.0.1:12214/";
|
||||
static uploadUrl = "https://rw.quwanya.cn";
|
||||
static ws = "wss://rw.quwanya.cn/wsadmin?id=admin";
|
||||
static userStatic = "https://rw.quwanya.cn/uploads/user/";
|
||||
static baseUrl = "https://www.hswzct.cn:12016/";
|
||||
static uploadUrl = "https://www.hswzct.cn:12016";
|
||||
static ws = "wss://www.hswzct.cn:12016/wsadmin?id=admin";
|
||||
static userStatic = "https://hswzct.cn:12016/uploads/user/";
|
||||
static videoApi = "https://sprh.hswzct.cn:4443/"; //
|
||||
static videoApis = "https://sprh.hswzct.cn:4443"; //
|
||||
}
|
||||
|
|
|
@ -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 }
|
Loading…
Reference in New Issue