修改监控为证书监控支持文件导入和smtp监控

监控支持多渠道通知
将静态文件打包到二进制文件
This commit is contained in:
v-me-50
2025-07-08 16:45:28 +08:00
parent b347ade900
commit e4917d7caf
396 changed files with 2263 additions and 584 deletions

View File

@@ -0,0 +1,232 @@
package monitor
import (
"ALLinSSL/backend/internal/monitor"
"ALLinSSL/backend/public"
"ALLinSSL/static"
"github.com/gin-gonic/gin"
"net/http"
"strings"
)
func GetMonitorList(c *gin.Context) {
var form struct {
Search string `form:"search"`
Page int64 `form:"p"`
Limit int64 `form:"limit"`
}
err := c.Bind(&form)
if err != nil {
public.FailMsg(c, err.Error())
return
}
data, count, err := monitor.GetList(form.Search, form.Page, form.Limit)
if err != nil {
public.FailMsg(c, err.Error())
return
}
public.SuccessData(c, data, count)
return
}
func AddMonitor(c *gin.Context) {
var form struct {
Name string `form:"name"`
Target string `form:"target"`
MonitorType string `form:"monitor_type"`
ReportTypes string `form:"report_types"`
Cycle string `form:"cycle"`
RepeatSendGap string `form:"repeat_send_gap"`
Active string `form:"active"`
AdvanceDay string `form:"advance_day"`
}
err := c.Bind(&form)
if err != nil {
public.FailMsg(c, err.Error())
return
}
form.Name = strings.TrimSpace(form.Name)
form.Target = strings.TrimSpace(form.Target)
err = monitor.AddMonitor(form.Name, form.Target, form.MonitorType, form.ReportTypes, form.Cycle, form.RepeatSendGap, form.Active, form.AdvanceDay)
if err != nil {
public.FailMsg(c, err.Error())
return
}
public.SuccessMsg(c, "添加成功")
return
}
func UpdMonitor(c *gin.Context) {
var form struct {
ID string `form:"id"`
Target string `form:"target"`
Name string `form:"name"`
Cycle string `form:"cycle"`
ReportTypes string `form:"report_types"`
RepeatSendGap string `form:"repeat_send_gap"`
Active string `form:"active"`
AdvanceDay string `form:"advance_day"`
}
err := c.Bind(&form)
if err != nil {
public.FailMsg(c, err.Error())
return
}
form.ID = strings.TrimSpace(form.ID)
form.Target = strings.TrimSpace(form.Target)
form.Name = strings.TrimSpace(form.Name)
form.ReportTypes = strings.TrimSpace(form.ReportTypes)
err = monitor.UpdMonitor(form.ID, form.Name, form.Target, form.ReportTypes, form.Cycle, form.RepeatSendGap, form.Active, form.AdvanceDay)
if err != nil {
public.FailMsg(c, err.Error())
return
}
public.SuccessMsg(c, "修改成功")
return
}
func DelMonitor(c *gin.Context) {
var form struct {
ID string `form:"id"`
}
err := c.Bind(&form)
if err != nil {
public.FailMsg(c, err.Error())
return
}
err = monitor.DelMonitor(form.ID)
if err != nil {
public.FailMsg(c, err.Error())
return
}
public.SuccessMsg(c, "删除成功")
return
}
func SetMonitor(c *gin.Context) {
var form struct {
ID string `form:"id"`
Active int `form:"active"`
}
err := c.Bind(&form)
if err != nil {
public.FailMsg(c, err.Error())
return
}
err = monitor.SetMonitor(form.ID, form.Active)
if err != nil {
public.FailMsg(c, err.Error())
return
}
public.SuccessMsg(c, "操作成功")
return
}
func GetMonitorInfo(c *gin.Context) {
var form struct {
ID string `form:"id"`
}
err := c.Bind(&form)
if err != nil {
public.FailMsg(c, err.Error())
return
}
form.ID = strings.TrimSpace(form.ID)
data, err := monitor.GetInfo(form.ID)
if err != nil {
public.FailMsg(c, err.Error())
return
}
public.SuccessData(c, data, 0)
return
}
func GetErrRecord(c *gin.Context) {
var form struct {
ID int64 `form:"id"`
Page int64 `form:"p"`
Limit int64 `form:"limit"`
}
err := c.Bind(&form)
if err != nil {
public.FailMsg(c, err.Error())
return
}
data, count, err := monitor.GetErrRecord(form.ID, form.Page, form.Limit)
if err != nil {
public.FailMsg(c, err.Error())
return
}
public.SuccessData(c, data, count)
return
}
func FileAddMonitor(c *gin.Context) {
file, err := c.FormFile("file")
if err != nil {
public.FailMsg(c, "上传文件失败: "+err.Error())
return
}
if file.Size > 10*1024*1024 { // 限制文件大小为10MB
public.FailMsg(c, "上传文件过大最大限制10MB")
return
}
data, err := monitor.ParseMonitorFile(file)
if err != nil {
public.FailMsg(c, "文件解析失败: "+err.Error())
return
}
if len(data) == 0 {
public.FailMsg(c, "文件中没有有效的监控数据")
return
}
err = monitor.MultiAddMonitor(data)
if err != nil {
public.FailMsg(c, "文件导入失败: "+err.Error())
return
}
public.SuccessMsg(c, "文件导入成功")
return
}
func GetTemplate(c *gin.Context) {
t := c.Query("type")
if t == "" {
c.String(http.StatusBadRequest, "参数 type 不能为空")
return
}
fileMap := map[string]string{
"txt": "monitor_templates/template.txt",
"csv": "monitor_templates/template.csv",
"json": "monitor_templates/template.json",
"xlsx": "monitor_templates/template.xlsx",
}
filePath, ok := fileMap[strings.ToLower(t)]
if !ok {
c.String(http.StatusBadRequest, "不支持的类型")
return
}
data, err := static.MonitorTemplatesFS.ReadFile(filePath)
if err != nil {
c.String(http.StatusInternalServerError, "模板文件读取失败")
return
}
// 设置 Content-Type
contentTypes := map[string]string{
"txt": "text/plain",
"csv": "text/csv",
"json": "application/json",
"xlsx": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
"xls": "application/vnd.ms-excel",
}
c.Header("Content-Type", contentTypes[t])
c.Header("Content-Disposition", "attachment; filename=template."+t)
c.Data(http.StatusOK, contentTypes[t], data)
}

View File

@@ -1,131 +0,0 @@
package api
import (
"ALLinSSL/backend/internal/siteMonitor"
"ALLinSSL/backend/public"
"github.com/gin-gonic/gin"
"strings"
)
func GetMonitorList(c *gin.Context) {
var form struct {
Search string `form:"search"`
Page int64 `form:"p"`
Limit int64 `form:"limit"`
}
err := c.Bind(&form)
if err != nil {
// c.JSON(http.StatusBadRequest, public.ResERR(err.Error()))
public.FailMsg(c, err.Error())
return
}
data, count, err := siteMonitor.GetList(form.Search, form.Page, form.Limit)
if err != nil {
// c.JSON(http.StatusBadRequest, public.ResERR(err.Error()))
public.FailMsg(c, err.Error())
return
}
// c.JSON(http.StatusOK, public.ResOK(len(data), data, ""))
public.SuccessData(c, data, count)
return
}
func AddMonitor(c *gin.Context) {
var form struct {
Name string `form:"name"`
Domain string `form:"domain"`
Cycle int `form:"cycle"`
ReportType string `form:"report_type"`
}
err := c.Bind(&form)
if err != nil {
// c.JSON(http.StatusBadRequest, public.ResERR(err.Error()))
public.FailMsg(c, err.Error())
return
}
form.Name = strings.TrimSpace(form.Name)
form.Domain = strings.TrimSpace(form.Domain)
err = siteMonitor.AddMonitor(form.Name, form.Domain, form.ReportType, form.Cycle)
if err != nil {
// c.JSON(http.StatusBadRequest, public.ResERR(err.Error()))
public.FailMsg(c, err.Error())
return
}
// c.JSON(http.StatusOK, public.ResOK(0, nil, "添加成功"))
public.SuccessMsg(c, "添加成功")
return
}
func UpdMonitor(c *gin.Context) {
var form struct {
ID string `form:"id"`
Name string `form:"name"`
Domain string `form:"domain"`
Cycle int `form:"cycle"`
ReportType string `form:"report_type"`
}
err := c.Bind(&form)
if err != nil {
// c.JSON(http.StatusBadRequest, public.ResERR(err.Error()))
public.FailMsg(c, err.Error())
return
}
form.ID = strings.TrimSpace(form.ID)
form.Name = strings.TrimSpace(form.Name)
form.Domain = strings.TrimSpace(form.Domain)
form.ReportType = strings.TrimSpace(form.ReportType)
err = siteMonitor.UpdMonitor(form.ID, form.Name, form.Domain, form.ReportType, form.Cycle)
if err != nil {
// c.JSON(http.StatusBadRequest, public.ResERR(err.Error()))
public.FailMsg(c, err.Error())
return
}
// c.JSON(http.StatusOK, public.ResOK(0, nil, "修改成功"))
public.SuccessMsg(c, "修改成功")
return
}
func DelMonitor(c *gin.Context) {
var form struct {
ID string `form:"id"`
}
err := c.Bind(&form)
if err != nil {
// c.JSON(http.StatusBadRequest, public.ResERR(err.Error()))
public.FailMsg(c, err.Error())
return
}
err = siteMonitor.DelMonitor(form.ID)
if err != nil {
// c.JSON(http.StatusBadRequest, public.ResERR(err.Error()))
public.FailMsg(c, err.Error())
return
}
// c.JSON(http.StatusOK, public.ResOK(0, nil, "删除成功"))
public.SuccessMsg(c, "删除成功")
return
}
func SetMonitor(c *gin.Context) {
var form struct {
ID string `form:"id"`
Active int `form:"active"`
}
err := c.Bind(&form)
if err != nil {
// c.JSON(http.StatusBadRequest, public.ResERR(err.Error()))
public.FailMsg(c, err.Error())
return
}
err = siteMonitor.SetMonitor(form.ID, form.Active)
if err != nil {
// c.JSON(http.StatusBadRequest, public.ResERR(err.Error()))
public.FailMsg(c, err.Error())
return
}
// c.JSON(http.StatusOK, public.ResOK(0, nil, "操作成功"))
public.SuccessMsg(c, "操作成功")
return
}

View File

@@ -0,0 +1,212 @@
package monitor
import (
"crypto/sha256"
"crypto/tls"
"crypto/x509"
"encoding/hex"
"fmt"
"net"
"net/http"
"net/smtp"
"strings"
"time"
)
// buildCertChainRecursive 构建证书链树结构
func buildCertChainRecursive(certs []*x509.Certificate, index int) *CertNode {
if index >= len(certs) {
return nil
}
node := &CertNode{
CommonName: certs[index].Subject.CommonName,
Subject: certs[index].Subject.String(),
Issuer: certs[index].Issuer.String(),
}
if index+1 < len(certs) {
child := buildCertChainRecursive(certs, index+1)
if child != nil {
node.Children = append(node.Children, child)
}
}
return node
}
// checkChainRecursive 递归检查链条完整性
func checkChainRecursive(node *CertNode, level int) error {
if node == nil || len(node.Children) == 0 {
return nil
}
for _, child := range node.Children {
if node.Issuer != child.Subject {
return fmt.Errorf("证书链第 %d 层 [CN=%s] 的 Issuer 与第 %d 层 [CN=%s] 的 Subject 不匹配,链条断裂",
level, node.CommonName,
level+1, child.CommonName,
)
}
if err := checkChainRecursive(child, level+1); err != nil {
return err
}
}
return nil
}
// Check 检查证书链的完整性和有效性
func Check(certs []*x509.Certificate, host string, advanceDay int) (result *CertInfo, err error) {
result = &CertInfo{}
if len(certs) == 0 {
return nil, fmt.Errorf("未获取到服务端证书")
}
leafCert := certs[0]
// 提取 CA 名称Issuer 的组织名)
result.CA = "UNKNOWN"
if len(leafCert.Issuer.Organization) > 0 {
result.CA = leafCert.Issuer.Organization[0]
} else if leafCert.Issuer.CommonName != "" {
result.CA = leafCert.Issuer.CommonName
}
result.CommonName = leafCert.Subject.CommonName
result.NotBefore = leafCert.NotBefore.Format("2006-01-02 15:04:05")
result.NotAfter = leafCert.NotAfter.Format("2006-01-02 15:04:05")
result.DaysLeft = int(leafCert.NotAfter.Sub(time.Now()).Hours() / 24)
result.SANs = strings.Join(leafCert.DNSNames, ",")
result.SignatureAlgo = leafCert.SignatureAlgorithm.String()
sha256Sum := sha256.Sum256(leafCert.Raw)
result.Sha256 = hex.EncodeToString(sha256Sum[:])
// 构建证书链树结构
result.CertChain = buildCertChainRecursive(certs, 0)
// 用系统根证书池校验是否受信任
roots, err := x509.SystemCertPool()
if err != nil {
return nil, fmt.Errorf("加载系统根证书失败:%v", err)
}
if roots == nil {
roots = x509.NewCertPool()
}
intermediates := x509.NewCertPool()
for _, intermediate := range certs[1:] {
intermediates.AddCert(intermediate)
}
opts := x509.VerifyOptions{
DNSName: host,
Roots: roots,
Intermediates: intermediates,
}
if _, err := leafCert.Verify(opts); err != nil {
result.Valid = false
result.VerifyError = fmt.Sprintf("证书验证失败:%v", err)
return result, nil
} else if result.DaysLeft <= advanceDay {
result.VerifyError = fmt.Sprintf("证书即将过期,剩余 %d 天,请及时更新", result.DaysLeft)
} else if err := checkChainRecursive(result.CertChain, 1); err != nil {
result.VerifyError = fmt.Sprintf("证书验证成功,但在检查真实获取到的证书链时出现问题:\n%v\n可忽略仅作提醒如遇到ssl证书问题可作为排查方向", err)
}
result.Valid = true
return result, nil
}
// CheckHttps 严格检查 HTTPS 证书链,基于 CertChain 结构检查链完整性
func CheckHttps(target string, advanceDay int) (result *CertInfo, err error) {
// 解析 host 和 port
host, port, err := net.SplitHostPort(target)
if err != nil {
host = target
port = "443"
}
// 校验 host
if net.ParseIP(host) == nil {
if _, err := net.LookupHost(host); err != nil {
return nil, fmt.Errorf("无效的域名或 IP%v", err)
}
}
// 拼接 HTTPS URL
url := fmt.Sprintf("https://%s", net.JoinHostPort(host, port))
// 构建 HTTP 客户端
client := &http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{
InsecureSkipVerify: true,
},
},
Timeout: 5 * time.Second,
}
// 发送请求
resp, err := client.Get(url)
if err != nil {
return nil, fmt.Errorf("无法建立 HTTPS 连接:%v", err)
}
defer resp.Body.Close()
// 获取证书链
certs := resp.TLS.PeerCertificates
return Check(certs, host, advanceDay)
}
// CheckSmtp 检查smtp
func CheckSmtp(target string, advanceDay int) (result *CertInfo, err error) {
// 解析 host 和 port
host, port, err := net.SplitHostPort(target)
if err != nil {
host = target
port = "465" // 默认端口
}
// 校验 host
if net.ParseIP(host) == nil {
if _, err := net.LookupHost(host); err != nil {
return nil, fmt.Errorf("无效的域名或 IP%v", err)
}
}
// 如果端口是 465使用 TCP
if port == "465" {
return CheckTCP(host, port, advanceDay)
}
// 建立smtp连接
conn, err := smtp.Dial(host + ":" + port)
if err != nil {
return nil, fmt.Errorf("无法建立 SMTP 连接:%v", err)
}
defer conn.Close()
// 升级到 TLS
if err := conn.StartTLS(&tls.Config{
InsecureSkipVerify: true,
ServerName: host,
}); err != nil {
return nil, fmt.Errorf("无法升级到 TLS%v", err)
}
// 获取证书
state, ok := conn.TLSConnectionState()
if !ok {
return nil, fmt.Errorf("无法获取 TLS 连接状态")
}
certs := state.PeerCertificates
return Check(certs, host, advanceDay)
}
// CheckTCP 通过 tcp 连接检查证书
func CheckTCP(host, port string, advanceDay int) (result *CertInfo, err error) {
// 建立 tcp 连接
url := fmt.Sprintf("%s:%s", host, port)
conn, err := tls.Dial("tcp", url, &tls.Config{
InsecureSkipVerify: true,
ServerName: host,
})
if err != nil {
return nil, fmt.Errorf("无法建立tcp连接%v", err)
}
defer conn.Close()
// 获取证书链
certs := conn.ConnectionState().PeerCertificates
return Check(certs, host, advanceDay)
}

