diff --git a/src/components/form/featch_select.tsx b/src/components/form/featch_select.tsx index 8e0feab..db520df 100644 --- a/src/components/form/featch_select.tsx +++ b/src/components/form/featch_select.tsx @@ -1,17 +1,25 @@ -import React, { useMemo, useRef, useState } from 'react'; -import { Select, Spin } from 'antd'; -import type { SelectProps } from 'antd'; -import debounce from 'lodash/debounce'; +import React, { useMemo, useRef, useState } from "react"; +import { Select, Spin } from "antd"; +import type { SelectProps } from "antd"; +import debounce from "lodash/debounce"; export interface DebounceSelectProps - extends Omit, 'options' | 'children'> { + extends Omit, "options" | "children"> { fetchOptions: (search: string) => Promise; debounceTimeout?: number; } const DebounceSelect = < - ValueType extends { key?: string; label: React.ReactNode; value: string | number } = any, ->({ fetchOptions, debounceTimeout = 800, ...props }: DebounceSelectProps) =>{ + ValueType extends { + key?: string; + label: React.ReactNode; + value: string | number; + } = any +>({ + fetchOptions, + debounceTimeout = 800, + ...props +}: DebounceSelectProps) => { const [fetching, setFetching] = useState(false); const [options, setOptions] = useState([]); const fetchRef = useRef(0); @@ -43,9 +51,10 @@ const DebounceSelect = < onSearch={debounceFetcher} notFoundContent={fetching ? : null} {...props} + options={options} /> ); -} +}; -export default DebounceSelect \ No newline at end of file +export default DebounceSelect; diff --git a/src/components/layout/layout.tsx b/src/components/layout/layout.tsx index dab81c0..1374963 100644 --- a/src/components/layout/layout.tsx +++ b/src/components/layout/layout.tsx @@ -7,107 +7,19 @@ import { HomeTwoTone } from "@ant-design/icons"; import { inject, observer } from "mobx-react"; import { Store } from "antd/es/form/interface"; import { useEffect } from "react"; +import { items } from "./layout_config"; const LayOut = (props: Store) => { const { usrStore } = props; const nav = useNavigate(); const location = useLocation(); - + useEffect(() => { - console.log("layout ",usrStore.isNeedLogin); if (usrStore.isNeedLogin) { nav("/login"); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [usrStore.isNeedLogin]); - const items = [ - { - key: "/admin/user", - label: `用户管理`, - children: [ - { - key: "/admin/dep", - label: `部门管理`, - }, - { - key: "/admin/user", - label: `用户管理`, - }, - { - key: "/admin/teamMgmt", - label: `队伍属性管理`, - }, - { - key: "/admin/persMgmt", - label: `个人身份管理`, - }, - { - key: "/admin/community", - label: `社区管理`, - }, - { - key: "/admin/grid", - label: `网格管理`, - }, - { - key: "/admin/patrolBrigade", - label: `巡防大队`, - }, - ], - }, - { - key: "/admin/archives/box", - label: `档案管理`, - }, - { - key: "/admin/material", - label: `物资管理`, - children: [ - { - key: "/admin/whse/whseMgmt", - label: `仓库管理`, - }, - { - key: "/admin/materialMgmt", - label: `物资管理`, - }, - ], - }, - { - key: "/admin/leaveApproval", - label: `请假审批`, - }, - { - key: "/admin/political", - label: `政治法规`, - children: [ - { - key: "/admin/politicalStudy", - label: `政治学习`, - }, - { - key: `/admin/polRegulations`, - label: `政治法规管理`, - }, - ], - }, - { - key: "/admin/task", - label: `任务管理`, - children: [ - { label: "处突任务", key: "/admin/emergency" }, - { label: "巡逻任务", key: "/admin/patrol" }, - { label: "训练任务", key: "/admin/training" }, - ], - }, - { - key: "/admin/sys", - label: `系统管理`, - children: [ - { label: "系统设置", key: "/admin/sys/setting" }, - { label: "光荣牌审核", key: "/admin/sys/gp" }, - ], - }, - ]; + return (
{ }} style={{ flex: 1, minWidth: 0 }} /> + + 退出登录
- 双流区黄水镇人民政府 ©{new Date().getFullYear()} Created + 双流区黄水镇人民政府 ©{new Date().getFullYear()} Created
); diff --git a/src/components/layout/layout_config.ts b/src/components/layout/layout_config.ts new file mode 100644 index 0000000..b329485 --- /dev/null +++ b/src/components/layout/layout_config.ts @@ -0,0 +1,87 @@ +export const items = [ + { + key: "/admin/user", + label: `用户管理`, + children: [ + { + key: "/admin/user", + label: `用户管理`, + }, + { + key: "/admin/teamMgmt", + label: `队伍属性管理`, + }, + { + key: "/admin/persMgmt", + label: `个人身份管理`, + }, + { + key: "/admin/community", + label: `社区管理`, + }, + { + key: "/admin/grid", + label: `网格管理`, + }, + { + key: "/admin/patrolBrigade", + label: `巡防大队`, + }, + ], + }, + { + key: "/admin/archives/box", + label: `档案管理`, + }, + { + key: "/admin/material", + label: `物资管理`, + children: [ + { + key: "/admin/whse/whseMgmt", + label: `仓库管理`, + }, + { + key: "/admin/materialMgmt", + label: `物资管理`, + }, + ], + }, + { + key: "/admin/leaveApproval", + label: `请假审批`, + }, + { + key: "/admin/political", + label: `政治法规`, + children: [ + { + key: "/admin/politicalStudy", + label: `政治学习`, + }, + { + key: `/admin/polRegulations`, + label: `政治法规管理`, + }, + ], + }, + { + key: "/admin/task", + label: `任务管理`, + children: [ + { label: "处突任务", key: "/admin/emergency" }, + { label: "巡逻任务", key: "/admin/patrol" }, + { label: "训练任务", key: "/admin/training" }, + ], + }, + { + key: "/admin/sys", + label: `系统管理`, + children: [ + { label: `部门管理`, key: "/admin/dep" }, + { label: "系统设置", key: "/admin/sys/setting" }, + { label: "光荣牌审核", key: "/admin/sys/gp" }, + { label: "评优审核", key: "/admin/sys/gp" }, + ], + }, +]; \ No newline at end of file diff --git a/src/pages/dep/index.tsx b/src/pages/dep/index.tsx index d24e2ed..cca5908 100644 --- a/src/pages/dep/index.tsx +++ b/src/pages/dep/index.tsx @@ -35,7 +35,7 @@ const Dep = (props: Store) => { setIsModalOpen(true); formRef.current?.setFieldsValue(data); setRecord(data); - setId(record.id); + setId(record.key); }; const onFinish = (values: any) => { if (!tagId) { @@ -95,11 +95,11 @@ const Dep = (props: Store) => { type DirectoryTreeProps = GetProps; const onSelect: DirectoryTreeProps["onSelect"] = (keys, info) => { - console.log("Trigger Select", keys, info); + // console.log("Trigger Select", keys, info); }; const onExpand: DirectoryTreeProps["onExpand"] = (keys, info) => { - console.log("Trigger Expand", keys, info); + // console.log("Trigger Expand", keys, info); }; return ( @@ -126,11 +126,32 @@ const Dep = (props: Store) => { onExpand={onExpand} treeData={org} titleRender={(nodeData: DataNode) => { - return <>{nodeData.title}编辑 + return ( + <> + {nodeData.title} + { + edit(nodeData); + }} + > + 编辑 + + { + depStore.deleteItem(nodeData.key); + getOrg() + }} + > + 删除 + + + ); }} /> formRef.current?.resetFields()} @@ -139,6 +160,7 @@ const Dep = (props: Store) => { cancelText="取消" onCancel={() => { setId(null); + setRecord(null); setIsModalOpen(false); }} > diff --git a/src/pages/emergency/index.tsx b/src/pages/emergency/index.tsx index 351ed58..a74a607 100644 --- a/src/pages/emergency/index.tsx +++ b/src/pages/emergency/index.tsx @@ -149,7 +149,7 @@ const Emergency = (props: Store) => { baseHttp.get("/user/list", null).then((res) => { let data = res.data?.record ?? []; data.forEach((item) => { - item.label = item.account; + item.label = item.user_name; item.value = item.identity; }); setUserList(data ?? []); diff --git a/src/pages/home/home.less b/src/pages/home/home.less index 0f58f63..22952c3 100644 --- a/src/pages/home/home.less +++ b/src/pages/home/home.less @@ -50,7 +50,7 @@ display: flex; align-items: center; justify-content: center; - flex: 2; + flex: 5; .title_img { margin-left: 10px; width: 20px; @@ -66,7 +66,7 @@ margin-left: 15px; margin-right: 15px; color: #fff; - font-size: 30px; + font-size:25px; font-weight: normal; line-height: normal; letter-spacing: 0.1em; @@ -81,7 +81,7 @@ margin-left: 15px; margin-right: 15px; color: #fff; - font-size: 20px; + font-size: 14px; font-weight: normal; line-height: normal; letter-spacing: 0.1em; diff --git a/src/pages/home/home.tsx b/src/pages/home/home.tsx index 33381e2..45a8fda 100644 --- a/src/pages/home/home.tsx +++ b/src/pages/home/home.tsx @@ -21,7 +21,7 @@ const Home = observer(() => {
- 黄水镇武装平台 + 黄水镇微网实格应急处突综合指挥服务平台
diff --git a/src/pages/home/homeBottom/ec.tsx b/src/pages/home/homeBottom/ec.tsx index c614722..aa4eee0 100644 --- a/src/pages/home/homeBottom/ec.tsx +++ b/src/pages/home/homeBottom/ec.tsx @@ -5,25 +5,33 @@ import { useState } from "react"; import "./bot.less"; import { PhoneTwoTone } from "@ant-design/icons"; import { webRTC } from "@/util/webRtc"; - +import DebounceSelect from "@/components/form/featch_select"; +interface UserValue { + label: string; + value: string; +} const Ec = (props: Store) => { const [isModalOpen, setIsModalOpen] = useState(false); const { usrStore } = props; - const [userList, setUserList] = useState([]); const openDispatch = () => { try { - usrStore.getlist().then(() => { - setUserList(usrStore.list); - webRTC.init(); - setIsModalOpen(true); - }); + setIsModalOpen(true); } catch (error) { console.log(error); } }; const callphone = (record: any) => { - webRTC.calls(record.identity); + webRTC.calls(record.value); }; + const [value, setValue] = useState([]); + async function fetchUserList(username: string): Promise { + return usrStore.serchUser(username).then((res) => { + return res.data.record.map((item) => ({ + label: item.user_name, + value: item.identity, + })); + }); + } return ( <> 应急连线 @@ -45,16 +53,27 @@ const Ec = (props: Store) => {

应急连线

- {userList.map((item: any) => { + { + setValue(newValue as UserValue[]); + }} + style={{ width: "100%" }} + /> +

+ {value.map((item: any) => { return ( -
-
姓名:{item.user_name} : 未在线
-

+
+
姓名:{item.label} : 未在线
点击呼叫: { + webRTC.init(); callphone(item); }} /> @@ -75,7 +94,6 @@ const Ec = (props: Store) => { style={{ width: "300px", height: "300px" }} >
-

{ diff --git a/src/pages/home/homeLeft/weather.tsx b/src/pages/home/homeLeft/weather.tsx index 8854019..3e91516 100644 --- a/src/pages/home/homeLeft/weather.tsx +++ b/src/pages/home/homeLeft/weather.tsx @@ -14,16 +14,33 @@ const Weather = () => {

-

天气:{wechaer?.weather}

-

风向:{wechaer?.windDirection}

-

风级:{wechaer?.windPower}

-

湿度:{wechaer?.humidity}

+
+ 天气:{wechaer?.weather} + 风向:{wechaer?.windDirection} +
+
+ 风级:{wechaer?.windPower} + 湿度:{wechaer?.humidity} +
); }; diff --git a/src/pages/home/video.tsx b/src/pages/home/video.tsx index a7c8953..2618e3d 100644 --- a/src/pages/home/video.tsx +++ b/src/pages/home/video.tsx @@ -10,7 +10,7 @@ const videoJsOptions = { fluid: true, sources: [ { - src: "http://112.19.145.68:18000/hls/stream_1_0/playlist.m3u8", + src: "http://183.221.86.205:18000/hls/stream_1_0/playlist.m3u8", type: "application/x-mpegURL", }, ], @@ -19,7 +19,6 @@ const Video = (props: Store) => { const { homeStore, onReady } = props; const videoRef = useRef(null); const playerRef = useRef(null); // 使用 any 类型 - useEffect(() => { homeStore.getNewTask(); }, [homeStore]); @@ -44,7 +43,6 @@ const Video = (props: Store) => { }, [videoRef, onReady]); useEffect(() => { const player = playerRef.current; - return () => { if (player && !player.isDisposed()) { player.dispose(); diff --git a/src/pages/polRegulations/regulations.tsx b/src/pages/polRegulations/regulations.tsx index 494bad8..7f005de 100644 --- a/src/pages/polRegulations/regulations.tsx +++ b/src/pages/polRegulations/regulations.tsx @@ -64,7 +64,7 @@ const Regulations = (props: Store) => { const onFinish = (values: any) => { let data = { ...values, - file_url: values.file_url[0].name, + file_url: (values.file_url.length>0)? values.file_url[0].name:'', }; if (!record?.id) { regulationsStore.add(data); diff --git a/src/pages/polRegulations/regulations_column.tsx b/src/pages/polRegulations/regulations_column.tsx index 0c67b03..408a983 100644 --- a/src/pages/polRegulations/regulations_column.tsx +++ b/src/pages/polRegulations/regulations_column.tsx @@ -37,7 +37,12 @@ export const defaultConfig = [ label: "法规副标题", name: "sub_title", value: "", - rules: [{ required: true, message: "请输入法规副标题!" }], + }, + { + type: FormType.inputNumber, + label: "排序", + name: "level", + value: 0, }, { type: "editor", diff --git a/src/service/base.ts b/src/service/base.ts index 269af73..ce21a34 100644 --- a/src/service/base.ts +++ b/src/service/base.ts @@ -24,7 +24,6 @@ axios.interceptors.response.use((res: AxiosResponse) => { } return res; }, (err) => { - if (err.status === 401) { store.usrStore.openLoginDilog() store.usrStore.logOut() diff --git a/src/static/org_tow.png b/src/static/org_tow.png index 632ad00..9fcb6bc 100644 Binary files a/src/static/org_tow.png and b/src/static/org_tow.png differ diff --git a/src/util/config.ts b/src/util/config.ts index acca640..50f108a 100644 --- a/src/util/config.ts +++ b/src/util/config.ts @@ -2,7 +2,7 @@ class Config { static baseUrl = "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 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 } diff --git a/src/util/webRtc.ts b/src/util/webRtc.ts index fa90d11..431583f 100644 --- a/src/util/webRtc.ts +++ b/src/util/webRtc.ts @@ -1,10 +1,10 @@ -import Config from "./config"; +import SocketService from "./socket"; class WebRtc { private mediaStream: MediaStream | Blob | null = null; private pee: RTCPeerConnection | null = null; - private ws: WebSocket | null = null; + private ws: SocketService | null = null; private video: HTMLVideoElement | null = null; private userToId: string = ""; open = () => { @@ -17,57 +17,55 @@ class WebRtc { })) } async init() { - this.ws = new WebSocket(Config.rtc) - this.ws.addEventListener('open', this.open); - let that = this; + this.ws = SocketService.getInstance(); + this.ws.on("message", this.onMessage); this.createOffer() - this.ws.onmessage = function (evt) { - let msg = JSON.parse(evt.data) - if (!msg) { - return console.log('failed to parse msg') - } - switch (msg.type) { - case 'offer': - let offer = msg.data.description - that.pee?.setRemoteDescription(offer) - that.pee?.createAnswer().then(answer => { - that.pee?.setLocalDescription(answer) - that.ws?.send(JSON.stringify({ - type: 'answer', data: { - 'to': msg.data.from, - 'from': "31283192", - 'description': { 'sdp': answer.sdp, 'type': answer.type }, - 'session_id': msg.data.from + "-31283192", - } - })) - }) - return + } + onMessage = (e: any) => { + let that = this; + let msg = JSON.parse(e.data) + if (!msg) { + return console.log('failed to parse msg') + } + switch (msg.type) { + case 'offer': + let offer = msg.data.description + that.pee?.setRemoteDescription(offer) + that.pee?.createAnswer().then(answer => { + that.pee?.setLocalDescription(answer) + that.ws?.send(JSON.stringify({ + type: 'answer', data: { + 'to': msg.data.from, + 'from': "31283192", + 'description': { 'sdp': answer.sdp, 'type': answer.type }, + 'session_id': msg.data.from + "-31283192", + } + })) + }) + return - case 'candidate': - let candidate = msg.data.candidate - if (!candidate) { - return console.log('failed to parse candidate') - } - that.pee?.addIceCandidate(candidate) - break; - case "answer": - that.pee?.setRemoteDescription(msg.data.description) - break; - case "bye": - that.pee?.close() - that.close() - break; - } + case 'candidate': + let candidate = msg.data.candidate + if (!candidate) { + return console.log('failed to parse candidate') + } + that.pee?.addIceCandidate(candidate) + break; + case "answer": + that.pee?.setRemoteDescription(msg.data.description) + break; + case "bye": + that.pee?.close() + that.close() + break; } } async createOffer() { - var url = 'http://rw.quwanya.cn:12217/api/turn?service=turn&username=flutter-webrtc'; fetch(url) .then(response => response.json()) .then(data => { - const configuration = { iceServers: [ { @@ -97,7 +95,7 @@ class WebRtc { remoteVideo.controls = true remoteVideo.srcObject = event.streams[0]; console.log(event); - + event.track.onmute = function () { remoteVideo.play() }