Skip to content

Commit

Permalink
init
Browse files Browse the repository at this point in the history
  • Loading branch information
ftlynx committed Oct 29, 2020
0 parents commit af64e66
Show file tree
Hide file tree
Showing 5 changed files with 308 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
go.sum
sqlexcel
main
go.sum
config.ini
85 changes: 85 additions & 0 deletions build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
#!/usr/bin/env bash


CURR_PATH=$(cd `dirname $0`;pwd)
BNARY_NAME=`cat $CURR_PATH/go.mod | grep ^module |awk '{print $2}'`

function _info(){
local msg=$1
local now=`date '+%Y-%m-%d %H:%M:%S'`
echo "\033[1;46;30m[INFO]\033[0m $now $msg"
}

function _version(){
local msg=$1
local now=`date '+%Y-%m-%d %H:%M:%S'`
echo "\033[1;46;30m[INFO]\033[0m $now $msg"
}

function get_tag () {
local tag=$(git describe --tags 2>>/dev/null)
if [ -n "$tag" ];then
tag=$(echo $tag | cut -d '-' -f 1)
else
tag='unknown'
fi
echo $tag
}

function get_branch () {
local branch=$(git rev-parse --abbrev-ref HEAD)
if [ -z "$branch" ]; then
branch='unknown'
fi
echo $branch
}

function get_commit () {
local commit=$(git rev-parse HEAD)
if [ -z "$commit" ]; then
commit='unknown'
fi
echo $commit
}


function main() {
local platform=$1
local bin_name=$2
local main_file=$3
local is_docker=$4

_info "开始构建 [$BNARY_NAME] ..."

TAG=$(get_tag)
BRANCH=$(get_branch)
COMMIT=$(get_commit)
DATE=$(date '+%Y-%m-%d %H:%M:%S')
version=$(go version | grep -o 'go[0-9].[0-9].*')

Path="$BNARY_NAME/version"
_version "构建版本的时间(Build Time): $DATE"
_version "当前构建的版本(Git Tag ): $TAG"
_version "当前构建的分支(Git Branch): $BRANCH"
_version "当前构建的提交(Git Commit): $COMMIT"

case $platform in
"linux")
_info "开始构建Linux平台版本 ..."
GOOS=linux GOARCH=amd64 \
CGO_ENABLED=0 go build -a -o $bin_name -ldflags "-X '$Path.GIT_TAG=$TAG' -X '$Path.GIT_BRANCH=$BRANCH' -X '$Path.GIT_COMMIT=$COMMIT' -X '$Path.BUILD_TIME=$DATE' -X '$Path.GO_VERSION=$version'" $main_file
;;
*)
_info "开始本地构建 ..."
CGO_ENABLED=0 go build -a -o $bin_name -ldflags "-X '$Path.GIT_TAG=$TAG' -X '$Path.GIT_BRANCH=$BRANCH' -X '$Path.GIT_COMMIT=$COMMIT' -X '$Path.BUILD_TIME=$DATE' -X '$Path.GO_VERSION=$version'" $main_file
;;
esac
if [ $? -ne 0 ];then
_info "构建失败"
exit 1
fi
_info "程序构建完成: $bin_name"
}

main ${1:-local} $BNARY_NAME $CURR_PATH/main.go

12 changes: 12 additions & 0 deletions config.ini.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[email]
smtp = "smtp.exmail.qq.com"
user = "[email protected]"
passwd = "xx"
port = 587

[data]
datasource = "root:root@tcp(127.0.0.1:3306)/xx?parseTime=true&loc=Local"
sql = "select a.id ,a.phone_number,a.username ,a.register_type,a.register_channel,a.register_time,hour(a.register_time) as hour ,case when b.receiver_id is null then 0 else 1 end as spread from uc.user_account a left join marketing.spread_record b on a.id=b.receiver_id where date(register_time)=curdate() order by register_time;"
sql = "select * from user"
name = "用户数据"
mailto = "[email protected];[email protected]"
12 changes: 12 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
module sqlexcel

go 1.13

require (
github.com/BurntSushi/toml v0.3.1
github.com/ftlynx/tsx v0.0.0-20200407075516-7380aaf715d7
github.com/go-sql-driver/mysql v1.5.0
github.com/tealeg/xlsx v1.0.5
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
)
194 changes: 194 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
package main

import (
"crypto/tls"
"database/sql"
"fmt"
"github.com/BurntSushi/toml"
"github.com/ftlynx/tsx/mysqlx"
_ "github.com/go-sql-driver/mysql"
"github.com/tealeg/xlsx"
"gopkg.in/gomail.v2"
"io/ioutil"
"mime"
"os"
"path/filepath"
"strings"
"time"
)

type Config struct {
Data *DataConfig `toml:"data"`
EMail *EmailConf `toml:"email"`
}

