first commit
This commit is contained in:
parent
77fc8ce739
commit
b51aaf7015
|
@ -49,7 +49,7 @@ const LayOut = (props: Store) => {
|
|||
style={{ flex: 1, minWidth: 0 }}
|
||||
/>
|
||||
|
||||
<span style={{ color: "#fff" }}>退出登录</span>
|
||||
<span style={{ color: "#fff" }} onClick={() => usrStore.logOut()}>退出登录</span>
|
||||
</Header>
|
||||
<Content style={{ padding: "0 20px" }}>
|
||||
<Outlet />
|
||||
|
|
|
@ -94,7 +94,7 @@ code {
|
|||
color: #fff;
|
||||
}
|
||||
}
|
||||
.ant-modal-close{
|
||||
.ant-modal-close {
|
||||
color: #fff;
|
||||
}
|
||||
.ant-modal-body {
|
||||
|
@ -110,3 +110,11 @@ code {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.text-overflow {
|
||||
display: inline-block;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
max-width: 200px;
|
||||
}
|
||||
|
|
|
@ -28,14 +28,17 @@ const ArchivesFolder = (props: Store) => {
|
|||
const formRef = React.useRef<FormInstance>(null);
|
||||
|
||||
const [tagId, setId] = useState<Number | null>(null);
|
||||
const [tagPId, setPId] = useState<Number | null>(null);
|
||||
const [folderId, setFolderId] = useState<String | null>(null);
|
||||
const [catList, setCatList] = useState<any>(null); // 仓库列表
|
||||
const onFinish = (values: any) => {
|
||||
let data = values;
|
||||
if (tagPId) {
|
||||
values.pid = tagPId;
|
||||
}
|
||||
if (!tagId) {
|
||||
folderStore.add(data);
|
||||
folderStore.add(values);
|
||||
} else {
|
||||
folderStore.putItem(tagId, data);
|
||||
folderStore.putItem(tagId, values);
|
||||
}
|
||||
setIsModalOpen(false);
|
||||
};
|
||||
|
@ -64,7 +67,7 @@ const ArchivesFolder = (props: Store) => {
|
|||
|
||||
const onFinishFailed = () => {};
|
||||
type DirectoryTreeProps = GetProps<typeof Tree.DirectoryTree>;
|
||||
const onSelect: DirectoryTreeProps["onSelect"] = (keys, info:any) => {
|
||||
const onSelect: DirectoryTreeProps["onSelect"] = (keys, info: any) => {
|
||||
setFolderId(info.node.identity);
|
||||
};
|
||||
|
||||
|
@ -80,10 +83,10 @@ const ArchivesFolder = (props: Store) => {
|
|||
</Button>
|
||||
</Space>
|
||||
<Row>
|
||||
<Col span={16} push={8} style={{ border:"1px solid #ccc" }}>
|
||||
<Col span={16} push={8} style={{ border: "1px solid #ccc" }}>
|
||||
<FileListPage id={folderId} />
|
||||
</Col>
|
||||
<Col span={8} pull={16} style={{ border:"1px solid #ccc" }}>
|
||||
<Col span={8} pull={16} style={{ border: "1px solid #ccc" }}>
|
||||
<DirectoryTree
|
||||
defaultExpandAll
|
||||
onSelect={onSelect}
|
||||
|
@ -96,8 +99,10 @@ const ArchivesFolder = (props: Store) => {
|
|||
<span
|
||||
style={{ marginLeft: "10px", color: "blue" }}
|
||||
onClick={(e) => {
|
||||
setPId(nodeData.id); // 设置当前id 为父节点id
|
||||
e?.stopPropagation();
|
||||
console.log("new")
|
||||
addHandler();
|
||||
console.log("new");
|
||||
}}
|
||||
>
|
||||
新建
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import { Button, UploadFile } from "antd";
|
||||
import { Button, Modal, Space, UploadFile } from "antd";
|
||||
import { useEffect, useState } from "react";
|
||||
import { inject, observer } from "mobx-react";
|
||||
import AliUpload from "@/components/ali_upload";
|
||||
import FileViewer from "@codesmith-99/react-file-preview";
|
||||
interface ArchiveUploadFile extends UploadFile {
|
||||
file_type: string | undefined;
|
||||
file_url: string | undefined;
|
||||
|
@ -9,11 +10,74 @@ interface ArchiveUploadFile extends UploadFile {
|
|||
const FileListPage = (props: any) => {
|
||||
const { folderStore, archivesStore, id } = props;
|
||||
const [fileList, setFileList] = useState<ArchiveUploadFile[]>([]);
|
||||
const [isModalOpen, setIsModalOpen] = useState<boolean>(false);
|
||||
const [fileNmae, setFileName] = useState<string>("");
|
||||
|
||||
useEffect(() => {
|
||||
folderStore.getAlist(id).then((res) => {
|
||||
setFileList(folderStore.alist);
|
||||
});
|
||||
}, [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 = () => {
|
||||
fileList.forEach((item) => {
|
||||
item.file_url = item.url;
|
||||
|
@ -21,21 +85,45 @@ const FileListPage = (props: any) => {
|
|||
});
|
||||
archivesStore.save(id, fileList);
|
||||
};
|
||||
|
||||
return (
|
||||
<div style={{ margin: "10px" }}>
|
||||
<div style={{ margin: "10px" }}></div>
|
||||
<div style={{ margin: "10px" }}>
|
||||
<Button type="primary" onClick={saveHandler}>
|
||||
保存
|
||||
上传文件
|
||||
</Button>
|
||||
</div>
|
||||
<AliUpload
|
||||
imgList={fileList ?? []}
|
||||
onChnage={(v) => {
|
||||
setFileList(v);
|
||||
}}
|
||||
maxCount={100}
|
||||
/>
|
||||
{fileList?.map((item: any) => {
|
||||
return (
|
||||
<div
|
||||
key={item?.file_name}
|
||||
style={{ display: "flex", margin: "10px" }}
|
||||
>
|
||||
<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>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -1,10 +1,24 @@
|
|||
import { Modal } from "antd";
|
||||
import { inject, observer } from "mobx-react";
|
||||
import { useState } from "react";
|
||||
|
||||
const WhichVideo = () => {
|
||||
const WhichVideo = (props) => {
|
||||
const { homeStore } = props;
|
||||
const [isModalOpen, setIsModalOpen] = useState<boolean>(false);
|
||||
const openDispatch = () => {
|
||||
const [channelList, setChannelList] = useState<Array<any>>([]);
|
||||
const openDispatch = async () => {
|
||||
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 (
|
||||
<>
|
||||
|
@ -12,7 +26,7 @@ const WhichVideo = () => {
|
|||
<Modal
|
||||
title={"视频查看"}
|
||||
className="owner_model"
|
||||
width={800}
|
||||
width={1000}
|
||||
open={isModalOpen}
|
||||
afterClose={() => {}}
|
||||
onOk={() => {}}
|
||||
|
@ -20,9 +34,20 @@ const WhichVideo = () => {
|
|||
onCancel={() => {
|
||||
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));
|
||||
|
|
|
@ -13,6 +13,7 @@ const Orgin = (props: Store) => {
|
|||
|
||||
useEffect(() => {
|
||||
homeStore.getOgCount();
|
||||
homeStore.getVideoUrlList();
|
||||
}, [homeStore]);
|
||||
const showModal = () => {
|
||||
setIsModalOpen(true);
|
||||
|
|
|
@ -13,6 +13,7 @@ const Login = (props) => {
|
|||
userName: values.account,
|
||||
passWord: values.password,
|
||||
});
|
||||
await usrStore.loginVideo()
|
||||
if (status) {
|
||||
usrStore.closeLoginDilog();
|
||||
navigate("/admin/user", { replace: true });
|
||||
|
|
|
@ -6,7 +6,7 @@ axios.defaults.headers.common["Content-Type"] = "application/json; charset=utf8"
|
|||
axios.defaults.headers.common["X-Requested-With"] = "XMLHttpRequest";
|
||||
axios.interceptors.request.use((config) => {
|
||||
config.baseURL = `${Config.baseUrl}v1/`;
|
||||
config.timeout = 5000;
|
||||
config.timeout = 50000;
|
||||
let token = window.localStorage.getItem("token")
|
||||
config.headers.Authorization = token ?? "1"
|
||||
return config;
|
||||
|
@ -32,10 +32,23 @@ axios.interceptors.response.use((res: AxiosResponse) => {
|
|||
return Promise.reject(err);
|
||||
});
|
||||
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) {
|
||||
let res = await axios({
|
||||
method: 'get',
|
||||
url: url,
|
||||
|
||||
params
|
||||
});
|
||||
return res.data;
|
||||
|
|
|
@ -4,6 +4,7 @@ import baseHttp from "@/service/base";
|
|||
import BaseStore from "./baseStore";
|
||||
import { TagDataType } from "@/model/userModel";
|
||||
import MapUtl from "@/components/map/mapUtil";
|
||||
import Config from "@/util/config";
|
||||
|
||||
class HomeConfig {
|
||||
static os: string = "public/os"
|
||||
|
@ -14,6 +15,10 @@ class HomeConfig {
|
|||
static ae: string = "public/ae"
|
||||
static newTask: string = "user/newTask"
|
||||
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> {
|
||||
constructor() {
|
||||
|
@ -49,6 +54,49 @@ class HomeStore extends BaseStore<TagDataType> {
|
|||
async getAe() {
|
||||
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() {
|
||||
let res = await baseHttp.get(HomeConfig.newTask, {});
|
||||
if (res.data?.record) {
|
||||
|
|
|
@ -4,6 +4,7 @@ import baseHttp from "@/service/base";
|
|||
import BaseStore from "./baseStore";
|
||||
import { UserDataType, UserInfos } from "@/model/userModel";
|
||||
import { message } from "antd";
|
||||
import Config from "@/util/config";
|
||||
class UserConfig {
|
||||
static LOGINURI: string = "anth/login"
|
||||
static LIST: string = "user/list"
|
||||
|
@ -15,6 +16,7 @@ class UserConfig {
|
|||
static per: string = "persMgmt/list"
|
||||
static serch: string = "user/serch"
|
||||
static getPatrol: string = "user/getPatrol"
|
||||
static videoLogin: string = "api/v1/login"
|
||||
|
||||
|
||||
}
|
||||
|
@ -34,7 +36,7 @@ class UserStore extends BaseStore<UserDataType> {
|
|||
serchUser: action,
|
||||
setPoverDe: action,
|
||||
setUserDetaul: action,
|
||||
getPatrol:action,
|
||||
getPatrol: action,
|
||||
_userinfo: observable,
|
||||
isNeedLogin: observable,
|
||||
poverDetail: observable,
|
||||
|
@ -53,7 +55,7 @@ class UserStore extends BaseStore<UserDataType> {
|
|||
return await baseHttp.get(UserConfig.pover, null)
|
||||
}
|
||||
async serchUser(params: any) {
|
||||
return await baseHttp.get(UserConfig.serch, {user_name:params})
|
||||
return await baseHttp.get(UserConfig.serch, { user_name: params })
|
||||
}
|
||||
async getPatrol() {
|
||||
return await baseHttp.get(UserConfig.getPatrol, {})
|
||||
|
@ -71,6 +73,7 @@ class UserStore extends BaseStore<UserDataType> {
|
|||
this._userinfo.token = "";
|
||||
window.localStorage.clear();
|
||||
this.item = "";
|
||||
window.location.href = '#/login'
|
||||
}
|
||||
async login(params: UserInfos) {
|
||||
let param = {
|
||||
|
@ -92,6 +95,20 @@ class UserStore extends BaseStore<UserDataType> {
|
|||
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() {
|
||||
this.isNeedLogin = true;
|
||||
}
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
class Config {
|
||||
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 rtc = "wss://rw.quwanya.cn/ws";
|
||||
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;
|
||||
|
||||
// 1、发布任务的时候选择视频列表
|
||||
// 2、人的数据区分
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
|
||||
import SocketService from "./socket";
|
||||
import baseHttp from "@/service/base";
|
||||
|
||||
class WebRtc {
|
||||
private mediaStream: MediaStream | Blob | null = null;
|
||||
|
@ -55,16 +54,22 @@ class WebRtc {
|
|||
}
|
||||
}
|
||||
async createOffer() {
|
||||
let basData =await baseHttp.get('/public/webRtcConfig', { service: "11", username: "admin" })
|
||||
const configuration = {
|
||||
iceServers: [
|
||||
{
|
||||
urls: basData.data.credential.uris,
|
||||
username: basData.data.credential.username,
|
||||
credential: basData.data.credential.password,
|
||||
ttl:basData.data.credential.ttl
|
||||
urls: "stun:118.114.255.222:3478",
|
||||
username: "admin",
|
||||
credential: "admin123456",
|
||||
"ttl": 86400
|
||||
},
|
||||
]
|
||||
{
|
||||
urls: "turn:118.114.255.222:3478",
|
||||
username: "admin",
|
||||
credential: "admin123456",
|
||||
"ttl": 86400
|
||||
}
|
||||
],
|
||||
sdpSemantics: "unified-plan",
|
||||
}
|
||||
this.gets(configuration)
|
||||
}
|
||||
|
@ -76,7 +81,6 @@ class WebRtc {
|
|||
const re = document.querySelector('#remoteVideo') as HTMLVideoElement;
|
||||
re.autoplay = true
|
||||
re.controls = true
|
||||
console.log(event.streams[0])
|
||||
re.srcObject = event.streams[0];
|
||||
event.track.onmute = function (event) {
|
||||
re.play()
|
||||
|
|
Loading…
Reference in New Issue