first commit

This commit is contained in:
wang_yp 2024-11-19 22:04:06 +08:00
parent 77fc8ce739
commit b51aaf7015
12 changed files with 252 additions and 41 deletions

View File

@ -49,7 +49,7 @@ const LayOut = (props: Store) => {
style={{ flex: 1, minWidth: 0 }} style={{ flex: 1, minWidth: 0 }}
/> />
<span style={{ color: "#fff" }}>退</span> <span style={{ color: "#fff" }} onClick={() => usrStore.logOut()}>退</span>
</Header> </Header>
<Content style={{ padding: "0 20px" }}> <Content style={{ padding: "0 20px" }}>
<Outlet /> <Outlet />

View File

@ -94,7 +94,7 @@ code {
color: #fff; color: #fff;
} }
} }
.ant-modal-close{ .ant-modal-close {
color: #fff; color: #fff;
} }
.ant-modal-body { .ant-modal-body {
@ -110,3 +110,11 @@ code {
} }
} }
} }
.text-overflow {
display: inline-block;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 200px;
}

View File

@ -28,14 +28,17 @@ const ArchivesFolder = (props: Store) => {
const formRef = React.useRef<FormInstance>(null); const formRef = React.useRef<FormInstance>(null);
const [tagId, setId] = useState<Number | null>(null); const [tagId, setId] = useState<Number | null>(null);
const [tagPId, setPId] = useState<Number | null>(null);
const [folderId, setFolderId] = useState<String | null>(null); const [folderId, setFolderId] = useState<String | null>(null);
const [catList, setCatList] = useState<any>(null); // 仓库列表 const [catList, setCatList] = useState<any>(null); // 仓库列表
const onFinish = (values: any) => { const onFinish = (values: any) => {
let data = values; if (tagPId) {
values.pid = tagPId;
}
if (!tagId) { if (!tagId) {
folderStore.add(data); folderStore.add(values);
} else { } else {
folderStore.putItem(tagId, data); folderStore.putItem(tagId, values);
} }
setIsModalOpen(false); setIsModalOpen(false);
}; };
@ -64,7 +67,7 @@ const ArchivesFolder = (props: Store) => {
const onFinishFailed = () => {}; const onFinishFailed = () => {};
type DirectoryTreeProps = GetProps<typeof Tree.DirectoryTree>; type DirectoryTreeProps = GetProps<typeof Tree.DirectoryTree>;
const onSelect: DirectoryTreeProps["onSelect"] = (keys, info:any) => { const onSelect: DirectoryTreeProps["onSelect"] = (keys, info: any) => {
setFolderId(info.node.identity); setFolderId(info.node.identity);
}; };
@ -80,10 +83,10 @@ const ArchivesFolder = (props: Store) => {
</Button> </Button>
</Space> </Space>
<Row> <Row>
<Col span={16} push={8} style={{ border:"1px solid #ccc" }}> <Col span={16} push={8} style={{ border: "1px solid #ccc" }}>
<FileListPage id={folderId} /> <FileListPage id={folderId} />
</Col> </Col>
<Col span={8} pull={16} style={{ border:"1px solid #ccc" }}> <Col span={8} pull={16} style={{ border: "1px solid #ccc" }}>
<DirectoryTree <DirectoryTree
defaultExpandAll defaultExpandAll
onSelect={onSelect} onSelect={onSelect}
@ -96,8 +99,10 @@ const ArchivesFolder = (props: Store) => {
<span <span
style={{ marginLeft: "10px", color: "blue" }} style={{ marginLeft: "10px", color: "blue" }}
onClick={(e) => { onClick={(e) => {
setPId(nodeData.id); // 设置当前id 为父节点id
e?.stopPropagation(); e?.stopPropagation();
console.log("new") addHandler();
console.log("new");
}} }}
> >

View File

@ -1,7 +1,8 @@
import { Button, UploadFile } from "antd"; import { Button, Modal, Space, UploadFile } from "antd";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import { inject, observer } from "mobx-react"; import { inject, observer } from "mobx-react";
import AliUpload from "@/components/ali_upload"; import AliUpload from "@/components/ali_upload";
import FileViewer from "@codesmith-99/react-file-preview";
interface ArchiveUploadFile extends UploadFile { interface ArchiveUploadFile extends UploadFile {
file_type: string | undefined; file_type: string | undefined;
file_url: string | undefined; file_url: string | undefined;
@ -9,11 +10,74 @@ interface ArchiveUploadFile extends UploadFile {
const FileListPage = (props: any) => { const FileListPage = (props: any) => {
const { folderStore, archivesStore, id } = props; const { folderStore, archivesStore, id } = props;
const [fileList, setFileList] = useState<ArchiveUploadFile[]>([]); const [fileList, setFileList] = useState<ArchiveUploadFile[]>([]);
const [isModalOpen, setIsModalOpen] = useState<boolean>(false);
const [fileNmae, setFileName] = useState<string>("");
useEffect(() => { useEffect(() => {
folderStore.getAlist(id).then((res) => { folderStore.getAlist(id).then((res) => {
setFileList(folderStore.alist); setFileList(folderStore.alist);
}); });
}, [folderStore, id]); }, [folderStore, id]);
const getFileTypeFromUrl = (url) => {
if (url === "" || url.length === 0) return;
// 解析URL以提取文件名
const filename = url.split("/").pop();
// 获取文件扩展名
const fileExtension = filename.split(".").pop();
// 返回文件扩展名
return fileExtension;
};
const preView = (imageUrl) => {
let fileType = getFileTypeFromUrl(imageUrl);
console.log(imageUrl);
switch (fileType) {
case "jpeg":
return <img style={{ width: "100%" }} src={imageUrl} alt="" />;
case "jpg":
return <img style={{ width: "100%" }} src={imageUrl} alt="" />;
case "png":
return <img style={{ width: "100%" }} src={imageUrl} alt="" />;
case "pdf":
return (
<div style={{ width: "100%", height: "500px" }}>
<iframe
style={{ width: "100%", height: "500px" }}
src={imageUrl}
title="描述"
></iframe>
;
</div>
);
case "mp4":
return (
<div key={imageUrl} style={{ width: "100%", height: "600px" }}>
<video
controls
style={{ width: "100%", height: "600px" }}
src={imageUrl}
></video>
</div>
);
case "docx":
return (
<div key={imageUrl} style={{ width: "100%", height: "600px" }}>
<FileViewer
loader={undefined}
src={imageUrl}
fileName="docx"
onError={(e) => {
console.log("error doc", e);
}}
/>
</div>
);
case "":
return <div style={{ width: "100%", height: "600px" }}></div>;
default:
return <div style={{ width: "100%", height: "600px" }}></div>;
}
};
const saveHandler = () => { const saveHandler = () => {
fileList.forEach((item) => { fileList.forEach((item) => {
item.file_url = item.url; item.file_url = item.url;
@ -21,21 +85,45 @@ const FileListPage = (props: any) => {
}); });
archivesStore.save(id, fileList); archivesStore.save(id, fileList);
}; };
return ( return (
<div style={{ margin: "10px" }}> <div style={{ margin: "10px" }}>
<div style={{ margin: "10px" }}></div>
<div style={{ margin: "10px" }}> <div style={{ margin: "10px" }}>
<Button type="primary" onClick={saveHandler}> <Button type="primary" onClick={saveHandler}>
</Button> </Button>
</div> </div>
<AliUpload {fileList?.map((item: any) => {
imgList={fileList ?? []} return (
onChnage={(v) => { <div
setFileList(v); key={item?.file_name}
}} style={{ display: "flex", margin: "10px" }}
maxCount={100} >
/> <Space>
<span className="text-overflow"> {item?.file_name}</span>
<Button
onClick={() => {
setFileName(item?.file_url);
setIsModalOpen(true);
}}
>
</Button>
<Button></Button>
</Space>
</div>
);
})}
<Modal
title="文件预览"
footer={null}
width={1200}
height={500}
open={isModalOpen}
onCancel={() => setIsModalOpen(false)}
>
{preView(fileNmae)}
</Modal>
</div> </div>
); );
}; };

View File

@ -1,10 +1,24 @@
import { Modal } from "antd"; import { Modal } from "antd";
import { inject, observer } from "mobx-react";
import { useState } from "react"; import { useState } from "react";
const WhichVideo = () => { const WhichVideo = (props) => {
const { homeStore } = props;
const [isModalOpen, setIsModalOpen] = useState<boolean>(false); const [isModalOpen, setIsModalOpen] = useState<boolean>(false);
const openDispatch = () => { const [channelList, setChannelList] = useState<Array<any>>([]);
const openDispatch = async () => {
setIsModalOpen(true); setIsModalOpen(true);
let req = await homeStore.getVideoUrlList();
let list: Array<any> = [];
for await (const item of req.EasyDarwin.Body.Devices) {
let reqs = await homeStore.getChannerUrlList(item.DeviceID);
if (reqs?.EasyDarwin) {
list.push(...reqs?.EasyDarwin?.Body.Channels);
}
}
setChannelList(list);
}; };
return ( return (
<> <>
@ -12,7 +26,7 @@ const WhichVideo = () => {
<Modal <Modal
title={"视频查看"} title={"视频查看"}
className="owner_model" className="owner_model"
width={800} width={1000}
open={isModalOpen} open={isModalOpen}
afterClose={() => {}} afterClose={() => {}}
onOk={() => {}} onOk={() => {}}
@ -20,9 +34,20 @@ const WhichVideo = () => {
onCancel={() => { onCancel={() => {
setIsModalOpen(false); setIsModalOpen(false);
}} }}
></Modal> >
<div style={{ height: "700px", overflowY: "scroll" }}>
{channelList.map((item, index) => {
return (
<div key={index} style={{ cursor: "pointer" }}>
<p style={{ color: "#fff" }}>{item.Name}</p>
</div>
);
})}
</div>
</Modal>
</> </>
); );
}; };
export default WhichVideo; // export default WhichVideo;
export default inject("homeStore")(observer(WhichVideo));

View File

@ -13,6 +13,7 @@ const Orgin = (props: Store) => {
useEffect(() => { useEffect(() => {
homeStore.getOgCount(); homeStore.getOgCount();
homeStore.getVideoUrlList();
}, [homeStore]); }, [homeStore]);
const showModal = () => { const showModal = () => {
setIsModalOpen(true); setIsModalOpen(true);

View File

@ -13,6 +13,7 @@ const Login = (props) => {
userName: values.account, userName: values.account,
passWord: values.password, passWord: values.password,
}); });
await usrStore.loginVideo()
if (status) { if (status) {
usrStore.closeLoginDilog(); usrStore.closeLoginDilog();
navigate("/admin/user", { replace: true }); navigate("/admin/user", { replace: true });

View File

@ -6,7 +6,7 @@ axios.defaults.headers.common["Content-Type"] = "application/json; charset=utf8"
axios.defaults.headers.common["X-Requested-With"] = "XMLHttpRequest"; axios.defaults.headers.common["X-Requested-With"] = "XMLHttpRequest";
axios.interceptors.request.use((config) => { axios.interceptors.request.use((config) => {
config.baseURL = `${Config.baseUrl}v1/`; config.baseURL = `${Config.baseUrl}v1/`;
config.timeout = 5000; config.timeout = 50000;
let token = window.localStorage.getItem("token") let token = window.localStorage.getItem("token")
config.headers.Authorization = token ?? "1" config.headers.Authorization = token ?? "1"
return config; return config;
@ -32,10 +32,23 @@ axios.interceptors.response.use((res: AxiosResponse) => {
return Promise.reject(err); return Promise.reject(err);
}); });
class BaseHttp { class BaseHttp {
async gets(url: string, params: any) {
let res = await axios({
method: 'get',
url: url,
headers: {
"token": window.localStorage.getItem("video-token"),
'Content-Type': 'application/json; charset=utf-8'
},
params
});
return res.data;
};
async get(url: string, params: any) { async get(url: string, params: any) {
let res = await axios({ let res = await axios({
method: 'get', method: 'get',
url: url, url: url,
params params
}); });
return res.data; return res.data;

View File

@ -4,6 +4,7 @@ import baseHttp from "@/service/base";
import BaseStore from "./baseStore"; import BaseStore from "./baseStore";
import { TagDataType } from "@/model/userModel"; import { TagDataType } from "@/model/userModel";
import MapUtl from "@/components/map/mapUtil"; import MapUtl from "@/components/map/mapUtil";
import Config from "@/util/config";
class HomeConfig { class HomeConfig {
static os: string = "public/os" static os: string = "public/os"
@ -14,6 +15,10 @@ class HomeConfig {
static ae: string = "public/ae" static ae: string = "public/ae"
static newTask: string = "user/newTask" static newTask: string = "user/newTask"
static taskulist: string = "public/taskInUser" static taskulist: string = "public/taskInUser"
static deviceList: string = "api/v1/devicesconfig" //设备列表
static channerList: string = "api/v1/channelsconfig" //设备列表
static channelstream: string = "api/v1/channelstream" //设备包活
} }
class HomeStore extends BaseStore<TagDataType> { class HomeStore extends BaseStore<TagDataType> {
constructor() { constructor() {
@ -49,6 +54,49 @@ class HomeStore extends BaseStore<TagDataType> {
async getAe() { async getAe() {
return await baseHttp.get(HomeConfig.ae, {}); return await baseHttp.get(HomeConfig.ae, {});
} }
// 获取视频推流连接
async getVideoUrlList() {
try {
let data = await baseHttp.gets(Config.videoApi + HomeConfig.deviceList, {
start: 0,
limit: 30
})
return data
} catch (error) {
console.log(error)
return false
}
}
// 通道列表
async getChannerUrlList(deviceId) {
try {
let data = await baseHttp.gets(Config.videoApi + HomeConfig.channerList, {
start: 0,
limit: 30,
device:deviceId
})
return data;
} catch (error) {
console.log(error)
return false
}
}
// 获取通道流
async getChannerStrem(deviceId,channel) {
try {
let data = await baseHttp.gets(Config.videoApi + HomeConfig.channelstream, {
device:deviceId,
channel:channel,
protocol:"HLS"
})
console.log(data)
return true
} catch (error) {
console.log(error)
return false
}
}
async getNewTask() { async getNewTask() {
let res = await baseHttp.get(HomeConfig.newTask, {}); let res = await baseHttp.get(HomeConfig.newTask, {});
if (res.data?.record) { if (res.data?.record) {

View File

@ -4,6 +4,7 @@ import baseHttp from "@/service/base";
import BaseStore from "./baseStore"; import BaseStore from "./baseStore";
import { UserDataType, UserInfos } from "@/model/userModel"; import { UserDataType, UserInfos } from "@/model/userModel";
import { message } from "antd"; import { message } from "antd";
import Config from "@/util/config";
class UserConfig { class UserConfig {
static LOGINURI: string = "anth/login" static LOGINURI: string = "anth/login"
static LIST: string = "user/list" static LIST: string = "user/list"
@ -15,6 +16,7 @@ class UserConfig {
static per: string = "persMgmt/list" static per: string = "persMgmt/list"
static serch: string = "user/serch" static serch: string = "user/serch"
static getPatrol: string = "user/getPatrol" static getPatrol: string = "user/getPatrol"
static videoLogin: string = "api/v1/login"
} }
@ -34,7 +36,7 @@ class UserStore extends BaseStore<UserDataType> {
serchUser: action, serchUser: action,
setPoverDe: action, setPoverDe: action,
setUserDetaul: action, setUserDetaul: action,
getPatrol:action, getPatrol: action,
_userinfo: observable, _userinfo: observable,
isNeedLogin: observable, isNeedLogin: observable,
poverDetail: observable, poverDetail: observable,
@ -53,7 +55,7 @@ class UserStore extends BaseStore<UserDataType> {
return await baseHttp.get(UserConfig.pover, null) return await baseHttp.get(UserConfig.pover, null)
} }
async serchUser(params: any) { async serchUser(params: any) {
return await baseHttp.get(UserConfig.serch, {user_name:params}) return await baseHttp.get(UserConfig.serch, { user_name: params })
} }
async getPatrol() { async getPatrol() {
return await baseHttp.get(UserConfig.getPatrol, {}) return await baseHttp.get(UserConfig.getPatrol, {})
@ -71,6 +73,7 @@ class UserStore extends BaseStore<UserDataType> {
this._userinfo.token = ""; this._userinfo.token = "";
window.localStorage.clear(); window.localStorage.clear();
this.item = ""; this.item = "";
window.location.href = '#/login'
} }
async login(params: UserInfos) { async login(params: UserInfos) {
let param = { let param = {
@ -92,6 +95,20 @@ class UserStore extends BaseStore<UserDataType> {
return false return false
} }
} }
async loginVideo() {
try {
let data = await baseHttp.get(Config.videoApi + UserConfig.videoLogin, {
username: "easycvr",
password: "4092c09db0af030641a977d76044de4f",
})
window.localStorage.setItem("video-token", data.EasyDarwin.Body.Token ?? "");
return true
} catch (error) {
console.log(error)
return false
}
}
openLoginDilog() { openLoginDilog() {
this.isNeedLogin = true; this.isNeedLogin = true;
} }

View File

@ -1,10 +1,11 @@
class Config { class Config {
static baseUrl = "https://rw.quwanya.cn/"; static baseUrl = "https://rw.quwanya.cn/";
static uploadUrl = "https://rw.quwanya.cn/"; static uploadUrl = "https://rw.quwanya.cn";
static ws = "wss://rw.quwanya.cn/wsadmin?id=admin"; static ws = "wss://rw.quwanya.cn/wsadmin?id=admin";
// static rtc = "wss://rw.quwanya.cn/ws";
static userStatic = "https://rw.quwanya.cn/uploads/user/"; static userStatic = "https://rw.quwanya.cn/uploads/user/";
// https://rw.quwanya.cn/uploads/user/%E5%B4%94%E6%96%87%E8%8C%9C.jpg static videoApi = "https://sprh.hswzct.cn:4443/"; //
} }
export default Config; export default Config;
// 1、发布任务的时候选择视频列表
// 2、人的数据区分

View File

@ -1,6 +1,5 @@
import SocketService from "./socket"; import SocketService from "./socket";
import baseHttp from "@/service/base";
class WebRtc { class WebRtc {
private mediaStream: MediaStream | Blob | null = null; private mediaStream: MediaStream | Blob | null = null;
@ -55,16 +54,22 @@ class WebRtc {
} }
} }
async createOffer() { async createOffer() {
let basData =await baseHttp.get('/public/webRtcConfig', { service: "11", username: "admin" })
const configuration = { const configuration = {
iceServers: [ iceServers: [
{ {
urls: basData.data.credential.uris, urls: "stun:118.114.255.222:3478",
username: basData.data.credential.username, username: "admin",
credential: basData.data.credential.password, credential: "admin123456",
ttl:basData.data.credential.ttl "ttl": 86400
}, },
] {
urls: "turn:118.114.255.222:3478",
username: "admin",
credential: "admin123456",
"ttl": 86400
}
],
sdpSemantics: "unified-plan",
} }
this.gets(configuration) this.gets(configuration)
} }
@ -76,7 +81,6 @@ class WebRtc {
const re = document.querySelector('#remoteVideo') as HTMLVideoElement; const re = document.querySelector('#remoteVideo') as HTMLVideoElement;
re.autoplay = true re.autoplay = true
re.controls = true re.controls = true
console.log(event.streams[0])
re.srcObject = event.streams[0]; re.srcObject = event.streams[0];
event.track.onmute = function (event) { event.track.onmute = function (event) {
re.play() re.play()