type DataConfig struct {
Datasource string `toml:"datasource"`
Sql string `toml:"sql"`
Name string `toml:"name"`
Mailto string `toml:"mailto"`
}

type EmailConf struct {
Smtp string `toml:"smtp"`
Port int `toml:"port"`
User string `toml:"user"`
Passwd string `toml:"passwd"`
}

func parseConfig(configpath string) (*Config, error) {
cfg := new(Config)

configPath, err := filepath.Abs(configpath)
if err != nil {
return cfg, fmt.Errorf("get config file absolute path failed, %s", err.Error())
}

file, err := os.Open(configPath)
defer file.Close()
if err != nil {
return cfg, fmt.Errorf("open config file error, %s", err.Error())
}

fd, err := ioutil.ReadAll(file)
if err != nil {
return cfg, fmt.Errorf("read config file error, %s", err.Error())
}

cfg.Data = new(DataConfig)
cfg.EMail = new(EmailConf)

if err := toml.Unmarshal(fd, cfg); err != nil {
return cfg, fmt.Errorf("load config file error, %s", err.Error())
}

return cfg, nil
}

type myDB struct {
DB *sql.DB
}

func (d *myDB) QueryData(sql string) ([]string, []map[string]interface{}, error) {
result := make([]map[string]interface{}, 0)
rows, err := d.DB.Query(sql)
if err != nil {
return make([]string, 0), result, err
}
columns, err := rows.Columns()
if err != nil {
return columns, result, err
}

cache := make([]interface{}, len(columns))
for index, _ := range cache {
var a interface{}
cache[index] = &a
}

for rows.Next() {
if err := rows.Scan(cache...); err != nil {
return columns, result, err
}
item := make(map[string]interface{})
for i, data := range cache {
item[columns[i]] = *data.(*interface{})
}
result = append(result, item)
}
return columns, result, err
}

func CreateExcel(columns []string, data []map[string]interface{}, filename string) error {
file := xlsx.NewFile()
sheet, err := file.AddSheet("sheet1")
if err != nil {
return err
}
row := sheet.AddRow()
row.SetHeightCM(1)
for _, v := range columns {
cell := row.AddCell()
cell.Value = v
}
for _, v1 := range data {
row := sheet.AddRow()
row.SetHeightCM(1)
for _, column := range columns {
cell := row.AddCell()
cell.Value = fmt.Sprintf("%s", v1[column])
}
}
return file.Save(filename)
}

type connMail struct {
User string `json:"user"`
Passwd string `json:"passwd"`
Smtp string `json:"smtp"`
Port int `json:"port"`
}

func (m *connMail) Send(to string, cc string, subject string, attaFile string) error {
d := gomail.NewDialer(m.Smtp, m.Port, m.User, m.Passwd)
d.TLSConfig = &tls.Config{InsecureSkipVerify: true}

//设置消息
msg := gomail.NewMessage()
msg.SetHeader("From", msg.FormatAddress(m.User, "系统邮件"))
msg.SetHeader("To", strings.Split(to, ";")...)
msg.SetHeader("CC", cc)
msg.SetHeader("Subject", subject)
msg.SetBody("text/plain", "hi, all:\r\n\r\n 相关数据见附件")

if attaFile != "" {
names := strings.Split(attaFile, "/")
name := names[len(names)-1]
msg.Attach(attaFile,
gomail.Rename(name),
gomail.SetHeader(map[string][]string{
"Content-Disposition": []string{
fmt.Sprintf(`attachment; filename="%s"`, mime.QEncoding.Encode("UTF-8", name)),
},
},
))
}

return d.DialAndSend(msg)
}

func main() {
if len(os.Args) < 2 {
panic(fmt.Sprintf("usage %s config.ini", os.Args[0]))
}
cfg, err := parseConfig(os.Args[1])
if err != nil {
panic(err)
}
maxConnNum := 10
maxIdleConn := 5
maxLifeTime := time.Duration(int64(86400))
db, err := mysqlx.SqlDB(cfg.Data.Datasource, maxConnNum, maxIdleConn, maxLifeTime)
if err != nil {
panic(err)
}
email := connMail{
User: cfg.EMail.User,
Passwd: cfg.EMail.Passwd,
Smtp: cfg.EMail.Smtp,
Port: cfg.EMail.Port,
}
sqldata := myDB{DB: db}
columns, result, err := sqldata.QueryData(cfg.Data.Sql)
if err != nil {
panic(err)
}
filename := fmt.Sprintf("/tmp/%s.xlsx", cfg.Data.Name)
if err := CreateExcel(columns, result, filename); err != nil {
panic(err)
}
if err := email.Send(cfg.Data.Mailto, "", cfg.Data.Name, filename); err != nil {
panic(err)
}
return
}

0 comments on commit af64e66

Please sign in to comment.