更改目录结构
This commit is contained in:
1 parent
be6b954dba
commit
68415a3061
20 files changed
+116
-15
No files matched your search
@@ -0,0 +1,75 @@
|
||||
package cameraFunc
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/jlaffaye/ftp"
|
||||
)
|
||||
|
||||
//连接到相机 FTP 服务器,下载文件
|
||||
func DownLoadCameraJpgByFtp(id,deviceId string,fileType string) error {
|
||||
ip := "192.168.88."+deviceId+":21"
|
||||
// 连接到 FTP 服务器
|
||||
c, err := ftp.Dial(ip) // 替换为你的 FTP 服务器地址
|
||||
if err != nil {
|
||||
g.Dump("ftp.Dial(ip) error:",err)
|
||||
return err
|
||||
}
|
||||
defer c.Quit()
|
||||
// 登录到 FTP 服务器
|
||||
err = c.Login("icatch", "icatch") // 替换为你的用户名和密码
|
||||
if err != nil {
|
||||
g.Dump("c.Login error:",err)
|
||||
return err
|
||||
}
|
||||
//现在本地创建文件夹和文件
|
||||
fileName := id+"_"+deviceId+"_"+fileType+".jpg"
|
||||
file,err := IsExistDirAndFileForCreate(id,fileName)
|
||||
if err != nil {
|
||||
defer file.Close()
|
||||
g.Dump("IsExistDirAndFileForCreate error:",err)
|
||||
return err
|
||||
}
|
||||
// 从 FTP 服务器获取文件
|
||||
r,err := c.Retr("jpg/"+fileName) // 远程文件名
|
||||
if err != nil {
|
||||
g.Dump("c.Retr error:",err)
|
||||
return err
|
||||
}
|
||||
defer file.Close()
|
||||
defer r.Close()
|
||||
_, err = io.Copy(file, r)
|
||||
if err != nil {
|
||||
g.Dump("io.Copy error:",err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
//判断当前根目录是否存在指定的文件夹和文件夹下的文件,没有则创建
|
||||
func IsExistDirAndFileForCreate(id string,fileName string) (file *os.File,err error) {
|
||||
// 指定的目录和文件名
|
||||
dirPath := "downloads_new/"+id // 目标文件夹
|
||||
//fileName := "myfile.txt" // 目标文件
|
||||
// 检查目录是否存在
|
||||
if _, err := os.Stat(dirPath); os.IsNotExist(err) {
|
||||
// 目录不存在,创建目录
|
||||
err := os.MkdirAll(dirPath, os.ModePerm)
|
||||
if err != nil {
|
||||
return nil,err
|
||||
}
|
||||
}
|
||||
// 检查文件是否存在
|
||||
filePath := filepath.Join(dirPath, fileName)
|
||||
// 文件不存在,创建文件
|
||||
file, err = os.Create(filePath)
|
||||
if err != nil {
|
||||
return nil,err
|
||||
}
|
||||
// 关闭文件
|
||||
return file,nil
|
||||
}
|
||||
@@ -0,0 +1,220 @@
|
||||
package db
|
||||
|
||||
import (
|
||||
"changeme/internal/model"
|
||||
"database/sql"
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
_ "github.com/mattn/go-sqlite3"
|
||||
)
|
||||
|
||||
// DB 结构体
|
||||
type DB struct {
|
||||
*sql.DB
|
||||
}
|
||||
|
||||
var (
|
||||
instance *DB
|
||||
once sync.Once
|
||||
)
|
||||
var TableName = "photo_studio_shoot_order"
|
||||
// GetInstance 返回数据库单例实例
|
||||
func GetInstance() *DB {
|
||||
once.Do(func() {
|
||||
db, err := sql.Open("sqlite3", "test.db")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
instance = &DB{db}
|
||||
//检测表是否存在
|
||||
checkTableSQL := `SELECT count(*) FROM sqlite_master WHERE type='table' AND name='`+TableName+`';`
|
||||
var count int
|
||||
if err := instance.QueryRow(checkTableSQL).Scan(&count); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if count > 0 {
|
||||
return
|
||||
}
|
||||
// 创建表
|
||||
createTableSQL := `CREATE TABLE "`+TableName+`" (
|
||||
"id" INTEGER NOT NULL,
|
||||
"pid" INTEGER NOT NULL,
|
||||
"customer_id" INTEGER NOT NULL,
|
||||
"customer_name" TEXT NOT NULL,
|
||||
"status" INTEGER NOT NULL,
|
||||
"order_id" INTEGER NOT NULL,
|
||||
"digital_order_id" INTEGER NOT NULL,
|
||||
"digital_type" INTEGER NOT NULL,
|
||||
"cover_path" TEXT NOT NULL,
|
||||
"cover_rotate_deg" INTEGER NOT NULL,
|
||||
"shoot_at_count" INTEGER NOT NULL,
|
||||
"shoot_done_count" INTEGER NOT NULL,
|
||||
"upload_cover_count" INTEGER NOT NULL,
|
||||
"upload_highmode_count" INTEGER NOT NULL,
|
||||
"upload_yuv_count" INTEGER NOT NULL,
|
||||
"first_shoot_at" DATETIME NULL,
|
||||
"first_shoot_done_at" DATETIME NULL,
|
||||
"last_shoot_at" DATETIME NULL,
|
||||
"last_shoot_done_at" DATETIME NULL,
|
||||
"check_status" INTEGER NOT NULL,
|
||||
"check_fail_reason" TEXT NOT NULL,
|
||||
"check_at" DATETIME NULL,
|
||||
"shop_id" INTEGER NOT NULL,
|
||||
"eq_id" INTEGER NOT NULL,
|
||||
"master_ver" TEXT NOT NULL,
|
||||
"eq_type" INTEGER NOT NULL,
|
||||
"created_at" DATETIME NULL,
|
||||
"upload_done_at" DATETIME NULL,
|
||||
"minipreview_upload_done_at" DATETIME NULL,
|
||||
"updated_at" DATETIME NULL,
|
||||
"is_privary" INTEGER NOT NULL,
|
||||
"cancel_at" DATETIME NULL,
|
||||
PRIMARY KEY ("id")
|
||||
);`
|
||||
if _, err = instance.Exec(createTableSQL); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
})
|
||||
return instance
|
||||
}
|
||||
|
||||
|
||||
//Add 新增数据
|
||||
func (db *DB) Add(addData *model.AddData) error {
|
||||
v := reflect.ValueOf(addData)
|
||||
// 确保传入的参数是指向结构体的指针
|
||||
if v.Kind() != reflect.Ptr || v.Elem().Kind() != reflect.Struct {
|
||||
return errors.New("invalid input")
|
||||
}
|
||||
// 获取结构体的类型和字段
|
||||
t := v.Elem().Type()
|
||||
fields := []string{}
|
||||
placeholders := []string{}
|
||||
values := []interface{}{}
|
||||
|
||||
for i := 0; i < v.Elem().NumField(); i++ {
|
||||
field := t.Field(i)
|
||||
value := v.Elem().Field(i)
|
||||
// 使用 db 标签作为字段名
|
||||
dbTag := field.Tag.Get("json")
|
||||
fields = append(fields, dbTag)
|
||||
placeholders = append(placeholders, "?")
|
||||
values = append(values, value.Interface())
|
||||
}
|
||||
// 生成 SQL 语句
|
||||
sqlStatement := fmt.Sprintf("INSERT INTO %s (%s) VALUES (%s)",
|
||||
TableName,
|
||||
strings.Join(fields, ", "),
|
||||
strings.Join(placeholders, ", "))
|
||||
// 执行 SQL 语句
|
||||
_, err := db.Exec(sqlStatement, values...)
|
||||
return err
|
||||
}
|
||||
|
||||
//根据查询列表数据
|
||||
// List 方法
|
||||
func (db *DB) List(req *model.PageReqData) (list []*model.Data, err error) {
|
||||
// 基本的 SQL 查询语句
|
||||
query := "SELECT cover_path,pid,customer_name FROM "+TableName+" WHERE 1=1"
|
||||
var args []interface{}
|
||||
|
||||
// 根据请求参数动态构建查询条件
|
||||
if req.Pid > 0 {
|
||||
query += " AND pid = ?"
|
||||
args = append(args, req.Pid)
|
||||
}
|
||||
if req.CustomerId > 0 {
|
||||
query += " AND customer_id = ?"
|
||||
args = append(args, req.CustomerId)
|
||||
}
|
||||
if req.CustomerName != "" {
|
||||
query += " AND customer_name LIKE ?"
|
||||
args = append(args, "%"+req.CustomerName+"%")
|
||||
}
|
||||
if req.Status > 0 {
|
||||
query += " AND status = ?"
|
||||
args = append(args, req.Status)
|
||||
}
|
||||
|
||||
// 添加分页条件
|
||||
if req.Page <= 0 {
|
||||
req.Page = 1
|
||||
}
|
||||
if req.Size <= 0 {
|
||||
req.Size = 20
|
||||
}
|
||||
offset := (req.Page - 1) * req.Size
|
||||
query += fmt.Sprintf(" LIMIT %d OFFSET %d", req.Size, offset)
|
||||
// 执行查询
|
||||
rows, err := db.Query(query, args...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
// 读取查询结果
|
||||
for rows.Next() {
|
||||
var addData model.Data
|
||||
if err := rows.Scan(&addData.CoverPath, &addData.Pid, &addData.CustomerName); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
list = append(list, &addData)
|
||||
}
|
||||
return list, nil
|
||||
}
|
||||
|
||||
func (db *DB) Delete(req *model.DeleteReqData) (err error) {
|
||||
if req.Pid == 0 && req.Id == 0 {
|
||||
return errors.New("参数不能为空")
|
||||
}
|
||||
query := "DELETE FROM "+TableName+" WHERE 1=1"
|
||||
var args []interface{}
|
||||
if req.Pid > 0 {
|
||||
query += " AND pid = ?"
|
||||
args = append(args, req.Pid)
|
||||
}
|
||||
if req.Id > 0 {
|
||||
query += " AND id = ?"
|
||||
args = append(args, req.Id)
|
||||
}
|
||||
_, err = db.Exec(query, args...)
|
||||
return err
|
||||
}
|
||||
|
||||
func (db *DB) Update(addData *model.Data) error {
|
||||
v := reflect.ValueOf(addData)
|
||||
// 确保传入的参数是指向结构体的指针
|
||||
if v.Kind() != reflect.Ptr || v.Elem().Kind() != reflect.Struct {
|
||||
return errors.New("invalid input")
|
||||
}
|
||||
|
||||
// 获取结构体的类型和字段
|
||||
t := v.Elem().Type()
|
||||
fields := []string{}
|
||||
values := []interface{}{}
|
||||
|
||||
for i := 0; i < v.Elem().NumField(); i++ {
|
||||
field := t.Field(i)
|
||||
value := v.Elem().Field(i)
|
||||
// 使用 db 标签作为字段名
|
||||
dbTag := field.Tag.Get("json")
|
||||
if gconv.String(value.Interface()) != "" && gconv.String(value.Interface()) != "0" && dbTag != "id" {
|
||||
fields = append(fields, fmt.Sprintf("%s = ?", dbTag))
|
||||
values = append(values, value.Interface())
|
||||
}
|
||||
}
|
||||
// 生成 Update SQL 语句
|
||||
sqlStatement := fmt.Sprintf("UPDATE %s SET %s WHERE id = %s",
|
||||
TableName,
|
||||
strings.Join(fields, ", "),
|
||||
gconv.String(addData.Id),
|
||||
)
|
||||
// 执行 SQL 语句
|
||||
_, err := db.Exec(sqlStatement, values...)
|
||||
return err
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package initFunc
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"time"
|
||||
)
|
||||
|
||||
//设备自检
|
||||
|
||||
//1.检测网络是否正常,如果不正常,提示用户检查主控箱电源是否跳闸 宽带是否欠费 网络接线是否有问题
|
||||
func CheckNetwork() error {
|
||||
err := pingNet("www.baidu.com")
|
||||
return err
|
||||
}
|
||||
|
||||
//2 检测路由器 192.168.881 检测主机 192.168.88.2 检测监控 192.168.88.7 检测AP 192.168.88.9 检测开关路由器 192.168.88.8 检测速哇服务器 mp.suwa3d.com
|
||||
func CheckDevice() map[string]string {
|
||||
arrIpDevices := map[string]string{
|
||||
"路由器":"192.168.88.1",
|
||||
"主机":"192.168.8.2",
|
||||
"AP":"192.168.88.9",
|
||||
"开关路由器":"192.168.88.8",
|
||||
"速哇服务器":"mp.suwa3d.com",
|
||||
"监控":"192.168.88.7",
|
||||
}
|
||||
errIpDevices := map[string]string{}
|
||||
for k,v := range arrIpDevices {
|
||||
err := pingNet(v)
|
||||
if err != nil {
|
||||
errIpDevices[k] = v
|
||||
}
|
||||
}
|
||||
return errIpDevices
|
||||
}
|
||||
|
||||
//ping ip的方法
|
||||
func pingNet(ip string) error {
|
||||
ipInfo := net.ParseIP(ip)
|
||||
if ipInfo == nil {
|
||||
return errors.New("IP信息有误")
|
||||
}
|
||||
// 创建 TCP 连接
|
||||
conn, err := net.DialTimeout("tcp", fmt.Sprintf("%s:80", ipInfo), time.Second*1)
|
||||
if err != nil {
|
||||
return errors.New("连接失败-"+err.Error())
|
||||
}
|
||||
defer conn.Close()
|
||||
// ping 成功
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
package initFunc
|
||||
|
||||
//检测是否有更新服务程序内容,重新下载安装
|
||||
@@ -0,0 +1,64 @@
|
||||
package initFunc
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/exec"
|
||||
)
|
||||
|
||||
//检查是否安装WebView2,没有安装的话就安装
|
||||
func CheckWebView2() error {
|
||||
cmd := exec.Command("cmd", "/C", "wmic product where \"name='Microsoft Edge WebView2 Runtime'\" get Name")
|
||||
output, err := cmd.Output()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// 检查输出是否包含 WebView2 Runtime 的名称
|
||||
if string(output) == "Name\r\nMicrosoft Edge WebView2 Runtime\r\n" {
|
||||
return nil // WebView2 已安装
|
||||
} else {
|
||||
err := runWebView2Installer()
|
||||
return err // WebView2 未安装
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func runWebView2Installer() error {
|
||||
url := "https://suwa3d-website.oss-cn-shanghai.aliyuncs.com/package/WebView2.exe"
|
||||
filePath := "C:\\Program Files\\WebView2.exe"
|
||||
err := downloadFile(url, filePath)
|
||||
if err != nil {
|
||||
return errors.New("下载安装包失败-"+err.Error()) //fmt.Println("Download failed:", err)
|
||||
}
|
||||
cmd := exec.Command(filePath)
|
||||
err = cmd.Run()
|
||||
if err != nil {
|
||||
return errors.New("安装包安装失败-"+err.Error())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
|
||||
func downloadFile(url string, filePath string) error {
|
||||
response, err := http.Get(url)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer response.Body.Close()
|
||||
|
||||
file, err := os.Create(filePath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
_, err = io.Copy(file, response.Body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
package initFunc
|
||||
|
||||
import (
|
||||
"crypto/x509"
|
||||
"encoding/pem"
|
||||
"fmt"
|
||||
"os"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
X509_ASN_ENCODING = 0x00000001
|
||||
PKCS_7_ASN_ENCODING = 0x00010000
|
||||
CERT_STORE_ADD_REPLACE_EXISTING = 3
|
||||
)
|
||||
|
||||
var (
|
||||
modcrypt32 = syscall.NewLazyDLL("crypt32.dll")
|
||||
procCertOpenSystemStore = modcrypt32.NewProc("CertOpenSystemStoreW")
|
||||
procCertEnumCertificatesInStore = modcrypt32.NewProc("CertEnumCertificatesInStore")
|
||||
procCertGetNameString = modcrypt32.NewProc("CertGetNameStringW")
|
||||
procCertCloseStore = modcrypt32.NewProc("CertCloseStore")
|
||||
)
|
||||
// 安装信任证书
|
||||
func SetupCert() {
|
||||
CheckCertIsInstalled()
|
||||
|
||||
//获取证书路径
|
||||
dir, _ := os.Getwd()
|
||||
certPath := dir+"/rootCA.crt" // 替换为您的证书路径
|
||||
|
||||
if CheckCertIsInstalled() == "yes"{
|
||||
return
|
||||
}
|
||||
// 读取证书文件
|
||||
certFile, err := os.ReadFile(certPath)
|
||||
if err != nil {
|
||||
fmt.Println("无法读取证书文件:", err)
|
||||
return
|
||||
}
|
||||
|
||||
// 解码 PEM 编码的证书
|
||||
block, _ := pem.Decode(certFile)
|
||||
if block == nil {
|
||||
fmt.Println("无法解码 PEM 格式的证书")
|
||||
return
|
||||
}
|
||||
|
||||
// 解析证书
|
||||
cert, err := x509.ParseCertificate(block.Bytes)
|
||||
if err != nil {
|
||||
fmt.Println("无法解析证书:", err)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
// 打开证书存储
|
||||
storeHandle, err := syscall.CertOpenSystemStore(0, syscall.StringToUTF16Ptr("ROOT"))
|
||||
|
||||
if err != nil {
|
||||
fmt.Println("无法打开证书存储:", err)
|
||||
return
|
||||
}
|
||||
defer syscall.CertCloseStore(storeHandle, 0)
|
||||
|
||||
// 将证书添加到存储中
|
||||
err = addCertificateToStore(cert.Raw, storeHandle)
|
||||
if err != nil {
|
||||
fmt.Println("无法将证书添加到存储中:", err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println("证书已成功导入到受信任的根证书颁发机构")
|
||||
}
|
||||
|
||||
func addCertificateToStore(cert []byte, storeHandle syscall.Handle) error {
|
||||
certContext, err := syscall.CertCreateCertificateContext(X509_ASN_ENCODING|PKCS_7_ASN_ENCODING, &cert[0], uint32(len(cert)))
|
||||
if err != nil {
|
||||
return fmt.Errorf("无法创建证书上下文: %v", err)
|
||||
}
|
||||
defer syscall.CertFreeCertificateContext(certContext)
|
||||
|
||||
err = syscall.CertAddCertificateContextToStore(storeHandle, certContext, CERT_STORE_ADD_REPLACE_EXISTING, nil)
|
||||
if err != nil {
|
||||
return fmt.Errorf("无法将证书上下文添加到存储中: %v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
//检测证书是否已经安装了
|
||||
func CheckCertIsInstalled() string {
|
||||
storeName := "Root" // 证书存储名称,这里使用了 "MY" 表示个人证书存储
|
||||
|
||||
storeHandle, _, _ := procCertOpenSystemStore.Call(0, uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(storeName))))
|
||||
if storeHandle == 0 {
|
||||
fmt.Println("Error opening certificate store")
|
||||
return "error"
|
||||
}
|
||||
defer procCertCloseStore.Call(storeHandle, 0)
|
||||
|
||||
var pCertContext uintptr
|
||||
for {
|
||||
pCertContext, _, _ = procCertEnumCertificatesInStore.Call(storeHandle, pCertContext)
|
||||
if pCertContext == 0 {
|
||||
break
|
||||
}
|
||||
res := printCertificateInfo(pCertContext) // 输出证书信息
|
||||
if res == "yes"{
|
||||
return res
|
||||
}
|
||||
}
|
||||
return "no"
|
||||
}
|
||||
//获取证书的信息
|
||||
func printCertificateInfo(pCertContext uintptr) string {
|
||||
var buffer [200]uint16
|
||||
size, _, _ := procCertGetNameString.Call(pCertContext, 5, 0, 0, uintptr(unsafe.Pointer(&buffer)), 200)
|
||||
issuer := syscall.UTF16ToString(buffer[:size])
|
||||
fmt.Println("Certificate Issuer:", issuer)
|
||||
if issuer == "SX"{
|
||||
return "yes"
|
||||
}
|
||||
return "no"
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package initFunc
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"syscall"
|
||||
"time"
|
||||
)
|
||||
|
||||
// 执行exe 文件,开启视频监控的服务进程
|
||||
func RunPiServerExe() {
|
||||
// 获取当前目录
|
||||
dir, _ := os.Getwd()
|
||||
applicationPath := dir + "/piVideo"
|
||||
// //切换到目录
|
||||
os.Chdir(applicationPath)
|
||||
//执行exe的路径
|
||||
exePath := dir + "/piVideo/piVideo.exe"
|
||||
fmt.Println("piVide 可执行路径:", exePath)
|
||||
killPiServerExe("piVideo.exe") //杀 piVideo 进程
|
||||
killPiServerExe("RTSPtoWeb.exe") //杀 RRTSPtoWeb 进程
|
||||
time.Sleep(3 * time.Second)
|
||||
cmd := exec.Command(exePath) // 替换为您的可执行文件路径
|
||||
// os.Chdir("piVideo")
|
||||
output, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
fmt.Println("执行失败", err.Error(), string(output))
|
||||
} else {
|
||||
fmt.Println("执行成功", string(output))
|
||||
}
|
||||
}
|
||||
func killPiServerExe(exeName string) {
|
||||
// 定义要关闭的程序的名称(或路径)
|
||||
if exeName == "" {
|
||||
exeName = "piVideo.exe"
|
||||
}
|
||||
// 使用exec.Command函数创建一个Cmd结构体,用于执行命令
|
||||
cmd := exec.Command("taskkill", "/f", "/im", exeName)
|
||||
cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow:true}
|
||||
// 将命令的输出和错误连接到当前进程的标准输出和标准错误
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
// 执行命令
|
||||
err := cmd.Run()
|
||||
|
||||
if err != nil {
|
||||
// 如果发生错误,输出错误信息
|
||||
fmt.Println("可能进程并没有开启/关闭视频监控进程Error:", err)
|
||||
}else{
|
||||
fmt.Println("关闭视频监控进程成功")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package initFunc
|
||||
|
||||
//影棚授权扫码
|
||||
func StudioAuthorization() error {
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package initFunc
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
)
|
||||
|
||||
// 请求api接口将,获取oem的配置信息
|
||||
func RequestOemSettingInfo(wailsConfig map[string]interface{}) map[string]interface{} {
|
||||
if wailsConfig == nil {
|
||||
return nil
|
||||
}
|
||||
mapData := gconv.Map(wailsConfig["ext_oem"])
|
||||
if mapData == nil {
|
||||
return nil
|
||||
}
|
||||
return mapData
|
||||
// url := "http://172.16.20.7:8199/api/oem/infoById?id="+gconv.String(mapData["id"])
|
||||
// //请求api接口))
|
||||
// resp, err := http.Get(url)
|
||||
// if err != nil {
|
||||
// return nil
|
||||
// }
|
||||
// defer resp.Body.Close()
|
||||
// //返回数据的转换
|
||||
// var data map[string]interface{}
|
||||
// decoder := json.NewDecoder(resp.Body)
|
||||
// err = decoder.Decode(&data)
|
||||
// if err != nil {
|
||||
// return nil
|
||||
// }
|
||||
// //提取data数据
|
||||
// settingData := gconv.Map(data["data"])
|
||||
// return settingData
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
package masterFunc
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/pkg/sftp"
|
||||
"golang.org/x/crypto/ssh"
|
||||
)
|
||||
|
||||
// DownLoadCameraJpgBySftp 使用 SFTP 连接下载远程文件
|
||||
func DownLoadMasterJpgBySftp(id int) error {
|
||||
ip := "192.168.88.2:22" // SFTP 服务器地址 (通常是 SSH 协议端口)
|
||||
username := "pi"
|
||||
password := "picc2008"
|
||||
|
||||
// 配置 SSH 客户端
|
||||
sshConfig := &ssh.ClientConfig{
|
||||
User: username,
|
||||
Auth: []ssh.AuthMethod{
|
||||
ssh.Password(password),
|
||||
},
|
||||
HostKeyCallback: ssh.InsecureIgnoreHostKey(), // 忽略主机密钥验证(不建议用于生产环境)
|
||||
}
|
||||
|
||||
// 连接到 SSH 服务器
|
||||
client, err := ssh.Dial("tcp", ip, sshConfig)
|
||||
if err != nil {
|
||||
fmt.Println("ssh.Dial error:", err)
|
||||
return err
|
||||
}
|
||||
defer client.Close()
|
||||
|
||||
// 创建 SFTP 客户端
|
||||
sftpClient, err := sftp.NewClient(client)
|
||||
if err != nil {
|
||||
fmt.Println("sftp.NewClient error:", err)
|
||||
return err
|
||||
}
|
||||
defer sftpClient.Close()
|
||||
|
||||
fmt.Println("id:", id)
|
||||
|
||||
// 设定远程目录路径
|
||||
remotePath := "/home/pi/photos/" + fmt.Sprint(id)
|
||||
// 本地目录路径
|
||||
localPathPhoto1 := "./downloads/" + fmt.Sprint(id) + "/photo1"
|
||||
localPathPhoto2 := "./downloads/" + fmt.Sprint(id) + "/photo2"
|
||||
|
||||
// 创建本地目录
|
||||
err = os.MkdirAll(localPathPhoto1, os.ModePerm)
|
||||
if err != nil {
|
||||
fmt.Println("os.MkdirAll error:", err)
|
||||
return err
|
||||
}
|
||||
|
||||
err = os.MkdirAll(localPathPhoto2, os.ModePerm)
|
||||
if err != nil {
|
||||
fmt.Println("os.MkdirAll error:", err)
|
||||
return err
|
||||
}
|
||||
|
||||
// 获取远程目录中的文件和子目录
|
||||
entries, err := sftpClient.ReadDir(remotePath)
|
||||
if err != nil {
|
||||
fmt.Println("sftpClient.ReadDir error:", err)
|
||||
return err
|
||||
}
|
||||
g.Dump("entries", entries, remotePath)
|
||||
|
||||
// 遍历远程目录中的所有文件
|
||||
for _, entry := range entries {
|
||||
localFilePath := ""
|
||||
|
||||
// 判断文件名称是否包含 _1.jpg
|
||||
if strings.Contains(entry.Name(), "_1.jpg") {
|
||||
// 生成本地文件路径
|
||||
localFilePath = filepath.Join(localPathPhoto1, entry.Name())
|
||||
}
|
||||
|
||||
// 判断文件名称是否包含 _8.jpg
|
||||
if strings.Contains(entry.Name(), "_8.jpg") {
|
||||
localFilePath = filepath.Join(localPathPhoto2, entry.Name())
|
||||
}
|
||||
|
||||
// 下载文件
|
||||
err := DownloadFile(sftpClient, remotePath+"/"+entry.Name(), localFilePath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// DownloadFile 下载单个文件
|
||||
func DownloadFile(client *sftp.Client, remoteFile, localFile string) error {
|
||||
// 创建本地文件
|
||||
file, err := os.Create(localFile)
|
||||
if err != nil {
|
||||
fmt.Println("os.Create error:", err)
|
||||
return err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
// 打开远程文件
|
||||
remoteFileHandle, err := client.Open(remoteFile)
|
||||
if err != nil {
|
||||
fmt.Println("client.Open error:", err)
|
||||
return err
|
||||
}
|
||||
defer remoteFileHandle.Close()
|
||||
|
||||
// 将文件内容从远程文件复制到本地文件
|
||||
_, err = io.Copy(file, remoteFileHandle)
|
||||
if err != nil {
|
||||
fmt.Println("io.Copy error:", err)
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Println("Downloaded file:", localFile)
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
package response
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
"github.com/gogf/gf/v2/os/gmutex"
|
||||
)
|
||||
|
||||
const (
|
||||
SuccessCode int = 1000
|
||||
ErrorCode int = -1
|
||||
)
|
||||
|
||||
type Response struct {
|
||||
// 代码
|
||||
Code int `json:"code" example:"200"`
|
||||
// 数据集
|
||||
Data interface{} `json:"data"`
|
||||
// 消息
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
var (
|
||||
response = new(Response)
|
||||
mu = gmutex.New()
|
||||
)
|
||||
|
||||
|
||||
func RJson(r *ghttp.Request, code int, message string, data ...interface{}) {
|
||||
response.RJson(r, code, message, data...)
|
||||
}
|
||||
|
||||
func SusJson(isExit bool, r *ghttp.Request, message string, data ...interface{}) {
|
||||
// message = lang.ToKey(r.GetCtx(), message)
|
||||
response.SusJson(isExit, r, message, data...)
|
||||
}
|
||||
|
||||
func FailJson(isExit bool, r *ghttp.Request, message string, data ...interface{}) {
|
||||
// message = lang.ToKey(r.GetCtx(), message)
|
||||
response.FailJson(isExit, r, message, data...)
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 返回JSON数据并退出当前HTTP执行函数。
|
||||
func (res *Response) JsonExit(r *ghttp.Request, code int, message string, data ...interface{}) {
|
||||
res.RJson(r, code, message, data...)
|
||||
r.Exit()
|
||||
}
|
||||
|
||||
|
||||
// 标准返回结果数据结构封装。
|
||||
// 返回固定数据结构的JSON:
|
||||
// code: 状态码(200:成功,302跳转,和http请求状态码一至);
|
||||
// message: 请求结果信息;
|
||||
// data: 请求结果,根据不同接口返回结果的数据结构不同;
|
||||
func (res *Response) RJson(r *ghttp.Request, code int, message string, data ...interface{}) {
|
||||
responseData := interface{}(nil)
|
||||
if len(data) > 0 {
|
||||
responseData = data[0]
|
||||
}
|
||||
response = &Response{
|
||||
Code: code,
|
||||
Message: message,
|
||||
Data: responseData,
|
||||
}
|
||||
r.SetParam("apiReturnRes", response)
|
||||
r.Response.WriteJson(response)
|
||||
}
|
||||
|
||||
// 成功返回JSON
|
||||
func (res *Response) SusJson(isExit bool, r *ghttp.Request, message string, data ...interface{}) {
|
||||
if isExit {
|
||||
res.JsonExit(r, SuccessCode, message, data...)
|
||||
}
|
||||
res.RJson(r, SuccessCode, message, data...)
|
||||
}
|
||||
|
||||
// 失败返回JSON
|
||||
func (res *Response) FailJson(isExit bool, r *ghttp.Request, message string, data ...interface{}) {
|
||||
if isExit {
|
||||
res.JsonExit(r, ErrorCode, message, data...)
|
||||
}
|
||||
res.RJson(r, ErrorCode, message, data...)
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user