diff --git a/main.js b/main.js index d96750d..664b5e8 100644 --- a/main.js +++ b/main.js @@ -1,4 +1,4 @@ -const { app, systemPreferences, BrowserWindow, screen, Tray, nativeImage, Menu, ipcMain } = require('electron'); +const { app, BrowserWindow, screen, Tray, nativeImage, Menu, ipcMain, clipboard } = require('electron'); const path = require('node:path') app.allowRendererProcessReuse = false; let mainWindow = null; @@ -141,6 +141,12 @@ app.on('ready', () => { ipcMain.handle('getIsMaximized', () => { return mainWindow.isMaximized(); }); + + // 复制文字 + ipcMain.handle('setWriteText', (event, text) => { + clipboard.writeText(text) + }); + // 设置桌面应用基础属性 ipcMain.handle('setMainWindowSize', (event, config) => { // 设置最小窗口尺寸 @@ -163,20 +169,3 @@ app.on('ready', () => { }); }); -// 检查并获取设备权限 -async function checkAndApplyDeviceAccessPrivilege() { - // 检查并获取摄像头权限 - const cameraPrivilege = systemPreferences.getMediaAccessStatus('camera'); - if (cameraPrivilege !== 'granted') { - await systemPreferences.askForMediaAccess('camera'); - } - - // 检查并获取麦克风权限 - const micPrivilege = systemPreferences.getMediaAccessStatus('microphone'); - if (micPrivilege !== 'granted') { - await systemPreferences.askForMediaAccess('microphone'); - } -} - -checkAndApplyDeviceAccessPrivilege(); - diff --git a/package-lock.json b/package-lock.json index aa0325e..bef7a8c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,6 +15,7 @@ "axios": "^1.7.2", "dayjs": "^1.11.11", "electron-squirrel-startup": "^1.0.1", + "js-md5": "^0.8.3", "path": "^0.12.7", "postcss-px-to-viewport-8-plugin": "^1.2.5", "react": "^18.3.1", @@ -8783,6 +8784,11 @@ "node": ">= 4" } }, + "node_modules/js-md5": { + "version": "0.8.3", + "resolved": "https://registry.npmmirror.com/js-md5/-/js-md5-0.8.3.tgz", + "integrity": "sha512-qR0HB5uP6wCuRMrWPTrkMaev7MJZwJuuw4fnwAzRgP4J4/F8RwtodOKpGp4XpqsLBFzzgqIO42efFAyz2Et6KQ==" + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmmirror.com/js-tokens/-/js-tokens-4.0.0.tgz", @@ -20730,6 +20736,11 @@ "is-object": "^1.0.1" } }, + "js-md5": { + "version": "0.8.3", + "resolved": "https://registry.npmmirror.com/js-md5/-/js-md5-0.8.3.tgz", + "integrity": "sha512-qR0HB5uP6wCuRMrWPTrkMaev7MJZwJuuw4fnwAzRgP4J4/F8RwtodOKpGp4XpqsLBFzzgqIO42efFAyz2Et6KQ==" + }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmmirror.com/js-tokens/-/js-tokens-4.0.0.tgz", diff --git a/package.json b/package.json index 8b55a64..135cfca 100644 --- a/package.json +++ b/package.json @@ -32,6 +32,7 @@ "axios": "^1.7.2", "dayjs": "^1.11.11", "electron-squirrel-startup": "^1.0.1", + "js-md5": "^0.8.3", "path": "^0.12.7", "postcss-px-to-viewport-8-plugin": "^1.2.5", "react": "^18.3.1", diff --git a/preload.js b/preload.js index 325adec..88b021b 100644 --- a/preload.js +++ b/preload.js @@ -7,7 +7,9 @@ const { VideoViewSetupMode, ScreenCaptureSourceType, RenderModeType, - ChannelProfileType + ChannelProfileType, + MediaRecorderContainerFormat, + MediaRecorderStreamType } = require("agora-electron-sdk"); const agoraAonfig = require('./src/utils/package/agoraConfig'); const { message } = require('antd'); @@ -15,16 +17,54 @@ const rtcEngine = createAgoraRtcEngine(); rtcEngine.initialize({ appId: agoraAonfig.appid, }); - let videoID = ''; +let iMediaRecorder = ''; + const getDom = () => { return document.getElementById(videoID); } +// 离开频道 +const leaveChannel = () => { + rtcEngine.leaveChannel({ + stopAudioMixing: true, + stopAllEffect: true, + stopMicrophoneRecording: true, + }) +} +// 离开频道 +const joinChannel = (bool) => { + if (bool) { + rtcEngine.joinChannel(agoraAonfig.token, agoraAonfig.channelId, 123, { + channelProfile: ChannelProfileType.ChannelProfileLiveBroadcasting, //设置频道场景为直播场景 + clientRoleType: ClientRoleType.ClientRoleBroadcaster, //用户角色 1主播 2观众 + publishMicrophoneTrack: true, //设置是否发布麦克风采集到的音频 + publishCameraTrack: false, //设置是否发布摄像头采集的视频 + publishScreenTrack: true, //设置是否发布屏幕采集的视频 + autoSubscribeAudio: true, //设置是否自动订阅所有音频流 + autoSubscribeVideo: true, //设置是否自动订阅所有视频流 + }); + } else { + rtcEngine.joinChannel(agoraAonfig.token, agoraAonfig.channelId, 123, { + channelProfile: ChannelProfileType.ChannelProfileLiveBroadcasting, //设置频道场景为直播场景 + clientRoleType: ClientRoleType.ClientRoleBroadcaster, //设置用户角色为主播;如果要将用户角色设置为观众,保持默认值即可 + publishMicrophoneTrack: true, //发布麦克风采集的音频 + publishCameraTrack: true, //发布摄像头采集的视频 + publishScreenTrack: false, //设置是否发布屏幕采集的视频 + autoSubscribeAudio: true, //自动订阅所有音频流 + autoSubscribeVideo: true, //自动订阅所有视频流 + }); + } +} -const EventHandles = { +// 停止共享屏幕 +const stopScreenCapture = () => { + rtcEngine.stopScreenCapture(); +} + +rtcEngine.registerEventHandler({ // 监听本地用户加入频道事件 onJoinChannelSuccess: ({ channelId, localUid }, elapsed) => { - console.log({ channelId, localUid }); + console.log({ channelId, localUid }, elapsed, '加入房间'); // 本地用户加入频道后,设置本地视频窗口 rtcEngine.setupLocalVideo({ renderMode: RenderModeType.RenderModeFit, @@ -50,6 +90,18 @@ const EventHandles = { ); }, + // 视频发布状态改变回调 + onVideoPublishStateChanged: (source, channel, oldState, newState, elapseSinceLastState) => { + if (newState === 1) { + + } + }, + // 音频发布状态改变回调 + onAudioPublishStateChanged: (channel, oldState, newState, elapseSinceLastState) => { + if (newState === 1) { + + } + }, // 监听用户离开频道事件 onUserOffline: ({ channelId, localUid }, remoteUid, reason) => { // 远端用户离开频道后,关闭远端视频窗口 @@ -70,8 +122,7 @@ const EventHandles = { document.getElementById('recordingDeviceTest').style.width = `${percentage}%` } } -}; -rtcEngine.registerEventHandler(EventHandles); +}); contextBridge.exposeInMainWorld( 'electron', @@ -83,7 +134,7 @@ contextBridge.exposeInMainWorld( // 共享屏幕采集 setDesktopCapturerVideo: (targetSource) => { - rtcEngine.stopScreenCapture() + stopScreenCapture() if ( targetSource.type === ScreenCaptureSourceType.ScreencapturesourcetypeScreen @@ -109,34 +160,13 @@ contextBridge.exposeInMainWorld( ); } videoID = `vidoe-${123}-${agoraAonfig.channelId}`; - rtcEngine.joinChannelEx(agoraAonfig.token, { - channelId: agoraAonfig.channelId, - localUid: 123, - }, { - autoSubscribeAudio: true, //设置是否自动订阅所有音频流 - autoSubscribeVideo: true, //设置是否自动订阅所有视频流 - publishMicrophoneTrack: false, //设置是否发布麦克风采集到的音频 - publishCameraTrack: false, //设置是否发布摄像头采集的视频 - clientRoleType: ClientRoleType.ClientRoleBroadcaster, //用户角色 1主播 2观众 - publishScreenTrack: true, //设置是否发布屏幕采集的视频 - }); + joinChannel(true) }, // 摄像头采集 setCameraCapture: () => { rtcEngine.startCameraCapture(VideoSourceType.VideoSourceCamera, {}) videoID = `vidoe-${123}-${agoraAonfig.channelId}`; - rtcEngine.joinChannelEx(agoraAonfig.token, { - channelId: agoraAonfig.channelId, - localUid: 123, - }, { - channelProfile: ChannelProfileType.ChannelProfileLiveBroadcasting, //设置频道场景为直播场景 - clientRoleType: ClientRoleType.ClientRoleBroadcaster, //设置用户角色为主播;如果要将用户角色设置为观众,保持默认值即可 - publishMicrophoneTrack: true, //发布麦克风采集的音频 - publishCameraTrack: true, //发布摄像头采集的视频 - autoSubscribeAudio: true, //自动订阅所有音频流 - autoSubscribeVideo: true, //自动订阅所有视频流 - publishScreenTrack: false, //设置是否发布屏幕采集的视频 - }); + joinChannel(false) }, // 加入频道 setJoinChannel: () => { @@ -153,6 +183,22 @@ contextBridge.exposeInMainWorld( publishScreenTrack: true, //设置是否发布屏幕采集的视频 }); }, + // 离开频道 + leaveChannel: () => { + leaveChannel() + }, + // 停止共享屏幕 + stopScreenCapture: () => { + stopScreenCapture() + }, + // 取消或恢复发布本地音频流 + muteLocalAudioStream: (mute) => { + rtcEngine.muteLocalAudioStream(mute) + }, + // 取消或恢复发布本地视频流 + muteLocalVideoStream: (mute) => { + rtcEngine.muteLocalVideoStream(mute) + }, // 获取当前生成的视频id getVideoId: () => { return videoID; @@ -223,7 +269,35 @@ contextBridge.exposeInMainWorld( resolve(true) }); }) - + }, + // 开始录制音视频 + startRecording: () => { + iMediaRecorder = rtcEngine.createMediaRecorder({ + channelId: agoraAonfig.channelId, + uid: 123, + }) + iMediaRecorder.setMediaRecorderObserver({ + // 录制状态发生改变回调。 + onRecorderStateChanged: (channelId, uid, state, reason) => { + console.log(channelId, uid, state, reason, '录制状态发生改变回调。'); + }, + // 录制信息更新回调。 + onRecorderInfoUpdated: (channelId, uid, info) => { + console.log(channelId, uid, info, '录制信息更新回调。'); + }, + }) + iMediaRecorder.startRecording({ + storagePath: `D:/word/${+new Date()}.mp4`, //录音文件在本地保存的绝对路径,需精确到文件名及格式 + containerFormat: MediaRecorderContainerFormat.FormatMp4, //录制文件的格式 + streamType: MediaRecorderStreamType.StreamTypeBoth, //录制内容 + maxDurationMs: 7200000, //maxDurationMs + }) + }, + // 停止录制音视频 + stopRecording: () => { + iMediaRecorder.stopRecording() + rtcEngine.destroyMediaRecorder(iMediaRecorder) + iMediaRecorder = "" }, // 设置窗口大小 setMainWindowSize: (config) => { @@ -236,6 +310,10 @@ contextBridge.exposeInMainWorld( // 获取当前是否全屏 getIsMaximized: () => { return ipcRenderer.invoke('getIsMaximized') + }, + // 复制文字 + setWriteText: (text) => { + return ipcRenderer.invoke('setWriteText', text) } } ) diff --git a/src/api/Home/Index/index.ts b/src/api/Home/Index/index.ts new file mode 100644 index 0000000..c865b53 --- /dev/null +++ b/src/api/Home/Index/index.ts @@ -0,0 +1,20 @@ +import { request } from '@/utils' +export const GetRoom = (data: { pageIndex: number, pageSize: number }) => + request({ + url: `/home/room?pageIndex=${data.pageIndex}&pageSize=${data.pageSize}`, + method: 'get' + }) + +export const PostRomm = (data: any) => + request({ + url: `/home/room`, + method: 'post', + data, + }) + +export const GetCheckoutRoomNum = (roomNum: string) => + request({ + url: `/room/checkout?roomNum=${roomNum}`, + method: 'get', + }) + diff --git a/src/api/Home/User/index.ts b/src/api/Home/User/index.ts new file mode 100644 index 0000000..03d6c3b --- /dev/null +++ b/src/api/Home/User/index.ts @@ -0,0 +1,39 @@ +import { request } from '@/utils' +export const GetUserList = (data: { pageIndex: number, pageSize: number, searchKeywod: string }) => + request({ + url: `/user/list?pageIndex=${data.pageIndex}&pageSize=${data.pageSize}&searchKeywod=${data.searchKeywod}`, + method: 'get' + }) + +export const PostUser = (data: any) => + request({ + url: `/user`, + method: 'post', + data, + }) + +export const PutUser = (data: any) => + request({ + url: `/user`, + method: 'put', + data + }) +export const DeleteUser = (data: any) => + request({ + url: `/user`, + method: 'delete', + data + }) + +export const PutUserPwd = (data: { id: string, pwd: string }) => + request({ + url: `/user/pwd`, + method: 'put', + data + }) + +export const GetRoleDpList = () => + request({ + url: `/pub/role-dp-list`, + method: 'get', + }) \ No newline at end of file diff --git a/src/api/Login/index.ts b/src/api/Login/index.ts index 7c7e7c2..91f3900 100644 --- a/src/api/Login/index.ts +++ b/src/api/Login/index.ts @@ -5,21 +5,10 @@ export const GetCheckUser = (userName: string) => method: 'get' }) -export const GetOcrDetail = (mid: string) => +export const PostLogin = (data: any) => request({ - url: `/api/ocr/${mid}`, - method: 'get' - }) - -export const PostSave = (data: any) => - request({ - url: `/api/ocr/save`, + url: `/auth/login`, method: 'post', data, }) -export const GetLock = (mid: string) => - request({ - url: `/api/ocr/lock?mid=${mid}`, - method: 'get', - }) \ No newline at end of file diff --git a/src/assets/icon27-actvie.png b/src/assets/icon27-active.png similarity index 100% rename from src/assets/icon27-actvie.png rename to src/assets/icon27-active.png diff --git a/src/main.tsx b/src/main.tsx index 6e77472..8d18f0f 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -2,10 +2,13 @@ import ReactDOM from 'react-dom/client' import App from './App.tsx' import '@/utils/styles/main.css' import { HashRouter } from 'react-router-dom'; - +import { ConfigProvider } from 'antd'; +import zhCN from 'antd/locale/zh_CN'; ReactDOM.createRoot(document.getElementById('root')!).render( - + + + ) diff --git a/src/page/Home/Index/index.module.scss b/src/page/Home/Index/index.module.scss index cd426be..98c76a1 100644 --- a/src/page/Home/Index/index.module.scss +++ b/src/page/Home/Index/index.module.scss @@ -44,18 +44,20 @@ color: white; font-size: 24px; font-weight: bold; - margin-bottom: 20px; } .indexContentList { + margin: 20px 0; overflow-y: scroll; flex-grow: 1; height: 0px; display: flex; flex-wrap: wrap; justify-content: space-between; + align-items: flex-start; + align-content: flex-start; - >div { + .indexContentListItem { border: 1px solid #353741; margin-bottom: 34px; background-color: #1E1E1F; @@ -118,5 +120,18 @@ } } } + + .indexContentEmpty { + flex-grow: 1; + display: flex; + justify-content: center; + margin-top: 18%; + } + + .indexContentPagination { + flex-shrink: 0; + display: flex; + justify-content: center; + } } } \ No newline at end of file diff --git a/src/page/Home/Index/index.tsx b/src/page/Home/Index/index.tsx index c113f40..6f5165b 100644 --- a/src/page/Home/Index/index.tsx +++ b/src/page/Home/Index/index.tsx @@ -2,13 +2,57 @@ import styles from '@/page/Home/Index/index.module.scss' import { useEffect, useState } from "react"; import Operation from '@/components/Operation'; import { useNavigate } from 'react-router-dom'; -import { Button } from "antd"; +import { Button, Input, Modal, Pagination, Empty, message } from "antd"; +import { GetRoom, PostRomm, GetCheckoutRoomNum } from '@/api/Home/Index'; +// import { clipboard } from 'electron' const Index: React.FC = () => { const navigate = useNavigate(); - const [list, setList] = useState([{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}]) + const [list, setList] = useState({ + data: [], + total: 0, + pageIndex: 1, + pageSize: 12, + }) + const [createRoomModal, setCreateRoomModal] = useState(false) + const [createRoomFrom, setCreateRoomFrom] = useState<{ roomName: string, roomNum: string }>({ + roomName: "", + roomNum: "" + }) + const [joinRoomModal, setJoinRoomModal] = useState(false) + const [joinRoomFrom, setJoinRoomFrom] = useState('') useEffect(() => { + getRoomList() + }, [list.pageIndex]); + + + const getRoomList = async (): Promise => { + await GetRoom({ + pageIndex: list.pageIndex, + pageSize: list.pageSize, + }).then(res => { + if (res.code === 200) { + setList({ + ...list, + total: res.data.total, + data: res.data.items, + }) + } + }) + } + + const copyRoomNum = (roomNum: string): void => { + window.electron.setWriteText(roomNum) + message.success('复制成功') + } + + const isGetCheckoutRoomNum = async (roomNum: string, callBack: Function): Promise => { + await GetCheckoutRoomNum(roomNum).then(res => { + if (res.code === 200) { + callBack(res.data) + } + }) + } - }, []); return ( <>
@@ -18,10 +62,21 @@ const Index: React.FC = () => {
- + + {/* */}
) })} -
-
+
+
+
: +
+ +
+ } +
+ { + setList({ + ...list, + pageIndex: e + }) + }} pageSize={list.pageSize} />
+ +
+
+ { + setCreateRoomFrom({ + ...createRoomFrom, + roomName: e.target.value + }) + }} + /> + { + const regex = /^[0-9 ]*$/; + if (regex.test(e.target.value)) { + setCreateRoomFrom({ + ...createRoomFrom, + roomNum: e.target.value + }) + } + }} + suffix={ + { + setCreateRoomFrom({ + ...createRoomFrom, + roomNum: Math.floor(+new Date() / 1000).toString().slice(-8), + }) + }} + >获取随机房间号 + + } + /> +
+
+ + +
+
+
+ +
+
+ { + const regex = /^[0-9 ]*$/; + if (regex.test(e.target.value)) { + setJoinRoomFrom(e.target.value) + } + }} + /> +
+
+ + +
+
+
) } diff --git a/src/page/Home/User/index.module.scss b/src/page/Home/User/index.module.scss index 4631c29..48c9ab3 100644 --- a/src/page/Home/User/index.module.scss +++ b/src/page/Home/User/index.module.scss @@ -63,7 +63,23 @@ >span { color: #8B8787; + font-size: 20px; } } } +} + +.addUserModal { + >div { + display: flex; + align-items: center; + margin-bottom: 20px; + + >span { + flex-shrink: 0; + color: #EEEEEE; + width: 120px; + text-align: right; + } + } } \ No newline at end of file diff --git a/src/page/Home/User/index.tsx b/src/page/Home/User/index.tsx index af8ff85..334bac4 100644 --- a/src/page/Home/User/index.tsx +++ b/src/page/Home/User/index.tsx @@ -1,55 +1,76 @@ import styles from '@/page/Home/User/index.module.scss' import { useEffect, useState } from "react"; import Operation from '@/components/Operation'; -import { Button, Input, Table, Pagination } from "antd"; +import { Button, Input, Table, Pagination, Modal, message, Select } from "antd"; import { SearchOutlined } from '@ant-design/icons'; -import type { TableColumnsType } from 'antd'; -const columns: TableColumnsType = [ - { - title: '姓名', - dataIndex: 'name', - }, - { - title: '账号', - dataIndex: 'account', - }, - { - title: '角色', - dataIndex: 'role', - }, - { - title: '账号状态', - dataIndex: 'status', - render: (text) => { - return ( -
{text}
- ) - }, - }, -]; - -const data = [] as any; -for (let i = 0; i < 46; i++) { - data.push({ - key: i, - name: `潇潇`, - account: 5256589545, - role: `教师`, - status: `在线`, - }); -} +import { GetUserList, PostUser, PutUser, DeleteUser, PutUserPwd, GetRoleDpList } from '@/api/Home/User'; +import { md5 } from 'js-md5'; +const { Column } = Table const User: React.FC = () => { const [selectedRowKeys, setSelectedRowKeys] = useState([]); - useEffect(() => { + const [isCreateUser, setIsCreateUser] = useState(false); + const [list, setList] = useState({ + data: [], + searchKeywod: '', + total: 0, + pageIndex: 1, + pageSize: 6, + }) + const [roleList, setRoleList] = useState([]) + const [addUserModal, setAddUserModal] = useState(false) + const [addUserFrom, setAddUserFrom] = useState({ + Id: "", + Account: "", + RoleId: null, + Pwd: "", + UserName: "" + }) + const [changeUserPawModal, setChangeUserPawModal] = useState(false) + const [changeUserPawFrom, setChangeUserPawFrom] = useState({ + Pwd: "", + newPwd: '', + }) + const [deleteUserPawModal, setDeleteUserPawModal] = useState(false) - }, []); - const onSelectChange = (newSelectedRowKeys: React.Key[]) => { - setSelectedRowKeys(newSelectedRowKeys); - }; - const rowSelection = { - selectedRowKeys, - onChange: onSelectChange, - }; + useEffect(() => { + getUserList() + }, [list.pageIndex]); + + const getUserList = async (): Promise => { + await GetUserList({ + pageIndex: list.pageIndex, + pageSize: list.pageSize, + searchKeywod: list.searchKeywod, + }).then(res => { + if (res.code === 200) { + setList({ + ...list, + total: res.data.total, + data: res.data.items.map((item: any) => { + return { + ...item, + key: item.id, + } + }), + }) + } + }) + } + + const getRoleDpList = async (callBack: Function): Promise => { + await GetRoleDpList().then(res => { + if (res.code === 200) { + setRoleList(res.data.map((item: any) => { + return { + ...item, + value: item.id, + label: item.roleName + } + })) + callBack(true) + } + }) + } return ( <>
@@ -59,36 +80,313 @@ const User: React.FC = () => {
- } /> - + } + onChange={(e) => { + setList({ + ...list, + searchKeywod: e.target.value, + }) + }} + /> +
{ + setSelectedRowKeys(newSelectedRowKeys); + } + }} + dataSource={list.data} pagination={false} - scroll={{ y: '64vh' }} - style={{ width: '77.6vw', flexGrow: 1 }} - /> + scroll={{ y: '70vh' }} + style={{ width: '81.4vw', flexGrow: 1 }} + > + + + + ( + <> +
{item.account}
+ + )} /> + ( + <> + + + + )} /> +
- 共653项数据 - + 共{list.total}项数据 + { + setList({ + ...list, + pageIndex: e + }) + }} pageSize={list.pageSize} current={list.pageIndex} hideOnSinglePage={true} />
+ +
+
+
+ 账号: + { + setAddUserFrom({ + ...addUserFrom, + Account: e.target.value, + }); + }} + /> +
+
+ 角色: + { + setAddUserFrom({ + ...addUserFrom, + UserName: e.target.value, + }); + }} + /> +
+
+
+ + +
+
+
+ +
+
+
+ 新密码: + { + setChangeUserPawFrom({ + ...changeUserPawFrom, + Pwd: e.target.value, + }); + }} + /> +
+
+ 确认密码: + { + setChangeUserPawFrom({ + ...changeUserPawFrom, + newPwd: e.target.value, + }); + }} + /> +
+
+
+ + +
+
+
+ +
+
+ 是否确认删除该用户? +
+
+ + +
+
+
) } diff --git a/src/page/Home/index.tsx b/src/page/Home/index.tsx index d20404c..74a693b 100644 --- a/src/page/Home/index.tsx +++ b/src/page/Home/index.tsx @@ -4,6 +4,7 @@ import { Outlet, useNavigate } from 'react-router-dom'; import { Popconfirm } from 'antd'; import dayjs from 'dayjs'; import 'dayjs/locale/zh-cn' +import { storage } from '@/utils'; dayjs.locale('zh-cn'); type navListType = { title: string; @@ -31,6 +32,7 @@ const Home: React.FC = () => { path: '/home/user' }, ]); + const [userInfo, setUserInfo] = useState({}) const [dateInfo, setDateInfo] = useState<{ work: string; time: string; @@ -41,6 +43,10 @@ const Home: React.FC = () => { specific: '', }) useEffect(() => { + const user = JSON.parse(storage.getItem('user') as string); + if (user) { + setUserInfo(user) + } const updateTime = () => { setDateInfo({ work: dayjs().format('ddd'), @@ -76,7 +82,7 @@ const Home: React.FC = () => {
- 欢迎您,u0001 + 欢迎您,{userInfo?.userName}
diff --git a/src/page/Login/index.tsx b/src/page/Login/index.tsx index 3fb736c..67f059b 100644 --- a/src/page/Login/index.tsx +++ b/src/page/Login/index.tsx @@ -2,13 +2,15 @@ import styles from '@/page/Login/index.module.scss' import { useEffect, useState } from "react"; import { useNavigate } from 'react-router-dom'; -import { Input, Button, Checkbox } from "antd" +import { Input, Button, Checkbox, message } from "antd" import { storage } from '@/utils' -import { GetCheckUser } from '@/api/Login' +import { GetCheckUser, PostLogin } from '@/api/Login' +import { md5 } from 'js-md5'; const Login: React.FC = () => { const navigate = useNavigate(); const [accountPasswordStatus, setAccountPasswordStatus] = useState(false); + const [accountStatus, setAccountStatus] = useState(false); const [operation, setOperation] = useState<{ isRememberPassword: boolean; isAutoLogin: boolean; @@ -29,6 +31,11 @@ const Login: React.FC = () => { }); useEffect(() => { + window.electron.setMainWindowSize({ + width: 752, + height: 520, + key: 'login' + }) if (storage.getItem('login')) { const login = JSON.parse(storage.getItem('login') as string); const data = { @@ -49,6 +56,11 @@ const Login: React.FC = () => { ...data, }) } + GetCheckUser(login.account).then(res => { + if (res.code === 200) { + setAccountStatus(res.data) + } + }) } }, []); @@ -88,18 +100,27 @@ const Login: React.FC = () => { // 登录 const loginClick = (): void => { - storage.setItem('login', JSON.stringify({ - isRememberPassword: operation.optionsValue.includes('isRememberPassword'), - isAutoLogin: operation.optionsValue.includes('isAutoLogin'), + PostLogin({ account: operation.account, - password: operation.password, - optionsValue: operation.optionsValue, - })) - window.electron.setMainWindowSize({ - width: 1200, - height: 800, + pwd: md5(operation.password) + }).then(res => { + if (res.code === 200) { + message.success('登录成功!') + storage.setItem('login', JSON.stringify({ + isRememberPassword: operation.optionsValue.includes('isRememberPassword'), + isAutoLogin: operation.optionsValue.includes('isAutoLogin'), + account: operation.account, + password: operation.password, + optionsValue: operation.optionsValue, + })) + storage.setItem('user', JSON.stringify(res.data)) + window.electron.setMainWindowSize({ + width: 1200, + height: 800, + }) + navigate('/home') + } }) - navigate('/home') } return ( @@ -126,9 +147,13 @@ const Login: React.FC = () => { ...operation, account: e.target.value }) - // GetCheckUser(e.target.value).then(res => { - // console.log(res); - // }) + if (e.target.value) { + GetCheckUser(e.target.value).then(res => { + if (res.code === 200) { + setAccountStatus(res.data) + } + }) + } }} className={`${styles.loginInputIcon} drag`} style={{ marginBottom: '12px' }} @@ -143,7 +168,7 @@ const Login: React.FC = () => { } /> - {operation.account && !accountPasswordStatus ?
+ {operation.account && !accountPasswordStatus && accountStatus ?