View File

@@ -0,0 +1,124 @@
package monitor
import (
"encoding/csv"
"encoding/json"
"fmt"
"github.com/tealeg/xlsx"
"io"
"mime/multipart"
"path/filepath"
"strings"
)
func ParseMonitorFile(fileHeader *multipart.FileHeader) ([]*Monitor, error) {
ext := strings.ToLower(filepath.Ext(fileHeader.Filename))
file, err := fileHeader.Open()
if err != nil {
return nil, fmt.Errorf("无法打开文件: %v", err)
}
defer file.Close()
switch ext {
case ".csv", ".txt":
return parseCSV(file)
case ".json":
return parseJSON(file)
case ".xlsx":
return parseXLSX(file)
default:
return nil, fmt.Errorf("不支持的文件类型: %s", ext)
}
}
func parseCSV(reader io.Reader) ([]*Monitor, error) {
csvReader := csv.NewReader(reader)
var monitors []*Monitor
isHeader := true
for {
record, err := csvReader.Read()
if err == io.EOF {
break
}
if err != nil {
return nil, fmt.Errorf("CSV 解析失败: %v", err)
}
if isHeader {
isHeader = false
continue
}
if len(record) < 8 {
continue
}
monitor := &Monitor{
Name: record[0],
Target: record[1],
MonitorType: record[2],
ReportTypes: record[3],
Cycle: record[4],
RepeatSendGap: record[5],
Active: record[6],
AdvanceDay: record[7],
}
monitors = append(monitors, monitor)
}
return monitors, nil
}
func parseJSON(reader io.Reader) ([]*Monitor, error) {
var monitors []*Monitor
err := json.NewDecoder(reader).Decode(&monitors)
if err != nil {
return nil, fmt.Errorf("JSON 解析失败: %v", err)
}
return monitors, nil
}
func parseXLSX(file multipart.File) ([]*Monitor, error) {
var monitors []*Monitor
// 读取文件内容到内存
data, err := io.ReadAll(file)
if err != nil {
return nil, err
}
// 解析 XLSX 内容
xlFile, err := xlsx.OpenBinary(data)
if err != nil {
return nil, fmt.Errorf("解析 xlsx 失败: %v", err)
}
if len(xlFile.Sheets) == 0 {
return nil, fmt.Errorf("未找到工作表")
}
sheet := xlFile.Sheets[0]
for i, row := range sheet.Rows {
if i == 0 {
continue // 跳过表头
}
if len(row.Cells) < 8 {
continue
}
monitor := &Monitor{
Name: row.Cells[0].String(),
Target: row.Cells[1].String(),
MonitorType: row.Cells[2].String(),
ReportTypes: row.Cells[3].String(),
Cycle: row.Cells[4].String(),
RepeatSendGap: row.Cells[5].String(),
Active: row.Cells[6].String(),
AdvanceDay: row.Cells[7].String(),
}
monitors = append(monitors, monitor)
}
return monitors, nil
}

View File

@@ -0,0 +1,35 @@
package monitor
// CertInfo 用于返回证书检查的详细信息
type CertInfo struct {
CommonName string `json:"common_name"` // 证书主体 CN
CA string `json:"ca"` // 颁发机构 CN
NotBefore string `json:"not_before"` // 生效时间
NotAfter string `json:"not_after"` // 失效时间
DaysLeft int `json:"days_left"` // 证书剩余天数
SANs string `json:"sans"` // 证书 SAN 列表
SignatureAlgo string `json:"signature_algo"` // 签名算法
Sha256 string `json:"sha256"` // 证书 SHA256 指纹
Valid bool `json:"valid"` // 是否校验通过
VerifyError string `json:"verify_error"` // 校验失败原因
CertChain *CertNode `json:"cert_chain"` // 证书链结构树
}
// CertNode 代表证书链中的节点
type CertNode struct {
CommonName string `json:"common_name"` // 当前节点证书 CN
Subject string `json:"subject"` // 证书 Subject 字符串
Issuer string `json:"issuer"` // 证书 Issuer 字符串
Children []*CertNode `json:"children"` // 下级节点
}
type Monitor struct {
Name string `json:"name"`
Target string `json:"target"`
MonitorType string `json:"monitor_type"` // 监控类型
ReportTypes string `json:"report_types"` // 报告类型
Cycle string `json:"cycle"` // 监控周期
RepeatSendGap string `json:"repeat_send_gap"` // 重复发送间隔
Active string `json:"active"` // 是否启用
AdvanceDay string `json:"advance_day"` // 提前多少天提醒
}

View File

@@ -0,0 +1,263 @@
package monitor
import (
"ALLinSSL/backend/public"
"encoding/json"
"fmt"
"time"
)
func GetSqlite() (*public.Sqlite, error) {
s, err := public.NewSqlite("data/monitor.db", "")
if err != nil {
return nil, err
}
s.TableName = "monitor"
return s, nil
}
func GetList(search string, p, limit int64) ([]map[string]any, int, error) {
var data []map[string]any
var count int64
s, err := GetSqlite()
if err != nil {
return data, 0, err
}
defer s.Close()
var limits []int64
if p >= 0 && limit >= 0 {
limits = []int64{0, limit}
if p > 1 {
limits[0] = (p - 1) * limit
limits[1] = limit
}
}
if search != "" {
count, err = s.Where("name like ? or target like ?", []interface{}{"%" + search + "%", "%" + search + "%"}).Count()
data, err = s.Where("name like ? or target like ?", []interface{}{"%" + search + "%", "%" + search + "%"}).Order("update_time", "desc").Limit(limits).Select()
} else {
count, err = s.Count()
data, err = s.Order("update_time", "desc").Limit(limits).Select()
}
if err != nil {
return data, 0, err
}
for _, v := range data {
info, ok := v["info"].(string)
if !ok || info == "" {
continue
}
var certInfo CertInfo
err := json.Unmarshal([]byte(info), &certInfo)
if err != nil {
continue
}
v["common_name"] = certInfo.CommonName
v["ca"] = certInfo.CA
v["not_before"] = certInfo.NotBefore
v["not_after"] = certInfo.NotAfter
v["days_left"] = certInfo.DaysLeft
v["sans"] = certInfo.SANs
//v["valid"] = certInfo.Valid
delete(v, "info")
}
return data, int(count), nil
}
func GetInfo(id string) (map[string]any, error) {
s, err := GetSqlite()
if err != nil {
return nil, err
}
defer s.Close()
data, err := s.Where("id=?", []interface{}{id}).Select()
if err != nil {
return nil, err
}
if len(data) == 0 || data[0] == nil {
return nil, fmt.Errorf("未找到对应的监控记录")
}
dataMap := data[0]
monitorInfo := map[string]any{
"id": dataMap["id"],
"name": dataMap["name"],
"target": dataMap["target"],
"monitor_type": dataMap["monitor_type"],
"valid": dataMap["valid"],
}
info, ok := dataMap["info"].(string)
if !ok || info == "" {
return monitorInfo, nil
}
var certInfo CertInfo
err = json.Unmarshal([]byte(info), &certInfo)
if err != nil {
return monitorInfo, fmt.Errorf("解析证书信息失败: %v", err)
}
monitorInfo["common_name"] = certInfo.CommonName
monitorInfo["ca"] = certInfo.CA
monitorInfo["not_before"] = certInfo.NotBefore
monitorInfo["not_after"] = certInfo.NotAfter
monitorInfo["days_left"] = certInfo.DaysLeft
monitorInfo["sans"] = certInfo.SANs
//monitorInfo["valid"] = certInfo.Valid
monitorInfo["verify_error"] = certInfo.VerifyError
monitorInfo["cert_chain"] = certInfo.CertChain
// 查询异常次数
// 计算7天前的时间
sevenDaysAgo := time.Now().AddDate(0, 0, -7).Format("2006-01-02 15:04:05")
s.TableName = "err_record"
errCount, err := s.Where("monitor_id=? and create_time >= ?", []interface{}{id, sevenDaysAgo}).Count()
if err != nil {
errCount = 0
}
monitorInfo["err_count"] = errCount
return monitorInfo, nil
}
// AddMonitor 添加新的监控记录
func AddMonitor(name, target, monitorType, reportTypes, cycle, repeatSendGap, active, advanceDay string) error {
s, err := GetSqlite()
if err != nil {
return err
}
defer s.Close()
data := map[string]any{
"name": name,
"target": target,
"monitor_type": monitorType,
"report_types": reportTypes,
"cycle": cycle,
"repeat_send_gap": repeatSendGap,
"active": active,
"advance_day": advanceDay,
"create_time": time.Now().Format("2006-01-02 15:04:05"),
"update_time": time.Now().Format("2006-01-02 15:04:05"),
}
if _, err := s.Insert(data); err != nil {
return fmt.Errorf("添加监控记录失败: %v", err)
}
return nil
}
// UpdMonitor 更新监控记录
func UpdMonitor(id, name, target, reportTypes, cycle, repeatSendGap, active, advanceDay string) error {
s, err := GetSqlite()
if err != nil {
return err
}
defer s.Close()
data := map[string]any{
"name": name,
"target": target,
"report_types": reportTypes,
"cycle": cycle,
"repeat_send_gap": repeatSendGap,
"active": active,
"advance_day": advanceDay,
"update_time": time.Now().Format("2006-01-02 15:04:05"),
"info": "", // 清空 info 字段
}
_, err = s.Where("id=?", []interface{}{id}).Update(data)
if err != nil {
return fmt.Errorf("更新监控记录失败: %v", err)
}
return nil
}
func DelMonitor(id string) error {
s, err := GetSqlite()
if err != nil {
return err
}
defer s.Close()
_, err = s.Where("id=?", []interface{}{id}).Delete()
if err != nil {
return err
}
s.TableName = "err_record"
_, err = s.Where("monitor_id=?", []interface{}{id}).Delete()
if err != nil {
return err
}
return nil
}
func SetMonitor(id string, active int) error {
s, err := GetSqlite()
if err != nil {
return err
}
defer s.Close()
_, err = s.Where("id=?", []interface{}{id}).Update(map[string]any{
"active": active,
"update_time": time.Now().Format("2006-01-02 15:04:05"),
})
if err != nil {
return err
}
return nil
}
func GetErrRecord(id, p, limit int64) ([]map[string]any, int, error) {
var data []map[string]any
var count int64
s, err := public.NewSqlite("data/monitor.db", "")
if err != nil {
return data, 0, err
}
defer s.Close()
s.TableName = "err_record"
var limits []int64
if p >= 0 && limit >= 0 {
limits = []int64{0, limit}
if p > 1 {
limits[0] = (p - 1) * limit
limits[1] = limit
}
}
count, err = s.Where("monitor_id=?", []any{id}).Count()
if err != nil {
return data, 0, err
}
data, err = s.Where("monitor_id=?", []any{id}).Order("create_time", "desc").Limit(limits).Select()
if err != nil {
return data, 0, err
}
return data, int(count), nil
}
func MultiAddMonitor(monitors []*Monitor) error {
s, err := GetSqlite()
if err != nil {
return err
}
defer s.Close()
for _, monitor := range monitors {
data := map[string]any{
"name": monitor.Name,
"target": monitor.Target,
"monitor_type": monitor.MonitorType,
"report_types": monitor.ReportTypes,
"cycle": monitor.Cycle,
"repeat_send_gap": monitor.RepeatSendGap,
"active": monitor.Active,
"advance_day": monitor.AdvanceDay,
"create_time": time.Now().Format("2006-01-02 15:04:05"),
"update_time": time.Now().Format("2006-01-02 15:04:05"),
}
if _, err := s.Insert(data); err != nil {
return fmt.Errorf("添加监控记录失败: %v", err)
}
}
return nil
}

View File

