add animation

This commit is contained in:
wang_yp 2025-03-13 22:48:04 +08:00
parent 66dba51bf9
commit 41d4a359af
30 changed files with 18743 additions and 248 deletions

34
git.sh
View File

@ -14,19 +14,21 @@ git push
# rm -rf card/ # rm -rf card/
# task # ps
# pc
# 1、首页统计 # 编辑用户 是否党员 没回显
# 1、组织架构组织架构图
# 2、武装力量 报表 # app 政治面貌没有展示
# 3、年度训练 查看档案
# 4、物资管理 处突 # 优待证 性别 没展示
# 5、档案管理 报表 # 服务年限 展示实际年限
# 6、评优
# 7 # 签到 个人中心 展示今日签到信息
# 2、物资借用以及归还
# 3、任务关联档案 # 通讯录,实时搜索
# app
# 1、退伍军人 列表 详情 申请领取光荣牌 # pc
# 2、接收任务 # 力量汇总,加一个新兴领域 网格员
# 3、任务列表
# 任务管理
# 添加 通知

39
package-lock.json generated
View File

@ -48,7 +48,6 @@
"eslint-webpack-plugin": "^3.1.1", "eslint-webpack-plugin": "^3.1.1",
"expose-loader": "^5.0.0", "expose-loader": "^5.0.0",
"file-loader": "^6.2.0", "file-loader": "^6.2.0",
"flv.js": "^1.6.2",
"fs-extra": "^10.0.0", "fs-extra": "^10.0.0",
"html-webpack-plugin": "^5.5.0", "html-webpack-plugin": "^5.5.0",
"identity-obj-proxy": "^3.0.0", "identity-obj-proxy": "^3.0.0",
@ -9935,11 +9934,6 @@
"es6-symbol": "^3.1.1" "es6-symbol": "^3.1.1"
} }
}, },
"node_modules/es6-promise": {
"version": "4.2.8",
"resolved": "https://registry.npmmirror.com/es6-promise/-/es6-promise-4.2.8.tgz",
"integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w=="
},
"node_modules/es6-symbol": { "node_modules/es6-symbol": {
"version": "3.1.4", "version": "3.1.4",
"resolved": "https://registry.npmmirror.com/es6-symbol/-/es6-symbol-3.1.4.tgz", "resolved": "https://registry.npmmirror.com/es6-symbol/-/es6-symbol-3.1.4.tgz",
@ -11313,15 +11307,6 @@
"readable-stream": "^2.3.6" "readable-stream": "^2.3.6"
} }
}, },
"node_modules/flv.js": {
"version": "1.6.2",
"resolved": "https://registry.npmmirror.com/flv.js/-/flv.js-1.6.2.tgz",
"integrity": "sha512-xre4gUbX1MPtgQRKj2pxJENp/RnaHaxYvy3YToVVCrSmAWUu85b9mug6pTXF6zakUjNP2lFWZ1rkSX7gxhB/2A==",
"dependencies": {
"es6-promise": "^4.2.8",
"webworkify-webpack": "^2.1.5"
}
},
"node_modules/follow-redirects": { "node_modules/follow-redirects": {
"version": "1.15.9", "version": "1.15.9",
"resolved": "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.9.tgz", "resolved": "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.9.tgz",
@ -33188,11 +33173,6 @@
"node": ">=0.8.0" "node": ">=0.8.0"
} }
}, },
"node_modules/webworkify-webpack": {
"version": "2.1.5",
"resolved": "https://registry.npmmirror.com/webworkify-webpack/-/webworkify-webpack-2.1.5.tgz",
"integrity": "sha512-2akF8FIyUvbiBBdD+RoHpoTbHMQF2HwjcxfDvgztAX5YwbZNyrtfUMgvfgFVsgDhDPVTlkbb5vyasqDHfIDPQw=="
},
"node_modules/whatwg-encoding": { "node_modules/whatwg-encoding": {
"version": "1.0.5", "version": "1.0.5",
"resolved": "https://registry.npmmirror.com/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", "resolved": "https://registry.npmmirror.com/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz",
@ -41161,11 +41141,6 @@
"es6-symbol": "^3.1.1" "es6-symbol": "^3.1.1"
} }
}, },
"es6-promise": {
"version": "4.2.8",
"resolved": "https://registry.npmmirror.com/es6-promise/-/es6-promise-4.2.8.tgz",
"integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w=="
},
"es6-symbol": { "es6-symbol": {
"version": "3.1.4", "version": "3.1.4",
"resolved": "https://registry.npmmirror.com/es6-symbol/-/es6-symbol-3.1.4.tgz", "resolved": "https://registry.npmmirror.com/es6-symbol/-/es6-symbol-3.1.4.tgz",
@ -42194,15 +42169,6 @@
"readable-stream": "^2.3.6" "readable-stream": "^2.3.6"
} }
}, },
"flv.js": {
"version": "1.6.2",
"resolved": "https://registry.npmmirror.com/flv.js/-/flv.js-1.6.2.tgz",
"integrity": "sha512-xre4gUbX1MPtgQRKj2pxJENp/RnaHaxYvy3YToVVCrSmAWUu85b9mug6pTXF6zakUjNP2lFWZ1rkSX7gxhB/2A==",
"requires": {
"es6-promise": "^4.2.8",
"webworkify-webpack": "^2.1.5"
}
},
"follow-redirects": { "follow-redirects": {
"version": "1.15.9", "version": "1.15.9",
"resolved": "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.9.tgz", "resolved": "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.9.tgz",
@ -58569,11 +58535,6 @@
"resolved": "https://registry.npmmirror.com/websocket-extensions/-/websocket-extensions-0.1.4.tgz", "resolved": "https://registry.npmmirror.com/websocket-extensions/-/websocket-extensions-0.1.4.tgz",
"integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==" "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg=="
}, },
"webworkify-webpack": {
"version": "2.1.5",
"resolved": "https://registry.npmmirror.com/webworkify-webpack/-/webworkify-webpack-2.1.5.tgz",
"integrity": "sha512-2akF8FIyUvbiBBdD+RoHpoTbHMQF2HwjcxfDvgztAX5YwbZNyrtfUMgvfgFVsgDhDPVTlkbb5vyasqDHfIDPQw=="
},
"whatwg-encoding": { "whatwg-encoding": {
"version": "1.0.5", "version": "1.0.5",
"resolved": "https://registry.npmmirror.com/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", "resolved": "https://registry.npmmirror.com/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz",

View File

@ -43,7 +43,6 @@
"eslint-webpack-plugin": "^3.1.1", "eslint-webpack-plugin": "^3.1.1",
"expose-loader": "^5.0.0", "expose-loader": "^5.0.0",
"file-loader": "^6.2.0", "file-loader": "^6.2.0",
"flv.js": "^1.6.2",
"fs-extra": "^10.0.0", "fs-extra": "^10.0.0",
"html-webpack-plugin": "^5.5.0", "html-webpack-plugin": "^5.5.0",
"identity-obj-proxy": "^3.0.0", "identity-obj-proxy": "^3.0.0",

View File

@ -69,7 +69,6 @@ function MyEditor(props: EditorProps) {
value={html} value={html}
onCreated={setEditor} onCreated={setEditor}
onChange={(editor) => { onChange={(editor) => {
console.log("onChange", editor.getHtml());
setHtml(editor.getHtml()); setHtml(editor.getHtml());
props.onChange(editor.getHtml()); props.onChange(editor.getHtml());
}} }}

View File

@ -114,7 +114,7 @@ const SimpleForm = (props: SimpleFormData) => {
<Form.Item <Form.Item
key={v.label} key={v.label}
label={v.label} label={v.label}
valuePropName="fileList" valuePropName="file_list"
name={v.name} name={v.name}
rules={v.rules} rules={v.rules}
initialValue={v.value} initialValue={v.value}

View File

@ -1,6 +1,7 @@
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import AMapLoader from "@amap/amap-jsapi-loader"; import AMapLoader from "@amap/amap-jsapi-loader";
import { mapArrs } from "@/store/map"; import { mapArrs } from "@/store/map";
import MapUtlTow from "./mapUtilTow";
export default function MapContainerTow() { export default function MapContainerTow() {
let [amap, setmaps] = useState<any>(null); let [amap, setmaps] = useState<any>(null);
@ -37,9 +38,13 @@ export default function MapContainerTow() {
}); });
amap.add(polygon); amap.add(polygon);
amap.setFitView(); amap.setFitView();
MapUtlTow.loadMap = Amap;
MapUtlTow.amap = amap;
setmaps(amap); setmaps(amap);
}; };
return ( return (
<div id="containerTow" style={{ height: "100vh", width: "100%" }}></div> <div id="containerTow" style={{ height: "100vh", width: "100%" }}></div>
); );

View File

@ -0,0 +1,137 @@
import makers from "../../static/map-maker.png";
import makers1 from "../../static/map-maker1.png";
interface makersInf {
userIdentity: string,
marker: any,
}
class MapUtlTow {
static makerList: makersInf[] = [];
static amap: any = null;
static loadMap: any = null;
static wecherInfo: any = null;
static addMaker(data: any) {
const { lng, lat, title, users,clicks } = data;
let mk, dep = "";
if (users?.militia_type === 1) {
mk = makers
dep = "民兵"
}
if (users?.grid_user === 1) {
mk = makers1
dep = "网格员"
}
if (users?.patrol_user === 1) {
dep = "巡防大队"
}
// if (MapUtl.loadMap === null) return;
const marker = new MapUtlTow.loadMap.Marker({
position: new MapUtlTow.loadMap.LngLat(lng, lat),
title: title,
icon: new MapUtlTow.loadMap.Icon({
imageSize: [20, 20],
image: mk,
style: {
backgroundImage: "red"
}// 默认的样式名
}),
});
var content = [
"<div><b>姓名 :" + users?.user_name + "</b>",
"职位 : " + users.pos_held,
"电话 : " + users.tel,
"部门 : " + dep,
"</div>",
];
var infoWindow = new MapUtlTow.loadMap.InfoWindow({
offset: new MapUtlTow.loadMap.Pixel(0, -30),
autoMove: true,
content: content.join("<br/>"),
});
marker.on("click", (e) => {
infoWindow.open(MapUtlTow.amap, e.target.getPosition());
clicks(users.id)
});
MapUtlTow.amap?.add(marker);
// 将maker添加到数组
MapUtlTow.makerList.push({
userIdentity: users.identity,
marker: marker
})
}
static addMakerDis(data: any) {
const { lng, lat, title } = data;
const marker = new MapUtlTow.loadMap.Marker({
position: new MapUtlTow.loadMap.LngLat(lng, lat),
icon: new MapUtlTow.loadMap.Icon({
image:
"https://img20.360buyimg.com/n1/jfs/t1/98676/8/28819/96905/62e1e96eE69561497/0e201e39d6d1c1e3.png",
imageSize: [30, 30],
}),
title: title,
});
var content = [
"<div><b>站点名称 :" + title + "</b>",
// "职位 : " + users.pos_held,
// "电话 : " + users.tel,
"</div>",
];
var infoWindow = new MapUtlTow.loadMap.InfoWindow({
offset: new MapUtlTow.loadMap.Pixel(0, -30),
autoMove: true,
content: content.join("<br/>"),
});
marker.on("click", (e) => {
infoWindow.open(MapUtlTow.amap, e.target.getPosition());
});
MapUtlTow.amap?.add(marker);
}
static setMakericon = (maker) => {
maker.setPosition([103.55, 30.342]);
var m = MapUtlTow.amap;
var newIcon = new m.Icon({
image: "//a.amap.com/jsapi_demos/static/demo-center/icons/dir-marker.png", //Icon 的图像
size: new m.Size(25, 34), // 图标大小
anchor: new m.Pixel(12, 32), // 图标锚点
});
maker.setIcon(newIcon);
}
static polyline = (lineArr) => {
let markerp = new MapUtlTow.loadMap.Marker({
map: MapUtlTow.amap,
position: [116.478935, 39.997761],
icon: "https://a.amap.com/jsapi_demos/static/demo-center-v2/car.png",
offset: new MapUtlTow.loadMap.Pixel(-13, -26),
});
new MapUtlTow.loadMap.Polyline({
map: MapUtlTow.amap,
path: lineArr,
showDir: true,
strokeColor: "#28F", //线颜色
strokeWeight: 6, //线宽
});
let passedPolyline = new MapUtlTow.loadMap.Polyline({
map: MapUtlTow.amap,
strokeColor: "#AF5", //线颜色
strokeWeight: 6, //线宽
});
markerp.on('moving', function (e) {
passedPolyline.setPath(e.passedPath);
MapUtlTow.amap.setCenter(e.target.getPosition(), true)
});
MapUtlTow.amap.setFitView();
markerp.moveAlong(lineArr, {
duration: 500,//可根据实际采集时间间隔设置
autoRotation: true,
});
}
static getWecher() {
}
}
export default MapUtlTow;

View File

@ -90,7 +90,6 @@
bottom: 0px; bottom: 0px;
z-index: 2; z-index: 2;
opacity: 1; opacity: 1;
background: rgba(37, 52, 70, 0.4);
backdrop-filter: blur(10px); backdrop-filter: blur(10px);
} }
.map_container_r { .map_container_r {
@ -101,13 +100,13 @@
width: 20%; width: 20%;
z-index: 2; z-index: 2;
opacity: 1; opacity: 1;
background: rgba(37, 52, 70, 0.4);
backdrop-filter: blur(10px); backdrop-filter: blur(10px);
height: 100%; height: 100%;
} }
.map_container_b_check { .map_container_b_check {
position: absolute; position: absolute;
bottom: 40px; bottom: 60px;
height: 60px; height: 60px;
width: 100%; width: 100%;
z-index: 1; z-index: 1;
@ -115,11 +114,10 @@
} }
.map_container_b { .map_container_b {
position: absolute; position: absolute;
bottom: 0px; bottom: 12px;
backdrop-filter: blur(10px);
height: 60px; height: 60px;
width: 100%; width: 100%;
z-index: 1; z-index: 2;
text-align: center; text-align: center;
.bottom_content { .bottom_content {
display: inline-block; display: inline-block;
@ -140,3 +138,7 @@
top: 70px; top: 70px;
right: calc(20%); right: calc(20%);
} }
:where(.css-dev-only-do-not-override-nqoqt9).ant-radio-button-wrapper:not(:first-child)::before {
background-color: #0f5693 !important;
}

View File

@ -39,7 +39,7 @@ const Home = observer(() => {
<HomeRight /> <HomeRight />
</div> </div>
<div className="map_container_b_check"> <div className="map_container_b_check">
{/* <HomeCheck /> */} <HomeCheck />
</div> </div>
<div className="map_container_b"> <div className="map_container_b">
<HomeBottom /> <HomeBottom />

View File

@ -2,7 +2,7 @@ import { Modal } from "antd";
import { inject, observer } from "mobx-react"; import { inject, observer } from "mobx-react";
import { useState } from "react"; import { useState } from "react";
import Config from "@/util/config"; import Config from "@/util/config";
import VideoPlayer from "@/pages/home/video"; import EasyPlayer from "../videoTow";
const WhichVideo = (props) => { const WhichVideo = (props) => {
const { homeStore } = props; const { homeStore } = props;
const [isModalOpen, setIsModalOpen] = useState<boolean>(false); const [isModalOpen, setIsModalOpen] = useState<boolean>(false);
@ -11,21 +11,39 @@ const WhichVideo = (props) => {
const [deviceId, setDeviceId] = useState<number>(0); const [deviceId, setDeviceId] = useState<number>(0);
const [channelId, setChannelId] = useState<number>(0); const [channelId, setChannelId] = useState<number>(0);
const [videoUrl, setVideoUrl] = useState<string | null>(""); const [videoUrl, setVideoUrl] = useState<string | null>("");
let timer: any = null;
const openDispatch = async () => { const openDispatch = async () => {
setIsModalOpen(true); setIsModalOpen(true);
let req = await homeStore.getVideoUrlList(); let req = await homeStore.getVideoUrlList();
setDeviceList(req.EasyDarwin.Body.Devices); setDeviceList(req.EasyDarwin.Body.Devices);
}; };
const getChannerList = async (id) => { const getChannerList = async (id) => {
let reqs = await homeStore.getChannerUrlList(id); let reqs = await homeStore.getChannerUrlList(id);
setChannelList(reqs.EasyDarwin.Body.Channels); setChannelList(reqs.EasyDarwin.Body.Channels);
}; };
const getUrl = async (id) => { const getUrl = async (id) => {
let reqs = await homeStore.getChannerStrem(deviceId, id); if (timer) {
if (!reqs.EasyDarwin) return; clearInterval(timer);
let url = Config.videoApis + reqs.EasyDarwin.Body.URL }
setVideoUrl(url);
const fetchUrl = async () => {
try {
const reqs = await homeStore.getChannerStrem(deviceId, id);
if (!reqs.EasyDarwin) return;
const url = Config.videoApis + reqs.EasyDarwin.Body.URL;
setVideoUrl(url);
} catch (error) {
console.error("Error fetching video URL:", error);
}
};
fetchUrl()
timer = setInterval( () => {
fetchUrl();
},15000);
}; };
return ( return (
<> <>
@ -51,7 +69,7 @@ const WhichVideo = (props) => {
> >
<div> <div>
<div style={{ display: "flex" }}> <div style={{ display: "flex" }}>
<div style={{overflowY: "scroll",height: "550px"}}> <div style={{ overflowY: "scroll", height: "550px" }}>
{deviceList.map((item, index) => { {deviceList.map((item, index) => {
return ( return (
<div <div
@ -74,7 +92,7 @@ const WhichVideo = (props) => {
})} })}
</div> </div>
<div style={{ width: "20px" }}></div> <div style={{ width: "20px" }}></div>
<div style={{height:"550px",overflow:"scroll"}}> <div style={{ height: "550px", overflow: "scroll" }}>
{channelList.map((item, index) => { {channelList.map((item, index) => {
return ( return (
<div <div
@ -98,9 +116,7 @@ const WhichVideo = (props) => {
</div> </div>
<div style={{ width: "20px" }}></div> <div style={{ width: "20px" }}></div>
<div className="video" style={{ width: "100%", height: "550px" }}> <div className="video" style={{ width: "100%", height: "550px" }}>
{ {<EasyPlayer url={videoUrl} />}
<VideoPlayer url={videoUrl} />
}
</div> </div>
</div> </div>
</div> </div>

View File

@ -23,18 +23,21 @@ const HomeLeft = () => {
</div> </div>
<Orgin /> <Orgin />
</div> </div>
<div style={{height:"10px"}}></div>
<div className="org"> <div className="org">
<div className="org_head"> <div className="org_head">
<p></p> <p></p>
</div> </div>
<Pover /> <Pover />
</div> </div>
<div style={{height:"10px"}}></div>
<div className="org"> <div className="org">
<div className="org_head"> <div className="org_head">
<p></p> <p></p>
</div> </div>
<Turn /> <Turn />
</div> </div>
<div style={{height:"20px"}}></div>
</div> </div>
); );
}; };

View File

@ -8,16 +8,18 @@
.org{ .org{
flex:1; flex:1;
width: 100%; width: 100%;
background: rgba(37, 52, 70, 0.4);
overflow-y: hidden; overflow-y: hidden;
text-align: center; text-align: center;
.org_head{ .org_head{
background-image: url("../../../static/sub_title.png"); background-image: url("../../../static/sub_title.png");
background-size: 100% 100%; background-size: 100% 100%;
background-repeat: no-repeat; background-repeat: no-repeat;
line-height: 36px; line-height: 32px;
height: 36px; height: 32px;
text-align: left; text-align: left;
padding-left: 30px; padding-left: 30px;
font-size: 15px;
} }
.orgin-content{ .orgin-content{
display: flex; display: flex;

View File

@ -11,7 +11,7 @@ export const trunEchatConfig = (data) => {
rotate: 30, rotate: 30,
}, },
}, },
grid: { top: "10%", bottom: "35%", right: "5%" }, grid: { top: "10%", bottom: "40%", right: "5%" },
yAxis: { yAxis: {
type: "value", type: "value",
splitLine: { splitLine: {

View File

@ -72,11 +72,11 @@ const Turn = (props: Store) => {
let fileType = getFileTypeFromUrl(imageUrl); let fileType = getFileTypeFromUrl(imageUrl);
switch (fileType) { switch (fileType) {
case "jpeg": case "jpeg":
return <img style={{ width: "100%" }} src={imageUrl} alt="" />; return <img style={{ width: "100%",objectFit:"fill" }} src={imageUrl} alt="" />;
case "jpg": case "jpg":
return <img style={{ width: "100%" }} src={imageUrl} alt="" />; return <img style={{ width: "100%" ,objectFit:"fill"}} src={imageUrl} alt="" />;
case "png": case "png":
return <img style={{ width: "100%" }} src={imageUrl} alt="" />; return <img style={{ width: "100%",objectFit:"fill" }} src={imageUrl} alt="" />;
case "pdf": case "pdf":
return ( return (
<div style={{ width: "100%", height: "500px" }}> <div style={{ width: "100%", height: "500px" }}>
@ -106,7 +106,7 @@ const Turn = (props: Store) => {
src={imageUrl} src={imageUrl}
fileName="docx" fileName="docx"
onError={(e) => { onError={(e) => {
console.log("error doc",e); console.log("error doc", e);
}} }}
/> />
</div> </div>
@ -137,34 +137,50 @@ const Turn = (props: Store) => {
setisModalOpen(false); setisModalOpen(false);
}} }}
> >
<div > <div>
<Row> <Row>
<Col span={2}> <Col span={2}>
<div style={{ color: "#fff" }}> <div style={{ color: "#fff" }}>
<p></p> <div
<div style={{ height: "600px",overflowY:"hidden" }}> style={{
{trainingStore.list?.map((item) => { height: "500px",
return ( overflowY: "hidden",
<p border: "1px solid #fff",
key={item.identity} padding: "10px",
style={{ margin: "5px",
color: item.identity === taskId ? "blue" : "#fff", }}
cursor: "pointer", >
}} <p></p>
onClick={() => { {trainingStore.list?.map((item) => {
setTaskId(item.identity); return (
getFolderhandler(item.identity); <p
}} key={item.identity}
> style={{
{item.title} margin: "5px",
</p> color: item.identity === taskId ? "blue" : "#fff",
); cursor: "pointer",
})} }}
</div> onClick={() => {
setTaskId(item.identity);
getFolderhandler(item.identity);
}}
>
{item.title}
</p>
);
})}
</div>
</div> </div>
</Col> </Col>
<Col span={2}> <Col span={2}>
<div style={{ color: "#fff" }}> <div
style={{
color: "#fff",
border: "1px solid #fff",
padding: "10px",
margin: "5px",
}}
>
<p></p> <p></p>
{folderList?.map((item) => { {folderList?.map((item) => {
return ( return (
@ -185,70 +201,73 @@ const Turn = (props: Store) => {
})} })}
</div> </div>
</Col> </Col>
<Col span={2} style={{height:"600px",overflowY:"hidden"}}> <Col span={2}>
<div style={{ color: "#fff" }}> <div style={{ color: "#fff", border: "1px solid #fff",
padding: "10px",
margin: "5px", }}>
<div style={{ height: "500px", overflowY: "scroll" }}>
<p></p> <p></p>
<div style={{height:"600px",overflowY:"scroll"}}> {imageList?.map((item) => {
{imageList?.map((item) => { let fileType = getFileTypeFromUrl(item.file_url);
let fileType = getFileTypeFromUrl(item.file_url); switch (fileType) {
switch (fileType) { case "png":
case "png": return imageWidget(item);
return imageWidget(item); case "jpeg":
case "jpeg": return imageWidget(item);
return imageWidget(item); case "jpg":
case "jpg": return imageWidget(item);
return imageWidget(item); case "pdf":
case "pdf": return (
return ( <p
<p key={item.identity}
key={item.identity} style={{ cursor: "pointer" }}
style={{ cursor: "pointer" }} onClick={() => {
onClick={() => { setImageUrl(item.file_url);
setImageUrl(item.file_url); }}
}} >
> {item.file_name}
{item.file_name} </p>
</p> );
); case "mp4":
case "mp4": return (
return ( <p
<p key={item.identity}
key={item.identity} style={{ cursor: "pointer" }}
style={{ cursor: "pointer" }} onClick={() => {
onClick={() => { setImageUrl(item.file_url);
setImageUrl(item.file_url); }}
}} >
> {item.file_name}
{item.file_name} </p>
</p> );
); case "docx":
case "docx": return (
return ( <p
<p key={item.identity}
key={item.identity} style={{ cursor: "pointer" }}
style={{ cursor: "pointer" }} onClick={() => {
onClick={() => { setImageUrl(item.file_url);
setImageUrl(item.file_url); }}
}} >
> {item.file_name}
{item.file_name} </p>
</p> );
); default:
default: return (
return ( <img
<img onClick={() => {
onClick={() => { setImageUrl(item.file_url);
setImageUrl(item.file_url); }}
}} key={item.identity}
key={item.identity} style={{ width: "80px" }}
style={{ width: "80px" }} src={item.file_url}
src={item.file_url} alt=""
alt="" />
/> );
); }
} })}
})} </div>
</div>
</div> </div>
</Col> </Col>
<Col span={18}> <Col span={18}>
@ -259,6 +278,7 @@ const Turn = (props: Store) => {
display: "flex", display: "flex",
alignItems: "center", alignItems: "center",
justifyContent: "center", justifyContent: "center",
padding:"10px"
}} }}
> >
{preView()} {preView()}

View File

@ -1,9 +1,18 @@
import FileViewer from "@codesmith-99/react-file-preview";
import { Modal, Space } from "antd";
import { Store } from "antd/es/form/interface"; import { Store } from "antd/es/form/interface";
import * as echarts from "echarts"; import * as echarts from "echarts";
import { inject, observer } from "mobx-react"; import { inject, observer } from "mobx-react";
import { useEffect } from "react"; import { useEffect, useState } from "react";
const Ac = (props: Store) => { const Ac = (props: Store) => {
const { homeStore } = props; const { homeStore } = props;
const [isModalOpen, setIsModalOpen] = useState<boolean>(false);
const [year, setYear] = useState<Array<any>>([]);
const [folder, setFolder] = useState<Array<any>>([]);
const [files, setFiles] = useState<Array<any>>([]);
const [imageUrl, setImageUrl] = useState<any>([]);
const [folderId, setFolderId] = useState<any>([]);
const [fileId, setFileId] = useState<any>([]);
const initChart = (data) => { const initChart = (data) => {
var myChart = echarts.init(document.getElementById("ac")); var myChart = echarts.init(document.getElementById("ac"));
@ -62,8 +71,177 @@ const Ac = (props: Store) => {
homeStore.getRm().then((res) => { homeStore.getRm().then((res) => {
initChart(res.data?.record); initChart(res.data?.record);
}); });
}, [homeStore]); }, [homeStore]);
return <div style={{ width: "100%", height: "100%" }} id="ac"></div>; const getFileTypeFromUrl = (url) => {
if (url === "" || url.length === 0) return;
// 解析URL以提取文件名
const filename = url.split("/").pop();
// 获取文件扩展名
const fileExtension = filename.split(".").pop();
// 返回文件扩展名
return fileExtension;
};
const preView = () => {
let fileType = getFileTypeFromUrl(imageUrl);
switch (fileType) {
case "jpeg":
return <img style={{ width: "100%",height:"100%" }} src={imageUrl} alt="" />;
case "jpg":
return <img style={{ width: "100%" ,height:"100%"}} src={imageUrl} alt="" />;
case "png":
return <img style={{ width: "100%",height:"100%" }} src={imageUrl} alt="" />;
case "pdf":
return (
<div style={{ width: "100%", height: "100%" }}>
<iframe
style={{ width: "100%", height: "100%" }}
src={imageUrl}
title="描述"
></iframe>
</div>
);
case "mp4":
return (
<div key={imageUrl} style={{ width: "100%", height: "100%" }}>
<video
controls
style={{ width: "100%", height: "100%" }}
src={imageUrl}
></video>
</div>
);
case "docx":
return (
<div key={imageUrl} style={{ width: "100%", height: "400px" }}>
<FileViewer
loader={undefined}
src={imageUrl}
fileName="docx"
onError={(e) => {
console.log("error doc", e);
}}
/>
</div>
);
case "":
return <div style={{ width: "100%", height: "400px" }}></div>;
default:
return <div style={{ width: "100%", height: "400px" }}></div>;
}
};
return (
<>
<div
style={{ width: "100%", height: "100%" }}
id="ac"
onClick={() => {
homeStore.getTimes().then((res) => {
setYear(res.data?.record);
});
homeStore.getFolders("2025").then((res) => {
setFolder(res.data?.record);
});
setIsModalOpen(true);
}}
></div>
<Modal
title="档案查看"
className="owner_model"
width={"80%"}
open={isModalOpen}
afterClose={() => {}}
onOk={() => {}}
footer={null}
onCancel={() => {
setIsModalOpen(false);
}}
>
<>
<Space style={{ color: "#fff" }}>
{year.map((item) => {
return (
<h2
style={{ cursor: "pointer" }}
onClick={() => {
homeStore.getFolders(item.unique_years).then((res) => {
setFolder(res.data?.record);
});
}}
>
{item.unique_years}
</h2>
);
})}
</Space>
<h2 style={{ color: "#fff" }}></h2>
<div style={{ height: "500px", overflow: "hidden" }}>
<div style={{ display: "flex", alignItems: "flex-start" }}>
<div
style={{
border: "1px solid #fff",
width: "200px",
overflow: "auto",
height: "480px",
flex:1
}}
>
{folder?.map((item) => {
return (
<p
style={{
color: folderId === item.identity ? "blue" : "#fff",
cursor: "pointer",
margin: "5px",
}}
onClick={() => {
homeStore.getFolderss(item.identity).then((res) => {
setFolderId(item.identity);
setFiles(res.data?.record);
});
}}
>
{item.folder_desc}
</p>
);
})}
</div>
<div
style={{
border: "1px solid #fff",
width: "200px",
height: "480px",
overflow: "auto",
flex:1
}}
>
{files?.map((item) => {
return (
<p
style={{
color: fileId === item.identity ? "blue" : "#fff",
cursor: "pointer",
margin: "5px",
}}
onClick={() => {
setFileId(item.identity)
setImageUrl(item.file_url);
}}
>
{item.file_name}
</p>
);
})}
</div>
<div style={{height:"400px",flex:4}}>
{preView()}
</div>
</div>
</div>
</>
</Modal>
</>
);
}; };
export default inject("homeStore")(observer(Ac)); export default inject("homeStore")(observer(Ac));

View File

@ -1,10 +1,8 @@
import { useNavigate } from "react-router";
import Ac from "./ac"; import Ac from "./ac";
import Pyzx from "./pyzx"; import Pyzx from "./pyzx";
import "./right.less"; import "./right.less";
import Wz from "./wz"; import Wz from "./wz";
const HomeRight = () => { const HomeRight = () => {
const nv = useNavigate();
return ( return (
<div className="right_container"> <div className="right_container">
<div className="org"> <div className="org">
@ -13,18 +11,21 @@ const HomeRight = () => {
</div> </div>
<Wz /> <Wz />
</div> </div>
<div className="org" onClick={()=>nv('/admin/archives/box')}> <div style={{ height: "10px" }}></div>
<div className="org">
<div className="org_head"> <div className="org_head">
<p></p> <p></p>
</div> </div>
<Ac /> <Ac />
</div> </div>
<div style={{ height: "10px" }}></div>
<div className="org"> <div className="org">
<div className="org_head"> <div className="org_head">
<p></p> <p></p>
</div> </div>
<Pyzx /> <Pyzx />
</div> </div>
<div style={{ height: "20px" }}></div>
</div> </div>
); );
}; };

View File

@ -18,7 +18,7 @@ const Pyzx = (props: Store) => {
}, [homeStore]); }, [homeStore]);
return ( return (
<div className="pyzx"> <div className="pyzx" style={{height:"150px"}}>
{user?.map((item) => { {user?.map((item) => {
return ( return (
<div <div

View File

@ -8,13 +8,15 @@
flex: 1; flex: 1;
width: 100%; width: 100%;
overflow-y: hidden; overflow-y: hidden;
background: rgba(37, 52, 70, 0.4);
text-align: center; text-align: center;
.org_head { .org_head {
background-image: url("../../../static/sub_title.png"); background-image: url("../../../static/sub_title.png");
background-size: 100% 100%; background-size: 100% 100%;
background-repeat: no-repeat; background-repeat: no-repeat;
line-height: 36px; line-height: 32px;
height: 36px; height: 32px;
font-size: 15px;
text-align: left; text-align: left;
padding-left: 30px; padding-left: 30px;
} }
@ -23,7 +25,6 @@
.pyzx { .pyzx {
height: 100%; height: 100%;
min-height: 200px;
padding: 10px; padding: 10px;
margin-bottom: 10px; margin-bottom: 10px;
overflow-y: scroll; overflow-y: scroll;

View File

@ -4,6 +4,7 @@ import { inject, observer } from "mobx-react";
import { Store } from "antd/es/form/interface"; import { Store } from "antd/es/form/interface";
import MapUtl from "@/components/map/mapUtil"; import MapUtl from "@/components/map/mapUtil";
import MapContainerTow from "@/components/map/MapComponentTow"; import MapContainerTow from "@/components/map/MapComponentTow";
import MapUtlTow from "@/components/map/mapUtilTow";
const HomeCheck = (props: Store) => { const HomeCheck = (props: Store) => {
const { homeStore ,usrStore} = props; const { homeStore ,usrStore} = props;
@ -45,7 +46,7 @@ const HomeCheck = (props: Store) => {
return; return;
} }
if (data.length > 0) { if (data.length > 0) {
MapUtl.polyline(data); MapUtlTow.polyline(data);
} }
} }
}); });
@ -64,7 +65,7 @@ const HomeCheck = (props: Store) => {
query = { patrol_brigade: 1 }; query = { patrol_brigade: 1 };
break; break;
} }
let marks = MapUtl.makerList; let marks = MapUtlTow.makerList;
if (marks.length) { if (marks.length) {
marks.forEach((item) => { marks.forEach((item) => {
item?.marker.remove(); item?.marker.remove();
@ -89,10 +90,10 @@ const HomeCheck = (props: Store) => {
}; };
return ( return (
<> <>
<Radio.Group value={size} onChange={handleSizeChange}> <Radio.Group value={size} onChange={handleSizeChange} >
<Radio.Button value="1"></Radio.Button> <Radio.Button style={{backgroundColor:"rgba(15,86,147, 0.4)",border:"0px",color:"#fff"}} value="1"></Radio.Button>
<Radio.Button value="2"></Radio.Button> <Radio.Button style={{backgroundColor:"rgba(15,86,187, 0.4)",border:"0px",color:"#fff"}} value="2"></Radio.Button>
<Radio.Button value="3"></Radio.Button> <Radio.Button style={{backgroundColor:"rgba(15,86,147, 0.4)",border:"0px",color:"#fff"}} value="3"></Radio.Button>
</Radio.Group> </Radio.Group>
<Modal <Modal
title={"轨迹回放"} title={"轨迹回放"}

View File

@ -1,9 +1,9 @@
import { Store } from "antd/es/form/interface"; import { Store } from "antd/es/form/interface";
import { inject, observer } from "mobx-react"; import { inject, observer } from "mobx-react";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import Video from "./video";
import "./video.less"; import "./video.less";
import { ZoomInOutlined } from "@ant-design/icons"; import { ZoomInOutlined } from "@ant-design/icons";
import VideoTow from "./videoTow";
const HomeVideo = (props: Store) => { const HomeVideo = (props: Store) => {
const { homeStore } = props; const { homeStore } = props;
const [videoUrls, setVideoUrl] = useState<Array<string> | null>([]); const [videoUrls, setVideoUrl] = useState<Array<string> | null>([]);
@ -43,8 +43,8 @@ const HomeVideo = (props: Store) => {
<div className="homeVideoBox" style={obj}> <div className="homeVideoBox" style={obj}>
{videoUrls?.map((videoUrl, index) => { {videoUrls?.map((videoUrl, index) => {
return ( return (
<div key={videoUrl} style={{ flex: "1", margin: "5px" }}> <div key={videoUrl} style={{ flex: "1", margin: "5px",height:"200px"}}>
<Video url={videoUrl} className="homeVideo" />; <VideoTow url={videoUrl} className="homeVideo" />;
</div> </div>
); );
})} })}

View File

@ -1,46 +0,0 @@
/* eslint-disable react-hooks/exhaustive-deps */
import React, { useEffect, useRef } from "react";
import flvjs from "flv.js";
import { Store } from "antd/es/form/interface";
const VideoPlayer = (props: Store) => {
const videoRef = useRef<HTMLVideoElement | null>(null);
let player: flvjs.Player | null = null;
useEffect(() => {
if (!props.url) return;
if (flvjs.isSupported()) {
const videoElement = videoRef.current;
if (videoElement) {
player = flvjs.createPlayer({
type: "mp4",
url: props.url,
});
player.attachMediaElement(videoElement);
player.load();
player.play();
}
}
return () => {
if (player) {
player.pause();
player.unload();
player.detachMediaElement();
player.destroy();
player = null;
}
};
}, [props.url]);
return (
<video
ref={videoRef}
style={{ width: "100%", height: "100%"}}
controls
autoPlay
/>
);
};
export default VideoPlayer;

View File

@ -0,0 +1,79 @@
import { Store } from "antd/es/form/interface";
import React, { useEffect } from "react";
// 声明 EasyPlayerPro 的类型
declare global {
interface Window {
EasyPlayerPro?: any; // 或者定义更精确的类型
}
}
// 创建 Player 组件
const EasyPlayer = (props: Store) => {
const myRef = React.useRef(null); // 用于引用 DOM 元素
const easyPro = React.useRef<any>(null); // 存储播放器实例
// 配置项
const config = {
isLive: true,
bufferTime: 0.2,
stretch: false,
MSE: true,
WCS: true,
hasAudio: false,
};
// 在组件挂载后创建播放器实例
useEffect(() => {
if (easyPro.current) {
easyPro.current?.destroy().then(() => {
if (props.url){
create();
}
});
} else {
if (props.url){
create();
}
}
return () => {
if (easyPro.current) {
easyPro.current.destroy()
}
};
}, [props.url],);
// 创建播放器实例
const create = () => {
easyPro.current = new window.EasyPlayerPro(myRef.current, {
isLive: config.isLive,
bufferTime: config.bufferTime,
stretch: config.stretch,
MSE: config.MSE,
WCS: config.WCS,
hasAudio: config.hasAudio,
watermark: { text: { content: "easyplayer-pro" }, right: 10, top: 10 },
});
play();
};
// 播放视频
const play = () => {
if (!easyPro.current) return create();
easyPro.current
?.play(props.url)
.then(() => {
console.log("player started");
})
.catch((e) => {
console.error("error", e);
});
};
return (
<div
style={{ width: "100%", height: "100%", backgroundColor: "#000000" }}
ref={myRef}
></div>
);
};
export default EasyPlayer;

View File

@ -240,7 +240,7 @@ const Patrol = (props: Store) => {
onFinish={onFinish} onFinish={onFinish}
initialValues={true} initialValues={true}
onFinishFailed={onFinishFailed} onFinishFailed={onFinishFailed}
childrenPosi={true} childrenPosi={false}
> >
<> <>
<Form.Item <Form.Item

View File

@ -1,4 +1,4 @@
import { Button, Space, Modal, FormInstance } from "antd"; import { Button, Space, Modal, FormInstance, Form } from "antd";
import { inject, observer } from "mobx-react"; import { inject, observer } from "mobx-react";
import BTable from "@/components/b_table"; import BTable from "@/components/b_table";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
@ -44,17 +44,28 @@ const PoliticalStudy = (props: Store) => {
); );
}; };
const edit = (record) => { const edit = (record) => {
let data = {
...record,
file_url: [record.file_url],
};
let config = defaultConfig;
config.forEach((e: any) => {
if (e.name === "file_url") {
e.value = [{ url: record.file_url }];
}
});
setProjectConfig(config);
setRecord(data);
setIsModalOpen(true); setIsModalOpen(true);
setRecord(record);
}; };
const onFinish = (values: any) => { const onFinish = (values: any) => {
let data = { let data = {
...values, ...values,
score: Number(values.score), score: Number(values.score),
}; };
if (values.file_url.length>0) { if (values.file_url.length > 0) {
data.file_url = values.file_url[0].url; data.file_url = values.file_url[0].url;
}else{ } else {
data.file_url = ""; data.file_url = "";
} }
if (!record?.id) { if (!record?.id) {
@ -88,7 +99,7 @@ const PoliticalStudy = (props: Store) => {
{ {
title: "操作", title: "操作",
dataIndex: "id", dataIndex: "id",
render: (any, record) => column_widget(any, record), render: (any, record) => column_widget(any, record),
}, },
]} ]}

View File

@ -172,7 +172,7 @@ export const defaultConfig =(team,per)=>
}, },
{ {
type: FormType.radio, type: FormType.radio,
label: "是否党员", label: "政治面貌",
name: "p_member", name: "p_member",
value: 1, value: 1,
radioData: [ radioData: [

Binary file not shown.

Before

Width:  |  Height:  |  Size: 135 KiB

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 142 KiB

After

Width:  |  Height:  |  Size: 62 KiB

View File

@ -21,7 +21,9 @@ class HomeConfig {
static channerList: string = "/api/v1/channelsconfig" //设备列表 static channerList: string = "/api/v1/channelsconfig" //设备列表
static channelstream: string = "/api/v1/devices/channelstream" //设备包活 static channelstream: string = "/api/v1/devices/channelstream" //设备包活
static scores: string = "/v1/user/scores" static scores: string = "/v1/user/scores"
static times: string = "/v1/archives/times"
static folderall: string = "/v1/archives/folder/all"
static folderalls: string = "/v1/archives/list"
} }
class HomeStore extends BaseStore<TagDataType> { class HomeStore extends BaseStore<TagDataType> {
scoreData = {} scoreData = {}
@ -29,7 +31,7 @@ class HomeStore extends BaseStore<TagDataType> {
super(HomeConfig) super(HomeConfig)
makeObservable(this, { makeObservable(this, {
getOgCount: action, getOgCount: action,
scoreData:observable, scoreData: observable,
ogMap: observable, ogMap: observable,
alist: observable, alist: observable,
showVideo: observable, showVideo: observable,
@ -42,7 +44,7 @@ class HomeStore extends BaseStore<TagDataType> {
async getScores(id) { async getScores(id) {
let data = await baseHttp.get(HomeConfig.scores + "/" + id, null) let data = await baseHttp.get(HomeConfig.scores + "/" + id, null)
this.scoreData = data.data.record this.scoreData = data.data.record
} }
async getOgCount() { async getOgCount() {
let res = await baseHttp.get(HomeConfig.os, {}); let res = await baseHttp.get(HomeConfig.os, {});
@ -72,6 +74,22 @@ class HomeStore extends BaseStore<TagDataType> {
return await baseHttp.get(HomeConfig.todo, params); return await baseHttp.get(HomeConfig.todo, params);
} }
// 获取档案时间
async getTimes() {
return await baseHttp.get(HomeConfig.times, {});
}
// 获取档案列表
async getFolders(year: string) {
return await baseHttp.get(HomeConfig.folderall, { "year": year });
}
async getFolderss(identity: string) {
return await baseHttp.get(HomeConfig.folderalls+"/"+identity, { });
}
// folderDetail
// 获取视频推流连接 // 获取视频推流连接
async getVideoUrlList() { async getVideoUrlList() {
try { try {
@ -103,7 +121,7 @@ class HomeStore extends BaseStore<TagDataType> {
let data = await baseHttp.gets(HomeConfig.channelstream, { let data = await baseHttp.gets(HomeConfig.channelstream, {
device: deviceId, device: deviceId,
channel: channel, channel: channel,
protocol: "fmp4" protocol: "flv"
}) })
return data; return data;
} catch (error) { } catch (error) {

View File

@ -1,8 +1,7 @@
class Config { class Config {
// static baseUrl = "https://www.hswzct.cn:12016/"; static baseUrl = "https://www.hswzct.cn:12016/";
static baseUrl = "http://127.0.0.1:12214/"; // static baseUrl = "http://127.0.0.1:12214/";
static ws = "wss://www.hswzct.cn:12016/wsadmin?id=admin"; static ws = "wss://www.hswzct.cn:12016/wsadmin?id=admin";
// static ws = "wss://rw.quwanya.cn/wsadmin?id=admin";
static userStatic = "https://www.hswzct.cn:12016/api/uploads/user/"; static userStatic = "https://www.hswzct.cn:12016/api/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"; //

18107
yarn.lock Normal file

File diff suppressed because it is too large Load Diff