From 52dbc0fe40b49c542f14bb5b42c0a106d65a04ea Mon Sep 17 00:00:00 2001 From: LingkongSky Date: Sun, 13 Apr 2025 10:46:32 +0800 Subject: [PATCH] add the Wol custom name --- server/proto/network.go | 5 ++ server/router/network.go | 10 +-- server/service/network/wol.go | 54 ++++++++++++++- web/src/api/network.ts | 5 ++ web/src/pages/desktop/menu/wol/index.tsx | 88 ++++++++++++++++++++---- 5 files changed, 142 insertions(+), 20 deletions(-) diff --git a/server/proto/network.go b/server/proto/network.go index 6008ff9..7393c22 100644 --- a/server/proto/network.go +++ b/server/proto/network.go @@ -12,6 +12,11 @@ type DeleteMacReq struct { Mac string `form:"mac" validate:"required"` } +type SetMacNameReq struct { + Mac string `form:"mac" validate:"required"` + Name string `form:"name" validate:"required"` +} + type TailscaleState string const ( diff --git a/server/router/network.go b/server/router/network.go index 08e4a6f..7ba7689 100644 --- a/server/router/network.go +++ b/server/router/network.go @@ -14,9 +14,9 @@ func networkRouter(r *gin.Engine) { api := r.Group("/api").Use(middleware.CheckToken()) - api.POST("/network/wol", service.WakeOnLAN) // wake on lan - api.GET("/network/wol/mac", service.GetMac) // get mac list - api.DELETE("/network/wol/mac", service.DeleteMac) // delete mac - - api.GET("/network/wifi", service.GetWifi) // get Wi-Fi information + api.POST("/network/wol", service.WakeOnLAN) // wake on lan + api.GET("/network/wol/mac", service.GetMac) // get mac list + api.DELETE("/network/wol/mac", service.DeleteMac) // delete mac + api.POST("/network/wol/mac/setName", service.SetMacName) // set mac name + api.GET("/network/wifi", service.GetWifi) // get Wi-Fi information } diff --git a/server/service/network/wol.go b/server/service/network/wol.go index 7240318..9176328 100644 --- a/server/service/network/wol.go +++ b/server/service/network/wol.go @@ -65,6 +65,54 @@ func (s *Service) GetMac(c *gin.Context) { rsp.OkRspWithData(c, data) } +func (s *Service) SetMacName(c *gin.Context) { + var req proto.SetMacNameReq // Mac:string Name:string + var rsp proto.Response + + if err := proto.ParseFormRequest(c, &req); err != nil { + rsp.ErrRsp(c, -1, "invalid arguments") + return + } + + content, err := os.ReadFile(WolMacFile) + if err != nil { + log.Errorf("failed to open %s: %s", WolMacFile, err) + rsp.ErrRsp(c, -2, "read failed") + return + } + + macs := strings.Split(string(content), "\n") + var newLines []string + macFound := false + + for _, line := range macs { + parts := strings.Split(line, " ") + if req.Mac != parts[0] { + newLines = append(newLines, line) + continue + } + newLines = append(newLines, parts[0]+" "+req.Name) + macFound = true + } + + if !macFound { + log.Errorf("failed to found mac %s: %s", req.Mac, err) + rsp.ErrRsp(c, -3, "write failed") + return + } + + data := strings.Join(newLines, "\n") + err = os.WriteFile(WolMacFile, []byte(data), 0o644) + if err != nil { + log.Errorf("failed to write %s: %s", WolMacFile, err) + rsp.ErrRsp(c, -3, "write failed") + return + } + + rsp.OkRsp(c) + log.Debugf("set wol mac name: %s %s", req.Mac, req.Name) +} + func (s *Service) DeleteMac(c *gin.Context) { var req proto.DeleteMacReq var rsp proto.Response @@ -85,7 +133,8 @@ func (s *Service) DeleteMac(c *gin.Context) { var newMacs []string for _, mac := range macs { - if req.Mac != mac { + parts := strings.Split(mac, " ") + if req.Mac != parts[0] { newMacs = append(newMacs, mac) } } @@ -164,7 +213,8 @@ func isMacExist(mac string) bool { macs := strings.Split(string(content), "\n") for _, item := range macs { - if mac == item { + parts := strings.Split(item, " ") + if mac == parts[0] { return true } } diff --git a/web/src/api/network.ts b/web/src/api/network.ts index 6c60474..29b3624 100644 --- a/web/src/api/network.ts +++ b/web/src/api/network.ts @@ -21,6 +21,11 @@ export function deleteWolMac(mac: string) { }); } +// set Mac name +export function setWolMacName(mac: string,name: string) { + return http.post('/api/network/wol/mac/setName', { mac, name }); +} + // get wifi information export function getWiFi() { return http.get('/api/network/wifi'); diff --git a/web/src/pages/desktop/menu/wol/index.tsx b/web/src/pages/desktop/menu/wol/index.tsx index 808b1e1..858e3f8 100644 --- a/web/src/pages/desktop/menu/wol/index.tsx +++ b/web/src/pages/desktop/menu/wol/index.tsx @@ -3,13 +3,21 @@ import { Button, Divider, Input, List } from 'antd'; import type { InputRef } from 'antd'; import clsx from 'clsx'; import { useSetAtom } from 'jotai'; -import { NetworkIcon, SendIcon, Trash2Icon } from 'lucide-react'; +import { Eye, EyeClosed, NetworkIcon, Pencil, SendIcon, Trash2Icon } from 'lucide-react'; import { useTranslation } from 'react-i18next'; -import { deleteWolMac, getWolMacs, wol } from '@/api/network.ts'; +import { deleteWolMac, getWolMacs, setWolMacName, wol } from '@/api/network.ts'; import { isKeyboardEnableAtom } from '@/jotai/keyboard.ts'; import { MenuItem } from '@/components/menu-item.tsx'; +interface MacItem { + name: string; + mac: string; + isShow: boolean; + isName: boolean; + isEdit: boolean; +} + export const Wol = () => { const { t } = useTranslation(); @@ -19,20 +27,18 @@ export const Wol = () => { const [status, setStatus] = useState(''); const [log, setLog] = useState(''); - const [macList, setMacList] = useState([]); + const [macList, setMacList] = useState([]); const inputRef = useRef(null); function handleOpenChange(open: boolean) { if (open) { getMacs(); - setIsKeyboardEnable(false); } else { setInput(''); setStatus(''); setLog(''); - setIsKeyboardEnable(true); } } @@ -48,14 +54,53 @@ export const Wol = () => { return; } - setMacList(rsp.data.macs.filter((mac: string) => mac !== '')); + const isEdit = false; + const macList = rsp.data.macs + .filter((item: string) => item.trim() !== '') + .map((item: string) => { + const parts = item.split(" "); + const isName = parts.length > 1; + const name = isName ? parts[1] : ''; + const mac = parts[0]; + const isShow = !isName; + return { name, mac, isShow, isName, isEdit}; + }); + + setMacList([]); + setMacList(macList); }); } + function toggleShow(mac: string) { + setMacList( + macList.map((item) => + item.mac === mac ? { ...item, isShow: !item.isShow } : item + ) + ); + } + + function editMac(mac: string,isEdit: boolean) { + setMacList( + macList.map((item) => + item.mac === mac ? { ...item, isEdit: !isEdit } : item + ) + ); + } + + async function setMacName(e: React.KeyboardEvent, mac: string) { + const value: string = e.currentTarget.value; + const rsp = await setWolMacName(mac,value); + if (rsp.code !== 0) { + console.log(rsp.msg); + return; + } + getMacs(); + } + function deleteMac(mac: string) { deleteWolMac(mac).then((rsp) => { if (rsp.code === 0) { - setMacList(macList.filter((item) => item !== mac)); + getMacs(); } }); } @@ -79,10 +124,12 @@ export const Wol = () => { setStatus('success'); setLog(t('wol.sent')); + getMacs(); + setInput(''); }) .catch(() => { setStatus('failed'); - }); + }); } const content = ( @@ -95,7 +142,7 @@ export const Wol = () => {
{t('wol.input')}
- + wake()}/> @@ -118,19 +165,34 @@ export const Wol = () => { itemLayout="horizontal" locale={{ emptyText: ' ' }} dataSource={macList} - renderItem={(mac) => ( + renderItem={(item) => ( -
{mac}
+
+ {item.isEdit ? setIsKeyboardEnable(false)} onBlur={() => setIsKeyboardEnable(true)} defaultValue={item.name} onPressEnter={(e) => setMacName(e, item.mac)} />:(item.isShow ? item.mac : item.name)} +
+
+ {item.isName &&
toggleShow(item.mac)} + > + {item.isShow ? : } +
} +
editMac(item.mac,item.isEdit)} + > + +
wake(mac)} + onClick={() => wake(item.mac)} >
deleteMac(mac)} + onClick={() => deleteMac(item.mac)} >