@@ -65,15 +65,15 @@ func GetCertCount() (map[string]int, error) {
return result, nil
}
func GetSiteMonitorCount() (map[string]any, error) {
s, err := public.NewSqlite("data/site_monitor.db", "")
func GetMonitorCount() (map[string]any, error) {
s, err := public.NewSqlite("data/monitor.db", "")
if err != nil {
return nil, err
}
defer s.Close()
cert, err := s.Query(`select count(*) as count,
count(case when state='异常' then 1 end ) as exception
from site_monitor`)
count(case when valid=-1 then 1 end ) as exception
from monitor`)
if err != nil {
return nil, err
}
@@ -144,18 +144,18 @@ func GetOverviewData() (map[string]any, error) {
if err != nil {
return nil, err
}
siteMonitorCount, err := GetSiteMonitorCount()
workflowHistory, err := GetWorkflowHistory()
if err != nil {
return nil, err
}
workflowHistory, err := GetWorkflowHistory()
monitorCount, err := GetMonitorCount()
if err != nil {
return nil, err
}
result := make(map[string]any)
result["workflow"] = workflowCount
result["cert"] = certCount
result["site_monitor"] = siteMonitorCount
result["monitor"] = monitorCount
result["workflow_history"] = workflowHistory
return result, nil
}

View File

@@ -1,255 +0,0 @@
package siteMonitor
import (
"ALLinSSL/backend/public"
"crypto/tls"
"fmt"
"net"
"net/http"
"strings"
"time"
)
// SSLInfo 定义结果结构体
type SSLInfo struct {
Target string
HTTPStatus int
HTTPStatusText string
Domains []string
Issuer string
NotBefore string
NotAfter string
DaysRemaining int
CertificateOK bool
CertificateNote string
}
func GetSqlite() (*public.Sqlite, error) {
s, err := public.NewSqlite("data/site_monitor.db", "")
if err != nil {
return nil, err
}
s.TableName = "site_monitor"
return s, nil
}
func GetList(search string, p, limit int64) ([]map[string]any, int, error) {
var data []map[string]any
var count int64
s, err := GetSqlite()
if err != nil {
return data, 0, err
}
defer s.Close()
var limits []int64
if p >= 0 && limit >= 0 {
limits = []int64{0, limit}
if p > 1 {
limits[0] = (p - 1) * limit
limits[1] = limit
}
}
if search != "" {
count, err = s.Where("name like ? or site_domain like ?", []interface{}{"%" + search + "%", "%" + search + "%"}).Count()
data, err = s.Where("name like ? or site_domain like ?", []interface{}{"%" + search + "%", "%" + search + "%"}).Order("update_time", "desc").Limit(limits).Select()
} else {
count, err = s.Count()
data, err = s.Order("update_time", "desc").Limit(limits).Select()
}
if err != nil {
return data, 0, err
}
for _, v := range data {
v["domain"] = v["site_domain"]
}
return data, int(count), nil
}
func AddMonitor(name, domain, reportType string, cycle int) error {
s, err := GetSqlite()
if err != nil {
return err
}
defer s.Close()
info, err := CheckWebsite(domain)
if err != nil {
return err
}
_, err = s.Insert(map[string]any{
"name": name,
"site_domain": domain,
"report_type": reportType,
"cycle": cycle,
"state": info.HTTPStatusText,
"ca": info.Issuer,
"cert_domain": strings.Join(info.Domains, ","),
"end_time": info.NotAfter,
"end_day": info.DaysRemaining,
"create_time": time.Now().Format("2006-01-02 15:04:05"),
"update_time": time.Now().Format("2006-01-02 15:04:05"),
"last_time": time.Now().Format("2006-01-02 15:04:05"),
"active": 1,
})
if err != nil {
return err
}
return nil
}
func UpdMonitor(id, name, domain, reportType string, cycle int) error {
s, err := GetSqlite()
if err != nil {
return err
}
defer s.Close()
info, err := CheckWebsite(domain)
if err != nil {
return err
}
_, err = s.Where("id=?", []interface{}{id}).Update(map[string]any{
"name": name,
"site_domain": domain,
"report_type": reportType,
"cycle": cycle,
"state": info.HTTPStatusText,
"ca": info.Issuer,
"cert_domain": strings.Join(info.Domains, ","),
"end_time": info.NotAfter,
"end_day": info.DaysRemaining,
"update_time": time.Now().Format("2006-01-02 15:04:05"),
"last_time": time.Now().Format("2006-01-02 15:04:05"),
"active": 1,
})
if err != nil {
return err
}
return nil
}
func DelMonitor(id string) error {
s, err := GetSqlite()
if err != nil {
return err
}
defer s.Close()
_, err = s.Where("id=?", []interface{}{id}).Delete()
if err != nil {
return err
}
return nil
}
func SetMonitor(id string, active int) error {
s, err := GetSqlite()
if err != nil {
return err
}
defer s.Close()
_, err = s.Where("id=?", []interface{}{id}).Update(map[string]any{
"active": active,
"update_time": time.Now().Format("2006-01-02 15:04:05"),
})
if err != nil {
return err
}
return nil
}
func UpdInfo(id, domain string, s *public.Sqlite, reportType string) error {
info, errCheck := CheckWebsite(domain)
now := time.Now()
updateData := map[string]any{
"state": info.HTTPStatusText,
"ca": info.Issuer,
"cert_domain": strings.Join(info.Domains, ","),
"end_time": info.NotAfter,
"end_day": info.DaysRemaining,
"last_time": now.Format("2006-01-02 15:04:05"),
"except_end_time": now.Format("2006-01-02 15:04:05"),
}
if errCheck != nil {
updateData["state"] = "异常"
// return err
} else {
if info.HTTPStatus != 0 && info.CertificateOK != false {
delete(updateData, "except_end_time")
} else {
errCheck = fmt.Errorf("证书异常")
}
}
_, err := s.Where("id=?", []interface{}{id}).Update(updateData)
if err != nil {
return err
}
return errCheck
}
// CheckWebsite 实际检测函数
func CheckWebsite(target string) (*SSLInfo, error) {
result := &SSLInfo{Target: target}
// 拆分 host 和 port
host, port, err := net.SplitHostPort(target)
if err != nil {
// 没有显式端口,默认 443
host = target
port = "443"
}
// 验证格式是否是 IP 或域名
if net.ParseIP(host) == nil {
if _, err := net.LookupHost(host); err != nil {
return result, fmt.Errorf("无效域名或 IP%v", err)
}
}
// TLS 连接(支持所有 TLS 版本)
conn, err := tls.Dial("tcp", net.JoinHostPort(host, port), &tls.Config{
InsecureSkipVerify: true,
MinVersion: tls.VersionTLS10, // 显式支持所有版本
MaxVersion: tls.VersionTLS13,
})
if err != nil {
return result, fmt.Errorf("目标不支持 HTTPS%v", err)
}
defer conn.Close()
// HTTP 状态检测(构造 URL保留端口
url := fmt.Sprintf("https://%s", net.JoinHostPort(host, port))
resp, err := http.Get(url)
if err != nil {
result.HTTPStatus = 0
result.HTTPStatusText = "异常"
} else {
result.HTTPStatus = resp.StatusCode
result.HTTPStatusText = "正常"
resp.Body.Close()
}
// 获取证书
cert := conn.ConnectionState().PeerCertificates[0]
result.Domains = cert.DNSNames
result.Issuer = cert.Issuer.CommonName
result.NotBefore = cert.NotBefore.Format("2006-01-02 15:04:05")
result.NotAfter = cert.NotAfter.Format("2006-01-02 15:04:05")
result.DaysRemaining = int(cert.NotAfter.Sub(time.Now()).Hours() / 24)
now := time.Now()
switch {
case now.Before(cert.NotBefore):
result.CertificateOK = false
result.CertificateNote = "尚未生效"
case now.After(cert.NotAfter):
result.CertificateOK = false
result.CertificateNote = "已过期"
default:
result.CertificateOK = true
result.CertificateNote = "有效"
}
return result, nil
}

View File

@@ -1,21 +0,0 @@
package siteMonitor
import (
"fmt"
"testing"
)
func Test(t *testing.T) {
site := "bt.cn" // 只传域名或 IP不要 http://
result, err := CheckWebsite(site)
if err != nil {
fmt.Printf("❌ 检测失败: %v\n", err)
return
}
fmt.Println(result.HTTPStatusText)
fmt.Println(result.Domains)
fmt.Println(result.Issuer)
fmt.Println(result.NotAfter)
// fmt.Println(result.Domains)
// fmt.Println(result.Domains)
}

View File

@@ -33,6 +33,10 @@ func SessionAuthMiddleware() gin.HandlerFunc {
session := sessions.Default(c)
now := time.Now()
gob.Register(time.Time{})
if public.Secure == "/" || public.Secure == "/login" {
// 如果安全入口是根目录或登录页,则不需要特殊处理
public.Secure = ""
}
if public.Secure == "" && session.Get("secure") == nil {
session.Set("secure", true)
session.Set("lastRequestTime", now)

View File

@@ -192,47 +192,6 @@ func init() {
fmt.Println("错误:", err)
}
db1, err := sql.Open("sqlite", "data/site_monitor.db")
if err != nil {
// fmt.Println("创建数据库失败:", err)
return
}
defer db1.Close()
// 创建表
_, err = db1.Exec(`
PRAGMA journal_mode=WAL;
create table IF NOT EXISTS site_monitor
(
id integer not null
constraint site_monitor_pk
primary key autoincrement,
name TEXT not null,
site_domain TEXT not null,
cycle integer not null,
report_type TEXT not null,
cert_domain TEXT,
ca TEXT,
active integer,
end_time TEXT,
end_day TEXT,
last_time TEXT,
except_end_time TEXT,
create_time TEXT,
state TEXT,
update_time TEXT,
repeat_send_gap INTEGER
);
`)
err = sqlite_migrate.EnsureDatabaseWithTables(
"data/settings.db",
"data/data.db",
[]string{"settings", "users"}, // 你要迁移的表
)
if err != nil {
fmt.Println("错误:", err)
}
dbSetting, err := sql.Open("sqlite", "data/settings.db")
if err != nil {
//fmt.Println("创建 settings 数据库失败:", err)
@@ -331,6 +290,82 @@ INSERT INTO settings (key, value, create_time, update_time, active, type) VALUES
on a.email = b.mail and a.type like b.ca||'%';
`
insertDefaultData(dbAcc, "accounts", insertSql)
sourceDBPath := "data/site_monitor.db"
if _, err := os.Stat(sourceDBPath); err != nil {
sourceDBPath = "data/data.db"
}
columnMapping := map[string]string{
"name": "name",
"site_domain": "target",
"report_type": "report_types",
"active": "active",
"last_time": "last_time",
"except_end_time": "except_end_time",
"update_time": "update_time",
"create_time": "create_time",
"cycle": "cycle",
"repeat_send_gap": "repeat_send_gap",
}
createTableSQL := `
create table monitor
(
id integer not null
constraint monitor_pk
primary key autoincrement,
name TEXT not null,
target TEXT not null,
monitor_type TEXT default 'https' not null,
report_types TEXT not null,
active integer default 1,
info TEXT,
last_time TEXT,
except_end_time TEXT,
update_time TEXT,
create_time TEXT,
cycle integer,
repeat_send_gap integer default 10,
advance_day integer default 30,
valid INTEGER default 0 not null
);`
err = sqlite_migrate.MigrateSQLiteTable(
sourceDBPath,
"site_monitor",
"data/monitor.db",
"monitor",
columnMapping,
createTableSQL,
1000,
)
if err != nil {
//fmt.Println("迁移失败:", err)
return
}
dbMonitor, err := sql.Open("sqlite", "data/monitor.db")
if err != nil {
// fmt.Println("创建 monitor 数据库失败:", err)
return
}
defer dbMonitor.Close()
// 创建表
_, err = dbMonitor.Exec(`
PRAGMA journal_mode=WAL;
create table if not exists err_record
(
id TEXT not null
constraint err_record_pk
primary key,
monitor_id INTEGER not null,
create_time TEXT not null,
info TEXT not null,
msg TEXT not null
);
`)
}
func insertDefaultData(db *sql.DB, table, insertSQL string) {

View File

@@ -58,11 +58,6 @@ func NewSqlite(DbFile string, PreFix string) (*Sqlite, error) {
if err != nil {
return nil, err
}
_, err = s.Conn.Exec("PRAGMA busy_timeout = 5000;")
if err != nil {
s.Close()
return nil, fmt.Errorf("设置PRAGMA busy_timeout失败: %w", err)
}
return &s, nil
}
@@ -80,7 +75,8 @@ func FileExists(file string) bool {
* @return error 错误信息
*/
func (s *Sqlite) Connect() error {
conn, err := sql.Open("sqlite", s.DbFile)
dsn := fmt.Sprintf("file:%s?_pragma=busy_timeout(60000)", s.DbFile)
conn, err := sql.Open("sqlite", dsn)
if err == nil {
s.Conn = conn
s.closed = false

View File

@@ -21,3 +21,58 @@ func Test(t *testing.T) {
fmt.Println("错误:", err)
}
}
func Test1(t *testing.T) {
err := os.Chdir("D:/code/ALLinSSL")
if err != nil {
fmt.Fprintf(os.Stderr, "切换目录失败: %v\n", err)
os.Exit(1)
}
columnMapping := map[string]string{
"name": "name",
"site_domain": "target",
"report_type": "report_types",
"active": "active",
"last_time": "last_time",
"except_end_time": "except_end_time",
"update_time": "update_time",
"create_time": "create_time",
"cycle": "cycle",
"repeat_send_gap": "repeat_send_gap",
}
createTableSQL := `
create table monitor
(
id integer not null
constraint monitor_pk
primary key autoincrement,
name TEXT not null,
target TEXT not null,
monitor_type TEXT default 'https' not null,
report_types TEXT not null,
active integer default 1,
info TEXT,
last_time TEXT,
except_end_time TEXT,
update_time TEXT,
create_time TEXT,
cycle integer,
repeat_send_gap integer default 10,
advance_day integer default 30,
valid INTEGER default 0 not null
);`
err = MigrateSQLiteTable(
"data/site_monitor.db",
"site_monitor",
"data/monitor.db",
"monitor",
columnMapping,
createTableSQL,
1000,
)
if err != nil {
fmt.Println("迁移失败:", err)
}
}

View File

@@ -94,6 +94,150 @@ func joinStrings(strs []string, sep string) string {
return result
}
// MigrateSQLiteTable 迁移方法
func MigrateSQLiteTable(sourceDBPath, sourceTable, targetDBPath, targetTable string, columnMapping map[string]string, createTableSQL string, batchSize int) error {
// 打开目标数据库
targetDB, err := sql.Open("sqlite", targetDBPath)
if err != nil {
//return fmt.Errorf("打开目标数据库失败: %v", err)
}
defer targetDB.Close()
// 检查目标表
exists, err := tableExists(targetDB, targetTable)
if err != nil {
return err
}
if exists {
//fmt.Printf("目标表 %s 已存在,跳过迁移。\n", targetTable)
return nil
}
// 创建目标表
//fmt.Printf("目标表 %s 不存在,正在创建...\n", targetTable)
if _, err := targetDB.Exec(createTableSQL); err != nil {
//return fmt.Errorf("创建目标表失败: %v", err)
}
fmt.Printf("目标表 %s 创建成功。\n", targetTable)
// 打开源数据库
sourceDB, err := sql.Open("sqlite", sourceDBPath)
if err != nil {
//return fmt.Errorf("打开源数据库失败: %v", err)
}
defer sourceDB.Close()
// 检查源表
exists, err = tableExists(sourceDB, sourceTable)
if err != nil {
return err
}
if !exists {
//return fmt.Errorf("源表 %s 不存在,迁移终止", sourceTable)
}
// 构建列映射
sourceCols, targetCols, placeholders := buildColumnMappings(columnMapping)
selectSQL := fmt.Sprintf("SELECT %s FROM %s", sourceCols, sourceTable)
insertSQL := fmt.Sprintf("INSERT INTO %s (%s) VALUES (%s)", targetTable, targetCols, placeholders)
rows, err := sourceDB.Query(selectSQL)
if err != nil {
//return fmt.Errorf("查询源数据失败: %v", err)
}
defer rows.Close()
stmt, err := targetDB.Prepare(insertSQL)
if err != nil {
//return fmt.Errorf("准备插入语句失败: %v", err)
}
defer stmt.Close()
colCount := len(columnMapping)
batch := make([][]interface{}, 0, batchSize)
total := 0
for rows.Next() {
values := make([]interface{}, colCount)
ptrs := make([]interface{}, colCount)
for i := range ptrs {
ptrs[i] = &values[i]
}
if err := rows.Scan(ptrs...); err != nil {
//return fmt.Errorf("读取行数据失败: %v", err)
}
batch = append(batch, values)
total++
if len(batch) >= batchSize {
if err := insertBatch(targetDB, stmt, batch); err != nil {
return err
}
batch = batch[:0]
}
}
if len(batch) > 0 {
if err := insertBatch(targetDB, stmt, batch); err != nil {
return err
}
}
//fmt.Printf("数据迁移完成,共迁移 %d 条记录。\n", total)
return nil
}
// tableExists 检查表是否存在
func tableExists(db *sql.DB, tableName string) (bool, error) {
query := `SELECT COUNT(*) FROM sqlite_master WHERE type='table' AND name=?`
var count int
if err := db.QueryRow(query, tableName).Scan(&count); err != nil {
return false, fmt.Errorf("检查表是否存在失败: %v", err)
}
return count > 0, nil
}
// buildColumnMappings 构建列映射 SQL 片段
func buildColumnMappings(mapping map[string]string) (string, string, string) {
srcCols := ""
tgtCols := ""
placeholders := ""
i := 0
for src, tgt := range mapping {
if i > 0 {
srcCols += ", "
tgtCols += ", "
placeholders += ", "
}
srcCols += src
tgtCols += tgt
placeholders += "?"
i++
}
return srcCols, tgtCols, placeholders
}
// insertBatch 批量插入数据
func insertBatch(db *sql.DB, stmt *sql.Stmt, batch [][]interface{}) error {
tx, err := db.Begin()
if err != nil {
return fmt.Errorf("开启事务失败: %v", err)
}
for _, vals := range batch {
if _, err := tx.Stmt(stmt).Exec(vals...); err != nil {
tx.Rollback()
return fmt.Errorf("插入数据失败: %v", err)
}
}
if err := tx.Commit(); err != nil {
return fmt.Errorf("提交事务失败: %v", err)
}
return nil
}
// 示例用法
func main() {
err := EnsureDatabaseWithTables(

View File

@@ -2,7 +2,10 @@ package route
import (
"ALLinSSL/backend/app/api"
"ALLinSSL/backend/app/api/monitor"
"ALLinSSL/static"
"github.com/gin-gonic/gin"
"io/fs"
"net/http"
)
@@ -15,14 +18,20 @@ func Register(r *gin.Engine) {
login.POST("/sign-out", api.SignOut)
login.GET("/get_code", api.GetCode)
}
siteMonitor := v1.Group("/siteMonitor")
_monitor := v1.Group("/monitor")
{
siteMonitor.POST("/get_list", api.GetMonitorList)
siteMonitor.POST("/add_site_monitor", api.AddMonitor)
siteMonitor.POST("/upd_site_monitor", api.UpdMonitor)
siteMonitor.POST("/del_site_monitor", api.DelMonitor)
siteMonitor.POST("/set_site_monitor", api.SetMonitor)
_monitor.POST("/get_list", monitor.GetMonitorList)
_monitor.POST("/add_monitor", monitor.AddMonitor)
_monitor.POST("/upd_monitor", monitor.UpdMonitor)
_monitor.POST("/del_monitor", monitor.DelMonitor)
_monitor.POST("/set_monitor", monitor.SetMonitor)
_monitor.POST("/get_monitor_info", monitor.GetMonitorInfo)
_monitor.POST("/get_err_record", monitor.GetErrRecord)
_monitor.POST("/file_add_monitor", monitor.FileAddMonitor)
_monitor.GET("/template", monitor.GetTemplate)
}
workflow := v1.Group("/workflow")
{
workflow.POST("/get_list", api.GetWorkflowList)
@@ -93,20 +102,28 @@ func Register(r *gin.Engine) {
overview.POST("/get_overviews", api.GetOverview)
}
// 1. 提供静态文件服务
r.StaticFS("/static", http.Dir("./frontend/static")) // 静态资源路径
r.StaticFS("/auto-deploy/static", http.Dir("./frontend/static")) // 静态资源路径
// 返回 favicon.ico
// 静态资源:/static -> build/static
staticFS, _ := fs.Sub(static.BuildFS, "build/static")
r.StaticFS("/static", http.FS(staticFS))
r.StaticFS("/auto-deploy/static", http.FS(staticFS))
// favicon.ico
r.GET("/favicon.ico", func(c *gin.Context) {
c.File("./frontend/favicon.ico")
data, err := static.BuildFS.ReadFile("build/favicon.ico")
if err != nil {
c.Status(http.StatusNotFound)
return
}
c.Data(http.StatusOK, "image/x-icon", data)
})
// 3. 前端路由托管:匹配所有其他路由返回 index.html
// 其他路由返回 index.html
r.NoRoute(func(c *gin.Context) {
c.File("./frontend/index.html")
})
// v2 := r.Group("/v2")
// {
// v2.POST("/submit")
// }
data, err := static.BuildFS.ReadFile("build/index.html")
if err != nil {
c.String(http.StatusInternalServerError, "页面加载失败")
return
}
c.Data(http.StatusOK, "text/html; charset=utf-8", data)
})
}

View File

@@ -0,0 +1,185 @@
package scheduler
import (
"ALLinSSL/backend/internal/monitor"
"ALLinSSL/backend/internal/report"
"ALLinSSL/backend/public"
"encoding/json"
"fmt"
"strconv"
"strings"
"sync"
"time"
)
var (
MonitorErrCount = make(map[int64]int)
monitorErrCountMu sync.Mutex
)
// 通知模板,先写死,后续做成配置
var MonitorErrTemplate = "监控名称:%v\n类型%v\n域名%v\n错误信息%v\n请及时处理\n检测时间%v"
func Monitor() {
defer func() {
if r := recover(); r != nil {
fmt.Printf("Monitor 主流程捕获 panic: %v\n", r)
}
}()
s, err := monitor.GetSqlite()
if err != nil {
fmt.Println(err)
}
defer s.Close()
s1, err := report.GetSqlite()
if err != nil {
fmt.Println(err)
return
}
defer s1.Close()
s1.TableName = "report"
data, err := s.Select()
if err != nil {
fmt.Println(err)
}
now := time.Now()
loc := now.Location()
var wg sync.WaitGroup
for _, v := range data {
if v["active"].(int64) == 1 {
lastTimeStr, ok := v["last_time"].(string)
if !ok || lastTimeStr == "" {
lastTimeStr = "1970-01-01 00:00:00"
}
lastTime, err := time.ParseInLocation("2006-01-02 15:04:05", lastTimeStr, loc)
if err != nil {
// fmt.Println(err)
continue
}
monitorType, ok := v["monitor_type"].(string)
if !ok {
fmt.Println("监控类型错误")
return
}
target, ok := v["target"].(string)
if !ok {
fmt.Println("监控目标错误")
return
}
advanceDay, ok := v["advance_day"].(int64)
if !ok {
advanceDay = 30 // 默认提前30天
}
if now.Sub(lastTime).Minutes() >= float64(v["cycle"].(int64)) {
wg.Add(1)
go func(v map[string]any) {
defer func() {
if r := recover(); r != nil {
fmt.Printf("监控任务发生错误: %v\n", r)
}
}()
defer wg.Done()
gs := *s
var (
certInfo *monitor.CertInfo
certJson string
Err error
checkErr string
)
switch monitorType {
case "https":
certInfo, Err = monitor.CheckHttps(target, int(advanceDay))
case "smtp":
certInfo, Err = monitor.CheckSmtp(target, int(advanceDay))
default:
Err = fmt.Errorf("不支持的监控类型:%s", monitorType)
}
if Err != nil {
checkErr = strings.Split(Err.Error(), "")[0] // 只取错误信息的第一部分
} else {
if certInfo.VerifyError != "" && (!certInfo.Valid || certInfo.DaysLeft <= int(advanceDay)) {
checkErr = certInfo.VerifyError
}
certBytes, err := json.Marshal(certInfo)
if err == nil {
certJson = string(certBytes)
}
}
id := v["id"].(int64)
// 此处应该发送错误邮件
if checkErr != "" {
// 更新监控记录
gs.Where("id=?", []interface{}{id}).Update(map[string]any{
"last_time": now.Format("2006-01-02 15:04:05"),
"except_end_time": now.Format("2006-01-02 15:04:05"),
"info": certJson,
"valid": -1, // 状态为异常
})
// 新增错误记录
if certInfo == nil || !certInfo.Valid {
gs.TableName = "err_record"
gs.Insert(map[string]any{
"id": public.GenerateUUID(),
"monitor_id": id,
"create_time": now.Format("2006-01-02 15:04:05"),
"msg": checkErr,
"info": certJson,
})
}
monitorErrCountMu.Lock()
MonitorErrCount[id] += 1
errCount := MonitorErrCount[id]
monitorErrCountMu.Unlock()
repeatSendGap, ok := v["repeat_send_gap"].(int64)
if !ok {
repeatSendGap = 10
}
reportTypes, ok := v["report_types"].(string)
if ok && errCount == 1 {
reportTypeArr := strings.Split(reportTypes, ",")
for _, reportType := range reportTypeArr {
if reportType == "" {
continue
}
rdata, err := s1.Where("type=?", []interface{}{reportType}).Select()
if err != nil {
return
}
if len(rdata) <= 0 {
return
}
report.Notify(map[string]any{
"provider": reportType,
"provider_id": strconv.FormatInt(rdata[0]["id"].(int64), 10),
"subject": "ALLinSSL 监控通知",
"body": fmt.Sprintf(MonitorErrTemplate, v["name"], monitorType, v["target"], checkErr, now.Format("2006-01-02 15:04:05")),
})
}
}
monitorErrCountMu.Lock()
if MonitorErrCount[id] >= int(repeatSendGap) {
MonitorErrCount[id] = 0
}
monitorErrCountMu.Unlock()
} else {
// 更新监控记录
gs.Where("id=?", []interface{}{id}).Update(map[string]any{
"last_time": now.Format("2006-01-02 15:04:05"),
"info": certJson,
"valid": 1, // 状态为正常
})
monitorErrCountMu.Lock()
MonitorErrCount[id] = 0
monitorErrCountMu.Unlock()
}
}(v)
}
}
}
wg.Wait()
}

View File

@@ -8,7 +8,7 @@ import (
// 你的任务列表
var funcs = []func(){
SiteMonitor,
Monitor,
RunWorkflows,
}

View File

@@ -1,96 +0,0 @@
package scheduler
import (
"ALLinSSL/backend/internal/report"
"ALLinSSL/backend/internal/siteMonitor"
"fmt"
"os"
"path/filepath"
"strconv"
"sync"
"time"
)
func SiteMonitor() {
s, err := siteMonitor.GetSqlite()
if err != nil {
fmt.Println(err)
}
defer s.Close()
s1, err := report.GetSqlite()
if err != nil {
fmt.Println(err)
return
}
defer s1.Close()
data, err := s.Select()
if err != nil {
fmt.Println(err)
}
now := time.Now()
loc := now.Location()
var wg sync.WaitGroup
for _, v := range data {
if v["active"].(int64) == 1 {
lastTimeStr := v["last_time"].(string)
lastTime, err := time.ParseInLocation("2006-01-02 15:04:05", lastTimeStr, loc)
if err != nil {
// fmt.Println(err)
continue
}
if now.Sub(lastTime).Minutes() >= float64(v["cycle"].(int64)) {
wg.Add(1)
go func() {
defer wg.Done()
Err := siteMonitor.UpdInfo(fmt.Sprintf("%d", v["id"].(int64)), v["site_domain"].(string), s, v["report_type"].(string))
path := fmt.Sprintf("data/site_monitor/%d", v["id"].(int64))
dir := filepath.Dir(path)
if err := os.MkdirAll(dir, os.ModePerm); err != nil {
return
}
errCount := 0
file, err := os.ReadFile(path)
if err != nil {
errCount = 0
}
errCount, err = strconv.Atoi(string(file))
if err != nil {
errCount = 0
}
// 此处应该发送错误邮件
if Err != nil {
errCount += 1
os.WriteFile(path, []byte(strconv.Itoa(errCount)), os.ModePerm)
repeatSendGap, ok := v["repeat_send_gap"].(int64)
if !ok {
repeatSendGap = 10
}
reportType, ok := v["report_type"].(string)
if ok && errCount >= int(repeatSendGap) {
s1.TableName = "report"
rdata, err := s1.Where("type=?", []interface{}{reportType}).Select()
if err != nil {
return
}
if len(rdata) <= 0 {
return
}
_ = report.Notify(map[string]any{
"provider": reportType,
"provider_id": strconv.FormatInt(rdata[0]["id"].(int64), 10),
"body": fmt.Sprintf("检测到域名为%s的网站出现异常请保持关注\n检测时间%s", v["site_domain"].(string), now.Format("2006-01-02 15:04:05")),
"subject": "ALLinSSL网站监控通知",
})
os.Remove(path)
}
} else {
os.Remove(path)
}
}()
}
}
}
wg.Wait()
}

View File

@@ -120,17 +120,9 @@ start - 启动 ALLinSSL
fmt.Print("请输入安全入口: ")
fmt.Scanln(&secure)
}
if len(secure) < 5 {
fmt.Println("安全入口至少需要5位")
return
}
if secure[0] != '/' {
if secure != "" && secure[0] != '/' {
secure = "/" + secure
}
if secure == "/login" {
fmt.Println("安全入口不能是/login")
return
}
err := public.UpdateSetting("secure", secure)
if err != nil {
fmt.Println("Error updating setting:", err)

3
go.mod
View File

@@ -28,7 +28,9 @@ require (
github.com/mitchellh/go-ps v1.0.0
github.com/mojocn/base64Captcha v1.3.8
github.com/pavlo-v-chernykh/keystore-go/v4 v4.5.0
github.com/pkg/sftp v1.13.9
github.com/qiniu/go-sdk/v7 v7.25.3
github.com/tealeg/xlsx v1.0.5
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1128
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ssl v1.0.1124
github.com/volcengine/volcengine-go-sdk v1.1.11
@@ -94,6 +96,7 @@ require (
github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/cpuid/v2 v2.2.10 // indirect
github.com/kr/fs v0.1.0 // indirect
github.com/kylelemons/godebug v1.1.0 // indirect
github.com/leodido/go-urn v1.4.0 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect

9
go.sum
View File

@@ -503,6 +503,8 @@ github.com/klauspost/cpuid/v2 v2.2.10/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQe
github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8=
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
@@ -610,6 +612,8 @@ github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA=
github.com/pkg/sftp v1.13.9 h1:4NGkvGudBL7GteO3m6qnaQ4pC0Kvf0onSVc9gR3EWBw=
github.com/pkg/sftp v1.13.9/go.mod h1:OBN7bVXdstkFFN/gdnHPUb5TE8eb8G1Rp9wCItqjkkA=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
@@ -689,6 +693,8 @@ github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/tealeg/xlsx v1.0.5 h1:+f8oFmvY8Gw1iUXzPk+kz+4GpbDZPK1FhPiQRd+ypgE=
github.com/tealeg/xlsx v1.0.5/go.mod h1:btRS8dz54TDnvKNosuAqxrM1QgN1udgk9O34bDCnORM=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1124/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1128 h1:NGnqDc8FQL0YdiCHgTO4Wkso6ToD8rE3JW9VOzoPBNA=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1128/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
@@ -778,6 +784,7 @@ golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDf
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM=
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE=
golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc=
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
@@ -981,6 +988,7 @@ golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20=
golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=
@@ -996,6 +1004,7 @@ golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58=
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0=
golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM=
golang.org/x/term v0.31.0 h1:erwDkOK1Msy6offm1mOgvspSkslFnIGsFnxOKoufg3o=
golang.org/x/term v0.31.0/go.mod h1:R4BeIy7D95HzImkxGkTW1UQTtP54tio2RyHz7PwK0aw=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=

9
static/assets.go Normal file
View File

@@ -0,0 +1,9 @@
package static
import "embed"
//go:embed monitor_templates/*
var MonitorTemplatesFS embed.FS
//go:embed build/*
var BuildFS embed.FS

BIN
static/build/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

14
static/build/index.html Normal file
View File

@@ -0,0 +1,14 @@
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<link rel="icon" href="./favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>AllinSSL</title>
<script type="module" crossorigin src="./static/js/main-DzwaUoFb.js"></script>
<link rel="stylesheet" crossorigin href="./static/css/style-DbV1_Tij.css">
</head>
<body>
<div id="app"></div>
</body>
</html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 47 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

View File

@@ -0,0 +1 @@
<svg width="1440.855" height="900.46" viewBox="0 0 1440.85 900.46" fill="none" xmlns="http://www.w3.org/2000/svg"><defs><linearGradient x1="0" y1="724" x2="442.31" y2="898.26" id="a" gradientUnits="userSpaceOnUse"><stop stop-color="#121212"/><stop offset=".969" stop-color="#333" stop-opacity=".969"/><stop offset="1" stop-color="#E3E4E8" stop-opacity="0"/></linearGradient><linearGradient x1="995.427" y1="642.73" x2="466.927" y2="898.31" id="b" gradientUnits="userSpaceOnUse"><stop stop-color="#121212"/><stop offset="1" stop-color="#333"/></linearGradient><linearGradient x1="0" y1="653.04" x2="1120.19" y2="653.04" id="c" gradientUnits="userSpaceOnUse"><stop stop-color="#121212"/><stop offset="1" stop-color="#333"/></linearGradient><linearGradient x1=".7" y1="58.87" x2="382.18" y2="58.87" id="d" gradientUnits="userSpaceOnUse"><stop stop-color="#121212"/><stop offset="1" stop-color="#333"/></linearGradient><linearGradient x1="1440.355" y1="665.73" x2="1152.355" y2="900.23" id="e" gradientUnits="userSpaceOnUse"><stop stop-color="#333"/><stop offset="1" stop-color="#121212"/></linearGradient><linearGradient x1="1206.355" y1="1.73" x2="1460.355" y2="314.73" id="f" gradientUnits="userSpaceOnUse"><stop stop-color="#121212"/><stop offset=".995" stop-color="#333" stop-opacity=".792"/></linearGradient></defs><path fill="#121212" d="M.7.46h1440v900H.7z"/><path d="M3.09 755.27 0 724.46l442.31 174.26h-79.56L3.09 755.27z" fill="url(#a)"/><path d="M532.78 898.72h83.62l526.16-259.19-22.38-27.13-587.4 286.32z" fill="url(#b)"/><path d="m3.09 585.09 470.03-177.73 647.06 205.04-587.4 286.32h-90.47L0 724.46l3.09-139.37z" fill="url(#c)"/><path d="m.7 79.92 88.22 37.37L382.18.45H.7v79.47z" fill="url(#d)"/><path d="M1440.35 665.73v234.5h-288l288-234.5z" fill="url(#e)" fill-opacity=".9" fill-rule="evenodd"/><path d="M1206.35 1.72h234.5v288.01L1206.35 1.72z" fill="url(#f)" fill-rule="evenodd"/></svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@@ -0,0 +1 @@
<svg width="1440.855" height="900.46" viewBox="0 0 1440.85 900.46" fill="none" xmlns="http://www.w3.org/2000/svg"><defs><linearGradient x1="0" y1="653.04" x2="1120.19" y2="653.04" id="a" gradientUnits="userSpaceOnUse"><stop stop-color="#F0F0F2"/><stop offset="1" stop-color="#F3F4F6"/></linearGradient><linearGradient x1=".7" y1="58.87" x2="382.18" y2="58.87" id="b" gradientUnits="userSpaceOnUse"><stop stop-color="#EBEBED"/><stop offset="1" stop-color="#F3F4F6"/></linearGradient><linearGradient x1="1506.855" y1="665.73" x2="1152.355" y2="900.23" id="c" gradientUnits="userSpaceOnUse"><stop stop-color="#EBECEE"/><stop offset="1" stop-color="#F2F3F5"/></linearGradient><linearGradient x1="1206.355" y1="1.73" x2="1460.355" y2="314.73" id="d" gradientUnits="userSpaceOnUse"><stop offset=".282" stop-color="#F1F2F3"/><stop offset="1" stop-color="#EBECEE" stop-opacity=".792"/></linearGradient></defs><path fill="#F3F4F6" d="M.7.46h1440v900H.7z"/><path d="M3.09 755.27 0 724.46l442.31 174.26h-79.56L3.09 755.27z" fill="#E3E4E8"/><path d="M532.78 898.72h83.62l526.16-259.19-22.38-27.13-587.4 286.32z" fill="#FBFBFC"/><path d="m3.09 585.09 470.03-177.73 647.06 205.04-587.4 286.32h-90.47L0 724.46l3.09-139.37z" fill="url(#a)"/><path d="m.7 79.92 88.22 37.37L382.18.45H.7v79.47z" fill="url(#b)"/><path d="M1440.35 665.73v234.5h-288l288-234.5z" fill="url(#c)" fill-opacity=".9" fill-rule="evenodd"/><path d="M1206.35 1.72h234.5v288.01L1206.35 1.72z" fill="url(#d)" fill-rule="evenodd"/></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 364 KiB

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
import{u as s}from"./index-DJVuZNft.js";import{d as t,c as o}from"./main-l9ONqWM3.js";import"./useStore-B_YQVTNZ.js";import"./index-CROykHUI.js";import"./access-DAUICydO.js";import"./index-DoEhNl1p.js";import"./throttle-CqQDPWAC.js";import"./index-Boi7lFs7.js";import"./data-DuVKJAVf.js";import"./index-DBGpolyE.js";import"./business-BHURL4si.js";import"./index-DDUoCc5m.js";const r=t({name:"CAManageForm",setup(){const{CAForm:t}=s();return()=>o(t,{labelPlacement:"top"},null)}});export{r as default};

View File

@@ -0,0 +1 @@
import{u as s}from"./index-CZGsWLu5.js";import{d as t,c as o}from"./main-DPHcWoLq.js";import"./useStore-Rp34S9LW.js";import"./index-B19cVdYt.js";import"./access-CRBQqgF7.js";import"./index-DtIETYgH.js";import"./throttle-JmbW0v_s.js";import"./index-G81Br7zM.js";import"./data-DlilpN2t.js";import"./index-CKj4hF6A.js";import"./business-DHKRFoyP.js";import"./index-CHVS5zLT.js";const r=t({name:"CAManageForm",setup(){const{CAForm:t}=s();return()=>o(t,{labelPlacement:"top"},null)}});export{r as default};

View File

@@ -0,0 +1 @@
import{u as s}from"./index-Bkq98n1o.js";import{d as t,c as o}from"./main-D37kYvfP.js";import"./useStore-BfxXiqmz.js";import"./index-DuE5FJUK.js";import"./access-D5PuzSlL.js";import"./index-CkZPJuYU.js";import"./throttle-DUJLBKRu.js";import"./index-atRq13wP.js";import"./data-C6c8domP.js";import"./index-CfX9d1jr.js";import"./business-3db_PQBB.js";import"./index-D8XFZQMn.js";const r=t({name:"CAManageForm",setup(){const{CAForm:t}=s();return()=>o(t,{labelPlacement:"top"},null)}});export{r as default};

View File

@@ -0,0 +1 @@
import{u as s}from"./index-DRzBjIiL.js";import{d as t,c as o}from"./main-BLIIbSTQ.js";import"./useStore-fVNzUh3F.js";import"./index-BpNpm-gE.js";import"./access-D0TDoR2F.js";import"./index-Cst_8GwD.js";import"./throttle-BeYFKTpy.js";import"./index-P8bDWxur.js";import"./data-bWxE0nrC.js";import"./index-nSsq-Cp3.js";import"./business-iC8kVSsk.js";import"./index-T_6gqO98.js";const r=t({name:"CAManageForm",setup(){const{CAForm:t}=s();return()=>o(t,{labelPlacement:"top"},null)}});export{r as default};

View File

@@ -0,0 +1 @@
import{u as t}from"./index-DO8we_Ld.js";import{d as s,c as e}from"./main-DzwaUoFb.js";import"./useStore-Bzsn7zfX.js";import"./index-BNb4DSrN.js";import"./access-D1d2FuYi.js";import"./index-CgB92oEK.js";import"./index-B9Dyybyi.js";import"./throttle-cf_E8cS3.js";import"./data-BqkycWmp.js";import"./index-Dhf2Wig3.js";import"./business-Ckv_hx4t.js";import"./index-sgsDdEi4.js";const o=s({name:"CAManageForm",props:{isEdit:{type:Boolean,default:!1},editId:{type:String,default:""}},setup(s){const{CAForm:o}=t(s);return()=>e(o,{labelPlacement:"top"},null)}});export{o as default};

View File

@@ -0,0 +1 @@
import{u as s}from"./index-poTMapw9.js";import{d as t,c as o}from"./main-TC3Bu45J.js";import"./useStore-B7wwrEXS.js";import"./index-jviZh_iP.js";import"./access-CVoV-9UZ.js";import"./index-D0djR_cB.js";import"./throttle-CQkMUevy.js";import"./index-DXyQC-X-.js";import"./data-CXwlriQE.js";import"./index-OvFH652L.js";import"./business-CSi1hkxo.js";import"./index-Cdsjg_sg.js";const e=t({name:"CAManageForm",setup(){const{CAForm:t}=s();return()=>o(t,{labelPlacement:"top"},null)}});export{e as default};

View File

@@ -0,0 +1 @@
import{u as s}from"./index-BfcToXUg.js";import{d as t,c as o}from"./main-BjWWkfgM.js";import"./useStore-D1h1SxQb.js";import"./index-CyQKn_q4.js";import"./access-C8j2cGON.js";import"./index-D_NskAyf.js";import"./throttle-Bs65PtnC.js";import"./index-DaAFB231.js";import"./data-DGp-Iau0.js";import"./index-BocM-74J.js";import"./business-CjXdXSjQ.js";import"./index-CEm6GyyI.js";const r=t({name:"CAManageForm",setup(){const{CAForm:t}=s();return()=>o(t,{labelPlacement:"top"},null)}});export{r as default};

View File

@@ -0,0 +1 @@
import{u as s}from"./index-BZGW-6lh.js";import{d as t,c as o}from"./main-JC8aq1By.js";import"./useStore-CN6rAXJa.js";import"./index-CCRs72lf.js";import"./access-CGnP5Z8L.js";import"./index-DEff3yds.js";import"./throttle-D-tgB-x9.js";import"./index-CmlwJ1kX.js";import"./data-7FrDFtiI.js";import"./index-0z5TG9kl.js";import"./business-0Klrz1zP.js";import"./index-Cfd72zNl.js";const r=t({name:"CAManageForm",setup(){const{CAForm:t}=s();return()=>o(t,{labelPlacement:"top"},null)}});export{r as default};

View File

@@ -0,0 +1 @@
import{u as s}from"./index-DdlylIcx.js";import{d as t,c as o}from"./main-Cd9NCLQB.js";import"./useStore-Vx4sk6zd.js";import"./index-DaWzl1ur.js";import"./access-INphxj4G.js";import"./index-yUaAtD-K.js";import"./throttle-D99ELLRH.js";import"./index-DyzEpAdl.js";import"./data-DMTi6uCf.js";import"./index-X52VisOU.js";import"./business-CPrm7sa6.js";import"./index-YNVPcluS.js";const r=t({name:"CAManageForm",setup(){const{CAForm:t}=s();return()=>o(t,{labelPlacement:"top"},null)}});export{r as default};

View File

@@ -0,0 +1 @@
import{d as a,Y as l,Z as n,_ as r}from"./main-JC8aq1By.js";const t={xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink",viewBox:"0 0 20 20"},o=a({name:"Certificate20Regular",render:function(a,o){return n(),l("svg",t,o[0]||(o[0]=[r("g",{fill:"none"},[r("path",{d:"M2 5a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v3.146a4.508 4.508 0 0 0-1-.678V5a1 1 0 0 0-1-1H4a1 1 0 0 0-1 1v8a1 1 0 0 0 1 1h7.258c.076.113.157.223.242.329V15H4a2 2 0 0 1-2-2V5zm16.5 6.5c0 .954-.381 1.818-1 2.45V18a.5.5 0 0 1-.8.4l-1.4-1.05a.5.5 0 0 0-.6 0l-1.4 1.05a.5.5 0 0 1-.8-.4v-4.05a3.5 3.5 0 1 1 6-2.45zM15 15c-.537 0-1.045-.12-1.5-.337v2.087l1.243-.746a.5.5 0 0 1 .514 0l1.243.746v-2.087A3.486 3.486 0 0 1 15 15zm0-1a2.5 2.5 0 1 0 0-5a2.5 2.5 0 0 0 0 5zM5 6.5a.5.5 0 0 1 .5-.5h9a.5.5 0 0 1 0 1h-9a.5.5 0 0 1-.5-.5zm.5 4.5a.5.5 0 0 0 0 1h4a.5.5 0 0 0 0-1h-4z",fill:"currentColor"})],-1)]))}}),h={xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink",viewBox:"0 0 32 32"},w=a({name:"CloudMonitoring",render:function(a,t){return n(),l("svg",h,t[0]||(t[0]=[r("path",{d:"M28 16v6H4V6h7V4H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h8v4H8v2h16v-2h-4v-4h8a2 2 0 0 0 2-2v-6zM18 28h-4v-4h4z",fill:"currentColor"},null,-1),r("path",{d:"M18 18h-.01a1 1 0 0 1-.951-.725L15.246 11H11V9h5a1 1 0 0 1 .962.725l1.074 3.76l3.009-9.78A1.014 1.014 0 0 1 22 3a.98.98 0 0 1 .949.684L24.72 9H30v2h-6a1 1 0 0 1-.949-.684l-1.013-3.04l-3.082 10.018A1 1 0 0 1 18 18z",fill:"currentColor"},null,-1)]))}}),v={xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink",viewBox:"0 0 32 32"},e=a({name:"Flow",render:function(a,t){return n(),l("svg",v,t[0]||(t[0]=[r("path",{d:"M27 22.14V17a2 2 0 0 0-2-2h-8V9.86a4 4 0 1 0-2 0V15H7a2 2 0 0 0-2 2v5.14a4 4 0 1 0 2 0V17h18v5.14a4 4 0 1 0 2 0zM8 26a2 2 0 1 1-2-2a2 2 0 0 1 2 2zm6-20a2 2 0 1 1 2 2a2 2 0 0 1-2-2zm12 22a2 2 0 1 1 2-2a2 2 0 0 1-2 2z",fill:"currentColor"},null,-1)]))}});export{o as C,e as F,w as a};

View File

@@ -0,0 +1 @@
import{d as a,U as l,W as n,X as r}from"./main-TC3Bu45J.js";const t={xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink",viewBox:"0 0 20 20"},o=a({name:"Certificate20Regular",render:function(a,o){return n(),l("svg",t,o[0]||(o[0]=[r("g",{fill:"none"},[r("path",{d:"M2 5a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v3.146a4.508 4.508 0 0 0-1-.678V5a1 1 0 0 0-1-1H4a1 1 0 0 0-1 1v8a1 1 0 0 0 1 1h7.258c.076.113.157.223.242.329V15H4a2 2 0 0 1-2-2V5zm16.5 6.5c0 .954-.381 1.818-1 2.45V18a.5.5 0 0 1-.8.4l-1.4-1.05a.5.5 0 0 0-.6 0l-1.4 1.05a.5.5 0 0 1-.8-.4v-4.05a3.5 3.5 0 1 1 6-2.45zM15 15c-.537 0-1.045-.12-1.5-.337v2.087l1.243-.746a.5.5 0 0 1 .514 0l1.243.746v-2.087A3.486 3.486 0 0 1 15 15zm0-1a2.5 2.5 0 1 0 0-5a2.5 2.5 0 0 0 0 5zM5 6.5a.5.5 0 0 1 .5-.5h9a.5.5 0 0 1 0 1h-9a.5.5 0 0 1-.5-.5zm.5 4.5a.5.5 0 0 0 0 1h4a.5.5 0 0 0 0-1h-4z",fill:"currentColor"})],-1)]))}}),h={xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink",viewBox:"0 0 32 32"},w=a({name:"CloudMonitoring",render:function(a,t){return n(),l("svg",h,t[0]||(t[0]=[r("path",{d:"M28 16v6H4V6h7V4H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h8v4H8v2h16v-2h-4v-4h8a2 2 0 0 0 2-2v-6zM18 28h-4v-4h4z",fill:"currentColor"},null,-1),r("path",{d:"M18 18h-.01a1 1 0 0 1-.951-.725L15.246 11H11V9h5a1 1 0 0 1 .962.725l1.074 3.76l3.009-9.78A1.014 1.014 0 0 1 22 3a.98.98 0 0 1 .949.684L24.72 9H30v2h-6a1 1 0 0 1-.949-.684l-1.013-3.04l-3.082 10.018A1 1 0 0 1 18 18z",fill:"currentColor"},null,-1)]))}}),v={xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink",viewBox:"0 0 32 32"},e=a({name:"Flow",render:function(a,t){return n(),l("svg",v,t[0]||(t[0]=[r("path",{d:"M27 22.14V17a2 2 0 0 0-2-2h-8V9.86a4 4 0 1 0-2 0V15H7a2 2 0 0 0-2 2v5.14a4 4 0 1 0 2 0V17h18v5.14a4 4 0 1 0 2 0zM8 26a2 2 0 1 1-2-2a2 2 0 0 1 2 2zm6-20a2 2 0 1 1 2 2a2 2 0 0 1-2-2zm12 22a2 2 0 1 1 2-2a2 2 0 0 1-2 2z",fill:"currentColor"},null,-1)]))}});export{w as C,e as F,o as a};

View File

@@ -0,0 +1 @@
import{d as a,Y as l,Z as n,_ as r}from"./main-BjWWkfgM.js";const t={xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink",viewBox:"0 0 20 20"},o=a({name:"Certificate20Regular",render:function(a,o){return n(),l("svg",t,o[0]||(o[0]=[r("g",{fill:"none"},[r("path",{d:"M2 5a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v3.146a4.508 4.508 0 0 0-1-.678V5a1 1 0 0 0-1-1H4a1 1 0 0 0-1 1v8a1 1 0 0 0 1 1h7.258c.076.113.157.223.242.329V15H4a2 2 0 0 1-2-2V5zm16.5 6.5c0 .954-.381 1.818-1 2.45V18a.5.5 0 0 1-.8.4l-1.4-1.05a.5.5 0 0 0-.6 0l-1.4 1.05a.5.5 0 0 1-.8-.4v-4.05a3.5 3.5 0 1 1 6-2.45zM15 15c-.537 0-1.045-.12-1.5-.337v2.087l1.243-.746a.5.5 0 0 1 .514 0l1.243.746v-2.087A3.486 3.486 0 0 1 15 15zm0-1a2.5 2.5 0 1 0 0-5a2.5 2.5 0 0 0 0 5zM5 6.5a.5.5 0 0 1 .5-.5h9a.5.5 0 0 1 0 1h-9a.5.5 0 0 1-.5-.5zm.5 4.5a.5.5 0 0 0 0 1h4a.5.5 0 0 0 0-1h-4z",fill:"currentColor"})],-1)]))}}),h={xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink",viewBox:"0 0 32 32"},w=a({name:"CloudMonitoring",render:function(a,t){return n(),l("svg",h,t[0]||(t[0]=[r("path",{d:"M28 16v6H4V6h7V4H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h8v4H8v2h16v-2h-4v-4h8a2 2 0 0 0 2-2v-6zM18 28h-4v-4h4z",fill:"currentColor"},null,-1),r("path",{d:"M18 18h-.01a1 1 0 0 1-.951-.725L15.246 11H11V9h5a1 1 0 0 1 .962.725l1.074 3.76l3.009-9.78A1.014 1.014 0 0 1 22 3a.98.98 0 0 1 .949.684L24.72 9H30v2h-6a1 1 0 0 1-.949-.684l-1.013-3.04l-3.082 10.018A1 1 0 0 1 18 18z",fill:"currentColor"},null,-1)]))}}),v={xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink",viewBox:"0 0 32 32"},e=a({name:"Flow",render:function(a,t){return n(),l("svg",v,t[0]||(t[0]=[r("path",{d:"M27 22.14V17a2 2 0 0 0-2-2h-8V9.86a4 4 0 1 0-2 0V15H7a2 2 0 0 0-2 2v5.14a4 4 0 1 0 2 0V17h18v5.14a4 4 0 1 0 2 0zM8 26a2 2 0 1 1-2-2a2 2 0 0 1 2 2zm6-20a2 2 0 1 1 2 2a2 2 0 0 1-2-2zm12 22a2 2 0 1 1 2-2a2 2 0 0 1-2 2z",fill:"currentColor"},null,-1)]))}});export{o as C,e as F,w as a};

View File

@@ -0,0 +1 @@
import{d as a,Y as l,Z as n,_ as r}from"./main-BLIIbSTQ.js";const t={xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink",viewBox:"0 0 20 20"},o=a({name:"Certificate20Regular",render:function(a,o){return n(),l("svg",t,o[0]||(o[0]=[r("g",{fill:"none"},[r("path",{d:"M2 5a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v3.146a4.508 4.508 0 0 0-1-.678V5a1 1 0 0 0-1-1H4a1 1 0 0 0-1 1v8a1 1 0 0 0 1 1h7.258c.076.113.157.223.242.329V15H4a2 2 0 0 1-2-2V5zm16.5 6.5c0 .954-.381 1.818-1 2.45V18a.5.5 0 0 1-.8.4l-1.4-1.05a.5.5 0 0 0-.6 0l-1.4 1.05a.5.5 0 0 1-.8-.4v-4.05a3.5 3.5 0 1 1 6-2.45zM15 15c-.537 0-1.045-.12-1.5-.337v2.087l1.243-.746a.5.5 0 0 1 .514 0l1.243.746v-2.087A3.486 3.486 0 0 1 15 15zm0-1a2.5 2.5 0 1 0 0-5a2.5 2.5 0 0 0 0 5zM5 6.5a.5.5 0 0 1 .5-.5h9a.5.5 0 0 1 0 1h-9a.5.5 0 0 1-.5-.5zm.5 4.5a.5.5 0 0 0 0 1h4a.5.5 0 0 0 0-1h-4z",fill:"currentColor"})],-1)]))}}),h={xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink",viewBox:"0 0 32 32"},w=a({name:"CloudMonitoring",render:function(a,t){return n(),l("svg",h,t[0]||(t[0]=[r("path",{d:"M28 16v6H4V6h7V4H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h8v4H8v2h16v-2h-4v-4h8a2 2 0 0 0 2-2v-6zM18 28h-4v-4h4z",fill:"currentColor"},null,-1),r("path",{d:"M18 18h-.01a1 1 0 0 1-.951-.725L15.246 11H11V9h5a1 1 0 0 1 .962.725l1.074 3.76l3.009-9.78A1.014 1.014 0 0 1 22 3a.98.98 0 0 1 .949.684L24.72 9H30v2h-6a1 1 0 0 1-.949-.684l-1.013-3.04l-3.082 10.018A1 1 0 0 1 18 18z",fill:"currentColor"},null,-1)]))}}),v={xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink",viewBox:"0 0 32 32"},e=a({name:"Flow",render:function(a,t){return n(),l("svg",v,t[0]||(t[0]=[r("path",{d:"M27 22.14V17a2 2 0 0 0-2-2h-8V9.86a4 4 0 1 0-2 0V15H7a2 2 0 0 0-2 2v5.14a4 4 0 1 0 2 0V17h18v5.14a4 4 0 1 0 2 0zM8 26a2 2 0 1 1-2-2a2 2 0 0 1 2 2zm6-20a2 2 0 1 1 2 2a2 2 0 0 1-2-2zm12 22a2 2 0 1 1 2-2a2 2 0 0 1-2 2z",fill:"currentColor"},null,-1)]))}});export{o as C,e as F,w as a};

View File

@@ -0,0 +1 @@
import{d as a,Y as l,Z as n,_ as r}from"./main-DzwaUoFb.js";const t={xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink",viewBox:"0 0 20 20"},o=a({name:"Certificate20Regular",render:function(a,o){return n(),l("svg",t,o[0]||(o[0]=[r("g",{fill:"none"},[r("path",{d:"M2 5a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v3.146a4.508 4.508 0 0 0-1-.678V5a1 1 0 0 0-1-1H4a1 1 0 0 0-1 1v8a1 1 0 0 0 1 1h7.258c.076.113.157.223.242.329V15H4a2 2 0 0 1-2-2V5zm16.5 6.5c0 .954-.381 1.818-1 2.45V18a.5.5 0 0 1-.8.4l-1.4-1.05a.5.5 0 0 0-.6 0l-1.4 1.05a.5.5 0 0 1-.8-.4v-4.05a3.5 3.5 0 1 1 6-2.45zM15 15c-.537 0-1.045-.12-1.5-.337v2.087l1.243-.746a.5.5 0 0 1 .514 0l1.243.746v-2.087A3.486 3.486 0 0 1 15 15zm0-1a2.5 2.5 0 1 0 0-5a2.5 2.5 0 0 0 0 5zM5 6.5a.5.5 0 0 1 .5-.5h9a.5.5 0 0 1 0 1h-9a.5.5 0 0 1-.5-.5zm.5 4.5a.5.5 0 0 0 0 1h4a.5.5 0 0 0 0-1h-4z",fill:"currentColor"})],-1)]))}}),h={xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink",viewBox:"0 0 32 32"},w=a({name:"CloudMonitoring",render:function(a,t){return n(),l("svg",h,t[0]||(t[0]=[r("path",{d:"M28 16v6H4V6h7V4H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h8v4H8v2h16v-2h-4v-4h8a2 2 0 0 0 2-2v-6zM18 28h-4v-4h4z",fill:"currentColor"},null,-1),r("path",{d:"M18 18h-.01a1 1 0 0 1-.951-.725L15.246 11H11V9h5a1 1 0 0 1 .962.725l1.074 3.76l3.009-9.78A1.014 1.014 0 0 1 22 3a.98.98 0 0 1 .949.684L24.72 9H30v2h-6a1 1 0 0 1-.949-.684l-1.013-3.04l-3.082 10.018A1 1 0 0 1 18 18z",fill:"currentColor"},null,-1)]))}}),v={xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink",viewBox:"0 0 32 32"},e=a({name:"Flow",render:function(a,t){return n(),l("svg",v,t[0]||(t[0]=[r("path",{d:"M27 22.14V17a2 2 0 0 0-2-2h-8V9.86a4 4 0 1 0-2 0V15H7a2 2 0 0 0-2 2v5.14a4 4 0 1 0 2 0V17h18v5.14a4 4 0 1 0 2 0zM8 26a2 2 0 1 1-2-2a2 2 0 0 1 2 2zm6-20a2 2 0 1 1 2 2a2 2 0 0 1-2-2zm12 22a2 2 0 1 1 2-2a2 2 0 0 1-2 2z",fill:"currentColor"},null,-1)]))}});export{o as C,e as F,w as a};

View File

@@ -0,0 +1 @@
import{d as a,Y as l,Z as n,_ as r}from"./main-D37kYvfP.js";const t={xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink",viewBox:"0 0 20 20"},o=a({name:"Certificate20Regular",render:function(a,o){return n(),l("svg",t,o[0]||(o[0]=[r("g",{fill:"none"},[r("path",{d:"M2 5a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v3.146a4.508 4.508 0 0 0-1-.678V5a1 1 0 0 0-1-1H4a1 1 0 0 0-1 1v8a1 1 0 0 0 1 1h7.258c.076.113.157.223.242.329V15H4a2 2 0 0 1-2-2V5zm16.5 6.5c0 .954-.381 1.818-1 2.45V18a.5.5 0 0 1-.8.4l-1.4-1.05a.5.5 0 0 0-.6 0l-1.4 1.05a.5.5 0 0 1-.8-.4v-4.05a3.5 3.5 0 1 1 6-2.45zM15 15c-.537 0-1.045-.12-1.5-.337v2.087l1.243-.746a.5.5 0 0 1 .514 0l1.243.746v-2.087A3.486 3.486 0 0 1 15 15zm0-1a2.5 2.5 0 1 0 0-5a2.5 2.5 0 0 0 0 5zM5 6.5a.5.5 0 0 1 .5-.5h9a.5.5 0 0 1 0 1h-9a.5.5 0 0 1-.5-.5zm.5 4.5a.5.5 0 0 0 0 1h4a.5.5 0 0 0 0-1h-4z",fill:"currentColor"})],-1)]))}}),h={xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink",viewBox:"0 0 32 32"},w=a({name:"CloudMonitoring",render:function(a,t){return n(),l("svg",h,t[0]||(t[0]=[r("path",{d:"M28 16v6H4V6h7V4H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h8v4H8v2h16v-2h-4v-4h8a2 2 0 0 0 2-2v-6zM18 28h-4v-4h4z",fill:"currentColor"},null,-1),r("path",{d:"M18 18h-.01a1 1 0 0 1-.951-.725L15.246 11H11V9h5a1 1 0 0 1 .962.725l1.074 3.76l3.009-9.78A1.014 1.014 0 0 1 22 3a.98.98 0 0 1 .949.684L24.72 9H30v2h-6a1 1 0 0 1-.949-.684l-1.013-3.04l-3.082 10.018A1 1 0 0 1 18 18z",fill:"currentColor"},null,-1)]))}}),v={xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink",viewBox:"0 0 32 32"},e=a({name:"Flow",render:function(a,t){return n(),l("svg",v,t[0]||(t[0]=[r("path",{d:"M27 22.14V17a2 2 0 0 0-2-2h-8V9.86a4 4 0 1 0-2 0V15H7a2 2 0 0 0-2 2v5.14a4 4 0 1 0 2 0V17h18v5.14a4 4 0 1 0 2 0zM8 26a2 2 0 1 1-2-2a2 2 0 0 1 2 2zm6-20a2 2 0 1 1 2 2a2 2 0 0 1-2-2zm12 22a2 2 0 1 1 2-2a2 2 0 0 1-2 2z",fill:"currentColor"},null,-1)]))}});export{o as C,e as F,w as a};

View File

@@ -0,0 +1 @@
import{d as a,Y as l,Z as n,_ as r}from"./main-DPHcWoLq.js";const t={xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink",viewBox:"0 0 20 20"},o=a({name:"Certificate20Regular",render:function(a,o){return n(),l("svg",t,o[0]||(o[0]=[r("g",{fill:"none"},[r("path",{d:"M2 5a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v3.146a4.508 4.508 0 0 0-1-.678V5a1 1 0 0 0-1-1H4a1 1 0 0 0-1 1v8a1 1 0 0 0 1 1h7.258c.076.113.157.223.242.329V15H4a2 2 0 0 1-2-2V5zm16.5 6.5c0 .954-.381 1.818-1 2.45V18a.5.5 0 0 1-.8.4l-1.4-1.05a.5.5 0 0 0-.6 0l-1.4 1.05a.5.5 0 0 1-.8-.4v-4.05a3.5 3.5 0 1 1 6-2.45zM15 15c-.537 0-1.045-.12-1.5-.337v2.087l1.243-.746a.5.5 0 0 1 .514 0l1.243.746v-2.087A3.486 3.486 0 0 1 15 15zm0-1a2.5 2.5 0 1 0 0-5a2.5 2.5 0 0 0 0 5zM5 6.5a.5.5 0 0 1 .5-.5h9a.5.5 0 0 1 0 1h-9a.5.5 0 0 1-.5-.5zm.5 4.5a.5.5 0 0 0 0 1h4a.5.5 0 0 0 0-1h-4z",fill:"currentColor"})],-1)]))}}),h={xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink",viewBox:"0 0 32 32"},w=a({name:"CloudMonitoring",render:function(a,t){return n(),l("svg",h,t[0]||(t[0]=[r("path",{d:"M28 16v6H4V6h7V4H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h8v4H8v2h16v-2h-4v-4h8a2 2 0 0 0 2-2v-6zM18 28h-4v-4h4z",fill:"currentColor"},null,-1),r("path",{d:"M18 18h-.01a1 1 0 0 1-.951-.725L15.246 11H11V9h5a1 1 0 0 1 .962.725l1.074 3.76l3.009-9.78A1.014 1.014 0 0 1 22 3a.98.98 0 0 1 .949.684L24.72 9H30v2h-6a1 1 0 0 1-.949-.684l-1.013-3.04l-3.082 10.018A1 1 0 0 1 18 18z",fill:"currentColor"},null,-1)]))}}),v={xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink",viewBox:"0 0 32 32"},e=a({name:"Flow",render:function(a,t){return n(),l("svg",v,t[0]||(t[0]=[r("path",{d:"M27 22.14V17a2 2 0 0 0-2-2h-8V9.86a4 4 0 1 0-2 0V15H7a2 2 0 0 0-2 2v5.14a4 4 0 1 0 2 0V17h18v5.14a4 4 0 1 0 2 0zM8 26a2 2 0 1 1-2-2a2 2 0 0 1 2 2zm6-20a2 2 0 1 1 2 2a2 2 0 0 1-2-2zm12 22a2 2 0 1 1 2-2a2 2 0 0 1-2 2z",fill:"currentColor"},null,-1)]))}});export{o as C,e as F,w as a};

View File

@@ -0,0 +1 @@
import{d as a,Y as l,Z as n,_ as r}from"./main-Cd9NCLQB.js";const t={xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink",viewBox:"0 0 20 20"},o=a({name:"Certificate20Regular",render:function(a,o){return n(),l("svg",t,o[0]||(o[0]=[r("g",{fill:"none"},[r("path",{d:"M2 5a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v3.146a4.508 4.508 0 0 0-1-.678V5a1 1 0 0 0-1-1H4a1 1 0 0 0-1 1v8a1 1 0 0 0 1 1h7.258c.076.113.157.223.242.329V15H4a2 2 0 0 1-2-2V5zm16.5 6.5c0 .954-.381 1.818-1 2.45V18a.5.5 0 0 1-.8.4l-1.4-1.05a.5.5 0 0 0-.6 0l-1.4 1.05a.5.5 0 0 1-.8-.4v-4.05a3.5 3.5 0 1 1 6-2.45zM15 15c-.537 0-1.045-.12-1.5-.337v2.087l1.243-.746a.5.5 0 0 1 .514 0l1.243.746v-2.087A3.486 3.486 0 0 1 15 15zm0-1a2.5 2.5 0 1 0 0-5a2.5 2.5 0 0 0 0 5zM5 6.5a.5.5 0 0 1 .5-.5h9a.5.5 0 0 1 0 1h-9a.5.5 0 0 1-.5-.5zm.5 4.5a.5.5 0 0 0 0 1h4a.5.5 0 0 0 0-1h-4z",fill:"currentColor"})],-1)]))}}),h={xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink",viewBox:"0 0 32 32"},w=a({name:"CloudMonitoring",render:function(a,t){return n(),l("svg",h,t[0]||(t[0]=[r("path",{d:"M28 16v6H4V6h7V4H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h8v4H8v2h16v-2h-4v-4h8a2 2 0 0 0 2-2v-6zM18 28h-4v-4h4z",fill:"currentColor"},null,-1),r("path",{d:"M18 18h-.01a1 1 0 0 1-.951-.725L15.246 11H11V9h5a1 1 0 0 1 .962.725l1.074 3.76l3.009-9.78A1.014 1.014 0 0 1 22 3a.98.98 0 0 1 .949.684L24.72 9H30v2h-6a1 1 0 0 1-.949-.684l-1.013-3.04l-3.082 10.018A1 1 0 0 1 18 18z",fill:"currentColor"},null,-1)]))}}),v={xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink",viewBox:"0 0 32 32"},e=a({name:"Flow",render:function(a,t){return n(),l("svg",v,t[0]||(t[0]=[r("path",{d:"M27 22.14V17a2 2 0 0 0-2-2h-8V9.86a4 4 0 1 0-2 0V15H7a2 2 0 0 0-2 2v5.14a4 4 0 1 0 2 0V17h18v5.14a4 4 0 1 0 2 0zM8 26a2 2 0 1 1-2-2a2 2 0 0 1 2 2zm6-20a2 2 0 1 1 2 2a2 2 0 0 1-2-2zm12 22a2 2 0 1 1 2-2a2 2 0 0 1-2 2z",fill:"currentColor"},null,-1)]))}});export{o as C,e as F,w as a};

View File

@@ -0,0 +1 @@
import{d as a,Y as l,Z as n,_ as r}from"./main-l9ONqWM3.js";const t={xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink",viewBox:"0 0 20 20"},o=a({name:"Certificate20Regular",render:function(a,o){return n(),l("svg",t,o[0]||(o[0]=[r("g",{fill:"none"},[r("path",{d:"M2 5a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v3.146a4.508 4.508 0 0 0-1-.678V5a1 1 0 0 0-1-1H4a1 1 0 0 0-1 1v8a1 1 0 0 0 1 1h7.258c.076.113.157.223.242.329V15H4a2 2 0 0 1-2-2V5zm16.5 6.5c0 .954-.381 1.818-1 2.45V18a.5.5 0 0 1-.8.4l-1.4-1.05a.5.5 0 0 0-.6 0l-1.4 1.05a.5.5 0 0 1-.8-.4v-4.05a3.5 3.5 0 1 1 6-2.45zM15 15c-.537 0-1.045-.12-1.5-.337v2.087l1.243-.746a.5.5 0 0 1 .514 0l1.243.746v-2.087A3.486 3.486 0 0 1 15 15zm0-1a2.5 2.5 0 1 0 0-5a2.5 2.5 0 0 0 0 5zM5 6.5a.5.5 0 0 1 .5-.5h9a.5.5 0 0 1 0 1h-9a.5.5 0 0 1-.5-.5zm.5 4.5a.5.5 0 0 0 0 1h4a.5.5 0 0 0 0-1h-4z",fill:"currentColor"})],-1)]))}}),h={xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink",viewBox:"0 0 32 32"},w=a({name:"CloudMonitoring",render:function(a,t){return n(),l("svg",h,t[0]||(t[0]=[r("path",{d:"M28 16v6H4V6h7V4H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h8v4H8v2h16v-2h-4v-4h8a2 2 0 0 0 2-2v-6zM18 28h-4v-4h4z",fill:"currentColor"},null,-1),r("path",{d:"M18 18h-.01a1 1 0 0 1-.951-.725L15.246 11H11V9h5a1 1 0 0 1 .962.725l1.074 3.76l3.009-9.78A1.014 1.014 0 0 1 22 3a.98.98 0 0 1 .949.684L24.72 9H30v2h-6a1 1 0 0 1-.949-.684l-1.013-3.04l-3.082 10.018A1 1 0 0 1 18 18z",fill:"currentColor"},null,-1)]))}}),v={xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink",viewBox:"0 0 32 32"},e=a({name:"Flow",render:function(a,t){return n(),l("svg",v,t[0]||(t[0]=[r("path",{d:"M27 22.14V17a2 2 0 0 0-2-2h-8V9.86a4 4 0 1 0-2 0V15H7a2 2 0 0 0-2 2v5.14a4 4 0 1 0 2 0V17h18v5.14a4 4 0 1 0 2 0zM8 26a2 2 0 1 1-2-2a2 2 0 0 1 2 2zm6-20a2 2 0 1 1 2 2a2 2 0 0 1-2-2zm12 22a2 2 0 1 1 2-2a2 2 0 0 1-2 2z",fill:"currentColor"},null,-1)]))}});export{o as C,e as F,w as a};

View File

@@ -0,0 +1 @@
import{d as c,Y as n,Z as r,_ as t}from"./main-JC8aq1By.js";const o={xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink",viewBox:"0 0 1024 1024"},s=c({name:"LockOutlined",render:function(c,s){return r(),n("svg",o,s[0]||(s[0]=[t("path",{d:"M832 464h-68V240c0-70.7-57.3-128-128-128H388c-70.7 0-128 57.3-128 128v224h-68c-17.7 0-32 14.3-32 32v384c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V496c0-17.7-14.3-32-32-32zM332 240c0-30.9 25.1-56 56-56h248c30.9 0 56 25.1 56 56v224H332V240zm460 600H232V536h560v304zM484 701v53c0 4.4 3.6 8 8 8h40c4.4 0 8-3.6 8-8v-53a48.01 48.01 0 1 0-56 0z",fill:"currentColor"},null,-1)]))}});export{s as L};

View File

@@ -0,0 +1 @@
import{d as c,Y as n,Z as r,_ as t}from"./main-DPHcWoLq.js";const o={xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink",viewBox:"0 0 1024 1024"},s=c({name:"LockOutlined",render:function(c,s){return r(),n("svg",o,s[0]||(s[0]=[t("path",{d:"M832 464h-68V240c0-70.7-57.3-128-128-128H388c-70.7 0-128 57.3-128 128v224h-68c-17.7 0-32 14.3-32 32v384c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V496c0-17.7-14.3-32-32-32zM332 240c0-30.9 25.1-56 56-56h248c30.9 0 56 25.1 56 56v224H332V240zm460 600H232V536h560v304zM484 701v53c0 4.4 3.6 8 8 8h40c4.4 0 8-3.6 8-8v-53a48.01 48.01 0 1 0-56 0z",fill:"currentColor"},null,-1)]))}});export{s as L};

View File

@@ -0,0 +1 @@
import{d as c,Y as n,Z as r,_ as t}from"./main-BLIIbSTQ.js";const o={xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink",viewBox:"0 0 1024 1024"},s=c({name:"LockOutlined",render:function(c,s){return r(),n("svg",o,s[0]||(s[0]=[t("path",{d:"M832 464h-68V240c0-70.7-57.3-128-128-128H388c-70.7 0-128 57.3-128 128v224h-68c-17.7 0-32 14.3-32 32v384c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V496c0-17.7-14.3-32-32-32zM332 240c0-30.9 25.1-56 56-56h248c30.9 0 56 25.1 56 56v224H332V240zm460 600H232V536h560v304zM484 701v53c0 4.4 3.6 8 8 8h40c4.4 0 8-3.6 8-8v-53a48.01 48.01 0 1 0-56 0z",fill:"currentColor"},null,-1)]))}});export{s as L};

View File

@@ -0,0 +1 @@
import{d as c,Y as n,Z as r,_ as t}from"./main-l9ONqWM3.js";const o={xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink",viewBox:"0 0 1024 1024"},s=c({name:"LockOutlined",render:function(c,s){return r(),n("svg",o,s[0]||(s[0]=[t("path",{d:"M832 464h-68V240c0-70.7-57.3-128-128-128H388c-70.7 0-128 57.3-128 128v224h-68c-17.7 0-32 14.3-32 32v384c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V496c0-17.7-14.3-32-32-32zM332 240c0-30.9 25.1-56 56-56h248c30.9 0 56 25.1 56 56v224H332V240zm460 600H232V536h560v304zM484 701v53c0 4.4 3.6 8 8 8h40c4.4 0 8-3.6 8-8v-53a48.01 48.01 0 1 0-56 0z",fill:"currentColor"},null,-1)]))}});export{s as L};

View File

@@ -0,0 +1 @@
import{d as c,Y as n,Z as r,_ as t}from"./main-Cd9NCLQB.js";const o={xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink",viewBox:"0 0 1024 1024"},s=c({name:"LockOutlined",render:function(c,s){return r(),n("svg",o,s[0]||(s[0]=[t("path",{d:"M832 464h-68V240c0-70.7-57.3-128-128-128H388c-70.7 0-128 57.3-128 128v224h-68c-17.7 0-32 14.3-32 32v384c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V496c0-17.7-14.3-32-32-32zM332 240c0-30.9 25.1-56 56-56h248c30.9 0 56 25.1 56 56v224H332V240zm460 600H232V536h560v304zM484 701v53c0 4.4 3.6 8 8 8h40c4.4 0 8-3.6 8-8v-53a48.01 48.01 0 1 0-56 0z",fill:"currentColor"},null,-1)]))}});export{s as L};

View File

@@ -0,0 +1 @@
import{d as c,Y as n,Z as r,_ as t}from"./main-DzwaUoFb.js";const o={xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink",viewBox:"0 0 1024 1024"},s=c({name:"LockOutlined",render:function(c,s){return r(),n("svg",o,s[0]||(s[0]=[t("path",{d:"M832 464h-68V240c0-70.7-57.3-128-128-128H388c-70.7 0-128 57.3-128 128v224h-68c-17.7 0-32 14.3-32 32v384c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V496c0-17.7-14.3-32-32-32zM332 240c0-30.9 25.1-56 56-56h248c30.9 0 56 25.1 56 56v224H332V240zm460 600H232V536h560v304zM484 701v53c0 4.4 3.6 8 8 8h40c4.4 0 8-3.6 8-8v-53a48.01 48.01 0 1 0-56 0z",fill:"currentColor"},null,-1)]))}});export{s as L};

View File

@@ -0,0 +1 @@
import{d as c,Y as n,Z as r,_ as t}from"./main-D37kYvfP.js";const o={xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink",viewBox:"0 0 1024 1024"},s=c({name:"LockOutlined",render:function(c,s){return r(),n("svg",o,s[0]||(s[0]=[t("path",{d:"M832 464h-68V240c0-70.7-57.3-128-128-128H388c-70.7 0-128 57.3-128 128v224h-68c-17.7 0-32 14.3-32 32v384c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V496c0-17.7-14.3-32-32-32zM332 240c0-30.9 25.1-56 56-56h248c30.9 0 56 25.1 56 56v224H332V240zm460 600H232V536h560v304zM484 701v53c0 4.4 3.6 8 8 8h40c4.4 0 8-3.6 8-8v-53a48.01 48.01 0 1 0-56 0z",fill:"currentColor"},null,-1)]))}});export{s as L};

View File

@@ -0,0 +1 @@
import{d as c,U as n,W as r,X as t}from"./main-TC3Bu45J.js";const o={xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink",viewBox:"0 0 1024 1024"},s=c({name:"LockOutlined",render:function(c,s){return r(),n("svg",o,s[0]||(s[0]=[t("path",{d:"M832 464h-68V240c0-70.7-57.3-128-128-128H388c-70.7 0-128 57.3-128 128v224h-68c-17.7 0-32 14.3-32 32v384c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V496c0-17.7-14.3-32-32-32zM332 240c0-30.9 25.1-56 56-56h248c30.9 0 56 25.1 56 56v224H332V240zm460 600H232V536h560v304zM484 701v53c0 4.4 3.6 8 8 8h40c4.4 0 8-3.6 8-8v-53a48.01 48.01 0 1 0-56 0z",fill:"currentColor"},null,-1)]))}});export{s as L};

View File

@@ -0,0 +1 @@
import{d as c,Y as n,Z as r,_ as t}from"./main-BjWWkfgM.js";const o={xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink",viewBox:"0 0 1024 1024"},s=c({name:"LockOutlined",render:function(c,s){return r(),n("svg",o,s[0]||(s[0]=[t("path",{d:"M832 464h-68V240c0-70.7-57.3-128-128-128H388c-70.7 0-128 57.3-128 128v224h-68c-17.7 0-32 14.3-32 32v384c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V496c0-17.7-14.3-32-32-32zM332 240c0-30.9 25.1-56 56-56h248c30.9 0 56 25.1 56 56v224H332V240zm460 600H232V536h560v304zM484 701v53c0 4.4 3.6 8 8 8h40c4.4 0 8-3.6 8-8v-53a48.01 48.01 0 1 0-56 0z",fill:"currentColor"},null,-1)]))}});export{s as L};

View File

@@ -0,0 +1 @@
import{d as c,Y as a,Z as n,_ as o}from"./main-DzwaUoFb.js";const r={xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink",viewBox:"0 0 512 512"},t=c({name:"LogoGithub",render:function(c,t){return n(),a("svg",r,t[0]||(t[0]=[o("path",{d:"M256 32C132.3 32 32 134.9 32 261.7c0 101.5 64.2 187.5 153.2 217.9a17.56 17.56 0 0 0 3.8.4c8.3 0 11.5-6.1 11.5-11.4c0-5.5-.2-19.9-.3-39.1a102.4 102.4 0 0 1-22.6 2.7c-43.1 0-52.9-33.5-52.9-33.5c-10.2-26.5-24.9-33.6-24.9-33.6c-19.5-13.7-.1-14.1 1.4-14.1h.1c22.5 2 34.3 23.8 34.3 23.8c11.2 19.6 26.2 25.1 39.6 25.1a63 63 0 0 0 25.6-6c2-14.8 7.8-24.9 14.2-30.7c-49.7-5.8-102-25.5-102-113.5c0-25.1 8.7-45.6 23-61.6c-2.3-5.8-10-29.2 2.2-60.8a18.64 18.64 0 0 1 5-.5c8.1 0 26.4 3.1 56.6 24.1a208.21 208.21 0 0 1 112.2 0c30.2-21 48.5-24.1 56.6-24.1a18.64 18.64 0 0 1 5 .5c12.2 31.6 4.5 55 2.2 60.8c14.3 16.1 23 36.6 23 61.6c0 88.2-52.4 107.6-102.3 113.3c8 7.1 15.2 21.1 15.2 42.5c0 30.7-.3 55.5-.3 63c0 5.4 3.1 11.5 11.4 11.5a19.35 19.35 0 0 0 4-.4C415.9 449.2 480 363.1 480 261.7C480 134.9 379.7 32 256 32z",fill:"currentColor"},null,-1)]))}});export{t as L};

View File

@@ -0,0 +1 @@
import{d as c,Y as a,Z as n,_ as o}from"./main-JC8aq1By.js";const r={xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink",viewBox:"0 0 512 512"},t=c({name:"LogoGithub",render:function(c,t){return n(),a("svg",r,t[0]||(t[0]=[o("path",{d:"M256 32C132.3 32 32 134.9 32 261.7c0 101.5 64.2 187.5 153.2 217.9a17.56 17.56 0 0 0 3.8.4c8.3 0 11.5-6.1 11.5-11.4c0-5.5-.2-19.9-.3-39.1a102.4 102.4 0 0 1-22.6 2.7c-43.1 0-52.9-33.5-52.9-33.5c-10.2-26.5-24.9-33.6-24.9-33.6c-19.5-13.7-.1-14.1 1.4-14.1h.1c22.5 2 34.3 23.8 34.3 23.8c11.2 19.6 26.2 25.1 39.6 25.1a63 63 0 0 0 25.6-6c2-14.8 7.8-24.9 14.2-30.7c-49.7-5.8-102-25.5-102-113.5c0-25.1 8.7-45.6 23-61.6c-2.3-5.8-10-29.2 2.2-60.8a18.64 18.64 0 0 1 5-.5c8.1 0 26.4 3.1 56.6 24.1a208.21 208.21 0 0 1 112.2 0c30.2-21 48.5-24.1 56.6-24.1a18.64 18.64 0 0 1 5 .5c12.2 31.6 4.5 55 2.2 60.8c14.3 16.1 23 36.6 23 61.6c0 88.2-52.4 107.6-102.3 113.3c8 7.1 15.2 21.1 15.2 42.5c0 30.7-.3 55.5-.3 63c0 5.4 3.1 11.5 11.4 11.5a19.35 19.35 0 0 0 4-.4C415.9 449.2 480 363.1 480 261.7C480 134.9 379.7 32 256 32z",fill:"currentColor"},null,-1)]))}});export{t as L};

View File

@@ -0,0 +1 @@
import{d as c,Y as a,Z as n,_ as o}from"./main-D37kYvfP.js";const r={xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink",viewBox:"0 0 512 512"},t=c({name:"LogoGithub",render:function(c,t){return n(),a("svg",r,t[0]||(t[0]=[o("path",{d:"M256 32C132.3 32 32 134.9 32 261.7c0 101.5 64.2 187.5 153.2 217.9a17.56 17.56 0 0 0 3.8.4c8.3 0 11.5-6.1 11.5-11.4c0-5.5-.2-19.9-.3-39.1a102.4 102.4 0 0 1-22.6 2.7c-43.1 0-52.9-33.5-52.9-33.5c-10.2-26.5-24.9-33.6-24.9-33.6c-19.5-13.7-.1-14.1 1.4-14.1h.1c22.5 2 34.3 23.8 34.3 23.8c11.2 19.6 26.2 25.1 39.6 25.1a63 63 0 0 0 25.6-6c2-14.8 7.8-24.9 14.2-30.7c-49.7-5.8-102-25.5-102-113.5c0-25.1 8.7-45.6 23-61.6c-2.3-5.8-10-29.2 2.2-60.8a18.64 18.64 0 0 1 5-.5c8.1 0 26.4 3.1 56.6 24.1a208.21 208.21 0 0 1 112.2 0c30.2-21 48.5-24.1 56.6-24.1a18.64 18.64 0 0 1 5 .5c12.2 31.6 4.5 55 2.2 60.8c14.3 16.1 23 36.6 23 61.6c0 88.2-52.4 107.6-102.3 113.3c8 7.1 15.2 21.1 15.2 42.5c0 30.7-.3 55.5-.3 63c0 5.4 3.1 11.5 11.4 11.5a19.35 19.35 0 0 0 4-.4C415.9 449.2 480 363.1 480 261.7C480 134.9 379.7 32 256 32z",fill:"currentColor"},null,-1)]))}});export{t as L};

View File

@@ -0,0 +1 @@
import{d as c,Y as a,Z as n,_ as o}from"./main-BjWWkfgM.js";const r={xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink",viewBox:"0 0 512 512"},t=c({name:"LogoGithub",render:function(c,t){return n(),a("svg",r,t[0]||(t[0]=[o("path",{d:"M256 32C132.3 32 32 134.9 32 261.7c0 101.5 64.2 187.5 153.2 217.9a17.56 17.56 0 0 0 3.8.4c8.3 0 11.5-6.1 11.5-11.4c0-5.5-.2-19.9-.3-39.1a102.4 102.4 0 0 1-22.6 2.7c-43.1 0-52.9-33.5-52.9-33.5c-10.2-26.5-24.9-33.6-24.9-33.6c-19.5-13.7-.1-14.1 1.4-14.1h.1c22.5 2 34.3 23.8 34.3 23.8c11.2 19.6 26.2 25.1 39.6 25.1a63 63 0 0 0 25.6-6c2-14.8 7.8-24.9 14.2-30.7c-49.7-5.8-102-25.5-102-113.5c0-25.1 8.7-45.6 23-61.6c-2.3-5.8-10-29.2 2.2-60.8a18.64 18.64 0 0 1 5-.5c8.1 0 26.4 3.1 56.6 24.1a208.21 208.21 0 0 1 112.2 0c30.2-21 48.5-24.1 56.6-24.1a18.64 18.64 0 0 1 5 .5c12.2 31.6 4.5 55 2.2 60.8c14.3 16.1 23 36.6 23 61.6c0 88.2-52.4 107.6-102.3 113.3c8 7.1 15.2 21.1 15.2 42.5c0 30.7-.3 55.5-.3 63c0 5.4 3.1 11.5 11.4 11.5a19.35 19.35 0 0 0 4-.4C415.9 449.2 480 363.1 480 261.7C480 134.9 379.7 32 256 32z",fill:"currentColor"},null,-1)]))}});export{t as L};

View File

@@ -0,0 +1 @@
import{d as c,Y as a,Z as n,_ as o}from"./main-BLIIbSTQ.js";const r={xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink",viewBox:"0 0 512 512"},t=c({name:"LogoGithub",render:function(c,t){return n(),a("svg",r,t[0]||(t[0]=[o("path",{d:"M256 32C132.3 32 32 134.9 32 261.7c0 101.5 64.2 187.5 153.2 217.9a17.56 17.56 0 0 0 3.8.4c8.3 0 11.5-6.1 11.5-11.4c0-5.5-.2-19.9-.3-39.1a102.4 102.4 0 0 1-22.6 2.7c-43.1 0-52.9-33.5-52.9-33.5c-10.2-26.5-24.9-33.6-24.9-33.6c-19.5-13.7-.1-14.1 1.4-14.1h.1c22.5 2 34.3 23.8 34.3 23.8c11.2 19.6 26.2 25.1 39.6 25.1a63 63 0 0 0 25.6-6c2-14.8 7.8-24.9 14.2-30.7c-49.7-5.8-102-25.5-102-113.5c0-25.1 8.7-45.6 23-61.6c-2.3-5.8-10-29.2 2.2-60.8a18.64 18.64 0 0 1 5-.5c8.1 0 26.4 3.1 56.6 24.1a208.21 208.21 0 0 1 112.2 0c30.2-21 48.5-24.1 56.6-24.1a18.64 18.64 0 0 1 5 .5c12.2 31.6 4.5 55 2.2 60.8c14.3 16.1 23 36.6 23 61.6c0 88.2-52.4 107.6-102.3 113.3c8 7.1 15.2 21.1 15.2 42.5c0 30.7-.3 55.5-.3 63c0 5.4 3.1 11.5 11.4 11.5a19.35 19.35 0 0 0 4-.4C415.9 449.2 480 363.1 480 261.7C480 134.9 379.7 32 256 32z",fill:"currentColor"},null,-1)]))}});export{t as L};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
import{c as s}from"./index-CyQKn_q4.js";const a=a=>s("/v1/access/get_list",a),c=a=>s("/v1/access/add_access",a),e=a=>s("/v1/access/upd_access",a),t=a=>s("/v1/access/del_access",a),_=a=>s("/v1/access/get_all",a),v=a=>s("/v1/access/get_eab_list",a),d=a=>s("/v1/access/add_eab",a),l=a=>s("/v1/access/del_eab",a),g=a=>s("/v1/access/get_all_eab",a),i=a=>s("/v1/access/test_access",a),b=a=>s("/v1/access/get_sites",a);export{c as a,v as b,d as c,t as d,l as e,g as f,a as g,b as h,_ as i,i as t,e as u};

View File

@@ -0,0 +1 @@
import{c as s}from"./index-CCRs72lf.js";const a=a=>s("/v1/access/get_list",a),c=a=>s("/v1/access/add_access",a),e=a=>s("/v1/access/upd_access",a),t=a=>s("/v1/access/del_access",a),_=a=>s("/v1/access/get_all",a),v=a=>s("/v1/access/get_eab_list",a),d=a=>s("/v1/access/add_eab",a),l=a=>s("/v1/access/del_eab",a),g=a=>s("/v1/access/get_all_eab",a),i=a=>s("/v1/access/test_access",a),b=a=>s("/v1/access/get_sites",a);export{c as a,v as b,d as c,t as d,l as e,g as f,a as g,b as h,_ as i,i as t,e as u};

View File

@@ -0,0 +1 @@
import{c as s}from"./index-B19cVdYt.js";const a=a=>s("/v1/access/get_list",a),c=a=>s("/v1/access/add_access",a),e=a=>s("/v1/access/upd_access",a),t=a=>s("/v1/access/del_access",a),_=a=>s("/v1/access/get_all",a),v=a=>s("/v1/access/get_eab_list",a),d=a=>s("/v1/access/add_eab",a),l=a=>s("/v1/access/del_eab",a),g=a=>s("/v1/access/get_all_eab",a),i=a=>s("/v1/access/test_access",a),b=a=>s("/v1/access/get_sites",a);export{c as a,v as b,d as c,t as d,l as e,g as f,a as g,b as h,_ as i,i as t,e as u};

View File

@@ -0,0 +1 @@
import{c as s}from"./index-jviZh_iP.js";const a=a=>s("/v1/access/get_list",a),c=a=>s("/v1/access/add_access",a),e=a=>s("/v1/access/upd_access",a),t=a=>s("/v1/access/del_access",a),_=a=>s("/v1/access/get_all",a),v=a=>s("/v1/access/get_eab_list",a),d=a=>s("/v1/access/add_eab",a),l=a=>s("/v1/access/del_eab",a),g=a=>s("/v1/access/get_all_eab",a),i=a=>s("/v1/access/test_access",a),b=a=>s("/v1/access/get_sites",a);export{c as a,v as b,d as c,t as d,l as e,g as f,a as g,b as h,_ as i,i as t,e as u};

View File

@@ -0,0 +1 @@
import{c as s}from"./index-BpNpm-gE.js";const a=a=>s("/v1/access/get_list",a),c=a=>s("/v1/access/add_access",a),e=a=>s("/v1/access/upd_access",a),t=a=>s("/v1/access/del_access",a),_=a=>s("/v1/access/get_all",a),v=a=>s("/v1/access/get_eab_list",a),d=a=>s("/v1/access/add_eab",a),l=a=>s("/v1/access/del_eab",a),g=a=>s("/v1/access/get_all_eab",a),i=a=>s("/v1/access/test_access",a),b=a=>s("/v1/access/get_sites",a);export{c as a,v as b,d as c,t as d,l as e,g as f,a as g,b as h,_ as i,i as t,e as u};

View File

@@ -0,0 +1 @@
import{c}from"./index-BNb4DSrN.js";const s=s=>c("/v1/access/get_list",s),a=s=>c("/v1/access/add_access",s),e=s=>c("/v1/access/upd_access",s),t=s=>c("/v1/access/del_access",s),_=s=>c("/v1/access/get_all",s),v=s=>c("/v1/acme_account/get_list",s),o=s=>c("/v1/acme_account/add_account",s),u=s=>c("/v1/acme_account/upd_account",s),d=s=>c("/v1/acme_account/del_account",s),n=s=>c("/v1/access/test_access",s),g=s=>c("/v1/access/get_sites",s),i=()=>c("/v1/access/get_plugins");export{a,i as b,v as c,t as d,o as e,u as f,s as g,d as h,g as i,_ as j,n as t,e as u};

View File

@@ -0,0 +1 @@
import{c as s}from"./index-DuE5FJUK.js";const a=a=>s("/v1/access/get_list",a),c=a=>s("/v1/access/add_access",a),e=a=>s("/v1/access/upd_access",a),t=a=>s("/v1/access/del_access",a),_=a=>s("/v1/access/get_all",a),v=a=>s("/v1/access/get_eab_list",a),d=a=>s("/v1/access/add_eab",a),l=a=>s("/v1/access/del_eab",a),g=a=>s("/v1/access/get_all_eab",a),i=a=>s("/v1/access/test_access",a),b=a=>s("/v1/access/get_sites",a);export{c as a,v as b,d as c,t as d,l as e,g as f,a as g,b as h,_ as i,i as t,e as u};

View File

@@ -0,0 +1 @@
import{c as s}from"./index-CROykHUI.js";const a=a=>s("/v1/access/get_list",a),c=a=>s("/v1/access/add_access",a),e=a=>s("/v1/access/upd_access",a),t=a=>s("/v1/access/del_access",a),_=a=>s("/v1/access/get_all",a),v=a=>s("/v1/access/get_eab_list",a),d=a=>s("/v1/access/add_eab",a),l=a=>s("/v1/access/del_eab",a),g=a=>s("/v1/access/get_all_eab",a),i=a=>s("/v1/access/test_access",a),b=a=>s("/v1/access/get_sites",a);export{c as a,v as b,d as c,t as d,l as e,g as f,a as g,b as h,_ as i,i as t,e as u};

View File

@@ -0,0 +1 @@
import{c as s}from"./index-DaWzl1ur.js";const a=a=>s("/v1/access/get_list",a),c=a=>s("/v1/access/add_access",a),e=a=>s("/v1/access/upd_access",a),t=a=>s("/v1/access/del_access",a),_=a=>s("/v1/access/get_all",a),v=a=>s("/v1/access/get_eab_list",a),d=a=>s("/v1/access/add_eab",a),l=a=>s("/v1/access/del_eab",a),g=a=>s("/v1/access/get_all_eab",a),i=a=>s("/v1/access/test_access",a),b=a=>s("/v1/access/get_sites",a);export{c as a,v as b,d as c,t as d,l as e,g as f,a as g,b as h,_ as i,i as t,e as u};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Some files were not shown because too many files have changed in this diff Show More