|
|
- package common
-
- import (
- "container/list"
- "errors"
- "fmt"
- "github.com/lianggx6/goutf16"
- "io/ioutil"
- "leit.com/leit_seat_aps/mysmtp"
- "log"
- "math/rand"
- "os"
- "os/exec"
- "path/filepath"
- "reflect"
- "regexp"
- "sort"
- "strconv"
- "strings"
- "syscall"
- "time"
- "unsafe"
- )
-
- type HWND uintptr
-
- const (
- ERROR_FILE_NOT_FOUND = 2
- ERROR_PATH_NOT_FOUND = 3
- ERROR_BAD_FORMAT = 11
- )
-
- const (
- SE_ERR_ACCESSDENIED = 5
- SE_ERR_OOM = 8
- SE_ERR_DLLNOTFOUND = 32
- SE_ERR_SHARE = 26
- SE_ERR_ASSOCINCOMPLETE = 27
- SE_ERR_DDETIMEOUT = 28
- SE_ERR_DDEFAIL = 29
- SE_ERR_DDEBUSY = 30
- SE_ERR_NOASSOC = 31
- )
-
- var (
- modshell32 = syscall.NewLazyDLL("shell32.dll")
- procShellExecute = modshell32.NewProc("ShellExecuteW")
- )
-
- // 将结构体内所有string类型字段去除首位空格
- // sp为结构体指针, s为结构体值
- func TrimStruct(sp interface{}, s interface{}) {
- // 判断类型是否为struct
- av := reflect.ValueOf(sp)
- avv := reflect.ValueOf(s)
- at := reflect.TypeOf(s)
- // 简单判断下
- if at.Kind() != reflect.Struct {
- log.Printf("s must be a struct")
- return
- }
- av = reflect.ValueOf(av.Interface())
- for i := 0; i < avv.NumField(); i++ {
- if at.Field(i).Type.Name() == "string" {
- f := av.Elem().Field(i)
- val := strings.TrimSpace(avv.Field(i).String())
- f.Set(reflect.ValueOf(val))
- }
-
- }
-
- return
- }
-
- // 将给定的整数值转换成给定长度的字符串,不足长度的在前面补足0
- func ConvInt2FormatString(input, ilen int) (retstring string) {
- var igap int
-
- if len(string(input)) >= ilen {
- retstring = string(input)
- } else {
- igap = ilen - len(strconv.Itoa(input))
- if igap > 0 {
- retstring = strings.Repeat("0", igap) + strconv.Itoa(input)
- } else {
- retstring = strconv.Itoa(input)
- }
-
- }
- return
- }
-
- // 基于文件信息中的修改时间按先后排序
- func SortByTime(pl []os.FileInfo) []os.FileInfo {
- sort.Slice(pl, func(i, j int) bool {
- flag := false
- if pl[i].ModTime().Before(pl[j].ModTime()) {
- flag = true
- } else if pl[i].ModTime().Equal(pl[j].ModTime()) {
- if pl[i].Name() < pl[j].Name() {
- flag = true
- }
- }
- return flag
- })
- return pl
- }
-
- // 将某目录下的文件按照修改时间先后依次列出
- func listAll(path string, curHier int) {
- readerInfos, err := ioutil.ReadDir(path)
- if err != nil {
- fmt.Println(err)
- return
- }
- readerInfos1 := SortByTime(readerInfos)
- for _, info := range readerInfos1 {
- if info.IsDir() {
- for tmpheir := curHier; tmpheir > 0; tmpheir-- {
- fmt.Printf("|\t")
- }
- fmt.Println(info.Name(), "\\")
- listAll(path+"\\"+info.Name(), curHier+1)
- } else {
- for tmpheir := curHier; tmpheir > 0; tmpheir-- {
- fmt.Printf("|\t")
- }
- fmt.Println(info.Name(), " ", info.ModTime())
- }
- }
- }
-
- func RemoveListAllBeforeItem(lst *list.List, delNode *list.Element, delItem bool) (err error) {
- var (
- e, el, prev, p *list.Element
- )
- // 删除litem之前所有的节点
- for e = lst.Front(); e != nil; e = e.Next() {
- if delNode == e {
- prev = e.Prev()
- if delItem {
- lst.Remove(e)
- }
- for el = prev; el != nil; el = p {
- p = el.Prev()
- lst.Remove(el)
- }
- break
- }
- }
- return
- }
-
- func RemoveListAllAfterItem(lst *list.List, delNode *list.Element, delItem bool) (err error) {
- var (
- e, el, next, n *list.Element
- )
- // 删除litem之前所有的节点
- for e = lst.Front(); e != nil; e = e.Next() {
- if delNode == e {
- next = e.Next()
- if delItem {
- lst.Remove(e)
- }
- for el = next; el != nil; el = n {
- n = el.Next()
- lst.Remove(el)
- }
- break
- }
- }
- return
- }
-
- func StructToMap(data []interface{}) map[string]string {
- keyMap := make(map[string]string)
- for _, v := range data {
- value := reflect.ValueOf(v)
- typeInfo := reflect.TypeOf(v)
- kd := value.Kind() //获取到a对应的类别
- if kd != reflect.Struct {
- continue
- }
- count := value.NumField()
- for i := 0; i < count; i++ {
- val := value.Field(i).Interface()
- key := typeInfo.Field(i).Tag.Get("json")
- //fmt.Println(key,":",val)
- keyMap[key] = ValueToString(val, "")
- }
- }
- return keyMap
- }
-
- func GetCurrentDir() string {
- file, err := exec.LookPath(os.Args[0])
- if err != nil {
- c, _ := os.Getwd()
- return c
- }
- return strings.Replace(filepath.Dir(file), "\\", "/", -1)
- }
-
- func GetAbsolutePath(path string) string {
- p := GetAbsolutePathNoFilter(path)
- p = strings.Replace(p, "\\", "/", -1) // 统一使用/
- for {
- a := strings.Index(p, "//")
- if a == -1 {
- break
- }
- p = strings.Replace(p, "//", "/", -1)
- }
- return p
- }
-
- func GetAbsolutePathNoFilter(path string) string {
- if strings.Index(path, "file:/") == 0 {
- path = path[5:]
- mpos := strings.Index(path, ":")
- if mpos >= 0 {
- //去除开头斜杠, 如: ///C:/test
- for {
- if len(path) > 0 && (path[0] == '/' || path[0] == '\\') {
- path = path[1:]
- } else {
- break
- }
- }
- return (path)
- }
-
- for {
- if len(path) > 1 && (path[0] == '/' || path[0] == '\\') && (path[1] == '/' || path[1] == '\\') {
- path = path[1:]
- } else {
- break
- }
- }
- path, _ = filepath.Abs(path)
- return (path)
- } else if strings.Index(path, "./") == 0 || strings.Index(path, ".\\") == 0 {
- r, _ := filepath.Abs(GetCurrentDir() + path[1:])
- return (r)
- }
- r, _ := filepath.Abs(path)
- return (r)
- }
-
- func GetDir(path string) string {
- if strings.Index(path, "./") == 0 || strings.Index(path, ".\\") == 0 {
- return filepath.ToSlash(filepath.Dir(GetCurrentDir() + path[1:]))
- }
- return filepath.ToSlash(filepath.Dir(path))
- }
-
- func EnsureDir(dir string) string {
- fullDir := GetAbsolutePath(dir)
- if IsExists(fullDir) {
- return fullDir
- }
-
- os.MkdirAll(fullDir, 777)
- return fullDir
- }
-
- func EnsureFilePath(filePath string) string {
- filePath = GetAbsolutePath(filePath)
- EnsureDir(GetDir(filePath))
- return filePath
- }
-
- func IsExists(path string) bool {
- if path == "" {
- return false
- }
- _, err := os.Stat(path)
- if err != nil && os.IsNotExist(err) {
- return false
- }
- return true
- }
-
- func Max(vals ...int) int {
- var max int
- for _, val := range vals {
- if val > max {
- max = val
- }
- }
- return max
- }
-
- func Min(vals ...int) int {
- var min int
- for _, val := range vals {
- if min == 0 || val <= min {
- min = val
- }
- }
- return min
- }
-
- func UintSliceTo256Uint(us []uint16) (res [256]uint16) {
- var i int
-
- for i = 0; i < len(us); i++ {
- res[i] = us[i]
- }
- return res
- }
-
- // 设置默认打印机
- func SetDefaultPrinter(printerName string, orientation int) error {
- var (
- dll = syscall.MustLoadDLL("winspool.drv")
- setDefaultPrinter = dll.MustFindProc("SetDefaultPrinterW")
- p []uint16
- pn [256]uint16
- )
-
- p = goutf16.EncodeStringToUTF16(printerName)
- pn = UintSliceTo256Uint(p)
- ret, _, msg := setDefaultPrinter.Call(uintptr(unsafe.Pointer(&pn)))
- if ret == 0 {
- return msg
- }
-
- return nil
- }
-
- func ShellExecute(hwnd HWND, lpOperation, lpFile, lpParameters, lpDirectory string, nShowCmd int) error {
- var op, param, directory uintptr
- if len(lpOperation) != 0 {
- op = uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpOperation)))
- }
- if len(lpParameters) != 0 {
- param = uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpParameters)))
- }
- if len(lpDirectory) != 0 {
- directory = uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpDirectory)))
- }
-
- ret, _, _ := procShellExecute.Call(
- uintptr(hwnd),
- op,
- uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpFile))),
- param,
- directory,
- uintptr(nShowCmd))
-
- errorMsg := ""
- if ret != 0 && ret <= 32 {
- switch int(ret) {
- case ERROR_FILE_NOT_FOUND:
- errorMsg = "The specified file was not found."
- case ERROR_PATH_NOT_FOUND:
- errorMsg = "The specified path was not found."
- case ERROR_BAD_FORMAT:
- errorMsg = "The .exe file is invalid (non-Win32 .exe or error in .exe image)."
- case SE_ERR_ACCESSDENIED:
- errorMsg = "The operating system denied access to the specified file."
- case SE_ERR_ASSOCINCOMPLETE:
- errorMsg = "The file name association is incomplete or invalid."
- case SE_ERR_DDEBUSY:
- errorMsg = "The DDE transaction could not be completed because other DDE transactions were being processed."
- case SE_ERR_DDEFAIL:
- errorMsg = "The DDE transaction failed."
- case SE_ERR_DDETIMEOUT:
- errorMsg = "The DDE transaction could not be completed because the request timed out."
- case SE_ERR_DLLNOTFOUND:
- errorMsg = "The specified DLL was not found."
- case SE_ERR_NOASSOC:
- errorMsg = "There is no application associated with the given file name extension. This error will also be returned if you attempt to print a file that is not printable."
- case SE_ERR_OOM:
- errorMsg = "There was not enough memory to complete the operation."
- case SE_ERR_SHARE:
- errorMsg = "A sharing violation occurred."
- default:
- errorMsg = fmt.Sprintf("Unknown error occurred with error code %v", ret)
- }
- } else {
- return nil
- }
-
- return errors.New(errorMsg)
- }
-
- // 将Excel的字母定位转换成数字定位值
- func GetExcelCellIntPos(pos string) (row, col int, err error) {
- var (
- chareg, numreg *regexp.Regexp
- cha, num [][]string
- i int
- uc []rune
- rowstr string
- )
-
- chareg = regexp.MustCompile("[a-zA-Z]")
- numreg = regexp.MustCompile("[0-9]")
- cha = chareg.FindAllStringSubmatch(pos, -1)
- num = numreg.FindAllStringSubmatch(pos, -1)
- // 获取字符的列值
- col = 0
- for i = 0; i < len(cha); i++ {
- uc = []rune(strings.ToUpper(cha[i][0]))
- col = col + i*26 + (int(uc[0]) - 65)
- }
-
- // 获取行值
- for i = 0; i < len(num); i++ {
- rowstr = rowstr + num[i][0]
- }
- row, _ = strconv.Atoi(rowstr)
-
- return row - 1, col, nil
- }
-
- // 将Excel的字母定位转换成数字定位值
- func AddExcelColLen(colname string, ilen int) (retcol string) {
- var (
- chareg *regexp.Regexp
- cha [][]string
- i, col, iloop, imod int
- uc []rune
- )
-
- chareg = regexp.MustCompile("[a-zA-Z]")
- cha = chareg.FindAllStringSubmatch(colname, -1)
- // 获取字符的列值
- col = 0
- for i = 0; i < len(cha); i++ {
- uc = []rune(strings.ToUpper(cha[i][0]))
- col = col + i*26 + (int(uc[0]) - 65)
- }
-
- col = col + ilen
-
- // 将增加后的数值再转换成字符
- iloop = col / 26
- imod = col % 26
- retcol = strings.Repeat("A", iloop)
- retcol = retcol + string('A'+imod)
-
- return retcol
- }
-
- //windows环境下获取绝对路径
- func GetCurrentPath(dir string) (string, error) {
- file, err := exec.LookPath(os.Args[0])
- if err != nil {
- return "", err
- }
- path, err := filepath.Abs(file)
- if err != nil {
- return "", err
- }
- i := strings.LastIndex(path, "/")
- if i < 0 {
- i = strings.LastIndex(path, "\\")
- }
- if i < 0 {
- return "", errors.New(`error: Can't find "/" or "\".`)
- }
- pathdir := string(path[0 : i+1])
- if len(dir) > 0 {
- dir = strings.Replace(dir, "/", "\\", -1)
- return filepath.Join(pathdir, dir), nil
- }
- return string(path[0 : i+1]), nil
- }
-
- func CreateCaptcha() string {
- return fmt.Sprintf("%02v", rand.New(rand.NewSource(time.Now().UnixNano())).Int31n(100))
- }
- func CreateCaptchaFive() string {
- return fmt.Sprintf("%05v", rand.New(rand.NewSource(time.Now().UnixNano())).Int31n(100000))
- }
-
- func CreateCaptchaFour() string {
- return fmt.Sprintf("%04v", rand.New(rand.NewSource(time.Now().UnixNano())).Int31n(10000))
- }
-
- /*!
- username 发送者邮件
- password 授权码
- host 主机地址 smtp.qq.com:587 或 smtp.qq.com:25
- to 接收邮箱 多个接收邮箱使用 ; 隔开
- name 发送人名称
- subject 发送主题
- body 发送内容
- mailType 发送邮件内容类型
- */
- func SendMail(username, password, host, to, name, subject, body, mailType string) error {
- hp := strings.Split(host, ":")
- auth := mysmtp.LoginAuth(username, password, hp[0])
- var contentType string
- if mailType == "html" {
- contentType = "Content-Type: text/" + mailType + "; charset=UTF-8"
- } else {
- contentType = "Content-Type: text/plain" + "; charset=UTF-8"
- }
- msg := []byte("To: " + to + "\r\nFrom: " + name + "<" + username + ">\r\nSubject: " + subject + "\r\n" + contentType + "\r\n\r\n" + body)
- sendTo := strings.Split(to, ";")
- err := mysmtp.SendMail(host, auth, username, sendTo, msg)
- return err
- }
|