├── .gitignore
├── README.md
├── add_node.png
├── connections
├── connection.go
└── model.go
├── const
└── const.go
├── dist
├── css
│ ├── 294.5efa506b.css
│ ├── 657.baf841e6.css
│ ├── app.8970c6b5.css
│ └── chunk-vendors.457c6cf1.css
├── favicon.ico
├── index.html
└── js
│ ├── 294.580a20f9.js
│ ├── 294.580a20f9.js.map
│ ├── 657.47dd038e.js
│ ├── 657.47dd038e.js.map
│ ├── app.cd909d50.js
│ ├── app.cd909d50.js.map
│ ├── chunk-vendors.954d9be3.js
│ └── chunk-vendors.954d9be3.js.map
├── go.mod
├── go.sum
├── handler
└── ws.go
├── init
└── run.go
├── main.go
├── middlewares
└── middlewares.go
├── router
└── router.go
├── ssh_terminal.png
└── ubzer
└── ubzer.go
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea
2 | .DS_Store
3 | log
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # websshterminal
2 | > go+echo+ssh+websocket+vue3 实现的web端通过ssh连接服务器
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | ## web vue代码
14 | [websshterminal-vue](https://github.com/jeffcail/websshterminal-vue)
15 |
16 |
17 | ## 运行
18 | ```shell
19 | go run main.go
20 | ```
21 |
22 | ## 访问
23 | localhost:5555
24 |
25 | ## 效果展示
26 | 添加服务器
27 |
28 |
29 |
30 | 模拟终端
31 |
32 |
--------------------------------------------------------------------------------
/add_node.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mazezen/websshterminal/2f8d5d091362a84a693b62bb6763a37a32060d15/add_node.png
--------------------------------------------------------------------------------
/connections/connection.go:
--------------------------------------------------------------------------------
1 | package connections
2 |
3 | import (
4 | "bufio"
5 | "encoding/base64"
6 | "encoding/json"
7 | "fmt"
8 | "log"
9 | "net"
10 | "time"
11 | "unicode/utf8"
12 |
13 | "github.com/gorilla/websocket"
14 | "golang.org/x/crypto/ssh"
15 | )
16 |
17 | func DecodeMsgToSSHClient(msg string) (SSHClient, error) {
18 | client := NewSSHClient()
19 | decoded, err := base64.StdEncoding.DecodeString(msg)
20 | if err != nil {
21 | return client, err
22 | }
23 | err = json.Unmarshal(decoded, &client)
24 | if err != nil {
25 | return client, err
26 | }
27 | return client, nil
28 | }
29 |
30 | func (this *SSHClient) GenerateClient(ip, name, password string, port int) error {
31 | var (
32 | auth []ssh.AuthMethod
33 | addr string
34 | clientConfig *ssh.ClientConfig
35 | client *ssh.Client
36 | config ssh.Config
37 | err error
38 | )
39 |
40 | auth = make([]ssh.AuthMethod, 0)
41 | auth = append(auth, ssh.Password(password))
42 | config = ssh.Config{
43 | Ciphers: []string{"aes128-ctr", "aes192-ctr", "aes256-ctr", "aes128-gcm@openssh.com", "arcfour256", "arcfour128", "aes128-cbc", "3des-cbc", "aes192-cbc", "aes256-cbc"},
44 | }
45 | clientConfig = &ssh.ClientConfig{
46 | User: name,
47 | Auth: auth,
48 | Timeout: 5 * time.Second,
49 | Config: config,
50 | HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error {
51 | return nil
52 | },
53 | }
54 | addr = fmt.Sprintf("%s:%d", ip, port)
55 | if client, err = ssh.Dial("tcp", addr, clientConfig); err != nil {
56 | return err
57 | }
58 | this.Client = client
59 | return nil
60 | }
61 |
62 | func (this *SSHClient) RequestTerminal(terminal Terminal) *SSHClient {
63 | session, err := this.Client.NewSession()
64 | if err != nil {
65 | return nil
66 | }
67 | this.Session = session
68 | channel, inRequests, err := this.Client.OpenChannel("session", nil)
69 | if err != nil {
70 | return nil
71 | }
72 | this.channel = channel
73 | go func() {
74 | for req := range inRequests {
75 | if req.WantReply {
76 | req.Reply(false, nil)
77 | }
78 | }
79 | }()
80 | modes := ssh.TerminalModes{
81 | ssh.ECHO: 1,
82 | ssh.TTY_OP_ISPEED: 14400,
83 | ssh.TTY_OP_OSPEED: 14400,
84 | }
85 | var modeList []byte
86 | for k, v := range modes {
87 | kv := struct {
88 | Key byte
89 | Val uint32
90 | }{k, v}
91 | modeList = append(modeList, ssh.Marshal(&kv)...)
92 | }
93 | modeList = append(modeList, 0)
94 | req := ptyRequestMsg{
95 | Term: "xterm",
96 | Columns: terminal.Columns,
97 | Rows: terminal.Rows,
98 | Width: uint32(terminal.Columns * 8),
99 | Height: uint32(terminal.Columns * 8),
100 | ModeList: string(modeList),
101 | }
102 | ok, err := channel.SendRequest("pty-req", true, ssh.Marshal(&req))
103 | if !ok || err != nil {
104 | return nil
105 | }
106 | ok, err = channel.SendRequest("shell", true, nil)
107 | if !ok || err != nil {
108 | return nil
109 | }
110 | return this
111 | }
112 |
113 | func (this *SSHClient) Connect(ws *websocket.Conn) {
114 | go func() {
115 | for {
116 | _, p, err := ws.ReadMessage()
117 | if err != nil {
118 | return
119 | }
120 | _, err = this.channel.Write(p)
121 | if err != nil {
122 | return
123 | }
124 | }
125 | }()
126 |
127 | go func() {
128 | br := bufio.NewReader(this.channel)
129 | buf := []byte{}
130 | t := time.NewTimer(time.Microsecond * 100)
131 | defer t.Stop()
132 | r := make(chan rune)
133 |
134 | go func() {
135 | defer this.Client.Close()
136 | defer this.Client.Close()
137 |
138 | for {
139 | x, size, err := br.ReadRune()
140 | if err != nil {
141 | log.Println(err)
142 | ws.WriteMessage(1, []byte("\033[31m已经关闭连接!\033[0m"))
143 | ws.Close()
144 | return
145 | }
146 | if size > 0 {
147 | r <- x
148 | }
149 | }
150 | }()
151 |
152 | for {
153 | select {
154 | case <-t.C:
155 | if len(buf) != 0 {
156 | err := ws.WriteMessage(websocket.TextMessage, buf)
157 | buf = []byte{}
158 | if err != nil {
159 | log.Println(err)
160 | return
161 | }
162 | }
163 | t.Reset(time.Microsecond * 100)
164 | case d := <-r:
165 | if d != utf8.RuneError {
166 | p := make([]byte, utf8.RuneLen(d))
167 | utf8.EncodeRune(p, d)
168 | buf = append(buf, p...)
169 | } else {
170 | buf = append(buf, []byte("@")...)
171 | }
172 | }
173 | }
174 | }()
175 |
176 | defer func() {
177 | if err := recover(); err != nil {
178 | log.Println(err)
179 | }
180 | }()
181 | }
182 |
--------------------------------------------------------------------------------
/connections/model.go:
--------------------------------------------------------------------------------
1 | package connections
2 |
3 | import "golang.org/x/crypto/ssh"
4 |
5 | type ptyRequestMsg struct {
6 | Term string
7 | Columns uint32
8 | Rows uint32
9 | Width uint32
10 | Height uint32
11 | ModeList string
12 | }
13 |
14 | type Terminal struct {
15 | Columns uint32 `json:"cols"`
16 | Rows uint32 `json:"rows"`
17 | }
18 |
19 | type SSHClient struct {
20 | Username string `json:"username"`
21 | Password string `json:"password"`
22 | IpAddress string `json:"ipaddress"`
23 | Port int `json:"port"`
24 | Session *ssh.Session
25 | Client *ssh.Client
26 | channel ssh.Channel
27 | }
28 |
29 | func NewSSHClient() SSHClient {
30 | client := SSHClient{}
31 | client.Username = "root"
32 | client.Port = 22
33 | return client
34 | }
35 |
--------------------------------------------------------------------------------
/const/const.go:
--------------------------------------------------------------------------------
1 | package _const
2 |
3 | const (
4 | Layout = "2006-01-02 15:04:05"
5 | LayoutDate = "2006-01-02"
6 | )
7 |
--------------------------------------------------------------------------------
/dist/css/294.5efa506b.css:
--------------------------------------------------------------------------------
1 | [data-v-58fd0009]:export{menuText:#bfcbd9;menuActiveText:#fff;subMenuActiveText:#f4f4f5;menuBg:#304156;menuHover:#263445;subMenuBg:#1f2d3d;subMenuHover:#001528;sideBarWidth:210px;hideSideBarWidth:67px}.content[data-v-58fd0009]{width:100%;background-color:#fff;border-radius:2px;box-shadow:0 1px 2px 0 rgba(0,0,0,.05)}.content .content-box[data-v-58fd0009]{max-width:1500px;height:120px;text-align:left}.content .content-box.box-one[data-v-58fd0009]{height:60px}.content .content-box.box-three[data-v-58fd0009]{height:150px}.content .content-box.box-three-one[data-v-58fd0009]{height:175px}.content .content-box.box-one-one[data-v-58fd0009]{height:100px}.content .content-box .ivu-row[data-v-58fd0009]{margin-bottom:15px}.content .content-box .col5[data-v-58fd0009],.content .content-box .content-list[data-v-58fd0009]{display:inline-block;min-width:100px;width:calc(20% - 10px);margin-right:10px}.content .content-box .content-list12[data-v-58fd0009]{min-width:100px;width:30%;margin-right:10px}.content .content-box .content-list17[data-v-58fd0009]{min-width:100px;width:21.177%;margin-right:10px}.content .content-box .content-list20[data-v-58fd0009]{min-width:100px;width:18.001%;margin-right:10px}.content .content-box .content-list24[data-v-58fd0009]{min-width:100px;width:15%;margin-right:10px}.content .content-box .supertube-btn[data-v-58fd0009]{min-width:120px;margin-top:25px;margin-right:10px;background-color:#09b396!important;border:1px solid #09b396!important;color:#fff!important}.content .content-box .supertube-text[data-v-58fd0009]{display:inline-block;vertical-align:middle;padding-top:20px}[data-v-58fd0009] .el-table .is-leaf{background-color:#fafafa!important}.demo-pagination-block[data-v-58fd0009]{margin-top:10px;display:flex;justify-content:center}.demo-pagination-block .el-pagination .el-select .el-input[data-v-58fd0009]{width:90px!important}[data-v-58fd0009] .el-select{width:192px;height:32px!important}[data-v-58fd0009] .el-select .el-input--large .el-input__inner{height:32px;line-height:32px;padding:0 15px}[data-v-58fd0009] .el-table .warning-row{--el-table-tr-bg-color:#fafafa!important}.flex[data-v-58fd0009]{margin-left:40px}
--------------------------------------------------------------------------------
/dist/css/657.baf841e6.css:
--------------------------------------------------------------------------------
1 | .xterm{position:relative;-moz-user-select:none;user-select:none;-ms-user-select:none;-webkit-user-select:none}.xterm.focus,.xterm:focus{outline:none}.xterm .xterm-helpers{position:absolute;top:0;z-index:5}.xterm .xterm-helper-textarea{padding:0;border:0;margin:0;position:absolute;opacity:0;left:-9999em;top:0;width:0;height:0;z-index:-5;white-space:nowrap;overflow:hidden;resize:none}.xterm .composition-view{background:#000;color:#fff;display:none;position:absolute;white-space:nowrap;z-index:1}.xterm .composition-view.active{display:block}.xterm .xterm-viewport{background-color:#000;overflow-y:scroll;cursor:default;position:absolute;right:0;left:0;top:0;bottom:0}.xterm .xterm-screen{position:relative}.xterm .xterm-screen canvas{position:absolute;left:0;top:0}.xterm .xterm-scroll-area{visibility:hidden}.xterm-char-measure-element{display:inline-block;visibility:hidden;position:absolute;top:0;left:-9999em;line-height:normal}.xterm{cursor:text}.xterm.enable-mouse-events{cursor:default}.xterm.xterm-cursor-pointer{cursor:pointer}.xterm.column-select.focus{cursor:crosshair}.xterm .xterm-accessibility,.xterm .xterm-message{position:absolute;left:0;top:0;bottom:0;right:0;z-index:10;color:transparent}.xterm .live-region{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}.xterm-dim{opacity:.5}.xterm-underline{text-decoration:underline}.xterm-strikethrough{text-decoration:line-through}[data-v-38881416]:export{menuText:#bfcbd9;menuActiveText:#fff;subMenuActiveText:#f4f4f5;menuBg:#304156;menuHover:#263445;subMenuBg:#1f2d3d;subMenuHover:#001528;sideBarWidth:210px;hideSideBarWidth:67px}.content[data-v-38881416]{width:100%;background-color:#fff;border-radius:2px;box-shadow:0 1px 2px 0 rgba(0,0,0,.05)}.content .content-box[data-v-38881416]{max-width:1500px;height:120px;text-align:left}.content .content-box.box-one[data-v-38881416]{height:60px}.content .content-box.box-three[data-v-38881416]{height:150px}.content .content-box.box-three-one[data-v-38881416]{height:175px}.content .content-box.box-one-one[data-v-38881416]{height:100px}.content .content-box .ivu-row[data-v-38881416]{margin-bottom:15px}.content .content-box .col5[data-v-38881416],.content .content-box .content-list[data-v-38881416]{display:inline-block;min-width:100px;width:calc(20% - 10px);margin-right:10px}.content .content-box .content-list12[data-v-38881416]{min-width:100px;width:30%;margin-right:10px}.content .content-box .content-list17[data-v-38881416]{min-width:100px;width:21.177%;margin-right:10px}.content .content-box .content-list20[data-v-38881416]{min-width:100px;width:18.001%;margin-right:10px}.content .content-box .content-list24[data-v-38881416]{min-width:100px;width:15%;margin-right:10px}.content .content-box .supertube-btn[data-v-38881416]{min-width:120px;margin-top:25px;margin-right:10px;background-color:#09b396!important;border:1px solid #09b396!important;color:#fff!important}.content .content-box .supertube-text[data-v-38881416]{display:inline-block;vertical-align:middle;padding-top:20px}[data-v-38881416] .el-table .is-leaf{background-color:#fafafa!important}.demo-pagination-block[data-v-38881416]{margin-top:10px;display:flex;justify-content:center}.demo-pagination-block .el-pagination .el-select .el-input[data-v-38881416]{width:90px!important}[data-v-38881416] .el-select{width:192px;height:32px!important}[data-v-38881416] .el-select .el-input--large .el-input__inner{height:32px;line-height:32px;padding:0 15px}[data-v-38881416] .el-table .warning-row{--el-table-tr-bg-color:#fafafa!important}.upload[data-v-38881416]{min-height:100px}.term1[data-v-38881416]{margin-left:60px}.go_out[data-v-38881416]{margin-left:-89%;margin-top:20px;margin-bottom:20px}
--------------------------------------------------------------------------------
/dist/css/app.8970c6b5.css:
--------------------------------------------------------------------------------
1 | #app{font-family:Avenir,Helvetica,Arial,sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;text-align:center;color:#2c3e50}nav{padding:30px}nav a{font-weight:700;color:#2c3e50}nav a.router-link-exact-active{color:#42b983}[data-v-40c889dc]:export{menuText:#bfcbd9;menuActiveText:#fff;subMenuActiveText:#f4f4f5;menuBg:#304156;menuHover:#263445;subMenuBg:#1f2d3d;subMenuHover:#001528;sideBarWidth:210px;hideSideBarWidth:67px}.content[data-v-40c889dc]{width:100%;background-color:#fff;border-radius:2px;box-shadow:0 1px 2px 0 rgba(0,0,0,.05)}.content .content-box[data-v-40c889dc]{max-width:1500px;height:120px;text-align:left}.content .content-box.box-one[data-v-40c889dc]{height:60px}.content .content-box.box-three[data-v-40c889dc]{height:150px}.content .content-box.box-three-one[data-v-40c889dc]{height:175px}.content .content-box.box-one-one[data-v-40c889dc]{height:100px}.content .content-box .ivu-row[data-v-40c889dc]{margin-bottom:15px}.content .content-box .col5[data-v-40c889dc],.content .content-box .content-list[data-v-40c889dc]{display:inline-block;min-width:100px;width:calc(20% - 10px);margin-right:10px}.content .content-box .content-list12[data-v-40c889dc]{min-width:100px;width:30%;margin-right:10px}.content .content-box .content-list17[data-v-40c889dc]{min-width:100px;width:21.177%;margin-right:10px}.content .content-box .content-list20[data-v-40c889dc]{min-width:100px;width:18.001%;margin-right:10px}.content .content-box .content-list24[data-v-40c889dc]{min-width:100px;width:15%;margin-right:10px}.content .content-box .supertube-btn[data-v-40c889dc]{min-width:120px;margin-top:25px;margin-right:10px;background-color:#09b396!important;border:1px solid #09b396!important;color:#fff!important}.content .content-box .supertube-text[data-v-40c889dc]{display:inline-block;vertical-align:middle;padding-top:20px}[data-v-40c889dc] .el-table .is-leaf{background-color:#fafafa!important}.demo-pagination-block[data-v-40c889dc]{margin-top:10px;display:flex;justify-content:center}.demo-pagination-block .el-pagination .el-select .el-input[data-v-40c889dc]{width:90px!important}[data-v-40c889dc] .el-select{width:192px;height:32px!important}[data-v-40c889dc] .el-select .el-input--large .el-input__inner{height:32px;line-height:32px;padding:0 15px}[data-v-40c889dc] .el-table .warning-row{--el-table-tr-bg-color:#fafafa!important}.app-container[data-v-40c889dc]{position:relative;width:100%;height:100vh}.container[data-v-40c889dc]{width:calc(100% - 210px);height:100%;position:fixed;top:0;right:0;z-index:9;transition:all .28s}.container.hidderContainer[data-v-40c889dc]{width:calc(100% - 67px)}[data-v-40c889dc] .el-header{padding:0}.el-menu-item[data-v-40c889dc]{height:40px!important;line-height:40px!important}.el-menu-item.is-active[data-v-40c889dc]{background-color:#009688!important}.caidan-auth-children[data-v-40c889dc],.caidan-auth[data-v-40c889dc]{font-size:14px;font-style:normal;color:hsla(0,0%,100%,.7);margin-left:10px}.caidan-auth-children[data-v-40c889dc]{height:100%}.htgl-title[data-v-40c889dc]{background-color:#20222a;box-shadow:0 1px 2px 0 rgba(0,0,0,.15);color:hsla(0,0%,100%,.8);width:100%;display:flex;justify-content:center;align-content:center;padding-left:10px;padding-right:10px;padding-top:15px;padding-bottom:15px;font-size:16px}.el-header[data-v-40c889dc]{--el-header-height:50px!important}.el-sub-menu .el-menu-item[data-v-40c889dc]{height:56px;line-height:56px;padding:0 45px;min-width:200px}.backstage-manage[data-v-40c889dc]{width:190px;display:flex;justify-content:center;align-items:center;color:hsla(0,0%,100%,.8);font-size:16px}.toolbar[data-v-40c889dc]{width:100%;height:100%;display:flex;justify-content:space-between;align-items:center;padding-right:20px}.toolbar .toolbar-open-close[data-v-40c889dc]{margin-left:25px;display:flex}.toolbar .el-breadcrumb[data-v-40c889dc]{margin-left:20px}.toolbar .toolbar-static[data-v-40c889dc]{display:flex}.toolbar .toolbar-static .static[data-v-40c889dc]{margin-right:20px;display:flex;align-items:center}.toolbar .toolbar-static .static .jcbj[data-v-40c889dc]{display:flex;align-items:center}.toolbar .toolbar-static .static .jcbj p[data-v-40c889dc]{padding-top:4px;color:red}.toolbar .toolbar-select[data-v-40c889dc]{display:flex;justify-content:center;align-items:center}.toolbar .toolbar-select .elIcon[data-v-40c889dc]{margin-right:8px;margin-top:5px}.toolbar .toolbar-select .username-sel[data-v-40c889dc]{padding-top:3px}[data-v-40c889dc] .el-scrollbar__view{height:100%!important}.el-main[data-v-40c889dc]{--el-main-padding:16px}.content{width:100%;background-color:#fff;border-radius:2px;box-shadow:0 1px 2px 0 rgba(0,0,0,.05)}.content .content-box{max-width:1500px;height:120px;text-align:left}.content .content-box.box-one{height:60px}.content .content-box.box-three{height:150px}.content .content-box.box-three-one{height:175px}.content .content-box.box-one-one{height:100px}.content .content-box .ivu-row{margin-bottom:15px}.content .content-box .col5,.content .content-box .content-list{display:inline-block;min-width:100px;width:calc(20% - 10px);margin-right:10px}.content .content-box .content-list12{min-width:100px;width:30%;margin-right:10px}.content .content-box .content-list17{min-width:100px;width:21.177%;margin-right:10px}.content .content-box .content-list20{min-width:100px;width:18.001%;margin-right:10px}.content .content-box .content-list24{min-width:100px;width:15%;margin-right:10px}.content .content-box .supertube-btn{min-width:120px;margin-top:25px;margin-right:10px;background-color:#09b396!important;border:1px solid #09b396!important;color:#fff!important}.content .content-box .supertube-text{display:inline-block;vertical-align:middle;padding-top:20px}::v-deep .el-table .is-leaf{background-color:#fafafa!important}.demo-pagination-block{margin-top:10px;display:flex;justify-content:center}.demo-pagination-block .el-pagination .el-select .el-input{width:90px!important}::v-deep .el-select{width:192px;height:32px!important}::v-deep .el-select .el-input--large .el-input__inner{height:32px;line-height:32px;padding:0 15px}::v-deep .el-table .warning-row{--el-table-tr-bg-color:#fafafa!important}:export{menuText:#bfcbd9;menuActiveText:#fff;subMenuActiveText:#f4f4f5;menuBg:#304156;menuHover:#263445;subMenuBg:#1f2d3d;subMenuHover:#001528;sideBarWidth:210px;hideSideBarWidth:67px}#app .main-container{min-height:100%;transition:margin-left .28s;margin-left:210px;position:relative}#app .sidebar-container{transition:width .28s;height:100%;position:fixed;top:0;bottom:0;left:0;z-index:1001;overflow:hidden;background-color:#304156}#app .sidebar-container .horizontal-collapse-transition{transition:width 0s ease-in-out,padding-left 0s ease-in-out,padding-right 0s ease-in-out}#app .sidebar-container .scrollbar-wrapper{overflow-x:hidden!important}#app .sidebar-container .el-scrollbar__bar.is-vertical{right:0}#app .sidebar-container .el-scrollbar{height:100%}#app .sidebar-container.has-logo .el-scrollbar{height:calc(100% - 50px)}#app .sidebar-container .is-horizontal{display:none}#app .sidebar-container a{display:inline-block;width:100%;overflow:hidden}#app .sidebar-container .svg-icon{margin-right:16px}#app .sidebar-container .sub-el-icon{margin-right:12px;margin-left:-2px}#app .sidebar-container .el-menu{border:none;height:100%;width:100%!important}#app .sidebar-container .is-active>.el-submenu__title{color:#f4f4f5!important}#app .sidebar-container .el-submenu .el-menu-item,#app .sidebar-container .nest-menu .el-submenu>.el-submenu__title{min-width:210px!important}#app .hideSidebar .sidebar-container{width:54px!important}#app .hideSidebar .main-container{margin-left:54px}#app .hideSidebar .submenu-title-noDropdown{padding:0!important;position:relative}#app .hideSidebar .submenu-title-noDropdown .el-tooltip{padding:0!important}#app .hideSidebar .submenu-title-noDropdown .el-tooltip .svg-icon{margin-left:20px}#app .hideSidebar .submenu-title-noDropdown .el-tooltip .sub-el-icon{margin-left:19px}#app .hideSidebar .el-submenu{overflow:hidden}#app .hideSidebar .el-submenu>.el-submenu__title{padding:0!important}#app .hideSidebar .el-submenu>.el-submenu__title .svg-icon{margin-left:20px}#app .hideSidebar .el-submenu>.el-submenu__title .sub-el-icon{margin-left:19px}#app .hideSidebar .el-submenu>.el-submenu__title .el-submenu__icon-arrow{display:none}#app .hideSidebar .el-menu--collapse .el-submenu>.el-submenu__title>span{height:0;width:0;overflow:hidden;visibility:hidden;display:inline-block}#app .el-menu--collapse .el-menu .el-submenu{min-width:210px!important}#app .withoutAnimation .main-container,#app .withoutAnimation .sidebar-container{transition:none}.el-menu--vertical>.el-menu .svg-icon{margin-right:16px}.el-menu--vertical>.el-menu .sub-el-icon{margin-right:12px;margin-left:-2px}.el-menu--vertical>.el-menu--popup{max-height:100vh;overflow-y:auto}.el-menu--vertical>.el-menu--popup::-webkit-scrollbar-track-piece{background:#d3dce6}.el-menu--vertical>.el-menu--popup::-webkit-scrollbar{width:6px}.el-menu--vertical>.el-menu--popup::-webkit-scrollbar-thumb{background:#99a9bf;border-radius:20px}.el-avatar{--el-avatar-background-color:none!important;--el-avatar-bg-color:none!important}.breadcrumb-enter-active,.breadcrumb-leave-active{transition:all .5s}.breadcrumb-enter-from,.breadcrumb-leave-active{opacity:0;transform:translateX(20px)}.breadcrumb-leave-active{position:absolute}.fade-transform-enter-active,.fade-transform-leave-active{transition:all .28s}.fade-transform-enter-from{opacity:0;transform:translateX(-30px)}.fade-transform-leave-to{opacity:0;transform:translateX(30px)}body,html{margin:0;padding:0;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;font-family:Helvetica Neue,Helvetica,PingFang SC,Hiragino Sans GB,Microsoft YaHei,Arial,sans-serif}#app,body,html{height:100%}*,:after,:before{box-sizing:inherit;margin:0;padding:0}a:active,a:focus{outline:none}a,a:focus,a:hover{cursor:pointer;color:inherit;text-decoration:none}div:focus{outline:none}.clearfix:after{visibility:hidden;display:block;font-size:0;content:" ";clear:both;height:0}div#driver-popover-item .driver-popover-title{color:#1890ff}div#driver-popover-item .driver-popover-footer .driver-next-btn{background-color:#1890ff;color:#fff;text-shadow:none;border-radius:4px}@font-face{font-family:iconfont;src:url(data:application/vnd.ms-fontobject;base64,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);src:url(data:application/vnd.ms-fontobject;base64,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#iefix) format("embedded-opentype"),url(data:application/x-font-woff2;charset=utf-8;base64,d09GMgABAAAAAAV8AAsAAAAACsAAAAUuAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHFQGYACDZAqHXIZFATYCJAMgCxIABCAFhGcHdxtUCREVpIuR/UiMY1LWmSVvoj0aM/kQf/v+zMytbtIzUQugdt1bg7UfZgGwuVZ3z0ZGqCV59smjLyQtZyebPv21X6v3TqZr19evR7PdP7cnquCNIf1EvYaFdCFhYhFCZgg1YWZb3eqLIUU94L/Tu4AAkCAKGaB5BWV1UAzrHjcCLuBA/QSoR5Jhg43d4J0P3IyUgOeE3D05kGUQAHQhfQRgaf775BvEEB6gEDDQcaoM+X249rnmcwsz2U0AexdpHwiwNgUgAMAAhD0sQEzzsSlgZS0MDJKx5TlUAJCBBwV36HI+n8d+3vm5xW5vgbe4w04RApkHxWQVABGE4A78x6MQAEQI6ZZB0lcXAZ9rYnNNvMEgBPEBAwcSCwYG0gEGAtIJBgpiwSQIAAB8uocKgBQgqQBZCqJpOSX+iBQMVKNWuRU6hKi08fKpayy6PkOy3iqTvn/1gKNxrXlsy9EHa3h00yqJzLKGEPNaqXxgNabKmPmAZR+oDCrTfqmcqgYOEibf0nxgaoPrRpvrWkfSQBqJxAvgbIyvLXdat8nJKeFMwh2JJe5U0D63bemH828Xnk29mHnQsXvbq6M7rVbCzDabu9br1+hbpdsXtM/vnMSScoCYQw8W3q0/H0ymKsisyZovG2NuuFFhlVhekQfIxl8CNV2WKgeu7sGutN0XFMBA6eyaipv267cwsnbb0lemWq0NawIuhl61ma1kOmCs6XX6/uRdfq/q/NnXua1zgtRqq33ZaBuof139/DWkDltcNky4OmJ69eqpz5HWk27QG7Zu3bd1gu47veH8UaPeeOLoJC3+Wn305ATd9zrj1gmPQV+EJx49l3XCvl76vfRRzCHfKka9iVC5j4uPnBK5t6v0EdIy4Tu5eiOp65e/605965zfniHCDiTdQuDt5q7mc4FnkbrKMyoq9os53dO+XzDNOzhl0fyLycMdXy4OLbr7R/ae3B98F8+uyo37NjA7ICA7UBgSQ0ED1Q8aXj1pUnz3n9+N9i9Szg/w7b/wyew6n+UfAXE/04jWjDSDIW2KMS3NmC4jLmpZRWBO5285ARXJg0KqqkKMKa1Zbga3J25Gt4NuE/P1JuhULJYeorHsiViuq9klz1kts02WqfXVJ33urnHOQ+oyoV/77OUNQb8L875/FDlmZuTY5qYxkTPHRgpDZVBfNebR93VCYX1QTlFBuUfT4RidQlaKrKS5CYPyPIu9d5T65HlNLkidm1HKU6/kK33ZWSNHZs0ekSX1ZmeNGJE9e2R2HDNBp2JPaD5gP8EIqwYARsjpfLkcegWw/8XmM5FQH2ar2LTGHPaCzfg9r4WWxD/OdyrTfuOlf/FZ70/5vlhm7HM48Nz4PRKwzb9e0sbk5YI8wHNj04t9IEfF2sFchQKQ+BnATzalwftHUi27AhDwLYtFChFckYGHD3CSEBRAihgUgkc6ShCK/P2l0GIUGAgnBhCA2QIJVNiPFAqcRwYV7gInsaEADvgChVDhP5SggciPJkUAgbhHQaPowf5Bctwp4jQf9A3DqEaGyl8oR0IR1mnpNl+xo+yxzfEdNlUCEm7wYs6HtTLswhmdTlF1v8wzjb3K5LidHgWNogf7B8lxp5Rf23/vDcOoRpjwFZFDmeTgsE4LA17dnTXlQ5Y/vsOmSmo9Em7wEkSw+hrDPr5aRqdT3FDZL7PkI657up62l3kRgAR0bJ5QwghHBERIRIQnYignJdND4sx5XHm0lX88XDdg96qMxUkf/mOiYQ3ftNTMncce6jidAAAA) format("woff2"),url(data:font/woff;base64,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) format("woff"),url(data:font/ttf;base64,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) format("truetype")}.iconfont{font-family:iconfont!important;font-size:20px;font-style:normal;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.icon-xiangxiajiantou:before{content:""}.icon-xiangyoujiantou:before{content:""}.icon-jian:before{content:""}.icon-tianjia:before{content:""}.icon-zhifubao:before{content:""}.icon-mima:before{content:""}.icon-denglu:before{content:""}
--------------------------------------------------------------------------------
/dist/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mazezen/websshterminal/2f8d5d091362a84a693b62bb6763a37a32060d15/dist/favicon.ico
--------------------------------------------------------------------------------
/dist/index.html:
--------------------------------------------------------------------------------
1 |
web-ssh-terminal
--------------------------------------------------------------------------------
/dist/js/294.580a20f9.js:
--------------------------------------------------------------------------------
1 | "use strict";(self["webpackChunkweb"]=self["webpackChunkweb"]||[]).push([[294],{4294:function(e,u,a){a.r(u),a.d(u,{default:function(){return v}});var l=a(4195),r=a(8276),n=a(3378),t=a(6252),o=a(2262),d=a(2201),s={class:"flex"},p=(0,t.Uk)("连接"),i=(0,t.Uk)("重置"),m=(0,t.aZ)({__name:"node",setup:function(e){var u=(0,d.tv)(),a=(0,o.iH)({ipaddress:"",username:"root",password:"",port:22}),m=function(){u.push({path:"/ssh/dial",query:{ipaddress:a.value.ipaddress,username:a.value.username,password:a.value.password,port:a.value.port}})},f=function(){a.value.ipaddress="",a.value.username="",a.value.password=""};return function(e,u){var o=n.EZ,d=l.nH,c=r.mi,v=l.ly;return(0,t.wg)(),(0,t.iD)("div",s,[(0,t.Wm)(v,{"label-width":"100px",class:"demo-ruleForm","label-position":"left"},{default:(0,t.w5)((function(){return[(0,t.Wm)(d,{label:"ip地址",prop:"ipaddress",required:""},{default:(0,t.w5)((function(){return[(0,t.Wm)(o,{type:"text",modelValue:a.value.ipaddress,"onUpdate:modelValue":u[0]||(u[0]=function(e){return a.value.ipaddress=e})},null,8,["modelValue"])]})),_:1}),(0,t.Wm)(d,{label:"用户名",prop:"username",required:""},{default:(0,t.w5)((function(){return[(0,t.Wm)(o,{type:"text",modelValue:a.value.username,"onUpdate:modelValue":u[1]||(u[1]=function(e){return a.value.username=e})},null,8,["modelValue"])]})),_:1}),(0,t.Wm)(d,{label:"密码",prop:"pass",required:""},{default:(0,t.w5)((function(){return[(0,t.Wm)(o,{type:"password",modelValue:a.value.password,"onUpdate:modelValue":u[2]||(u[2]=function(e){return a.value.password=e}),autocomplete:"off"},null,8,["modelValue"])]})),_:1}),(0,t.Wm)(d,{label:"端口",prop:"port",required:""},{default:(0,t.w5)((function(){return[(0,t.Wm)(o,{modelValue:a.value.port,"onUpdate:modelValue":u[3]||(u[3]=function(e){return a.value.port=e}),modelModifiers:{number:!0}},null,8,["modelValue"])]})),_:1}),(0,t.Wm)(d,null,{default:(0,t.w5)((function(){return[(0,t.Wm)(c,{type:"primary",onClick:m,plain:""},{default:(0,t.w5)((function(){return[p]})),_:1}),(0,t.Wm)(c,{onClick:f},{default:(0,t.w5)((function(){return[i]})),_:1})]})),_:1})]})),_:1})])}}}),f=a(3744);const c=(0,f.Z)(m,[["__scopeId","data-v-58fd0009"]]);var v=c}}]);
2 | //# sourceMappingURL=294.580a20f9.js.map
--------------------------------------------------------------------------------
/dist/js/294.580a20f9.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"js/294.580a20f9.js","mappings":"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","sources":["webpack://web/./src/views/node.vue","webpack://web/./src/views/node.vue?a656"],"sourcesContent":["import { defineComponent as _defineComponent } from 'vue';\nimport { resolveComponent as _resolveComponent, createVNode as _createVNode, withCtx as _withCtx, createTextVNode as _createTextVNode, openBlock as _openBlock, createElementBlock as _createElementBlock, pushScopeId as _pushScopeId, popScopeId as _popScopeId } from \"vue\";\n\nvar _withScopeId = function (n) {\n return _pushScopeId(\"data-v-58fd0009\"), n = n(), _popScopeId(), n;\n};\n\nvar _hoisted_1 = {\n class: \"flex\"\n};\n\nvar _hoisted_2 = /*#__PURE__*/_createTextVNode(\"连接\");\n\nvar _hoisted_3 = /*#__PURE__*/_createTextVNode(\"重置\");\n\nimport { ref } from 'vue';\nimport { useRouter } from 'vue-router';\nexport default /*#__PURE__*/_defineComponent({\n __name: 'node',\n setup: function (__props) {\n var router = useRouter();\n var ruleForm = ref({\n ipaddress: \"\",\n username: \"root\",\n password: \"\",\n port: 22\n });\n\n var connectSsh = function () {\n router.push({\n path: \"/ssh/dial\",\n query: {\n ipaddress: ruleForm.value.ipaddress,\n username: ruleForm.value.username,\n password: ruleForm.value.password,\n port: ruleForm.value.port\n }\n });\n };\n\n var resetForm = function () {\n ruleForm.value.ipaddress = \"\";\n ruleForm.value.username = \"\";\n ruleForm.value.password = \"\";\n };\n\n return function (_ctx, _cache) {\n var _component_el_input = _resolveComponent(\"el-input\");\n\n var _component_el_form_item = _resolveComponent(\"el-form-item\");\n\n var _component_el_button = _resolveComponent(\"el-button\");\n\n var _component_el_form = _resolveComponent(\"el-form\");\n\n return _openBlock(), _createElementBlock(\"div\", _hoisted_1, [_createVNode(_component_el_form, {\n \"label-width\": \"100px\",\n class: \"demo-ruleForm\",\n \"label-position\": \"left\"\n }, {\n default: _withCtx(function () {\n return [_createVNode(_component_el_form_item, {\n label: \"ip地址\",\n prop: \"ipaddress\",\n required: \"\"\n }, {\n default: _withCtx(function () {\n return [_createVNode(_component_el_input, {\n type: \"text\",\n modelValue: ruleForm.value.ipaddress,\n \"onUpdate:modelValue\": _cache[0] || (_cache[0] = function ($event) {\n return ruleForm.value.ipaddress = $event;\n })\n }, null, 8, [\"modelValue\"])];\n }),\n _: 1\n }), _createVNode(_component_el_form_item, {\n label: \"用户名\",\n prop: \"username\",\n required: \"\"\n }, {\n default: _withCtx(function () {\n return [_createVNode(_component_el_input, {\n type: \"text\",\n modelValue: ruleForm.value.username,\n \"onUpdate:modelValue\": _cache[1] || (_cache[1] = function ($event) {\n return ruleForm.value.username = $event;\n })\n }, null, 8, [\"modelValue\"])];\n }),\n _: 1\n }), _createVNode(_component_el_form_item, {\n label: \"密码\",\n prop: \"pass\",\n required: \"\"\n }, {\n default: _withCtx(function () {\n return [_createVNode(_component_el_input, {\n type: \"password\",\n modelValue: ruleForm.value.password,\n \"onUpdate:modelValue\": _cache[2] || (_cache[2] = function ($event) {\n return ruleForm.value.password = $event;\n }),\n autocomplete: \"off\"\n }, null, 8, [\"modelValue\"])];\n }),\n _: 1\n }), _createVNode(_component_el_form_item, {\n label: \"端口\",\n prop: \"port\",\n required: \"\"\n }, {\n default: _withCtx(function () {\n return [_createVNode(_component_el_input, {\n modelValue: ruleForm.value.port,\n \"onUpdate:modelValue\": _cache[3] || (_cache[3] = function ($event) {\n return ruleForm.value.port = $event;\n }),\n modelModifiers: {\n number: true\n }\n }, null, 8, [\"modelValue\"])];\n }),\n _: 1\n }), _createVNode(_component_el_form_item, null, {\n default: _withCtx(function () {\n return [_createVNode(_component_el_button, {\n type: \"primary\",\n onClick: connectSsh,\n plain: \"\"\n }, {\n default: _withCtx(function () {\n return [_hoisted_2];\n }),\n _: 1\n }), _createVNode(_component_el_button, {\n onClick: resetForm\n }, {\n default: _withCtx(function () {\n return [_hoisted_3];\n }),\n _: 1\n })];\n }),\n _: 1\n })];\n }),\n _: 1\n })]);\n };\n }\n});","/* unplugin-vue-components disabled */import script from \"./node.vue?vue&type=script&lang=ts&setup=true\"\nexport * from \"./node.vue?vue&type=script&lang=ts&setup=true\"\n\nimport \"./node.vue?vue&type=style&index=0&id=58fd0009&lang=scss&scoped=true\"\n\nimport exportComponent from \"/Users/cc/github.com/websshterminal-vue/node_modules/vue-loader/dist/exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['__scopeId',\"data-v-58fd0009\"]])\n\nexport default __exports__"],"names":["_hoisted_1","class","_hoisted_2","_hoisted_3","__name","setup","__props","router","ruleForm","ipaddress","username","password","port","connectSsh","push","path","query","value","resetForm","_ctx","_cache","_component_el_input","_component_el_form_item","_component_el_button","_component_el_form","default","label","prop","required","type","modelValue","$event","_","autocomplete","modelModifiers","number","onClick","plain","__exports__"],"sourceRoot":""}
--------------------------------------------------------------------------------
/dist/js/app.cd909d50.js:
--------------------------------------------------------------------------------
1 | (function(){"use strict";var e={1361:function(e,t,n){var r=n(9963),o=n(6252);function a(e,t){const n=(0,o.up)("router-view");return(0,o.wg)(),(0,o.j4)(n)}var i=n(3744);const u={},c=(0,i.Z)(u,[["render",a]]);var s=c,l=n(2201),f=n(5704),d=n(4408),m=n(984),p=n(2262),h=n(655),v=n(3907),b=n(9669),g=n.n(b),w=n(1348),y=g().create({baseURL:{NODE_ENV:"production",BASE_URL:"/"}.VUE_APP_BASE_API,timeout:5e3});function _(e){return-404===e.status&&w.z8.error("请求未找到"),e.data&&!e.data.success&&w.z8.error("未请求到数据"),e}function A(e){if(!e||!/^(200|304|400)$/.test(e.status))return!1;if(!e.data||21004!==e.data.code&&21005!==e.data.code&&21006!==e.data.code&&21008!==e.data.code){if(2e3===e.data.code)return e.data.success?e.data:e.data.msg?(w.z8.error(e.data.msg),e.data):(w.z8.error("请求出错"),!1);w.z8.error(e.data.msg)}else W.push("/login")}y.interceptors.request.use((function(e){return e}),(function(e){return Promise.reject(new Error(e))})),y.interceptors.response.use((function(e){return e}),(function(e){return Promise.reject(new Error(e.response.data))}));var E={service:y,getJson:function(e,t){var n="Bearer "+window.localStorage.getItem("token");return g()({method:"GET",url:t,data:e,headers:{Authorization:n,key:"2A3F43B2E46DDAFC6E12C2B386704EF4",secret:"7FE6461015477B0F24ADD487CBC4A398",sign:"dbbcbb3266ce08f5b8549bcf43bda750","Content-type":"application/json;charset=UTF-8"}}).then((function(e){return A(e)})).catch((function(e){return _(e)}))},postJson:function(e,t){var n="Bearer "+window.localStorage.getItem("token");return g()({method:"POST",url:t,data:e,headers:{Authorization:n,key:"2A3F43B2E46DDAFC6E12C2B386704EF4",secret:"7FE6461015477B0F24ADD487CBC4A398",sign:"dbbcbb3266ce08f5b8549bcf43bda750","Content-type":"application/json;charset=UTF-8"}}).then((function(e){return A(e)})).catch((function(e){return _(e)}))},postJson2:function(e,t){var n="Bearer "+window.localStorage.getItem("token");return g()({method:"POST",url:t,data:e,headers:{Authorization:n,key:"2A3F43B2E46DDAFC6E12C2B386704EF4",secret:"7FE6461015477B0F24ADD487CBC4A398",sign:"dbbcbb3266ce08f5b8549bcf43bda750","Content-Type":"multipart/form-data"}}).then((function(e){return A(e)})).catch((function(e){return _(e)}))}},C=function(){return E.getJson("","/api/menus/list")},k=n(4702),F=(0,v.MT)({state:{menuListAll:[],openNames:"",activeName:""},getters:{},mutations:{activeName:function(e,t){e.activeName=t},openNames:function(e,t){e.openNames=t},menuList:function(e){return(0,h.mG)(this,void 0,void 0,(function(){var t;return(0,h.Jh)(this,(function(n){switch(n.label){case 0:return n.trys.push([0,2,,3]),[4,C()];case 1:return t=n.sent(),t&&(e.menuListAll=t.data),[3,3];case 2:return n.sent(),[3,3];case 3:return[2]}}))}))}},actions:{loadmenuList:function(e){window.localStorage.getItem("token")&&e.commit("menuList")}},modules:{},plugins:[(0,k.Z)({storage:window.sessionStorage,key:"store",reducer:function(e){return{menuListAll:e.menuListAll,openNames:e.openNames,activeName:e.activeName}}})]});const B=e=>((0,o.dD)("data-v-40c889dc"),e=e(),(0,o.Cn)(),e),O=B((()=>(0,o._)("span",{class:"backstage-manage"},"web-ssh-terminal",-1))),j=B((()=>(0,o._)("span",{class:"caidan-auth"},"节点服务器",-1))),N=B((()=>(0,o._)("span",{class:"caidan-auth"},"节点服务器",-1))),S=B((()=>(0,o._)("div",{class:"toolbar"},[(0,o._)("div",{class:"toolbar-open-close"},[(0,o._)("div",null,[(0,o._)("i",{class:"layui-icon"})])]),(0,o._)("div",{class:"toolbar-static"})],-1)));var D={__name:"index",setup(e){const t=(0,o.Fl)((()=>"210"));return(e,n)=>{const r=m.E_,a=m.F8,i=m.Q8,u=d.Mr,c=f.$w,s=f.nZ,l=(0,o.up)("router-view"),h=f.b2,v=f.G4;return(0,o.wg)(),(0,o.j4)(v,{class:"app-wrapper"},{default:(0,o.w5)((()=>[(0,o.Wm)(c,{width:(0,p.SU)(t),class:"sidebar-container"},{default:(0,o.w5)((()=>[(0,o.Wm)(u,{style:{height:"'100%'"}},{default:(0,o.w5)((()=>[(0,o.Wm)(i,{"active-text-color":"#ffd04b","background-color":"#20222A",class:"el-menu-vertical-demo","default-active":e.activePath,"text-color":"#fff","unique-opened":"",router:""},{default:(0,o.w5)((()=>[(0,o.Wm)(r,{index:"board",onClick:n[0]||(n[0]=t=>e.goUrl("web-ssh-terminal","","board")),style:{height:"50px !important","background-color":"var(--el-menu-hover-bg-color) !important"}},{default:(0,o.w5)((()=>[O])),_:1}),(0,o.Wm)(a,null,{title:(0,o.w5)((()=>[j])),default:(0,o.w5)((()=>[(0,o.Wm)(r,null,{default:(0,o.w5)((()=>[N])),_:1})])),_:1})])),_:1},8,["default-active"])])),_:1})])),_:1},8,["width"]),(0,o.Wm)(v,{class:"container"},{default:(0,o.w5)((()=>[(0,o.Wm)(s,{style:{"font-size":"16px","background-color":"#ffffff"}},{default:(0,o.w5)((()=>[S])),_:1}),(0,o.Wm)(h,{style:{"background-color":"#f2f2f2"}},{default:(0,o.w5)((()=>[(0,o.Wm)(l)])),_:1})])),_:1})])),_:1})}}};const P=(0,i.Z)(D,[["__scopeId","data-v-40c889dc"]]);for(var T=P,L=[{path:"/",name:"/ssh/node",component:T,redirect:"/ssh/node",children:[{path:"/ssh/node",name:"/ssh/node",component:function(){return n.e(294).then(n.bind(n,4294))}},{path:"/ssh/dial",name:"/ssh/dial",component:function(){return n.e(657).then(n.bind(n,6657))}}]}],x=(0,l.p7)({history:(0,l.PO)("/"),routes:L}),W=x,z=(n(4415),n(9213)),U=n(8642),I=n(5781),Z=(0,r.ri)(s),J=0,M=Object.entries(I);J=a)&&Object.keys(n.O).every((function(e){return n.O[e](r[c])}))?r.splice(c--,1):(u=!1,a0&&e[l-1][2]>a;l--)e[l]=e[l-1];e[l]=[r,o,a]}}(),function(){n.n=function(e){var t=e&&e.__esModule?function(){return e["default"]}:function(){return e};return n.d(t,{a:t}),t}}(),function(){n.d=function(e,t){for(var r in t)n.o(t,r)&&!n.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})}}(),function(){n.f={},n.e=function(e){return Promise.all(Object.keys(n.f).reduce((function(t,r){return n.f[r](e,t),t}),[]))}}(),function(){n.u=function(e){return"js/"+e+"."+{294:"580a20f9",657:"47dd038e"}[e]+".js"}}(),function(){n.miniCssF=function(e){return"css/"+e+"."+{294:"5efa506b",657:"baf841e6"}[e]+".css"}}(),function(){n.g=function(){if("object"===typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"===typeof window)return window}}()}(),function(){n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)}}(),function(){var e={},t="web:";n.l=function(r,o,a,i){if(e[r])e[r].push(o);else{var u,c;if(void 0!==a)for(var s=document.getElementsByTagName("script"),l=0;l {\n return config\n },\n error => {\n return Promise.reject(new Error(error))\n }\n)\n\nservice.interceptors.response.use(\n response => {\n debugger\n return response\n }, error => {\n debugger\n return Promise.reject(new Error(error.response.data))\n }\n)\n\ninterface BZResponse {\n success: boolean;\n obj: U;\n errMsg?: string;\n code?: number;\n}\n\nfunction checkCode(res: any) {\n if (res.status === -404) {\n ElMessage.error(\"请求未找到\")\n }\n if (res.data && !res.data.success) {\n ElMessage.error(\"未请求到数据\")\n }\n return res\n}\n\nfunction checkStatus(response: any) {\n // 未登陆 || Token错误 || 账号禁用\n if ( response && (/^(200|304|400)$/.test(response.status)) ) {\n if (response.data && (response.data.code === 21004 || \n response.data.code === 21005 || \n response.data.code === 21006 || \n response.data.code === 21008)) {\n router.push('/login');\n } else if (response.data.code !== 2000) { // 错误提示\n ElMessage.error(response.data.msg);\n } else if (response.data.success) {\n return response.data;\n } else if (response.data.msg) { // 提示\n ElMessage.error(response.data.msg);\n return response.data\n } else {\n ElMessage.error('请求出错')\n return false\n }\n } else {\n return false\n }\n}\n\nexport default {\n service,\n getJson(data: any, url: string) {\n let token: any = \"Bearer \"+window.localStorage.getItem(\"token\")\n return axios({\n method: \"GET\",\n url: url,\n data: data,\n headers: {\n \"Authorization\": token,\n \"key\": \"2A3F43B2E46DDAFC6E12C2B386704EF4\",\n \"secret\": \"7FE6461015477B0F24ADD487CBC4A398\",\n \"sign\": \"dbbcbb3266ce08f5b8549bcf43bda750\",\n \"Content-type\": \"application/json;charset=UTF-8\"\n }\n }).then((res: any) => {\n return checkStatus(res);\n }).catch((err) => {\n return checkCode(err);\n });\n },\n postJson(data: any, url: string) {\n let token: any = \"Bearer \"+window.localStorage.getItem(\"token\")\n return axios({\n method: \"POST\",\n url: url,\n data: data,\n headers: {\n \"Authorization\": token,\n \"key\": \"2A3F43B2E46DDAFC6E12C2B386704EF4\",\n \"secret\": \"7FE6461015477B0F24ADD487CBC4A398\",\n \"sign\": \"dbbcbb3266ce08f5b8549bcf43bda750\",\n \"Content-type\": \"application/json;charset=UTF-8\"\n }\n }).then((res: any) => {\n return checkStatus(res);\n }).catch((err) => {\n return checkCode(err);\n });\n },\n\n postJson2(data: any, url: string) {\n let token: any = \"Bearer \"+window.localStorage.getItem(\"token\")\n return axios({\n method: \"POST\",\n url: url,\n data: data,\n headers: {\n \"Authorization\": token,\n \"key\": \"2A3F43B2E46DDAFC6E12C2B386704EF4\",\n \"secret\": \"7FE6461015477B0F24ADD487CBC4A398\",\n \"sign\": \"dbbcbb3266ce08f5b8549bcf43bda750\",\n 'Content-Type': 'multipart/form-data'\n }\n }).then((res: any) => {\n return checkStatus(res);\n }).catch((err) => {\n return checkCode(err);\n });\n },\n}\n","import axios from \"./axios\";\n\n// 左侧菜单列表\nexport const menu = () => {\n return axios.getJson(\"\", \"/api/menus/list\")\n}\n","import { createStore } from 'vuex'\nimport { menu } from '@/request/api'\nimport createPersistedstate from 'vuex-persistedstate'\n\nexport default createStore({\n state: {\n /** 左侧菜单列表 */\n menuListAll: [],\n /** 左边导航栏: 当前展开的一级菜单名 */\n openNames: '',\n /** 左边菜单栏: 当前选中的菜单名 */\n activeName: '',\n },\n getters: {\n },\n mutations: {\n activeName(state: any, name) {\n state.activeName = name;\n },\n openNames(state: any, name) {\n state.openNames = name\n },\n // 菜单列表\n async menuList(state) {\n try {\n let res = await menu();\n if (res) {\n state.menuListAll = res.data\n // console.log(state.menuListAll);\n \n // state.menuListAll = state.menuListAll\n }\n } catch (err) {\n\n }\n },\n },\n actions: {\n /** 请求左侧菜单 */\n loadmenuList(obj) {\n window.localStorage.getItem('token') && obj.commit('menuList')\n }\n },\n modules: {\n },\n plugins: [\n createPersistedstate({\n storage: window.sessionStorage,\n key: \"store\",\n reducer(state) {\n return {\n menuListAll: state.menuListAll,\n openNames: state.openNames,\n activeName: state.activeName\n }\n }\n })\n ]\n})\n","import { unref as _unref, createElementVNode as _createElementVNode, resolveComponent as _resolveComponent, withCtx as _withCtx, createVNode as _createVNode, openBlock as _openBlock, createBlock as _createBlock, pushScopeId as _pushScopeId, popScopeId as _popScopeId } from \"vue\";\n\nconst _withScopeId = n => (_pushScopeId(\"data-v-40c889dc\"), n = n(), _popScopeId(), n);\n\nconst _hoisted_1 = /*#__PURE__*/_withScopeId(() => /*#__PURE__*/_createElementVNode(\"span\", {\n class: \"backstage-manage\"\n}, \"web-ssh-terminal\", -1));\n\nconst _hoisted_2 = /*#__PURE__*/_withScopeId(() => /*#__PURE__*/_createElementVNode(\"span\", {\n class: \"caidan-auth\"\n}, \"节点服务器\", -1));\n\nconst _hoisted_3 = /*#__PURE__*/_withScopeId(() => /*#__PURE__*/_createElementVNode(\"span\", {\n class: \"caidan-auth\"\n}, \"节点服务器\", -1));\n\nconst _hoisted_4 = /*#__PURE__*/_withScopeId(() => /*#__PURE__*/_createElementVNode(\"div\", {\n class: \"toolbar\"\n}, [/*#__PURE__*/_createElementVNode(\"div\", {\n class: \"toolbar-open-close\"\n}, [/*#__PURE__*/_createElementVNode(\"div\", null, [/*#__PURE__*/_createElementVNode(\"i\", {\n class: \"layui-icon\"\n})])]), /*#__PURE__*/_createElementVNode(\"div\", {\n class: \"toolbar-static\"\n})], -1));\n\nimport { ref, computed, watch } from \"vue\";\nimport { useRouter } from \"vue-router\";\nimport { Location, Document, Menu as IconMenu, Setting } from '@element-plus/icons-vue';\nimport variables from \"@/assets/styles/variables.scss\";\nimport store from \"@/store/index.ts\";\nimport { ElMessage } from 'element-plus';\nexport default {\n __name: 'index',\n\n setup(__props) {\n const asideWidth = computed(() => {\n return \"210\";\n }); // // 保存信息和url到缓存里面\n // const goUrl = (authName, authName2, url) => {\n // store.commit(\"openNames\", authName);\n // store.commit(\"activeName\", authName2);\n // sessionStorage.setItem(`url`,`${url}`)\n // activePath.value = sessionStorage.getItem(`url`) \n // }\n\n return (_ctx, _cache) => {\n const _component_el_menu_item = _resolveComponent(\"el-menu-item\");\n\n const _component_el_sub_menu = _resolveComponent(\"el-sub-menu\");\n\n const _component_el_menu = _resolveComponent(\"el-menu\");\n\n const _component_el_scrollbar = _resolveComponent(\"el-scrollbar\");\n\n const _component_el_aside = _resolveComponent(\"el-aside\");\n\n const _component_el_header = _resolveComponent(\"el-header\");\n\n const _component_router_view = _resolveComponent(\"router-view\");\n\n const _component_el_main = _resolveComponent(\"el-main\");\n\n const _component_el_container = _resolveComponent(\"el-container\");\n\n return _openBlock(), _createBlock(_component_el_container, {\n class: \"app-wrapper\"\n }, {\n default: _withCtx(() => [_createVNode(_component_el_aside, {\n width: _unref(asideWidth),\n class: \"sidebar-container\"\n }, {\n default: _withCtx(() => [_createVNode(_component_el_scrollbar, {\n style: {\n \"height\": \"'100%'\"\n }\n }, {\n default: _withCtx(() => [_createVNode(_component_el_menu, {\n \"active-text-color\": \"#ffd04b\",\n \"background-color\": \"#20222A\",\n class: \"el-menu-vertical-demo\",\n \"default-active\": _ctx.activePath,\n \"text-color\": \"#fff\",\n \"unique-opened\": \"\",\n router: \"\"\n }, {\n default: _withCtx(() => [_createVNode(_component_el_menu_item, {\n index: \"board\",\n onClick: _cache[0] || (_cache[0] = $event => _ctx.goUrl('web-ssh-terminal', '', 'board')),\n style: {\n \"height\": \"50px !important\",\n \"background-color\": \"var(--el-menu-hover-bg-color) !important\"\n }\n }, {\n default: _withCtx(() => [_hoisted_1]),\n _: 1\n }), _createVNode(_component_el_sub_menu, null, {\n title: _withCtx(() => [_hoisted_2]),\n default: _withCtx(() => [_createVNode(_component_el_menu_item, null, {\n default: _withCtx(() => [_hoisted_3]),\n _: 1\n })]),\n _: 1\n })]),\n _: 1\n }, 8, [\"default-active\"])]),\n _: 1\n })]),\n _: 1\n }, 8, [\"width\"]), _createVNode(_component_el_container, {\n class: \"container\"\n }, {\n default: _withCtx(() => [_createVNode(_component_el_header, {\n style: {\n \"font-size\": \"16px\",\n \"background-color\": \"#ffffff\"\n }\n }, {\n default: _withCtx(() => [_hoisted_4]),\n _: 1\n }), _createVNode(_component_el_main, {\n style: {\n \"background-color\": \"#f2f2f2\"\n }\n }, {\n default: _withCtx(() => [_createVNode(_component_router_view)]),\n _: 1\n })]),\n _: 1\n })]),\n _: 1\n });\n };\n }\n\n};","/* unplugin-vue-components disabled */import script from \"./index.vue?vue&type=script&setup=true&lang=js\"\nexport * from \"./index.vue?vue&type=script&setup=true&lang=js\"\n\nimport \"./index.vue?vue&type=style&index=0&id=40c889dc&lang=scss&scoped=true\"\n\nimport exportComponent from \"/Users/cc/github.com/websshterminal-vue/node_modules/vue-loader/dist/exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['__scopeId',\"data-v-40c889dc\"]])\n\nexport default __exports__","import { createApp } from 'vue'\nimport App from './App.vue'\nimport router from './router'\nimport store from './store'\nimport \"@/assets/styles/index.scss\"\nimport 'element-plus/dist/index.css'\nimport ElementPlus from 'element-plus'\nimport zhCn from 'element-plus/es/locale/lang/zh-cn'\nimport * as ElementPlusIconsVue from '@element-plus/icons-vue'\n\nconst app = createApp(App)\nfor (const [key, component] of Object.entries(ElementPlusIconsVue)) {\n app.component(key, component)\n }\napp.use(ElementPlus, {\n locale: zhCn,\n})\napp.use(store)\napp.use(router)\napp.mount('#app')\n","import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router'\nimport Index from '@/views/home/index.vue';\n\n\nconst routes: Array = [\n {\n path: '/',\n name: '/ssh/node',\n component: Index,\n redirect: '/ssh/node',\n children: [\n // 首页看板\n {\n path: \"/ssh/node\",\n name: \"/ssh/node\",\n component: () => import(\"@/views/node.vue\"),\n },\n {\n path: \"/ssh/dial\",\n name: \"/ssh/dial\",\n component: () => import(\"@/views/dial.vue\"),\n },\n ]\n }\n]\n\nconst router = createRouter({\n history: createWebHistory(process.env.BASE_URL),\n routes\n})\n\nexport default router\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n// expose the modules object (__webpack_modules__)\n__webpack_require__.m = __webpack_modules__;\n\n","var deferred = [];\n__webpack_require__.O = function(result, chunkIds, fn, priority) {\n\tif(chunkIds) {\n\t\tpriority = priority || 0;\n\t\tfor(var i = deferred.length; i > 0 && deferred[i - 1][2] > priority; i--) deferred[i] = deferred[i - 1];\n\t\tdeferred[i] = [chunkIds, fn, priority];\n\t\treturn;\n\t}\n\tvar notFulfilled = Infinity;\n\tfor (var i = 0; i < deferred.length; i++) {\n\t\tvar chunkIds = deferred[i][0];\n\t\tvar fn = deferred[i][1];\n\t\tvar priority = deferred[i][2];\n\t\tvar fulfilled = true;\n\t\tfor (var j = 0; j < chunkIds.length; j++) {\n\t\t\tif ((priority & 1 === 0 || notFulfilled >= priority) && Object.keys(__webpack_require__.O).every(function(key) { return __webpack_require__.O[key](chunkIds[j]); })) {\n\t\t\t\tchunkIds.splice(j--, 1);\n\t\t\t} else {\n\t\t\t\tfulfilled = false;\n\t\t\t\tif(priority < notFulfilled) notFulfilled = priority;\n\t\t\t}\n\t\t}\n\t\tif(fulfilled) {\n\t\t\tdeferred.splice(i--, 1)\n\t\t\tvar r = fn();\n\t\t\tif (r !== undefined) result = r;\n\t\t}\n\t}\n\treturn result;\n};","// getDefaultExport function for compatibility with non-harmony modules\n__webpack_require__.n = function(module) {\n\tvar getter = module && module.__esModule ?\n\t\tfunction() { return module['default']; } :\n\t\tfunction() { return module; };\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};","// define getter functions for harmony exports\n__webpack_require__.d = function(exports, definition) {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.f = {};\n// This file contains only the entry chunk.\n// The chunk loading function for additional chunks\n__webpack_require__.e = function(chunkId) {\n\treturn Promise.all(Object.keys(__webpack_require__.f).reduce(function(promises, key) {\n\t\t__webpack_require__.f[key](chunkId, promises);\n\t\treturn promises;\n\t}, []));\n};","// This function allow to reference async chunks\n__webpack_require__.u = function(chunkId) {\n\t// return url for filenames based on template\n\treturn \"js/\" + chunkId + \".\" + {\"294\":\"580a20f9\",\"657\":\"47dd038e\"}[chunkId] + \".js\";\n};","// This function allow to reference async chunks\n__webpack_require__.miniCssF = function(chunkId) {\n\t// return url for filenames based on template\n\treturn \"css/\" + chunkId + \".\" + {\"294\":\"5efa506b\",\"657\":\"baf841e6\"}[chunkId] + \".css\";\n};","__webpack_require__.g = (function() {\n\tif (typeof globalThis === 'object') return globalThis;\n\ttry {\n\t\treturn this || new Function('return this')();\n\t} catch (e) {\n\t\tif (typeof window === 'object') return window;\n\t}\n})();","__webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }","var inProgress = {};\nvar dataWebpackPrefix = \"web:\";\n// loadScript function to load a script via script tag\n__webpack_require__.l = function(url, done, key, chunkId) {\n\tif(inProgress[url]) { inProgress[url].push(done); return; }\n\tvar script, needAttach;\n\tif(key !== undefined) {\n\t\tvar scripts = document.getElementsByTagName(\"script\");\n\t\tfor(var i = 0; i < scripts.length; i++) {\n\t\t\tvar s = scripts[i];\n\t\t\tif(s.getAttribute(\"src\") == url || s.getAttribute(\"data-webpack\") == dataWebpackPrefix + key) { script = s; break; }\n\t\t}\n\t}\n\tif(!script) {\n\t\tneedAttach = true;\n\t\tscript = document.createElement('script');\n\n\t\tscript.charset = 'utf-8';\n\t\tscript.timeout = 120;\n\t\tif (__webpack_require__.nc) {\n\t\t\tscript.setAttribute(\"nonce\", __webpack_require__.nc);\n\t\t}\n\t\tscript.setAttribute(\"data-webpack\", dataWebpackPrefix + key);\n\t\tscript.src = url;\n\t}\n\tinProgress[url] = [done];\n\tvar onScriptComplete = function(prev, event) {\n\t\t// avoid mem leaks in IE.\n\t\tscript.onerror = script.onload = null;\n\t\tclearTimeout(timeout);\n\t\tvar doneFns = inProgress[url];\n\t\tdelete inProgress[url];\n\t\tscript.parentNode && script.parentNode.removeChild(script);\n\t\tdoneFns && doneFns.forEach(function(fn) { return fn(event); });\n\t\tif(prev) return prev(event);\n\t}\n\t;\n\tvar timeout = setTimeout(onScriptComplete.bind(null, undefined, { type: 'timeout', target: script }), 120000);\n\tscript.onerror = onScriptComplete.bind(null, script.onerror);\n\tscript.onload = onScriptComplete.bind(null, script.onload);\n\tneedAttach && document.head.appendChild(script);\n};","// define __esModule on exports\n__webpack_require__.r = function(exports) {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","__webpack_require__.p = \"/\";","var createStylesheet = function(chunkId, fullhref, resolve, reject) {\n\tvar linkTag = document.createElement(\"link\");\n\n\tlinkTag.rel = \"stylesheet\";\n\tlinkTag.type = \"text/css\";\n\tvar onLinkComplete = function(event) {\n\t\t// avoid mem leaks.\n\t\tlinkTag.onerror = linkTag.onload = null;\n\t\tif (event.type === 'load') {\n\t\t\tresolve();\n\t\t} else {\n\t\t\tvar errorType = event && (event.type === 'load' ? 'missing' : event.type);\n\t\t\tvar realHref = event && event.target && event.target.href || fullhref;\n\t\t\tvar err = new Error(\"Loading CSS chunk \" + chunkId + \" failed.\\n(\" + realHref + \")\");\n\t\t\terr.code = \"CSS_CHUNK_LOAD_FAILED\";\n\t\t\terr.type = errorType;\n\t\t\terr.request = realHref;\n\t\t\tlinkTag.parentNode.removeChild(linkTag)\n\t\t\treject(err);\n\t\t}\n\t}\n\tlinkTag.onerror = linkTag.onload = onLinkComplete;\n\tlinkTag.href = fullhref;\n\n\tdocument.head.appendChild(linkTag);\n\treturn linkTag;\n};\nvar findStylesheet = function(href, fullhref) {\n\tvar existingLinkTags = document.getElementsByTagName(\"link\");\n\tfor(var i = 0; i < existingLinkTags.length; i++) {\n\t\tvar tag = existingLinkTags[i];\n\t\tvar dataHref = tag.getAttribute(\"data-href\") || tag.getAttribute(\"href\");\n\t\tif(tag.rel === \"stylesheet\" && (dataHref === href || dataHref === fullhref)) return tag;\n\t}\n\tvar existingStyleTags = document.getElementsByTagName(\"style\");\n\tfor(var i = 0; i < existingStyleTags.length; i++) {\n\t\tvar tag = existingStyleTags[i];\n\t\tvar dataHref = tag.getAttribute(\"data-href\");\n\t\tif(dataHref === href || dataHref === fullhref) return tag;\n\t}\n};\nvar loadStylesheet = function(chunkId) {\n\treturn new Promise(function(resolve, reject) {\n\t\tvar href = __webpack_require__.miniCssF(chunkId);\n\t\tvar fullhref = __webpack_require__.p + href;\n\t\tif(findStylesheet(href, fullhref)) return resolve();\n\t\tcreateStylesheet(chunkId, fullhref, resolve, reject);\n\t});\n}\n// object to store loaded CSS chunks\nvar installedCssChunks = {\n\t143: 0\n};\n\n__webpack_require__.f.miniCss = function(chunkId, promises) {\n\tvar cssChunks = {\"294\":1,\"657\":1};\n\tif(installedCssChunks[chunkId]) promises.push(installedCssChunks[chunkId]);\n\telse if(installedCssChunks[chunkId] !== 0 && cssChunks[chunkId]) {\n\t\tpromises.push(installedCssChunks[chunkId] = loadStylesheet(chunkId).then(function() {\n\t\t\tinstalledCssChunks[chunkId] = 0;\n\t\t}, function(e) {\n\t\t\tdelete installedCssChunks[chunkId];\n\t\t\tthrow e;\n\t\t}));\n\t}\n};\n\n// no hmr","// no baseURI\n\n// object to store loaded and loading chunks\n// undefined = chunk not loaded, null = chunk preloaded/prefetched\n// [resolve, reject, Promise] = chunk loading, 0 = chunk loaded\nvar installedChunks = {\n\t143: 0\n};\n\n__webpack_require__.f.j = function(chunkId, promises) {\n\t\t// JSONP chunk loading for javascript\n\t\tvar installedChunkData = __webpack_require__.o(installedChunks, chunkId) ? installedChunks[chunkId] : undefined;\n\t\tif(installedChunkData !== 0) { // 0 means \"already installed\".\n\n\t\t\t// a Promise means \"currently loading\".\n\t\t\tif(installedChunkData) {\n\t\t\t\tpromises.push(installedChunkData[2]);\n\t\t\t} else {\n\t\t\t\tif(true) { // all chunks have JS\n\t\t\t\t\t// setup Promise in chunk cache\n\t\t\t\t\tvar promise = new Promise(function(resolve, reject) { installedChunkData = installedChunks[chunkId] = [resolve, reject]; });\n\t\t\t\t\tpromises.push(installedChunkData[2] = promise);\n\n\t\t\t\t\t// start chunk loading\n\t\t\t\t\tvar url = __webpack_require__.p + __webpack_require__.u(chunkId);\n\t\t\t\t\t// create error before stack unwound to get useful stacktrace later\n\t\t\t\t\tvar error = new Error();\n\t\t\t\t\tvar loadingEnded = function(event) {\n\t\t\t\t\t\tif(__webpack_require__.o(installedChunks, chunkId)) {\n\t\t\t\t\t\t\tinstalledChunkData = installedChunks[chunkId];\n\t\t\t\t\t\t\tif(installedChunkData !== 0) installedChunks[chunkId] = undefined;\n\t\t\t\t\t\t\tif(installedChunkData) {\n\t\t\t\t\t\t\t\tvar errorType = event && (event.type === 'load' ? 'missing' : event.type);\n\t\t\t\t\t\t\t\tvar realSrc = event && event.target && event.target.src;\n\t\t\t\t\t\t\t\terror.message = 'Loading chunk ' + chunkId + ' failed.\\n(' + errorType + ': ' + realSrc + ')';\n\t\t\t\t\t\t\t\terror.name = 'ChunkLoadError';\n\t\t\t\t\t\t\t\terror.type = errorType;\n\t\t\t\t\t\t\t\terror.request = realSrc;\n\t\t\t\t\t\t\t\tinstalledChunkData[1](error);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\t\t\t\t\t__webpack_require__.l(url, loadingEnded, \"chunk-\" + chunkId, chunkId);\n\t\t\t\t} else installedChunks[chunkId] = 0;\n\t\t\t}\n\t\t}\n};\n\n// no prefetching\n\n// no preloaded\n\n// no HMR\n\n// no HMR manifest\n\n__webpack_require__.O.j = function(chunkId) { return installedChunks[chunkId] === 0; };\n\n// install a JSONP callback for chunk loading\nvar webpackJsonpCallback = function(parentChunkLoadingFunction, data) {\n\tvar chunkIds = data[0];\n\tvar moreModules = data[1];\n\tvar runtime = data[2];\n\t// add \"moreModules\" to the modules object,\n\t// then flag all \"chunkIds\" as loaded and fire callback\n\tvar moduleId, chunkId, i = 0;\n\tif(chunkIds.some(function(id) { return installedChunks[id] !== 0; })) {\n\t\tfor(moduleId in moreModules) {\n\t\t\tif(__webpack_require__.o(moreModules, moduleId)) {\n\t\t\t\t__webpack_require__.m[moduleId] = moreModules[moduleId];\n\t\t\t}\n\t\t}\n\t\tif(runtime) var result = runtime(__webpack_require__);\n\t}\n\tif(parentChunkLoadingFunction) parentChunkLoadingFunction(data);\n\tfor(;i < chunkIds.length; i++) {\n\t\tchunkId = chunkIds[i];\n\t\tif(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) {\n\t\t\tinstalledChunks[chunkId][0]();\n\t\t}\n\t\tinstalledChunks[chunkId] = 0;\n\t}\n\treturn __webpack_require__.O(result);\n}\n\nvar chunkLoadingGlobal = self[\"webpackChunkweb\"] = self[\"webpackChunkweb\"] || [];\nchunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0));\nchunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal));","// startup\n// Load entry module and return exports\n// This entry module depends on other loaded chunks and execution need to be delayed\nvar __webpack_exports__ = __webpack_require__.O(undefined, [998], function() { return __webpack_require__(1361); })\n__webpack_exports__ = __webpack_require__.O(__webpack_exports__);\n"],"names":["render","_ctx","_cache","_component_router_view","script","__exports__","service","axios","baseURL","process","VUE_APP_BASE_API","timeout","checkCode","res","status","ElMessage","data","success","checkStatus","response","test","code","msg","router","interceptors","request","use","config","error","Promise","reject","Error","getJson","url","token","window","localStorage","getItem","method","headers","then","catch","err","postJson","postJson2","menu","createStore","state","menuListAll","openNames","activeName","getters","mutations","name","menuList","_a","actions","loadmenuList","obj","commit","modules","plugins","createPersistedstate","storage","sessionStorage","key","reducer","_withScopeId","n","_hoisted_1","_","class","_hoisted_2","_hoisted_3","_hoisted_4","__name","setup","__props","asideWidth","_component_el_menu_item","_component_el_sub_menu","_component_el_menu","_component_el_scrollbar","_component_el_aside","_component_el_header","_component_el_main","_component_el_container","default","width","style","activePath","index","onClick","$event","goUrl","title","routes","path","component","Index","redirect","children","createRouter","history","createWebHistory","app","createApp","App","Object","entries","ElementPlusIconsVue","_i","ElementPlus","locale","zhCn","store","mount","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","undefined","exports","module","__webpack_modules__","call","m","deferred","O","result","chunkIds","fn","priority","notFulfilled","Infinity","i","length","fulfilled","j","keys","every","splice","r","getter","__esModule","d","a","definition","o","defineProperty","enumerable","get","f","e","chunkId","all","reduce","promises","u","miniCssF","g","globalThis","this","Function","prop","prototype","hasOwnProperty","inProgress","dataWebpackPrefix","l","done","push","needAttach","scripts","document","getElementsByTagName","s","getAttribute","createElement","charset","nc","setAttribute","src","onScriptComplete","prev","event","onerror","onload","clearTimeout","doneFns","parentNode","removeChild","forEach","setTimeout","bind","type","target","head","appendChild","Symbol","toStringTag","value","p","createStylesheet","fullhref","resolve","linkTag","rel","onLinkComplete","errorType","realHref","href","findStylesheet","existingLinkTags","tag","dataHref","existingStyleTags","loadStylesheet","installedCssChunks","miniCss","cssChunks","installedChunks","installedChunkData","promise","loadingEnded","realSrc","message","webpackJsonpCallback","parentChunkLoadingFunction","moreModules","runtime","some","id","chunkLoadingGlobal","self","__webpack_exports__"],"sourceRoot":""}
--------------------------------------------------------------------------------
/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/c/websshterminal.io
2 |
3 | go 1.17
4 |
5 | require (
6 | github.com/dgrijalva/jwt-go v3.2.0+incompatible // indirect
7 | github.com/google/uuid v1.3.0 // indirect
8 | github.com/gorilla/websocket v1.5.0 // indirect
9 | github.com/labstack/echo v3.3.10+incompatible // indirect
10 | github.com/labstack/gommon v0.4.0 // indirect
11 | github.com/mattn/go-colorable v0.1.13 // indirect
12 | github.com/mattn/go-isatty v0.0.16 // indirect
13 | github.com/robfig/cron v1.2.0 // indirect
14 | github.com/valyala/bytebufferpool v1.0.0 // indirect
15 | github.com/valyala/fasttemplate v1.2.1 // indirect
16 | go.uber.org/atomic v1.7.0 // indirect
17 | go.uber.org/multierr v1.6.0 // indirect
18 | go.uber.org/zap v1.23.0 // indirect
19 | golang.org/x/crypto v0.0.0-20221010152910-d6f0a8c073c2 // indirect
20 | golang.org/x/net v0.0.0-20221004154528-8021a29435af // indirect
21 | golang.org/x/sys v0.0.0-20221010170243-090e33056c14 // indirect
22 | golang.org/x/text v0.3.8 // indirect
23 | gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect
24 | )
25 |
--------------------------------------------------------------------------------
/go.sum:
--------------------------------------------------------------------------------
1 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
2 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
3 | github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
4 | github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
5 | github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
6 | github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
7 | github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
8 | github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
9 | github.com/labstack/echo v3.3.10+incompatible h1:pGRcYk231ExFAyoAjAfD85kQzRJCRI8bbnE7CX5OEgg=
10 | github.com/labstack/echo v3.3.10+incompatible/go.mod h1:0INS7j/VjnFxD4E2wkz67b8cVwCLbBmJyDaka6Cmk1s=
11 | github.com/labstack/gommon v0.4.0 h1:y7cvthEAEbU0yHOf4axH8ZG2NH8knB9iNSoTO8dyIk8=
12 | github.com/labstack/gommon v0.4.0/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM=
13 | github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
14 | github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
15 | github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
16 | github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
17 | github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ=
18 | github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
19 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
20 | github.com/robfig/cron v1.2.0 h1:ZjScXvvxeQ63Dbyxy76Fj3AT3Ut0aKsyd2/tl3DTMuQ=
21 | github.com/robfig/cron v1.2.0/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfmt2k=
22 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
23 | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
24 | github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
25 | github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
26 | github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
27 | github.com/valyala/fasttemplate v1.2.1 h1:TVEnxayobAdVkhQfrfes2IzOB6o+z4roRkPF52WA1u4=
28 | github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
29 | go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
30 | go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
31 | go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4=
32 | go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
33 | go.uber.org/zap v1.23.0 h1:OjGQ5KQDEUawVHxNwQgPpiypGHOxo2mNZsOqTak4fFY=
34 | go.uber.org/zap v1.23.0/go.mod h1:D+nX8jyLsMHMYrln8A0rJjFt/T/9/bGgIhAqxv5URuY=
35 | golang.org/x/crypto v0.0.0-20221010152910-d6f0a8c073c2 h1:x8vtB3zMecnlqZIwJNUUpwYKYSqCz5jXbiyv0ZJJZeI=
36 | golang.org/x/crypto v0.0.0-20221010152910-d6f0a8c073c2/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
37 | golang.org/x/net v0.0.0-20221004154528-8021a29435af h1:wv66FM3rLZGPdxpYL+ApnDe2HzHcTFta3z5nsc13wI4=
38 | golang.org/x/net v0.0.0-20221004154528-8021a29435af/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
39 | golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
40 | golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
41 | golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
42 | golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
43 | golang.org/x/sys v0.0.0-20221010170243-090e33056c14 h1:k5II8e6QD8mITdi+okbbmR/cIyEbeXLBhy5Ha4nevyc=
44 | golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
45 | golang.org/x/text v0.3.8 h1:nAL+RVCQ9uMn3vJZbV+MRnydTJFPf8qqY42YiA6MrqY=
46 | golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
47 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
48 | gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8=
49 | gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
50 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
51 | gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
52 |
--------------------------------------------------------------------------------
/handler/ws.go:
--------------------------------------------------------------------------------
1 | package handler
2 |
3 | import (
4 | "fmt"
5 | "net/http"
6 |
7 | "github.com/gorilla/websocket"
8 |
9 | "github.com/c/websshterminal.io/connections"
10 | "github.com/c/websshterminal.io/ubzer"
11 | "github.com/labstack/echo"
12 | "go.uber.org/zap"
13 | )
14 |
15 | var (
16 | upgrader = &websocket.Upgrader{
17 | ReadBufferSize: 1024,
18 | WriteBufferSize: 1024,
19 | CheckOrigin: func(r *http.Request) bool {
20 | return true
21 | },
22 | }
23 | )
24 |
25 | func ShellWeb(c echo.Context) error {
26 | var err error
27 |
28 | conn, err := upgrader.Upgrade(c.Response(), c.Request(), nil)
29 | if err != nil {
30 | ubzer.MLog.Error("websocket upgrade 失败", zap.Error(err))
31 | return err
32 | }
33 | _, readContent, err := conn.ReadMessage()
34 | if err != nil {
35 | ubzer.MLog.Error("websocket 读取ip、用户名、密码 失败", zap.Error(err))
36 | return err
37 | }
38 | fmt.Printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ readContent: %v\n", string(readContent))
39 |
40 | sshClient, err := connections.DecodeMsgToSSHClient(string(readContent))
41 | if err != nil {
42 | return err
43 | }
44 | fmt.Printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ sshClient: %v\n", sshClient)
45 |
46 | terminal := connections.Terminal{
47 | Columns: 150,
48 | Rows: 35,
49 | }
50 |
51 | var port = 22
52 | err = sshClient.GenerateClient(sshClient.IpAddress, sshClient.Username, sshClient.Password, port)
53 | if err != nil {
54 | conn.WriteMessage(1, []byte(err.Error()))
55 | conn.Close()
56 | return err
57 | }
58 | sshClient.RequestTerminal(terminal)
59 | sshClient.Connect(conn)
60 | return nil
61 | }
62 |
--------------------------------------------------------------------------------
/init/run.go:
--------------------------------------------------------------------------------
1 | package _init
2 |
3 | import "github.com/c/websshterminal.io/ubzer"
4 |
5 | func CmdRun() {
6 | ubzer.InitLogger("./log/web-ssh-terminal.log")
7 | }
8 |
--------------------------------------------------------------------------------
/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | _init "github.com/c/websshterminal.io/init"
5 | "github.com/c/websshterminal.io/router"
6 | )
7 |
8 | func main() {
9 | _init.CmdRun()
10 | router.RunSshTerminal()
11 | }
12 |
--------------------------------------------------------------------------------
/middlewares/middlewares.go:
--------------------------------------------------------------------------------
1 | package middlewares
2 |
3 | import (
4 | "runtime"
5 | "strings"
6 |
7 | "github.com/google/uuid"
8 |
9 | "github.com/c/websshterminal.io/ubzer"
10 | "go.uber.org/zap"
11 |
12 | "github.com/labstack/echo"
13 | "github.com/labstack/echo/middleware"
14 | )
15 |
16 | var (
17 | UIDKey = "Service"
18 | )
19 |
20 | // RequestLog
21 | func RequestLog() echo.MiddlewareFunc {
22 | return func(handlerFunc echo.HandlerFunc) echo.HandlerFunc {
23 | return func(context echo.Context) error {
24 | defer func() {
25 | if err := recover(); err != nil {
26 | stack := make([]byte, 4<<10)
27 | length := runtime.Stack(stack, false)
28 | ubzer.MLog.Error("程序崩溃", zap.String("崩溃日志", string(stack[:length])))
29 | }
30 | }()
31 | if !strings.HasPrefix(context.Path(), "/api/") {
32 | ubzer.MLog.Info("请求开始", zap.Any(context.Request().RequestURI, "网页请求"))
33 | return handlerFunc(context)
34 | }
35 | uid := uuid.New().String()
36 | context.Set(UIDKey, uid)
37 | err := handlerFunc(context)
38 | return err
39 | }
40 | }
41 | }
42 |
43 | var DefaultBodyDumpConfig = middleware.BodyDumpConfig{
44 | Skipper: BodyDumpDefaultSkipper,
45 | Handler: func(context echo.Context, bytes []byte, bytes2 []byte) {
46 | if !strings.HasPrefix(context.Path(), "/api/") {
47 | return
48 | }
49 | uid := context.Get(UIDKey).(string)
50 | ubzer.MLog.Info("请求结束", zap.String("请求UID", uid), zap.String(context.Request().RequestURI, string(bytes2)))
51 | },
52 | }
53 |
54 | func BodyDumpDefaultSkipper(c echo.Context) bool {
55 | if !strings.HasPrefix(c.Path(), "/api/") {
56 | return true
57 | }
58 | return false
59 | }
60 |
--------------------------------------------------------------------------------
/router/router.go:
--------------------------------------------------------------------------------
1 | package router
2 |
3 | import (
4 | "time"
5 |
6 | "github.com/c/websshterminal.io/middlewares"
7 | "github.com/c/websshterminal.io/ubzer"
8 |
9 | "github.com/c/websshterminal.io/handler"
10 | "github.com/labstack/echo"
11 | "github.com/labstack/echo/middleware"
12 | )
13 |
14 | // RunSshTerminal
15 | func RunSshTerminal() {
16 | e := echo.New()
17 | e.Static("/", "dist")
18 | e.Static("/ssh/node", "dist")
19 | e.Static("/ssh/dial", "dist")
20 |
21 | e.Use(middleware.CORSWithConfig(
22 | middleware.CORSConfig{
23 | AllowOrigins: []string{"*"},
24 | AllowMethods: []string{echo.POST, echo.GET, echo.OPTIONS, echo.PATCH, echo.DELETE},
25 | AllowCredentials: true,
26 | MaxAge: int(time.Hour) * 24,
27 | }))
28 |
29 | e.Use(middleware.LoggerWithConfig(middleware.LoggerConfig{
30 | Format: "ip=${remote_ip} time=${time_rfc3339}, method=${method}, uri=${uri}, status=${status}, latency_human=${latency_human}\n",
31 | Output: ubzer.EchoLog,
32 | }))
33 |
34 | e.Use(middleware.GzipWithConfig(middleware.GzipConfig{
35 | Level: 5,
36 | }))
37 |
38 | e.Use(middlewares.RequestLog())
39 | e.Use(middleware.BodyDumpWithConfig(middlewares.DefaultBodyDumpConfig))
40 |
41 | e.GET("/ssh", handler.ShellWeb)
42 |
43 | e.Logger.Fatal(e.Start(":5555"))
44 | }
45 |
--------------------------------------------------------------------------------
/ssh_terminal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mazezen/websshterminal/2f8d5d091362a84a693b62bb6763a37a32060d15/ssh_terminal.png
--------------------------------------------------------------------------------
/ubzer/ubzer.go:
--------------------------------------------------------------------------------
1 | package ubzer
2 |
3 | import (
4 | "os"
5 |
6 | _const "github.com/c/websshterminal.io/const"
7 |
8 | "github.com/robfig/cron"
9 |
10 | "gopkg.in/natefinch/lumberjack.v2"
11 |
12 | "go.uber.org/zap"
13 | "go.uber.org/zap/zapcore"
14 | )
15 |
16 | var MLog *zap.Logger
17 |
18 | // InitLogger
19 | func InitLogger(filepath string) {
20 | encoder := getEncoder()
21 | writeSyncer := getLogWriter(filepath)
22 | core := zapcore.NewCore(encoder, writeSyncer, zapcore.DebugLevel)
23 | consoleDebug := zapcore.Lock(os.Stdout)
24 | consoleEncoder := zapcore.NewConsoleEncoder(zap.NewDevelopmentEncoderConfig())
25 | p := zap.LevelEnablerFunc(func(level zapcore.Level) bool {
26 | return level >= zapcore.DebugLevel
27 | })
28 | var allCode []zapcore.Core
29 | allCode = append(allCode, core)
30 | allCode = append(allCode, zapcore.NewCore(consoleEncoder, consoleDebug, p))
31 | c := zapcore.NewTee(allCode...)
32 | MLog = zap.New(c, zap.AddCaller())
33 | }
34 |
35 | // getEncoder
36 | func getEncoder() zapcore.Encoder {
37 | encoderConfig := zap.NewProductionEncoderConfig()
38 | encoderConfig.EncodeTime = zapcore.TimeEncoderOfLayout(_const.Layout)
39 | encoderConfig.EncodeLevel = zapcore.CapitalLevelEncoder
40 | return zapcore.NewConsoleEncoder(encoderConfig)
41 | }
42 |
43 | // getLogWriter
44 | func getLogWriter(path string) zapcore.WriteSyncer {
45 | lumberjackLogger := &lumberjack.Logger{
46 | Filename: path,
47 | MaxSize: 10240,
48 | MaxAge: 7,
49 | LocalTime: true,
50 | Compress: true,
51 | }
52 | c := cron.New()
53 | c.AddFunc("0 0 0 1/1 * ?", func() {
54 | lumberjackLogger.Rotate()
55 | })
56 | c.Start()
57 | return zapcore.AddSync(lumberjackLogger)
58 | }
59 |
60 | var EchoLog *EchoLogger
61 |
62 | type EchoLogger struct{}
63 |
64 | func (this *EchoLogger) Write(p []byte) (n int, err error) {
65 | MLog.Info("ECHO", zap.String("请求", string(p)))
66 | return len(p), nil
67 | }
68 |
--------------------------------------------------------------------------------